Skip to main content
When a request fails, RevDesk returns a consistent error envelope. Call-related errors carry two tiers so you can act on them precisely and show something friendly to a person:
  • code — a granular, machine-readable reason (e.g. caller_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.
{
  "error": {
    "code": "caller_id_not_verified",
    "category": "invalid_request",
    "message": "The caller ID isn't verified for this account.",
    "doc_url": "https://docs.revdesk.com/api-reference/errors#invalid-request"
  }
}
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.
CategoryWhat it meansWhat the caller can do
invalid_requestThe request was malformed — bad/missing destination, caller ID not verified, no number on the accountFix the request
compliance_blockedBlocked by a calling rule — DNC, opt-out, no consent, calling window/day, frequency cap, emergency numberRemove from list / wait for the window
account_limitAn account-level limit — minutes exhausted, no active subscription, payment required, rate/concurrency capUpgrade / add payment / retry later
unreachablePlaced, but never reached a person — busy, no answer, invalid/disconnected number, carrier rejectedRetry later
voicemailReached an answering machineInformational
provider_errorA RevDesk / telephony infrastructure failureRetry, then contact support

When you receive them

invalid_request, compliance_blocked, 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.
CodeHTTPRetryableMeaning
destination_missing400noNo destination phone number was provided
destination_invalid400noThe destination isn’t a valid, dialable E.164 number
no_active_number409noNo active phone number is available to place the call (e.g. still provisioning)
caller_id_not_verified422noThe caller ID isn’t verified for this account

Compliance blocked

403 / 429 — returned synchronously. The call was refused by a calling rule.
CodeHTTPRetryableMeaning
destination_blocked403noEmergency or special-service number that can’t be dialed
dnc_suppressed403noThe number is on a Do-Not-Call list
recipient_opted_out403noThe contact has opted out of calls
no_consent403noNo calling consent is on file for the contact
outside_calling_window403yesIt’s outside the permitted calling hours for the recipient
calling_day_not_allowed403yesCalls aren’t permitted to the recipient today
frequency_cap_exceeded429yesThe contact has already been called the maximum number of times

Account limit

402 / 429 — returned synchronously.
CodeHTTPRetryableMeaning
voice_usage_exhausted402noYour included calling minutes are used up
no_active_subscription402noNo active subscription is available to place calls
no_number_available429yesAll of your numbers are busy right now
rate_limited429yesToo many calls are being placed at once

Unreachable

Asynchronous — these appear on the call resource and the phone_call.ended webhook, not on the dial response.
CodeRetryableMeaning
busyyesThe line was busy
no_answeryesNo one answered
number_unreachablenoThe number could not be reached (invalid or disconnected)
call_declinednoThe recipient declined the call
carrier_rejectednoThe carrier rejected the call

Voicemail

Asynchronous — appears on the call resource and the phone_call.ended webhook.
CodeRetryableMeaning
voicemail_reachedyesReached an answering machine

Provider error

500 / 502 — returned synchronously. A transient RevDesk / telephony infrastructure failure; safe to retry.
CodeHTTPRetryableMeaning
room_creation_failed502yesWe couldn’t start the call session
agent_dispatch_failed502yesWe couldn’t connect an agent to the call
sip_gateway_failed502yesWe couldn’t reach the phone network
provider_api_error502yesThe telephony provider returned an error
internal_error500yesAn unexpected server error occurred

Example

Place a call:
curl -X POST https://api.revdesk.com/v1/calls/dial \
  -H "Authorization: Bearer $REVDESK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from_number": "+14155551234", "to_number": "+14155556789"}'
A successful dial returns 202 Accepted with the call_id; subscribe to the webhook for the final outcome. Representative failures:
// 422 — the from_number isn't verified on this account
{
  "error": {
    "code": "caller_id_not_verified",
    "category": "invalid_request",
    "message": "The caller ID isn't verified for this account.",
    "doc_url": "https://docs.revdesk.com/api-reference/errors#invalid-request"
  }
}

// 409 — the number exists but isn't active yet
{
  "error": {
    "code": "no_active_number",
    "category": "invalid_request",
    "message": "from_number is not yet active — wait for provisioning to finish.",
    "doc_url": "https://docs.revdesk.com/api-reference/errors#invalid-request"
  }
}

// 502 — couldn't connect an agent to the call (safe to retry)
{
  "error": {
    "code": "agent_dispatch_failed",
    "category": "provider_error",
    "message": "We couldn't connect an agent to the call. Please try again.",
    "doc_url": "https://docs.revdesk.com/api-reference/errors#provider-error"
  }
}
An unreachable / voicemail outcome shows up later on the call resource:
{
  "data": {
    "id": "call_a1b2c3",
    "status": "busy",
    "call_outcome": "busy",
    "failure_code": "busy",
    "failure_category": "unreachable",
    "disconnection_reason": "user_busy"
  }
}

HTTP and authentication errors

These apply to every endpoint, not just calls. They use the same envelope (without a category).
CodeHTTPDescription
validation_error400Request body or parameters are invalid (see fields)
unauthorized401Missing or invalid API key
forbidden403API key does not have access to this resource
not_found404The requested resource does not exist
idempotency_conflict409An Idempotency-Key already succeeded with a different body
rate_limited429Too many requests — slow down
internal_error500An unexpected server error occurred
See Authentication for scope_missing and demo-key errors, and Conventions for idempotency and pagination.