Create a file for direct upload
const url = 'https://api.elephants.inc/api/v1/organizations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/files';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"byte_size":1,"content_type":"example","filename":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.elephants.inc/api/v1/organizations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/files \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "byte_size": 1, "content_type": "example", "filename": "example" }'Create a file for the organization and return a URL to upload its bytes to.
Upload the file with a single HTTP PUT to upload_url, sending the raw
bytes as the body and the returned headers exactly: Content-Type as
given and Content-Length equal to byte_size. No form encoding and no
authorization header. The URL is on this API’s own host, bound to that
size and type, and expires at expires_at; a client behind an outbound
allowlist needs that host allowed before the PUT will connect. This operation is not replayed under an idempotency
key: a retried request creates a new file with its own URL.
Once the PUT succeeds, pass the file’s id as file_id to
attachExpenseReceipt or createExpense to make it a receipt, or to
createBill to read it as a supplier invoice. Until then the file
exists but has no content, and those operations answer
file_not_uploaded. Accepted types: PDF, images (JPEG, PNG, GIF, WebP, HEIC, TIFF, BMP), and Word documents (DOC, DOCX);
at most 100 MB. The invoice reader
behind createBill takes only PDF, JPEG, PNG, GIF and WebP; a bill
made from any other type is refused with invalid_content_type.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The organization’s ID
Request Bodyrequired
Section titled “Request Bodyrequired”The file to create
object
Exact size of the file in bytes; the upload must match it
MIME type of the file, e.g. ‘application/pdf’ or ‘image/jpeg’
Filename with its extension, e.g. ‘invoice.pdf’
Example generated
{ "byte_size": 1, "content_type": "example", "filename": "example"}Responses
Section titled “Responses”The file and where to upload its bytes
object
Headers the PUT must send exactly
object
The file’s id
Signed URL to PUT the bytes to
Example
{ "method": "PUT"}Invalid request parameters or body
Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.
object
object
Structured error details (e.g. validation errors), when present
Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.
Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.
object
Method used to deliver this challenge
Challenge expiry
Sudo session ID returned to completeStepUp
3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.
Available verification methods
The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.
object
object
Machine-readable error code from a stable vocabulary (open enum — handle unknown values)
Example generated
{ "error": { "details": "example", "message": "example", "request_id": "example", "step_up": { "delivery": "example", "expires_at": "2026-04-15T12:00:00Z", "id": "example", "match_code": "example", "methods": [ "example" ], "step_up_authentication_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "webauthn": { "allow_credentials": [ { "id": "example", "transports": [ "example" ], "type": "example" } ], "challenge": "example", "challenge_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "rp_id": "example", "timeout": 1, "user_verification": "example" } }, "type": "example" }}Missing, invalid, or expired bearer token
Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.
object
object
Structured error details (e.g. validation errors), when present
Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.
Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.
object
Method used to deliver this challenge
Challenge expiry
Sudo session ID returned to completeStepUp
3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.
Available verification methods
The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.
object
object
Machine-readable error code from a stable vocabulary (open enum — handle unknown values)
Example generated
{ "error": { "details": "example", "message": "example", "request_id": "example", "step_up": { "delivery": "example", "expires_at": "2026-04-15T12:00:00Z", "id": "example", "match_code": "example", "methods": [ "example" ], "step_up_authentication_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "webauthn": { "allow_credentials": [ { "id": "example", "transports": [ "example" ], "type": "example" } ], "challenge": "example", "challenge_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "rp_id": "example", "timeout": 1, "user_verification": "example" } }, "type": "example" }}Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.
Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.
object
object
Structured error details (e.g. validation errors), when present
Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.
Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.
object
Method used to deliver this challenge
Challenge expiry
Sudo session ID returned to completeStepUp
3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.
Available verification methods
The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.
object
object
Machine-readable error code from a stable vocabulary (open enum — handle unknown values)
Example generated
{ "error": { "details": "example", "message": "example", "request_id": "example", "step_up": { "delivery": "example", "expires_at": "2026-04-15T12:00:00Z", "id": "example", "match_code": "example", "methods": [ "example" ], "step_up_authentication_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "webauthn": { "allow_credentials": [ { "id": "example", "transports": [ "example" ], "type": "example" } ], "challenge": "example", "challenge_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "rp_id": "example", "timeout": 1, "user_verification": "example" } }, "type": "example" }}Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.
Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.
object
object
Structured error details (e.g. validation errors), when present
Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.
Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.
object
Method used to deliver this challenge
Challenge expiry
Sudo session ID returned to completeStepUp
3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.
Available verification methods
The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.
object
object
Machine-readable error code from a stable vocabulary (open enum — handle unknown values)
Example generated
{ "error": { "details": "example", "message": "example", "request_id": "example", "step_up": { "delivery": "example", "expires_at": "2026-04-15T12:00:00Z", "id": "example", "match_code": "example", "methods": [ "example" ], "step_up_authentication_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "webauthn": { "allow_credentials": [ { "id": "example", "transports": [ "example" ], "type": "example" } ], "challenge": "example", "challenge_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "rp_id": "example", "timeout": 1, "user_verification": "example" } }, "type": "example" }}Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.
Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.
object
object
Structured error details (e.g. validation errors), when present
Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.
Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.
object
Method used to deliver this challenge
Challenge expiry
Sudo session ID returned to completeStepUp
3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.
Available verification methods
The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.
object
object
Machine-readable error code from a stable vocabulary (open enum — handle unknown values)
Example generated
{ "error": { "details": "example", "message": "example", "request_id": "example", "step_up": { "delivery": "example", "expires_at": "2026-04-15T12:00:00Z", "id": "example", "match_code": "example", "methods": [ "example" ], "step_up_authentication_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "webauthn": { "allow_credentials": [ { "id": "example", "transports": [ "example" ], "type": "example" } ], "challenge": "example", "challenge_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "rp_id": "example", "timeout": 1, "user_verification": "example" } }, "type": "example" }}Too many requests
object
object
Structured error details (e.g. validation errors), when present
Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.
Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.
object
Method used to deliver this challenge
Challenge expiry
Sudo session ID returned to completeStepUp
3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.
Available verification methods
The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.
object
object
Machine-readable error code from a stable vocabulary (open enum — handle unknown values)
object
Example
{ "error": { "type": "rate_limited" }}Headers
Section titled “Headers”How long to wait before retrying, expressed as delay seconds or an HTTP date
Unexpected server error
Error response. error.type is the machine-readable code — branch on it, never on error.message or the HTTP status. error.message is display-grade prose safe to render to a user; when a failure has no specific copy it falls back to a generic sentence, so it never carries a machine code. Unrecognised failures collapse to the generic unprocessable_entity code, so treat type as an open enum: match the codes you handle and fall through to a default branch for the rest.
object
object
Structured error details (e.g. validation errors), when present
Display-grade message, safe to render verbatim. Never a machine code — do not branch on it.
Correlation ID for this request (also in the x-request-id response header). Include it when contacting support.
object
Method used to deliver this challenge
Challenge expiry
Sudo session ID returned to completeStepUp
3-digit number-matching code. This response is the ORIGINATING surface: display the code; a user approving from the Ele mobile app is asked to enter it. Null only for challenges minted before match codes existed.
Available verification methods
The step-up authentication this challenge was minted from — a DIFFERENT id from id (the sudo session). completeStepUp takes id as sudo_session_id; requestStepUpFallback takes this one.
object
object
Machine-readable error code from a stable vocabulary (open enum — handle unknown values)
Example generated
{ "error": { "details": "example", "message": "example", "request_id": "example", "step_up": { "delivery": "example", "expires_at": "2026-04-15T12:00:00Z", "id": "example", "match_code": "example", "methods": [ "example" ], "step_up_authentication_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "webauthn": { "allow_credentials": [ { "id": "example", "transports": [ "example" ], "type": "example" } ], "challenge": "example", "challenge_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "rp_id": "example", "timeout": 1, "user_verification": "example" } }, "type": "example" }}