Approvals API reference

Updated

7 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.

  • Creating an approval request grants nothing until a person approves it.
  • Approving needs approval:decide from a fresh session or an independent API credential.
  • Only an approval that nobody has used yet can be revoked.

Operations

What is an approval request?

An approval request asks a person to say yes to one send. The agent names a quote, and the server copies what the quote fixes into the request. That is the document and its hash, the destination, the sender and the amount. The answer returns that copy under bound. The request expires with the quote.

The summary of the create operation ends with "grants nothing". A pending request cannot send a fax. Only an approved one can, once, for the quote it was made from.

How does an agent ask?

POST /v1/approval-requests with a quote_id opens a request of kind send. It needs approval:request, which agent keys carry. The answer has the id, the status, the kind and who asked.

The same operation opens a request of kind help. The body then carries a message and can name a fax_job_id. The schema says the message is shown as data: a person reads it, and the server never acts on it.

Who can approve or reject?

POST /v1/approval-requests/{approval_id}/approve and /reject need approval:decide. The summary of the approve operation names the two ways to hold it. One is a fresh session, which means a person who signed in or proved it again a short time ago. The other is an independent API credential, which means a different API key from the one that asked. An agent key is never issued the scope.

Both take a reason. Rejecting records why, and the requester can read it. The approvals guide has the codes a later send can be refused with.

How does the agent learn the decision?

GET /v1/approval-requests/{approval_id} returns the request with its status, decided_at, decided_by and the reason. An approved request is what POST /v1/faxes takes as approval_id. After the send, consumed_by_job_id names the fax that used it.

GET /v1/approval-requests lists requests with the pending ones first. It filters by status and pages with cursor and limit. Both reads need approval:read.

Can an approval be taken back?

POST /v1/approvals/{approval_id}/revoke withdraws an approval that nobody has used yet. It needs approval:decide, like the decision itself. After a revoke the agent has to quote and ask again. An approval a fax has consumed cannot be revoked. Cancel the fax in the faxes group when it has not ended.

What is the integration review read?

GET /v1/integration-reviews/{org_id}/{environment}/{operation_id}/{binding_id} returns the approval request that one review binding names, in the same shape as the other reads. It takes a signed-in session only, with approval:read. The organization and the environment in the path have to be the ones the session is looking at. An API key is refused.

What does a send need besides an approval?

Nothing more from this group. A live send needs either an approved request or a delegated policy that allows it. Test keys send in the sandbox without either. The approval is checked again at the send. A changed document, destination, sender or amount no longer matches what was approved, and the send is refused.

Each operation in detail

GET /v1/approval-requests

Approval requests, pending first

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

Parameters

GET /v1/approval-requests parameters
NameInTypeRequiredNotes
statusquerystring or nullno
cursorquerystring or nullno
limitqueryintegerno Default 50.

Responses

GET /v1/approval-requests 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/approval-requests response fields
FieldTypeRequiredDescription
itemsarray of object ApprovalRequestyes
next_cursorstring or nullno

Example

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

POST /v1/approval-requests

Ask a human to approve a quoted send, or ask for help (grants nothing)

Credential: an API key or a signed-in session. Scope: approval:request.

Parameters

POST /v1/approval-requests 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

POST /v1/approval-requests request body
FieldTypeRequiredDescription
fax_job_idstring or nullno
kindstring (send, help)no
messagestring or nullnoWhat the person should know (kind help). Shown as data.
quote_idstring or nullnoThe quote to bind (kind send).

Responses

POST /v1/approval-requests 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.
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/approval-requests response fields
FieldTypeRequiredDescription
boundobjectyes
consumed_by_job_idstring or nullyes
created_atstringyes
decided_atstring or nullyes
decided_bystring or nullyes
expires_atstring or nullyes
idstringyes
kindstring (send, help)yes
messagestring or nullyes
notifiedboolean or nullnoOn creation: whether the organization was mailed. false when the request repeats a pending one or the organization's daily cap of request mails is reached; the request is still shown in the dashboard.
quote_idstring or nullyes
reasonstring or nullyes
requested_bystringyes
statusstring (pending, approved, rejected, revoked, expired)yes

Example

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

GET /v1/approval-requests/{approval_id}

Read one request

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

Parameters

GET /v1/approval-requests/{approval_id} parameters
NameInTypeRequiredNotes
approval_idpathstringyes

Responses

GET /v1/approval-requests/{approval_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/approval-requests/{approval_id} response fields
FieldTypeRequiredDescription
boundobjectyes
consumed_by_job_idstring or nullyes
created_atstringyes
decided_atstring or nullyes
decided_bystring or nullyes
expires_atstring or nullyes
idstringyes
kindstring (send, help)yes
messagestring or nullyes
notifiedboolean or nullnoOn creation: whether the organization was mailed. false when the request repeats a pending one or the organization's daily cap of request mails is reached; the request is still shown in the dashboard.
quote_idstring or nullyes
reasonstring or nullyes
requested_bystringyes
statusstring (pending, approved, rejected, revoked, expired)yes

Example

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

POST /v1/approval-requests/{approval_id}/approve

Approve the bound quote (approval:decide, fresh session or independent API credential)

Credential: an API key or a signed-in session. Scope: approval:decide.

Parameters

POST /v1/approval-requests/{approval_id}/approve parameters
NameInTypeRequiredNotes
approval_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.

Request body application/json, required

POST /v1/approval-requests/{approval_id}/approve request body
FieldTypeRequiredDescription
reasonstring or nullno

Responses

POST /v1/approval-requests/{approval_id}/approve 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/approval-requests/{approval_id}/approve response fields
FieldTypeRequiredDescription
boundobjectyes
consumed_by_job_idstring or nullyes
created_atstringyes
decided_atstring or nullyes
decided_bystring or nullyes
expires_atstring or nullyes
idstringyes
kindstring (send, help)yes
messagestring or nullyes
notifiedboolean or nullnoOn creation: whether the organization was mailed. false when the request repeats a pending one or the organization's daily cap of request mails is reached; the request is still shown in the dashboard.
quote_idstring or nullyes
reasonstring or nullyes
requested_bystringyes
statusstring (pending, approved, rejected, revoked, expired)yes

Example

curl https://api.faxforagents.com/v1/approval-requests/APPROVAL_ID/approve \
  -X POST \
  -H "Authorization: Bearer ffa_test_..." \
  -H "Content-Type: application/json" \
  -d '{}'

POST /v1/approval-requests/{approval_id}/reject

Reject with a reason

Credential: an API key or a signed-in session. Scope: approval:decide.

Parameters

POST /v1/approval-requests/{approval_id}/reject parameters
NameInTypeRequiredNotes
approval_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.

Request body application/json, required

POST /v1/approval-requests/{approval_id}/reject request body
FieldTypeRequiredDescription
reasonstring or nullno

Responses

POST /v1/approval-requests/{approval_id}/reject 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/approval-requests/{approval_id}/reject response fields
FieldTypeRequiredDescription
boundobjectyes
consumed_by_job_idstring or nullyes
created_atstringyes
decided_atstring or nullyes
decided_bystring or nullyes
expires_atstring or nullyes
idstringyes
kindstring (send, help)yes
messagestring or nullyes
notifiedboolean or nullnoOn creation: whether the organization was mailed. false when the request repeats a pending one or the organization's daily cap of request mails is reached; the request is still shown in the dashboard.
quote_idstring or nullyes
reasonstring or nullyes
requested_bystringyes
statusstring (pending, approved, rejected, revoked, expired)yes

Example

curl https://api.faxforagents.com/v1/approval-requests/APPROVAL_ID/reject \
  -X POST \
  -H "Authorization: Bearer ffa_test_..." \
  -H "Content-Type: application/json" \
  -d '{}'

POST /v1/approvals/{approval_id}/revoke

Revoke an approval nobody has used yet

Credential: an API key or a signed-in session. Scope: approval:decide.

Parameters

POST /v1/approvals/{approval_id}/revoke parameters
NameInTypeRequiredNotes
approval_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.

Request body application/json, required

POST /v1/approvals/{approval_id}/revoke request body
FieldTypeRequiredDescription
reasonstring or nullno

Responses

POST /v1/approvals/{approval_id}/revoke 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/approvals/{approval_id}/revoke response fields
FieldTypeRequiredDescription
boundobjectyes
consumed_by_job_idstring or nullyes
created_atstringyes
decided_atstring or nullyes
decided_bystring or nullyes
expires_atstring or nullyes
idstringyes
kindstring (send, help)yes
messagestring or nullyes
notifiedboolean or nullnoOn creation: whether the organization was mailed. false when the request repeats a pending one or the organization's daily cap of request mails is reached; the request is still shown in the dashboard.
quote_idstring or nullyes
reasonstring or nullyes
requested_bystringyes
statusstring (pending, approved, rejected, revoked, expired)yes

Example

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

GET /v1/integration-reviews/{org_id}/{environment}/{operation_id}/{binding_id}

Get Integration Review

Credential: a signed-in session. Scope: approval:read.

Parameters

GET /v1/integration-reviews/{org_id}/{environment}/{operation_id}/{binding_id} parameters
NameInTypeRequiredNotes
org_idpathstringyes
environmentpathstringyes
operation_idpathstringyes
binding_idpathstringyes

Responses

GET /v1/integration-reviews/{org_id}/{environment}/{operation_id}/{binding_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/integration-reviews/{org_id}/{environment}/{operation_id}/{binding_id} response fields
FieldTypeRequiredDescription
boundobjectyes
consumed_by_job_idstring or nullyes
created_atstringyes
decided_atstring or nullyes
decided_bystring or nullyes
expires_atstring or nullyes
idstringyes
kindstring (send, help)yes
messagestring or nullyes
notifiedboolean or nullnoOn creation: whether the organization was mailed. false when the request repeats a pending one or the organization's daily cap of request mails is reached; the request is still shown in the dashboard.
quote_idstring or nullyes
reasonstring or nullyes
requested_bystringyes
statusstring (pending, approved, rejected, revoked, expired)yes

Example

curl https://api.faxforagents.com/v1/integration-reviews/ORG_ID/ENVIRONMENT/OPERATION_ID/BINDING_ID