Upload receipts to an expense
Needs a token with the write:expenses scope. Authentication
Try in Playground sends a real request to app.helvetly.com with a token you paste. It stays in this browser tab only (session storage) and goes to no one else.
Attaches 1 to 10 receipts (multipart field files[], each up to 20 MB; PDF, JPEG, PNG, WebP or HEIC/HEIF, checked by their bytes) to a draft or booked expense; a voided expense answers 409 invalid_state. Receipts added to a booked expense are retention-locked. All files are checked before any is stored: 422 validation_failed (fields.files) for a wrong type or size, 413 payload_too_large. Duplicate check: the SHA-256 of each file's actual bytes is compared inside the workspace with live Documents, client files and receipts on non-deleted expenses; identical bytes answer 409 duplicate_file whatever the name, with details {existing_id, existing_name, resource: document or receipt, expense_id?} (details are left out when the caller may not read that resource). The same bytes twice in one request answer 409 duplicate_file with details {existing_name, resource: upload}, before anything is stored, and nothing from the batch is kept. Trashed documents and deleted expenses do not block. Another workspace never matches. Retrying a request that succeeded answers 409 duplicate_file, so it is safe.
bearerAuthAuthorizationBearer <token>A personal API token, hvt_…, with scopes such as read:* or write:invoices
id*stringThe expense's id.
multipart/form-data- body
files[]*array<>1 to 10 receipts, each up to 20 MB: PDF, JPEG, PNG, WebP or HEIC/HEIF (decided by the file's bytes, not its name).
items <= 10Created
application/json- response
data*array<>curl -X POST 'https://app.helvetly.com/api/v1/expenses/string/receipts' \ -F 'files[]=[ "string"]'{ "data": [ { "id": "string", "name": "string", "size": 0, "content_type": "string", "created_at": "2019-08-24T14:15:22Z", "uploaded_by": { "id": "string", "name": "string" } } ]}