Errors & limits
Errors use HTTP status codes and a JSON body:
{ "error": { "code": "insufficient_credits", "message": "Not enough credits for a session. Top up in the dashboard." } }
| Status | code | Meaning |
|---|---|---|
| 400 | invalid_request | A field is missing or out of range. The message names it. |
| 401 | invalid_api_key, unauthorized | Missing, wrong or revoked key or token |
| 402 | insufficient_credits | Top up or upgrade |
| 403 | plan_required | Your plan doesn't include this feature |
| 403 | account_suspended | Contact support |
| 403 | feature_unavailable | Not enabled yet (for example, cloning) |
| 404 | voice_not_found | Check GET /v1/voices |
| 429 | rate_limited | Slow down and retry with backoff |
| 502 | synthesis_failed | Upstream voice provider error. Retry. |
WebSocket close codes
| Code | Meaning |
|---|---|
4001 | Session time is up (maxMinutes reached) |
HTTP 401 on connect | Token invalid, or the expiresIn connect window passed |
HTTP 409 on connect | This token already has a live connection |
Realtime errors that don't end the session arrive as error events with code and message (for example agent_disabled, voice_forbidden, tts_error).