Error Reason Codes¶
Note
AI Context
Every 4xx/5xx response from the VoIPbin API contains an error.reason field in UPPER_SNAKE that identifies the specific cause. This page catalogues all published reasons. Clients should branch on reason for self-healing behavior. status maps 1:1 to HTTP (see RESTful API(Application Programming Interface)).
The error envelope contains status / reason / message / request_id (and an optional details array). Reason codes are append-only once published — adding a new reason does not require a schema version bump; removing or renaming one does and triggers a deprecation window.
Reasons are organized below into two groups:
Generic / Cross-cutting Reasons apply across every endpoint regardless of resource (authentication, authorization, validation, transport, billing pre-checks, generic state errors, generic not-found).
Resource-Prefixed Reasons carry an explicit resource prefix (
CALL_*,FLOW_*,RECORDING_*, …) and only fire on endpoints that operate on that resource.
Generic / Cross-cutting Reasons¶
These reasons are not tied to a specific resource and may be returned by any endpoint. They cover authentication, authorization, validation, transport-layer failures, and generic fallback reasons (RESOURCE_NOT_FOUND, STATE_INVALID, INSUFFICIENT_BALANCE, SERVICE_UNAVAILABLE) that surface when the underlying condition does not carry a more specific resource-prefixed reason. Treat this group as the baseline catch-all for client error handling.
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
401 |
No token or access key was supplied. Send a valid JWT in the |
|
401 |
The supplied token or access key is invalid or expired. Refresh the token via |
|
403 |
The customer account is frozen (typically because unregister was scheduled). Inspect |
|
403 |
The authenticated user does not have permission for this resource. |
|
403 |
The endpoint requires a JWT login flow that the current direct access (access key) cannot satisfy. Re-authenticate via JWT. |
|
429 |
Client exceeded the rate limit for this endpoint. Back off and retry with exponential delay. |
|
404 |
The requested resource does not exist or does not belong to the authenticated customer. Verify the UUID was obtained from a recent |
|
404 |
The requested HTTP endpoint does not exist (wrong path or typo). Verify the URL against the API reference; check API version prefix ( |
|
400 |
The request body or a path/query parameter is invalid. Inspect |
|
400 |
The request body is not valid JSON. Ensure |
|
400 |
A path or body parameter is not a valid UUID. Verify the ID was obtained from a recent |
|
409 |
The target resource is in a state that does not allow the requested operation. Check the current state via the resource’s |
|
402 |
Customer balance is below the minimum required for a chargeable operation (e.g., |
|
503 |
Upstream manager did not respond within the deadline. Retry with the same idempotency key after a short delay. |
|
503 |
The request was canceled before completion (typically the client disconnected). Usually safe to ignore; the server did not finish processing. |
|
503 |
An upstream manager service is temporarily unavailable. Retry the request with the same idempotency key after a short delay (exponential backoff). |
|
500 |
Unexpected server error. Include |
Resource-Prefixed Reasons¶
These reasons carry an explicit resource prefix in the reason code (e.g., CALL_NOT_FOUND, FLOW_STATE_INVALID) and only surface on endpoints that operate on that resource. Branch on the reason code’s prefix to scope your client-side error handling to the right resource.
Call Reasons¶
Reasons fired by call endpoints (/calls, /calls/{id}*, /groupcalls, /service_agents/calls*).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Call ID does not exist or belongs to another customer. Verify the ID was obtained from a recent |
|
409 |
Operation invalid because the call has already ended. Check current status via |
|
409 |
Operation invalid for the current call state (e.g., transfer from a call that is not yet progressing). Check |
|
404 |
Groupcall ID does not exist or belongs to another customer. Verify via |
Recording Reasons¶
Reasons fired by recording endpoints (/recordings, /calls/{id}/recording-*).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Recording ID does not exist or belongs to another customer. Verify via |
|
409 |
A recording is already in progress on this call. Stop the existing recording with |
|
409 |
No recording is active on this call. Start one with |
Flow / Activeflow Reasons¶
Reasons fired by flow and activeflow endpoints (/flows, /flows/{id}, /activeflows, /activeflows/{id}*).
Note
POST /activeflows/{id}/stop is idempotent in production today — stopping an already-stopped activeflow returns 200 (no-op). The 409 ACTIVEFLOW_ALREADY_STOPPED response declared in the OpenAPI spec is forward-compatible for clients that prefer opt-in idempotency-aware semantics.
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Flow ID does not exist or belongs to another customer. Verify the ID was obtained from a recent |
|
404 |
Activeflow ID does not exist or belongs to another customer. Verify via |
|
409 |
Operation invalid for the current activeflow state (e.g., stop on an already-stopped activeflow). Check current status via |
|
409 |
Stop requested on an activeflow that has already terminated. Idempotent — treat as success or check status before retrying. |
Billing Reasons¶
Reasons fired by billing endpoints (/billings/{id}, /billing-accounts/{id}*). The cross-cutting INSUFFICIENT_BALANCE (402) reason is documented in the Generic / Cross-cutting Reasons table above.
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Billing record ID does not exist or belongs to another customer. Fired by |
|
404 |
Billing account ID does not exist or belongs to another customer. Fired by the |
Number Reasons¶
Reasons fired by number endpoints (/numbers, /numbers/{id}, /numbers/renew).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Number ID does not exist or belongs to another customer. Verify the ID was obtained from a recent |
|
403 |
Customer identity verification is required for this operation. Fired by |
Trunk / Provider Reasons¶
Admin-only reasons fired by the provisioning surfaces (/providers, /providers/setup, /providercalls, /trunks, /routes and their sub-paths). Non-admin callers receive 403 PERMISSION_DENIED.
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Provider ID does not exist. Verify the ID was obtained from a recent |
|
404 |
Trunk ID does not exist. Verify via |
|
404 |
Provider-call ID does not exist. Verify via |
Storage Reasons¶
Reasons fired by storage endpoints (/storage-accounts/{id}, /storage_files, /storage_files/{id}*, and their /service_agents/files* agent-surface counterparts).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Storage account ID does not exist or belongs to another customer. Fired by |
|
404 |
Storage file ID does not exist or belongs to another customer. Fired by |
Conversation Reasons¶
Reasons fired by conversation endpoints (/conversation-accounts/{id}, /conversations/{id}*, /service-agents/conversations/{id}*).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Conversation account ID does not exist or belongs to another customer. Fired by |
|
404 |
Conversation ID does not exist or belongs to another customer. Fired by |
Message Reasons¶
Reasons fired by SMS message endpoints (/messages, /messages/{id}). POST /messages is billing-sensitive — see INSUFFICIENT_BALANCE in the Generic / Cross-cutting Reasons table above.
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Message ID does not exist or belongs to another customer. Fired by |
Email Reasons¶
Reasons fired by email endpoints (/emails, /emails/{id}). POST /emails is billing-sensitive — see INSUFFICIENT_BALANCE in the Generic / Cross-cutting Reasons table above.
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Email ID does not exist or belongs to another customer. Fired by |
AI Reasons¶
Reasons fired by AI endpoints (/aimessages, /ais, /aicalls, /aisummaries, /teams).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
AI message ID does not exist or belongs to another customer. Fired by |
|
404 |
AI configuration ID does not exist or belongs to another customer. Fired by |
|
404 |
AI call ID does not exist or belongs to another customer. Fired by |
|
404 |
AI summary ID does not exist or belongs to another customer. Fired by |
|
404 |
Team ID does not exist or belongs to another customer. Fired by |
RAG Reasons¶
Reasons fired by RAG endpoints (/rags, /rags/{id}*).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
RAG knowledge-base ID does not exist or belongs to another customer. Fired by |
|
404 |
RAG document/source ID does not exist or belongs to another customer. Fired by |
Speaking Reasons¶
Reasons fired by TTS speaking endpoints (/speakings, /speakings/{id}*). POST /speakings/{id}/stop is idempotent today — stopping an already-stopped speaking session returns success (no-op).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Speaking session ID does not exist or belongs to another customer. Fired by |
Transcribe Reasons¶
Reasons fired by STT transcribe endpoints (/transcribes, /transcribes/{id}*). POST /transcribes/{id}/stop is idempotent today — stopping an already-stopped transcription returns success (no-op).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Transcribe ID does not exist or belongs to another customer. Fired by |
Agent Reasons¶
Reasons fired by agent endpoints (/agents, /agents/{id}*, /service_agents/agents*). Agent write surfaces are admin-gated; non-admin callers receive 403 PERMISSION_DENIED.
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Agent ID does not exist or belongs to another customer. Fired by |
Tag Reasons¶
Reasons fired by tag endpoints (/tags, /tags/{id}, /service_agents/tags*). Tag write surfaces are admin-gated; non-admin callers receive 403 PERMISSION_DENIED.
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Tag ID does not exist or belongs to another customer. Fired by |
Customer / Accesskey Reasons¶
Reasons fired by customer and access-key endpoints (/customers/{id}, /accesskeys, /accesskeys/{id}). Access-key write surfaces and admin customer endpoints are admin-gated; non-admin callers receive 403 PERMISSION_DENIED.
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Access-key ID does not exist or belongs to another customer. Fired by |
|
404 |
Customer ID does not exist. Fired by admin endpoints |
Campaign Reasons¶
Reasons fired by campaign, campaign-call, and outplan endpoints (/campaigns, /campaigns/{id}*, /campaigncalls, /outplans, /outplans/{id}*). Campaign state-transition operations are idempotent today — for example, stopping an already-stopped campaign returns success (no-op).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Campaign ID does not exist or belongs to another customer. Fired by |
|
404 |
Campaign-call ID does not exist or belongs to another customer. Fired by |
|
404 |
Outplan ID does not exist or belongs to another customer. Fired by |
Outdial Reasons¶
Reasons fired by outdial endpoints (/outdials, /outdials/{id}*, /outdials/{id}/targets*).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Outdial ID does not exist or belongs to another customer. Fired by |
|
404 |
Outdial-target ID does not exist or does not belong to the supplied outdial. Fired by |
Conference Reasons¶
Reasons fired by conference endpoints (/conferences, /conferences/{id}*, /conferencecalls, /conferencecalls/{id}). Conference state-mutation operations are idempotent today — stopping an already-stopped recording or transcription returns success (no-op).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Conference ID does not exist or belongs to another customer. Fired by |
|
404 |
Conference-call ID does not exist or belongs to another customer. Fired by |
Queue Reasons¶
Reasons fired by queue endpoints (/queues, /queues/{id}*, /queuecalls, /queuecalls/{id}*). Queue-call kick operations are idempotent today — kicking an already-ended queue-call returns success (no-op).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Queue ID does not exist or belongs to another customer. Fired by |
|
404 |
Queue-call ID (or reference ID) does not exist or belongs to another customer. Fired by |
Contact Reasons¶
Reasons fired by contact endpoints (/contacts, /contacts/{id}* and the /service_agents/contacts* agent-surface counterparts) and their nested phone-number, email, and tag sub-resources.
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Contact ID does not exist or belongs to another customer. Fired by |
|
404 |
Phone-number ID does not exist on the supplied contact. Fired by |
|
404 |
Email ID does not exist on the supplied contact. Fired by |
|
404 |
Tag ID is not currently associated with the supplied contact. Fired by |
Extension Reasons¶
Reasons fired by extension endpoints (/extensions, /extensions/{id}*, /service_agents/extensions*).
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Extension ID does not exist or belongs to another customer. Fired by |
Talk Reasons¶
Reasons fired by the agent-scoped talk surface (chats, channels, messages, participants, reactions) under /service_agents/talk_chats*, /service_agents/talk_channels, and /service_agents/talk_messages*. The talk surface is internal agent collaboration only — it does not deduct balance.
Note
TALK_MESSAGE_NOT_FOUND is intentionally distinct from MESSAGE_NOT_FOUND in the Message Reasons section above (which covers SMS messages under /messages); the two share no code path despite the similar shape.
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
404 |
Chat ID does not exist or belongs to another customer. Fired by |
|
404 |
Talk message ID does not exist or belongs to another customer. Fired by |
|
404 |
Participant ID is not currently associated with the supplied chat. Fired by |
Timeline Reasons¶
Reasons fired by the timeline gateway endpoints: GET /aggregated-events, GET /timelines/{resource_type}/{resource_id}/events, GET /timelines/calls/{call_id}/sip-analysis, and GET /timelines/calls/{call_id}/pcap. These endpoints do not yet emit timeline-specific not-found reasons of their own — generic not-found, permission, and validation conditions surface as the cross-cutting reasons (RESOURCE_NOT_FOUND, PERMISSION_DENIED, INVALID_ARGUMENT, INTERNAL) documented in the Generic / Cross-cutting Reasons table above.
The aggregated-events and resource-events endpoints additionally emit INVALID_ARGUMENT with the following resource-specific sub-reasons for syntactically invalid query-param or path-enum input:
Reason |
HTTP |
Cause → Fix |
|---|---|---|
|
400 |
The |
|
400 |
The |
|
400 |
The |