Errors
HTTP status codes, WebSocket error events, and error payload formats.
Error response formats
OpenAI format (/v1/audio/* endpoints)
Used for realtime WebSocket, offline HTTP, and session-token endpoints:
{
"error": {
"message": "API key is missing.",
"type": "invalid_request_error",
"code": "missing_api_key"
}
}
type is rate_limit_error for 429 responses, otherwise invalid_request_error.
Envelope format (Key management API)
{
"ok": false,
"error": {
"code": "admin_unauthorized",
"message": "Admin token required.",
"retryable": false
}
}
retryable is true for 429 and ≥500 responses.
HTTP error codes
| Code | HTTP | Cause | Client action |
|---|---|---|---|
missing_api_key | 401 | No Authorization header / query token | Add API key |
invalid_api_key | 401 | Key format invalid or unknown | Check key |
revoked_api_key | 401 | Key has been revoked | Contact provider |
expired_api_key | 401 | Key has expired | Re-provision |
auth_unavailable | 503 | Key store unavailable | Retry later |
invalid_session_token | 401 | Session token invalid or expired | Obtain new token |
token_issuer_unavailable | 503 | Token issuer not configured | Retry later |
websocket_required | 426 | Non-WS upgrade request | Use WebSocket client |
gateway_disabled | 503 | Realtime gateway disabled | Contact provider |
upstream_unavailable | 503 | Upstream unavailable (circuit breaker) | Back off and retry |
connection_rate_limited | 429 | Connection rate exceeded | Honor Retry-After |
concurrent_connection_limit | 429 | Max concurrent connections exceeded | Wait for release |
request_rate_limited | 429 | Request rate exceeded | Honor Retry-After |
audio_quota_exhausted | 429 | Audio window budget exhausted | Retry later |
audio_too_long | 413 | Single request audio exceeds plan limit | Reduce audio duration |
internal_error | 500 | Uncaught exception | Contact provider |
bad_request | 400 | Invalid request body | Fix and retry |
WebSocket error events
Within an active WebSocket connection, the server may send error events:
{ "type": "error", "code": "...", "message": "...", "request_id": "..." }
WebSocket error codes
| Code | Description | Close code |
|---|---|---|
audio_frame_too_large | Audio frame exceeds 1 MiB | 1009 |
concurrent_utterance_limit | Concurrent utterance limit exceeded | — |
upstream_backpressure | Upstream backpressure | 1013 |
client_backpressure | Client backpressure | — |
upstream_unavailable | Upstream unavailable | 1013 |
idle_timeout | Idle timeout reached | 4408 |
session_duration_limit | Session duration exceeded | 1008 |
session_audio_limit | Session audio budget exceeded | 1008 |
audio_quota_exhausted | Audio quota exhausted | 1008 |
bad_json | JSON parse failure | — |
bad_message | Invalid message type | — |
invalid_audio | Invalid audio data | — |
Key management API errors
| Code | HTTP | Description |
|---|---|---|
admin_unauthorized | 401 | Missing admin token |
invalid_plan | 400 | Unknown plan |
invalid_expiry | 400 | Invalid or past expiry date |
store_unavailable | 500 | R2 storage unavailable |
key_not_found | 404 | Key ID not found |
not_found | 404 | Unknown management route |
Troubleshooting
| Problem | Check |
|---|---|
401 missing_api_key | Ensure request includes Authorization: Bearer sk-... |
401 invalid_api_key | Verify key starts with sk-, length ≥ 16 |
429 *_rate_limited | Honor Retry-After header, exponential backoff |
503 upstream_unavailable | Check /readyz for upstream status |
WS idle_timeout | Keep sending audio frames, or close explicitly |
WS audio_frame_too_large | Reduce frame size to ≤ 1 MiB |
Related
- Authentication — auth methods
- Reconnection & Retries — retry strategies
- Rate Limits — plan limits
