Voice API errors return a non-2xx HTTP status and a JSON body with an error object holding a machine-readable code, a human-readable message and, for validation errors, a details object. Branch on the HTTP status and code, not on the message text, which can change.
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Only one of 'text', 'url', 'voiceml', 'stream_url' or 'application_id' may be provided",
"details": { "ignored_fields": ["Url"] }
}
}
details.ignored_fields lists body fields the API did not recognise. On success the same list appears in meta.ignored_fields.
Codes#
| HTTP | Code | Meaning | What to do |
|---|---|---|---|
| 400 | VALIDATION_ERROR |
A field is missing, out of range, or two instruction sources were sent | Read message and details; fix the request |
| 401 | UNAUTHORIZED |
Missing or invalid credentials | Check the key or Account SID and Auth Token |
| 402 | INSUFFICIENT_BALANCE |
Wallet too low for the call or purchase | Top up the wallet |
| 403 | FORBIDDEN |
The Account SID in the path is not your workspace | Use your own Account SID |
| 403 | NUMBER_NOT_OWNED |
from is not a number in your workspace |
Use a number you own |
| 403 | KYC_NOT_APPROVED |
Buying a number before KYC is approved | Complete KYC |
| 404 | NOT_FOUND |
The call, number or resource does not exist in this workspace | Check the ID and workspace |
| 409 | CALL_ENDED |
The call has already ended | Nothing to do |
| 409 | QUOTE_STALE |
A number's price changed since you loaded it | Reload and retry |
| 429 | CONCURRENCY_LIMIT |
All of the workspace's channels are in use | Retry after Retry-After seconds, or add channels in Billing |
| 429 | CPS_LIMIT |
Calls started faster than the workspace's calls-per-second limit | Slow down; retry after Retry-After seconds |
| 500 | INTERNAL_ERROR |
Something failed on our side | Retry with backoff; contact support with meta.request_id if it persists |
| 503 | SERVICE_UNAVAILABLE |
No route is available right now, or all routes are at capacity | Retry shortly |
Limit responses#
429 responses carry headers you can act on:
| Header | Meaning |
|---|---|
Retry-After |
Seconds to wait before retrying |
X-Channel-Limit, X-Channels-In-Use |
Channel limit and current usage (CONCURRENCY_LIMIT) |
X-CPS-Limit |
Calls-per-second limit (CPS_LIMIT) |
The body also includes limit, in_use and retry_after.
Phone number routing errors#
The number routing endpoints (PUT/v1/phone-numbers/{id}/inbound and related) use lower-case codes:
| HTTP | Code | Meaning |
|---|---|---|
| 400 | validation / bind_failed |
Invalid ID or body, for example a target without its URL |
| 404 | not_found |
Number not found in this workspace |
| 409 | inbound_conflict |
The number is bound to something set up outside these APIs; pass "force": true to take it over |
Call failures are not API errors#
A call that is accepted (201) but then does not connect is not an API error. Its result arrives as status, hangup_cause and call_outcome. See Call Events and Outcomes.