Faxes API reference

Updated

8 operations of the Fax for Agents API, from the OpenAPI document version 1.20.0, snapshot of 2026-11-13. The base URL is https://api.faxforagents.com/v1. This is one group of the full reference.

  • POST /v1/faxes sends a quoted fax, and its only required field is quote_id.
  • Cancelling a fax is best effort once sending has started.
  • The receipt of a fax is served as JSON and as the same facts in a one-page PDF.

Operations

How is a fax sent?

POST /v1/faxes with a quote_id. The quote already holds the document, the destination, the sender and the price, so the send repeats none of them. Two optional fields ride along. approval_id is an approved request bound to this quote, and this one send consumes it. client_reference is your own label for the job.

The answer is the job, in state queued. Sending is asynchronous. The call returns as soon as the job is written, and the outcome arrives later on the job and as an event.

Why send an Idempotency-Key?

The summary of the operation recommends the Idempotency-Key header. A send that times out leaves you not knowing whether a job exists. Repeat the call with the same key and the answer is the same job, not a second fax. The list also filters by idempotency_key, so a client can look a job up by the key it used.

Which states can a job be in?

Six: queued, active, delivered, partial, failed and unknown. GET /v1/faxes/{fax_id} returns the state with pages_sent, attempt_count, captured_micro and, when the fax failed, a failure_code. A delivered job carries evidence, the carrier's report of the delivery.

delivered is said only with that evidence. unknown means no outcome was reported in time. A job in unknown or partial is never sent again by the service on its own. The errors page explains each state and what it means for the money held.

How do I follow one fax in detail?

Three reads. GET /v1/faxes/{fax_id}/attempts is the attempt history, one row per try. GET /v1/faxes/{fax_id}/events is the ordered list of events of this fax. GET /v1/faxes lists jobs newest first and filters by state.

For every fax at once, use webhooks, or walk the log in the events group.

Can a fax be cancelled?

POST /v1/faxes/{fax_id}/cancel cancels if that is still possible. A queued job is cancelled at once. Once sending has started the cancel is best effort, as the summary says: the carrier may already have the pages. A fax that has ended answers 409 not_cancelable. The call needs fax:cancel.

What is the receipt?

GET /v1/faxes/{fax_id}/receipt returns the delivery evidence as JSON once the fax has ended. It has the state, the numbers, pages_sent, the amount captured, the hash of the document and of the transmitted copy, the attempts and a note. GET /v1/faxes/{fax_id}/receipt.pdf is the same receipt as a one-page PDF, for a file or a person.

The receipt is the carrier's report, not legal proof of acceptance, and the PDF says so.

What can refuse a send?

A send answers 402 when the wallet cannot cover the quote. It answers 403 when a live API key has neither an approval nor a policy that allows the send. It answers 409 with quote_expired or quote_consumed when the quote can no longer be sent, and with an approval code when the approval does not match. A refused send creates no job.

Which scopes does the group use?

fax:send for the send, fax:cancel for the cancel and fax:read for every read, the receipt included. The default API key carries all three. A read-only API key keeps fax:read and drops the other two.

Each operation in detail

GET /v1/faxes

List fax jobs, newest first

Credential: an API key or a signed-in session. Scope: fax:read.

Parameters

GET /v1/faxes parameters
NameInTypeRequiredNotes
statequerystring or nullno
idempotency_keyquerystring or nullnoFind the send job using its Idempotency-Key. This lookup requires the stored replay record. An empty result does not prove no fax was sent.
cursorquerystring or nullno
limitqueryintegerno Default 50.

Responses

GET /v1/faxes responses
StatusMeaning
200Successful Response
401No credential, or one that was not accepted: invalid_token for an API key, unauthenticated where a signed-in session is needed. error.details.reason says why a key was refused.
403The credential is valid and is not allowed to do this. scope_missing puts the scope in error.details.scope. Other codes are agent_forbidden and approval_required. A session can also meet csrf_invalid and reauth_required.
422A field failed validation: invalid_request, with one entry per field in error.details, or a code that names the rule.
429rate_limited. Retry-After and the RateLimit-* headers say when to try again.

Response fields

GET /v1/faxes response fields
FieldTypeRequiredDescription
itemsarray of object FaxJobyes
next_cursorstring or nullno

Example

curl https://api.faxforagents.com/v1/faxes \
  -H "Authorization: Bearer ffa_test_..."

POST /v1/faxes

Send a quoted fax (Idempotency-Key recommended)

Credential: an API key or a signed-in session. Scope: fax:send.

Parameters

POST /v1/faxes parameters
NameInTypeRequiredNotes
Idempotency-KeyheaderstringnoReplay the first successful response for the same request within 24 hours. Reusing the idempotency header with a different request returns 409 idempotency_key_conflict. Responses include Idempotent-Replayed: true on replay.

Request body application/json, required

M9: an approved request authorizes the send; without one a quote that needs authorization is evaluated against the caller's delegated policies.

POST /v1/faxes request body
FieldTypeRequiredDescription
approval_idstring or nullnoAn approved approval request bound to this quote. Consumed by this one send.
client_referencestring or nullno
quote_idstringyes

Responses

POST /v1/faxes responses
StatusMeaning
201Successful Response
401No credential, or one that was not accepted: invalid_token for an API key, unauthenticated where a signed-in session is needed. error.details.reason says why a key was refused.
402The prepaid balance does not cover the call: insufficient_balance.
403The credential is valid and is not allowed to do this. scope_missing puts the scope in error.details.scope. Other codes are agent_forbidden and approval_required. A session can also meet csrf_invalid and reauth_required.
404not_found: no such resource for this credential. A resource of another organization answers the same.
409The resource is in a state that refuses the call, or the Idempotency-Key was used with a different request (idempotency_key_conflict). error.code names the state.
422A field failed validation: invalid_request, with one entry per field in error.details, or a code that names the rule.
429rate_limited. Retry-After and the RateLimit-* headers say when to try again.

Response fields

POST /v1/faxes response fields
FieldTypeRequiredDescription
amount_microintegeryes
attempt_countintegeryes
billable_pagesintegeryes
cancel_requested_atstring or nullyes
captured_microintegeryes
client_referencestring or nullyes
completed_atstring or nullyes
cover_pagesintegeryes
created_atstringyes
currencystringyes
delete_after_sendbooleanno
directionstringyes
document_idstringyes
document_sha256stringyes
environmentstring (live, test)yes
evidenceobject or nullnoThe carrier's evidence once delivered or partial; null before.
failure_codestring or nullyes
fromstring or nullno
idstringyes
one_timeobject OneTimeJob or nullno
one_time_order_idstring or nullnoThe one-time order this fax was paid by; null for a wallet fax.
pages_sentintegeryes
providerstringyes
provider_refstring or nullyes
qualitystringno
quote_idstring or nullyes
routestringyes
sender_namestring or nullno
statestring (queued, active, partial, failed, unknown, delivered)yes
tostringyes
transmitted_sha256string or nullyes
updated_atstringyes

Example

curl https://api.faxforagents.com/v1/faxes \
  -X POST \
  -H "Authorization: Bearer ffa_test_..." \
  -H "Content-Type: application/json" \
  -d '{"quote_id":"quote_example"}'

GET /v1/faxes/{fax_id}

Read a fax job (with evidence once delivered)

Credential: an API key or a signed-in session. Scope: fax:read.

Parameters

GET /v1/faxes/{fax_id} parameters
NameInTypeRequiredNotes
fax_idpathstringyes

Responses

GET /v1/faxes/{fax_id} responses
StatusMeaning
200Successful Response
401No credential, or one that was not accepted: invalid_token for an API key, unauthenticated where a signed-in session is needed. error.details.reason says why a key was refused.
403The credential is valid and is not allowed to do this. scope_missing puts the scope in error.details.scope. Other codes are agent_forbidden and approval_required. A session can also meet csrf_invalid and reauth_required.
404not_found: no such resource for this credential. A resource of another organization answers the same.
422A field failed validation: invalid_request, with one entry per field in error.details, or a code that names the rule.
429rate_limited. Retry-After and the RateLimit-* headers say when to try again.

Response fields

GET /v1/faxes/{fax_id} response fields
FieldTypeRequiredDescription
amount_microintegeryes
attempt_countintegeryes
billable_pagesintegeryes
cancel_requested_atstring or nullyes
captured_microintegeryes
client_referencestring or nullyes
completed_atstring or nullyes
cover_pagesintegeryes
created_atstringyes
currencystringyes
delete_after_sendbooleanno
directionstringyes
document_idstringyes
document_sha256stringyes
environmentstring (live, test)yes
evidenceobject or nullnoThe carrier's evidence once delivered or partial; null before.
failure_codestring or nullyes
fromstring or nullno
idstringyes
one_timeobject OneTimeJob or nullno
one_time_order_idstring or nullnoThe one-time order this fax was paid by; null for a wallet fax.
pages_sentintegeryes
providerstringyes
provider_refstring or nullyes
qualitystringno
quote_idstring or nullyes
routestringyes
sender_namestring or nullno
statestring (queued, active, partial, failed, unknown, delivered)yes
tostringyes
transmitted_sha256string or nullyes
updated_atstringyes

Example

curl https://api.faxforagents.com/v1/faxes/FAX_ID \
  -H "Authorization: Bearer ffa_test_..."

GET /v1/faxes/{fax_id}/attempts

Attempt history

Credential: an API key or a signed-in session. Scope: fax:read.

Parameters

GET /v1/faxes/{fax_id}/attempts parameters
NameInTypeRequiredNotes
fax_idpathstringyes

Responses

GET /v1/faxes/{fax_id}/attempts responses
StatusMeaning
200Successful Response
401No credential, or one that was not accepted: invalid_token for an API key, unauthenticated where a signed-in session is needed. error.details.reason says why a key was refused.
403The credential is valid and is not allowed to do this. scope_missing puts the scope in error.details.scope. Other codes are agent_forbidden and approval_required. A session can also meet csrf_invalid and reauth_required.
404not_found: no such resource for this credential. A resource of another organization answers the same.
422A field failed validation: invalid_request, with one entry per field in error.details, or a code that names the rule.
429rate_limited. Retry-After and the RateLimit-* headers say when to try again.

Response fields

GET /v1/faxes/{fax_id}/attempts response fields
FieldTypeRequiredDescription
itemsarray of object Attemptyes

Example

curl https://api.faxforagents.com/v1/faxes/FAX_ID/attempts \
  -H "Authorization: Bearer ffa_test_..."

POST /v1/faxes/{fax_id}/cancel

Cancel if still possible (best effort once sending)

Credential: an API key or a signed-in session. Scope: fax:cancel.

Parameters

POST /v1/faxes/{fax_id}/cancel parameters
NameInTypeRequiredNotes
fax_idpathstringyes
Idempotency-KeyheaderstringnoReplay the first successful response for the same request within 24 hours. Reusing the idempotency header with a different request returns 409 idempotency_key_conflict. Responses include Idempotent-Replayed: true on replay.

Responses

POST /v1/faxes/{fax_id}/cancel responses
StatusMeaning
200Successful Response
401No credential, or one that was not accepted: invalid_token for an API key, unauthenticated where a signed-in session is needed. error.details.reason says why a key was refused.
403The credential is valid and is not allowed to do this. scope_missing puts the scope in error.details.scope. Other codes are agent_forbidden and approval_required. A session can also meet csrf_invalid and reauth_required.
404not_found: no such resource for this credential. A resource of another organization answers the same.
409The resource is in a state that refuses the call, or the Idempotency-Key was used with a different request (idempotency_key_conflict). error.code names the state.
422A field failed validation: invalid_request, with one entry per field in error.details, or a code that names the rule.
429rate_limited. Retry-After and the RateLimit-* headers say when to try again.

Response fields

POST /v1/faxes/{fax_id}/cancel response fields
FieldTypeRequiredDescription
amount_microintegeryes
attempt_countintegeryes
billable_pagesintegeryes
cancel_requested_atstring or nullyes
captured_microintegeryes
client_referencestring or nullyes
completed_atstring or nullyes
cover_pagesintegeryes
created_atstringyes
currencystringyes
delete_after_sendbooleanno
directionstringyes
document_idstringyes
document_sha256stringyes
environmentstring (live, test)yes
evidenceobject or nullnoThe carrier's evidence once delivered or partial; null before.
failure_codestring or nullyes
fromstring or nullno
idstringyes
one_timeobject OneTimeJob or nullno
one_time_order_idstring or nullnoThe one-time order this fax was paid by; null for a wallet fax.
pages_sentintegeryes
providerstringyes
provider_refstring or nullyes
qualitystringno
quote_idstring or nullyes
routestringyes
sender_namestring or nullno
statestring (queued, active, partial, failed, unknown, delivered)yes
tostringyes
transmitted_sha256string or nullyes
updated_atstringyes

Example

curl https://api.faxforagents.com/v1/faxes/FAX_ID/cancel \
  -X POST \
  -H "Authorization: Bearer ffa_test_..."

GET /v1/faxes/{fax_id}/events

Ordered events of one fax

Credential: an API key or a signed-in session. Scope: fax:read.

Parameters

GET /v1/faxes/{fax_id}/events parameters
NameInTypeRequiredNotes
fax_idpathstringyes

Responses

GET /v1/faxes/{fax_id}/events responses
StatusMeaning
200Successful Response
401No credential, or one that was not accepted: invalid_token for an API key, unauthenticated where a signed-in session is needed. error.details.reason says why a key was refused.
403The credential is valid and is not allowed to do this. scope_missing puts the scope in error.details.scope. Other codes are agent_forbidden and approval_required. A session can also meet csrf_invalid and reauth_required.
404not_found: no such resource for this credential. A resource of another organization answers the same.
422A field failed validation: invalid_request, with one entry per field in error.details, or a code that names the rule.
429rate_limited. Retry-After and the RateLimit-* headers say when to try again.

Response fields

GET /v1/faxes/{fax_id}/events response fields
FieldTypeRequiredDescription
itemsarray of object Eventyes
next_cursorstring or nullno

Example

curl https://api.faxforagents.com/v1/faxes/FAX_ID/events \
  -H "Authorization: Bearer ffa_test_..."

GET /v1/faxes/{fax_id}/receipt

Delivery evidence as a receipt (JSON)

Credential: an API key or a signed-in session. Scope: fax:read.

Parameters

GET /v1/faxes/{fax_id}/receipt parameters
NameInTypeRequiredNotes
fax_idpathstringyes

Responses

GET /v1/faxes/{fax_id}/receipt responses
StatusMeaning
200Successful Response
401No credential, or one that was not accepted: invalid_token for an API key, unauthenticated where a signed-in session is needed. error.details.reason says why a key was refused.
403The credential is valid and is not allowed to do this. scope_missing puts the scope in error.details.scope. Other codes are agent_forbidden and approval_required. A session can also meet csrf_invalid and reauth_required.
404not_found: no such resource for this credential. A resource of another organization answers the same.
409The resource is in a state that refuses the call, or the Idempotency-Key was used with a different request (idempotency_key_conflict). error.code names the state.
422A field failed validation: invalid_request, with one entry per field in error.details, or a code that names the rule.
429rate_limited. Retry-After and the RateLimit-* headers say when to try again.

Response fields

GET /v1/faxes/{fax_id}/receipt response fields
FieldTypeRequiredDescription
amount_microintegeryes
attemptsarray of object Attemptyes
billable_pagesintegeryes
captured_microintegeryes
completed_atstring or nullyes
cover_pagesintegernoHow many of the billable pages are the cover sheet: 0 or 1.
created_atstringyes
currencystringyes
document_sha256stringyes
evidenceobject or nullyes
failure_codestring or nullyes
fax_job_idstringyes
fromstring or nullno
generated_atstringyes
notestringyes
one_timeobject OneTimeJob or nullnoSet on the receipt of a fax that a one-time order paid for. It names the order, its status, the card and the amount the card was authorized for. captured_micro in it is the amount charged, written once the payment provider confirmed the capture. For a card order read the money here. Null for a fax paid from the wallet.
pages_sentintegeryes
providerstringyes
statestringyes
tostringyes
transmitted_sha256string or nullyes

Example

curl https://api.faxforagents.com/v1/faxes/FAX_ID/receipt \
  -H "Authorization: Bearer ffa_test_..."

GET /v1/faxes/{fax_id}/receipt.pdf

The same receipt as a one-page PDF

Credential: an API key or a signed-in session. Scope: fax:read.

Parameters

GET /v1/faxes/{fax_id}/receipt.pdf parameters
NameInTypeRequiredNotes
fax_idpathstringyes

Responses

GET /v1/faxes/{fax_id}/receipt.pdf responses
StatusMeaning
200The receipt as a PDF
401No credential, or one that was not accepted: invalid_token for an API key, unauthenticated where a signed-in session is needed. error.details.reason says why a key was refused.
403The credential is valid and is not allowed to do this. scope_missing puts the scope in error.details.scope. Other codes are agent_forbidden and approval_required. A session can also meet csrf_invalid and reauth_required.
404not_found: no such resource for this credential. A resource of another organization answers the same.
409The resource is in a state that refuses the call, or the Idempotency-Key was used with a different request (idempotency_key_conflict). error.code names the state.
422A field failed validation: invalid_request, with one entry per field in error.details, or a code that names the rule.
429rate_limited. Retry-After and the RateLimit-* headers say when to try again.

Example

curl https://api.faxforagents.com/v1/faxes/FAX_ID/receipt.pdf \
  -H "Authorization: Bearer ffa_test_..."