OAuth consent API reference

Updated

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

  • Allowing an authorization mints the authorization code and returns where the browser goes next.
  • Denying an authorization sends the app an access_denied answer.
  • An OAuth access token works on the MCP server only, and the REST API answers it with 401.

Operations

What is this group for?

For the consent screen. When an AI client connects to the MCP server with OAuth, it sends the person to a consent URL. The dashboard reads the pending authorization from this group, shows it, and posts the person's answer. The token endpoints of the OAuth flow are outside /v1 and are not part of this document.

GET /v1/oauth/authorizations/{authorization_id} returns the pending consent. client is the app that asks, and redirect_host is the host it will return to. The answer also has the scopes_requested, the person's organizations and the default environment. It expires at expires_at. The call takes a signed-in session.

How is the answer given?

POST /v1/oauth/authorizations/{authorization_id}/approve allows. The body names the org_id and the environment the app is connected to. It mints the authorization code and returns redirect_to, the address the browser opens next. auto_send is the consent screen's checkbox, for owners only.

POST /v1/oauth/authorizations/{authorization_id}/deny denies. The app gets an access_denied answer through the same redirect_to.

How are connected apps listed and revoked?

GET /v1/oauth/grants lists the connected apps of the organization. DELETE /v1/oauth/grants/{grant_id} revokes one, and that connection's tokens stop working. Both need key:admin, the scope that also guards API keys.

Revoking an app does not cancel a fax that is already queued. The OAuth guide walks through the screen a person sees.

Does an OAuth token work on this API?

No. An access token from the MCP sign-in works on the MCP server only. The REST API answers it with 401 invalid_token. A script that calls REST uses an API key from the identity group.

Each operation in detail

GET /v1/oauth/authorizations/{authorization_id}

The pending consent behind a consent URL: the app, the scopes and your organizations

Credential: a signed-in session.

Parameters

GET /v1/oauth/authorizations/{authorization_id} parameters
NameInTypeRequiredNotes
authorization_idpathstringyes

Responses

GET /v1/oauth/authorizations/{authorization_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.
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/oauth/authorizations/{authorization_id} response fields
FieldTypeRequiredDescription
clientobject OAuthConsentClientyes
default_environmentstring (live, test)yes
expires_atstringyes
idstringyes
organizationsarray of object OAuthConsentOrganizationyes
redirect_hoststringyes
scopes_requestedarray of stringyes

Example

curl https://api.faxforagents.com/v1/oauth/authorizations/AUTHORIZATION_ID

POST /v1/oauth/authorizations/{authorization_id}/approve

Allow: mint the authorization code and return where the browser goes next

Credential: a signed-in session.

Parameters

POST /v1/oauth/authorizations/{authorization_id}/approve parameters
NameInTypeRequiredNotes
authorization_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/oauth/authorizations/{authorization_id}/approve request body
FieldTypeRequiredDescription
auto_sendboolean or nullnoThe consent screen's checkbox, owners only: false turns the organization's auto-send setting off for this environment, true turns it on with its current limits. Omitted leaves it.
environmentstring (live, test)no
org_idstringyes

Responses

POST /v1/oauth/authorizations/{authorization_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/oauth/authorizations/{authorization_id}/approve response fields
FieldTypeRequiredDescription
redirect_tostringyesWhere the browser goes next: the client's registered redirect URI.

Example

curl https://api.faxforagents.com/v1/oauth/authorizations/AUTHORIZATION_ID/approve \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"org_id":"org_example"}'

POST /v1/oauth/authorizations/{authorization_id}/deny

Deny: send the app an access_denied answer

Credential: a signed-in session.

Parameters

POST /v1/oauth/authorizations/{authorization_id}/deny parameters
NameInTypeRequiredNotes
authorization_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/oauth/authorizations/{authorization_id}/deny 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/oauth/authorizations/{authorization_id}/deny response fields
FieldTypeRequiredDescription
redirect_tostringyesWhere the browser goes next: the client's registered redirect URI.

Example

curl https://api.faxforagents.com/v1/oauth/authorizations/AUTHORIZATION_ID/deny \
  -X POST

GET /v1/oauth/grants

Your connected apps in this organization

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

Parameters

GET /v1/oauth/grants parameters
NameInTypeRequiredNotes
cursorquerystring or nullno
limitqueryintegerno Default 100.

Responses

GET /v1/oauth/grants 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/oauth/grants response fields
FieldTypeRequiredDescription
itemsarray of object Grantyes
next_cursorstring or nullno

Example

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

DELETE /v1/oauth/grants/{grant_id}

Revoke a connected app

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

Parameters

DELETE /v1/oauth/grants/{grant_id} parameters
NameInTypeRequiredNotes
grant_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

DELETE /v1/oauth/grants/{grant_id} responses
StatusMeaning
204Successful 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.

Example

curl https://api.faxforagents.com/v1/oauth/grants/GRANT_ID \
  -X DELETE \
  -H "Authorization: Bearer ffa_test_..."