Platform
Errors
When a request fails, the HTTP status says what kind of failure it was and the body says exactly which. Every error has the same shape.
The shape of an error
402 Payment Required
{
"error": "Insufficient balance ($0.00). Please recharge to make calls.",
"code": "INSUFFICIENT_BALANCE",
"status": 402,
"balance": 0,
"currency": "USD"
}errorstringA sentence for a person to read. Good for logs; do not match on it, since the wording can change.
codestringA fixed name for the failure. This is what your code should branch on.
statusintegerThe HTTP status, repeated.
…anySome errors add fields of their own, such as balance here or retryAfterSeconds on a rate limit.
Validation errors
A body that does not match what the endpoint expects answers 400, with one entry in details for each thing that is wrong. Unknown fields are refused on the stricter endpoints, such as Start a call, so a typo in a field name shows up here instead of being silently ignored.
400 Bad Request
{
"error": "Invalid request body",
"code": "HTTP_ERROR",
"status": 400,
"details": [
{ "path": "participant.ttlSeconds", "message": "Too small: expected number to be >=60" },
{ "path": "", "message": "Unrecognized key: \"agent_id\"" }
]
}Codes
| Status | Code | What it means | What to do |
|---|---|---|---|
| 400 | HTTP_ERROR | The request is malformed. details or error says how. | Fix the request. |
| 400 | INVALID_JSON | The body is not valid JSON. | Fix the request. |
| 400 | AGENT_REQUIRED | A call was started without an agentId. | Send one. |
| 400 | URL_NOT_ALLOWED | A tool or webhook URL is not a public address. | Use a public http(s) URL. |
| 400 | CONFIG_VALIDATION_ERROR | A call’s config has a value that is not allowed. issues lists them. | Fix the config. |
| 400 | UNSUPPORTED_LANGUAGE | A call’s language is not one the platform lists, or the agent’s voice or transcription cannot follow it. | Send a language the agent can follow, or leave it out. |
| 401 | UNAUTHORIZED | The key is missing, wrong or revoked. | Check the key. |
| 402 | INSUFFICIENT_BALANCE | The workspace has no credit left. | Add credit. |
| 403 | FORBIDDEN | The key may not do this, or you named a workspace that is not yours. | Use a workspace key; drop userId. |
| 403 | ACCOUNT_SUSPENDED | The account has been suspended. | Do not retry. |
| 403 | CONFIG_FIELD_NOT_ALLOWED | A call’s config tried to set something outside prompt, vad, turn and call. | Set it on the agent instead. |
| 404 | NOT_FOUND | There is nothing with that ID in your workspace. | Check the ID. |
| 404 | AGENT_NOT_FOUND | A call named an agent that is not in your workspace. | Check the agentId. |
| 409 | HTTP_ERROR | The request does not fit the current state, such as speaking into a call that has ended. | Do not retry. |
| 429 | RATE_LIMITED | Too many requests in a minute. | Wait retryAfterSeconds, then retry. |
| 429 | WORKSPACE_CONCURRENCY_LIMIT_REACHED | The workspace is on as many calls as its plan allows. | Retry when a call ends. |
| 429 | CONCURRENCY_LIMIT_REACHED | The platform is at capacity. | Retry shortly. |
| 500 | INTERNAL_SERVER_ERROR | Something went wrong on our side. | Retry after a pause. |
Things worth knowing
- 404 also means “not yours”. Something in another workspace answers exactly as something that does not exist, so a 404 on an ID you are sure of usually means the wrong key.
- Which errors to retry.
429and5xxare worth retrying after a pause. Other4xxerrors will fail the same way again until the request changes. - A retry may repeat an action. If a request to start a call times out on your side, the call may still have been created. List recent calls before starting another.