HTTP errors
We use standard HTTP status codes to indicate the success or failure of a request:
- 400 -
bad_request: The request is malformed or contains invalid content. - 401 -
unauthorized: A usage limit was exceeded for this API key. - 403 -
forbidden: Your API key is missing, invalid, or doesn't have permission to access this resource. - 404 -
not_found: The requested resource doesn't exist. - 429 -
too_many_requests: You've hit a rate or billing limit. Slow down and retry with backoff. - 5xx -
server_error: Something went wrong on our end. Retry with exponential backoff.
Error shapes
We return errors as JSON.
400 Bad Request
{
"error": "Voice 'foo' not found."
}Streaming errors
When you consume a streaming response — binary audio chunks from POST /v1/ai/speech/bytes or messages from a speech session WebSocket — an error that occurs after the initial 200 (or successful WebSocket handshake) won't be delivered as a JSON error body.
- For the streaming bytes endpoint, we terminate the connection and reset the underlying HTTP/2 stream.
- For the WebSocket session, we send a close frame with a status code and reason describing the failure.
Treat an early end-of-stream as a potential mid-flight error rather than a clean completion.
Long requests
Some networks drop idle TCP connections after a variable period, which can cause long-lived non-streaming requests to fail without a response. To synthesize a large amount of text, split it into smaller requests or use one of the streaming endpoints, which deliver audio continuously and keep the connection active.