code: a granular, machine-readable reason (e.g.call_id_not_verified,busy,agent_dispatch_failed). Branch on this in your integration.category: a generalized, user-facing bucket (e.g.invalid_request,provider_error). Map it straight to a message you display to an end user.
message is human-readable but may change; never branch on it. fields (when present)
maps a request field to a per-field explanation. doc_url deep-links to the relevant
section below.
Categories
The generalized bucket. If you only surface one thing to an end user, surface this.When you receive them
invalid_request, compliance_block, account_limit, and provider_error codes come
back synchronously on the dial request (with the HTTP status shown below).
unreachable and voicemail describe how a placed call ended; they are not returned
on the dial request. They arrive on the call resource (failure_code / failure_category)
and on the phone_call.ended webhook once the call completes.
Invalid request
400 / 409 / 422: returned synchronously.
Compliance block
403 / 429: returned synchronously. The call was refused by a calling rule.
Texting not ready
403: returned synchronously by POST /v1/sms/send when the workspace’s A2P/10DLC texting
registration blocks the send. Not retryable until the registration state changes —
subscribe to the TEXTING_REGISTRATION_STATUS_CHANGED webhook or check texting_status
on GET /v1/phone-numbers before sending.
Content policy forbidden
403: returned synchronously by GET /v1/calls/{id}/transcript (and other call-content endpoints)
when the organization’s call-content policy pins content to a compliance (HIPAA) boundary. Transcripts,
recordings, and derived analysis are never returned over the public API for these organizations.
Account limit
402 / 429: returned synchronously.
Unreachable
Asynchronous: these appear on the call resource and thephone_call.ended webhook, not on
the dial response.
Voicemail
Asynchronous: appears on the call resource and thephone_call.ended webhook.
Provider error
500 / 502: returned synchronously. A transient RevDesk / telephony infrastructure
failure; safe to retry.
Example
Place a call:202 Accepted with the call_id; subscribe to the webhook for
the final outcome. Representative failures:
unreachable / voicemail outcome shows up later on the call resource:
HTTP and authentication errors
These apply to every endpoint, not just calls. They use the same envelope (without acategory).
With the SDK
@revdesk/sdk throws a typed RevDeskError for every non-2xx response,
mapping the envelope above onto these fields:
error.isRetryable is true for 429 and 5xx responses.
scope_missing and demo-key errors,
and Conventions for idempotency and pagination.