HTTP error codes
Status codes returned by the STT, TTS, Live Streaming, and WebSocket APIs — what each one means, why it happens, and how to fix it.
Speech-to-Text (ASR)
Returned by the /v1/asr/transcribe endpoint when submitting audio for transcription.
OK — transcription succeeded
What happened
Your audio was received and transcribed. The response body contains the transcript as JSON or raw text depending on the response_format you set.
What to do
Nothing - read the transcript from the response body. Check language and confidence fields if your use case needs them.
Created - resource successfully created
What happened
A new resource (e.g. a custom vocabulary or async job) was created on the server. The response body contains the new resource's id and initial status.
What to do
Store the returned id - you'll need it to poll for status or retrieve results later.
Accepted - queued for async processing
What happened
Your request was received and queued but hasn't been processed yet. The response body will include a job id and status: "processing". This is normal for long audio files submitted via the async endpoint.
What to do
Poll the job status endpoint with the returned id at a reasonable interval (e.g. every 5 s) until the status changes to completed or failed.
No Content - request succeeded, no body
What happened
The action completed successfully but there's nothing to return - typical for DELETE operations or config updates.
What to do
Treat this as success. Don't attempt to parse a response body - it will be empty.
Bad Request - missing or invalid fields
What happened
The request was malformed. Common causes: missing audio field, unsupported file format, invalid language code, or a field set to the wrong type. The detail field in the response body explains exactly what was wrong.
How to fix it
- Read the
detailmessage in the JSON body - it identifies the exact field. - Verify your audio is one of the supported formats (WAV, MP3, FLAC, OGG, M4A).
- Check that required fields like
audioandmodelare present. - Confirm field types match the schema (e.g.,
languagemust be an ISO 639-1 string).
Unauthorized - API key missing or invalid
What happened
The server could not verify your identity. Either no Authorization header was sent, the API key is incorrect, or the key has been revoked.
How to fix it
- Confirm you're sending
Authorization: Bearer <your-key>in every request. - Copy your key fresh from the dashboard - avoid extra spaces or newlines.
- If the key was recently rotated, update it in your app's config and redeploy.
- Check your dashboard to ensure the key is active and hasn't been revoked.
Forbidden - permission denied
What happened
Your credentials are valid but your account or API key doesn't have access to this resource. This differs from 401 - the server knows who you are, it just won't let you in.
How to fix it
- Confirm the resource belongs to your account (check the resource
id). - Verify your plan includes access to this feature or endpoint.
- Check that your API key has the required scopes enabled in the dashboard.
- Contact support if you believe access should be permitted.
Not Found - endpoint or resource doesn\'t exist
What happened
The URL path or resource ID you requested doesn't exist. Common causes: typo in the endpoint path, a stale resource id that was already deleted, or using a deprecated API version.
How to fix it
- Double-check the endpoint URL against the API reference.
- Confirm the resource
idstill exists (it may have been deleted). - Ensure you're targeting the correct API version prefix (e.g.,
/v1/).
Method Not Allowed - wrong HTTP verb
What happened
The endpoint exists but doesn't support the HTTP method you used (e.g., sending a GET to an endpoint that only accepts POST).
How to fix it
- Check the API reference for the correct method for this endpoint.
- Inspect the
Allowresponse header - it lists the accepted methods.
Request Timeout - client took too long to send
What happened
The server closed the connection because your client didn't finish sending the request within the allowed time. Usually caused by slow upload of large audio files on a poor connection.
How to fix it
- Check your upload speed - large files on slow connections will time out.
- Compress or reduce audio quality before uploading if file size is large.
- Increase your HTTP client's send timeout setting.
- Retry on a more stable network connection.
Conflict - request contradicts current state
What happened
Your request conflicts with the server's current state. For example, trying to create a resource with a name that already exists, or modifying a job that's already completed.
How to fix it
- Read the error
messageto identify what's in conflict. - Fetch the current state of the resource before modifying it.
- Use a unique name or identifier if creating a resource that already exists.
Payload Too Large - file or body exceeds size limit
What happened
The uploaded audio file or request body exceeds the maximum allowed size for a single synchronous request.
How to fix it
- Check the file size limit in the API reference for your plan tier.
- Compress the audio (e.g., lower bitrate MP3) to reduce file size.
- Split long recordings into shorter segments and submit them separately.
- Use the async transcription endpoint, which supports larger files.
Unsupported Media Type - format not accepted
What happened
The audio format or Content-Type header you sent isn't supported. Common causes: sending a video file, an uncommon codec (e.g., AMR-NB), or a mismatched Content-Type header.
How to fix it
- Convert your audio to a supported format: WAV, MP3, FLAC, OGG, or M4A.
- Set the
Content-Typeheader to match the actual file format (e.g.,audio/mpegfor MP3). - If sending JSON, ensure
Content-Type: application/jsonis set.
Unprocessable - audio or config rejected by the model
What happened
The request was structurally valid but the transcription engine rejected it. Common causes: corrupt or silent audio file, audio duration exceeds the limit, or an unsupported combination of model parameters.
How to fix it
- Play the audio locally to confirm it's audible and not corrupt.
- Check that the file duration is within the per-request limit (see rate limits).
- Remove non-default model parameters and retry with defaults first.
- Re-export or re-encode the audio if the file may be malformed.
Too Many Requests - rate limit reached
What happened
Your account has exceeded the allowed number of requests per minute (or per hour). Requests are being dropped until the window resets. Check the Retry-After response header for the exact wait time.
How to fix it
- Wait for the number of seconds in the
Retry-Afterheader, then retry. - Implement exponential back-off in your retry loop (e.g., 1 s → 2 s → 4 s).
- Queue requests client-side to stay within your tier's limits.
- If you regularly hit this limit, request a higher-throughput plan from the dashboard.
Internal Server Error - unexpected failure
What happened
Something went wrong on our side that wasn't caused by your request. This is almost always transient and resolves on its own.
How to fix it
- Wait 5–10 seconds and retry with the same request.
- Use exponential back-off for up to 3 retries before surfacing an error to users.
- If the error persists for more than a few minutes, contact support with the request ID.
- Report the issue with your request ID (from the
X-Request-Idheader) if it continues.
Bad Gateway - upstream returned an invalid response
What happened
The API gateway received a bad or unreadable response from an upstream service (e.g., the inference engine or an internal microservice). This is a server-side issue, not caused by your request.
How to fix it
- Wait a few seconds and retry - upstream errors are often momentary.
- Contact support if the error continues.
- If the error recurs consistently, report it with the
X-Request-Idheader value.
Service Unavailable - backend temporarily down
What happened
The inference backend (Triton) or cache layer (Redis) is temporarily unavailable. This typically happens during a deployment, a restart, or an unexpected outage and usually lasts under 60 seconds.
How to fix it
- Retry after 15–30 seconds.
- Honour the
Retry-Afterheader if present. - Contact support if the error continues.
- Consider queuing requests in your app so users aren't directly exposed to this error.
Gateway Timeout - request took too long
What happened
The request didn't complete within the gateway's processing window. Most common with long audio files (>10 min) submitted during peak load.
How to fix it
- Split long audio files into shorter segments (recommended: ≤5 min each) and submit them in parallel.
- Retry the same request during off-peak hours if the audio is short.
- Consider using the async transcription endpoint for files longer than 5 minutes.
- If timeouts are frequent for normal-length audio, contact support with the
X-Request-Id.
Text-to-Speech (TTS)
Returned by the /v1/tts/synthesize endpoint when generating speech from text.
OK - audio generated
What happened
Speech synthesis completed. The response body is the raw audio bytes in the format you requested via output_format (defaults to MP3).
What to do
Read the binary body as audio. Use the Content-Type header to confirm the audio format if needed.
Created - voice or resource successfully created
What happened
A new resource was created - for example, a custom voice clone or a saved pronunciation. The response body contains the new resource's id.
What to do
Store the returned id to reference this resource in future synthesis requests via the voice parameter.
Accepted - queued for async synthesis
What happened
Your synthesis job was accepted and queued but the audio isn't ready yet. The response body includes a job id and status: "processing".
What to do
Poll the job status endpoint using the returned id until status becomes completed, then download the audio from the provided URL.
No Content - request succeeded, no body
What happened
The action completed successfully with nothing to return - typical for deleting a custom voice or clearing a pronunciation dictionary entry.
What to do
Treat this as success. The response body is empty - don't try to parse it.
Bad Request - missing or invalid fields
What happened
The request body was malformed. Common causes: missing text field, unsupported voice ID, invalid output_format, or speed/pitch values outside the allowed range. The JSON body's detail key identifies the specific problem.
How to fix it
- Read the
detailkey in the error body — it names the offending field. - Confirm the
textfield is non-empty and within the character limit. - Verify the
voiceID exists in your account's voice library. - Check that numeric params like
speed(0.25–4.0) are within documented bounds.
Unauthorized - API key missing or invalid
What happened
The Authorization header is missing, the key is wrong, or it's been deactivated.
How to fix it
- Send
Authorization: Bearer <your-key>with every request. - Paste your key directly from the dashboard to avoid whitespace issues.
- Confirm the key is enabled in your account settings.
Forbidden - permission denied
What happened
Your credentials are valid but you don't have access to this resource. Common example: attempting to use a voice that belongs to a different account.
How to fix it
- Confirm the
voiceID belongs to your account. - Check that your plan includes access to the feature you're requesting.
- Verify your API key has the necessary scopes in the dashboard.
Not Found - endpoint or resource doesn\'t exist
What happened
The URL path or resource ID you referenced doesn't exist. Common causes: typo in the path, a voice or job id that was deleted, or targeting a deprecated API version.
How to fix it
- Check the endpoint URL against the API reference for exact spelling.
- Verify the resource
idis still valid (it may have been deleted). - Ensure you're using the correct API version prefix (e.g.,
/v1/).
Method Not Allowed - wrong HTTP verb
What happened
You used an HTTP method the endpoint doesn't support - for example, sending a GET to the synthesis endpoint instead of POST.
How to fix it
- Check the API reference to confirm the correct method for this endpoint.
- Read the
Allowresponse header for the list of accepted methods.
Request Timeout - client took too long to send
What happened
The server closed the connection before your client finished sending the request. Usually caused by a slow or unstable network connection.
How to fix it
- Check your network connection stability.
- Increase your HTTP client's connection and send timeout values.
- Retry the request on a more reliable connection.
Conflict - request contradicts current state
What happened
Your request conflicts with existing data - for example, creating a custom voice with a name that already exists in your account.
How to fix it
- Read the error
messageto identify the conflict. - Use a unique name or
idfor the new resource. - Delete or rename the existing conflicting resource first if you want to replace it.
Payload Too Large - text or body exceeds size limit
What happened
The request body (text input or audio sample for voice cloning) is larger than the maximum allowed per request for your plan.
How to fix it
- Split long text into smaller chunks (≤3,000 characters each) and synthesize them separately.
- For voice cloning uploads, trim or compress the audio sample to meet the size limit.
- Use the async TTS endpoint which supports larger payloads.
Unsupported Media Type - format not accepted
What happened
The output_format you requested or the Content-Type of the request body isn't supported. Also occurs when uploading an unsupported audio format for voice cloning.
How to fix it
- Set
output_formatto a supported value:mp3,wav,ogg, orflac. - Ensure your request body uses
Content-Type: application/json. - For voice sample uploads, use WAV or MP3 format.
Unprocessable - text or config rejected by the model
What happened
The request was structurally valid but synthesis failed. Common causes: text too long (exceeds per-request character limit), text contains only whitespace or unsupported characters, or SSML markup is invalid.
How to fix it
- Check the
detailfield for the synthesis failure reason. - Split long input into smaller chunks (recommended: ≤3,000 characters each).
- Strip or escape any special characters that may break SSML parsing.
- Validate your SSML against the SSML reference if you're using markup.
Too Many Requests - rate limit reached
What happened
You've exceeded the number of synthesis requests allowed in the current time window. The Retry-After header tells you exactly how many seconds to wait.
How to fix it
- Wait for the duration in
Retry-After, then retry. - Implement exponential back-off in your retry loop.
- Batch small texts into fewer requests where possible.
- Upgrade your plan if you consistently hit the limit in production.
Internal Server Error - unexpected failure
What happened
An unexpected error occurred on our servers. Your request was not processed. This is almost always transient.
How to fix it
- Wait 5–10 seconds, then retry the identical request.
- Use exponential back-off for up to 3 automatic retries.
- Contact support with the
X-Request-Idif the problem persists.
Bad Gateway - upstream returned an invalid response
What happened
The API gateway got a bad response from an upstream service (e.g. the synthesis engine). This is a server-side issue - your request was valid.
How to fix it
- Retry after a few seconds - these errors are usually transient.
- Contact support with the
X-Request-Idif the error recurs.
Service Unavailable - synthesis backend down
What happened
The Triton inference server or Redis cache is temporarily unavailable, typically during a deploy or restart. Usually resolves within 30–60 seconds.
How to fix it
- Retry after 15–30 seconds.
- Contact support if the error continues.
- Queue pending synthesis requests so users see a loading state rather than an error.
Gateway Timeout - synthesis took too long
What happened
The synthesis job exceeded the gateway's time limit before completing. Most common with very long texts during peak hours.
How to fix it
- Break your text into shorter segments (≤3,000 characters) and synthesize them in parallel.
- Retry the same request once - it may have been a transient spike.
- Use the async TTS endpoint for long-form content that exceeds the synchronous limit.
- Report repeated timeouts for short texts to support with the
X-Request-Id.
WebSocket close codes
Returned by the Live Streaming and WebSocket APIs when a connection is closed. Check your WebSocket client's CloseEvent.code property to identify which code was received.
Normal Closure - session ended cleanly
What happened
The WebSocket connection was closed intentionally by either side after completing its purpose. This is expected behaviour at the end of a streaming session.
What to do
Nothing - the session ended successfully. Open a new connection when you're ready to start another session.
Endpoint Going Away - server shutting down
What happened
The server endpoint is going offline - typically a planned restart or rolling deployment. The connection was closed gracefully before shutdown.
How to fix it
- Reconnect after a short delay (5–10 seconds).
- Implement automatic reconnection logic in your WebSocket client.
- Resume the session from the last acknowledged checkpoint if your protocol supports it.
Protocol Error - WebSocket handshake or framing violation
What happened
The client sent a frame that violates the WebSocket protocol - for example, a malformed control frame or an invalid opcode.
How to fix it
- Use a well-tested WebSocket library rather than a hand-rolled implementation.
- Ensure you're following the correct framing format defined in RFC 6455.
- Check your client library version - upgrade if outdated.
Unsupported Data - wrong message type
What happened
The server received a message type it doesn't support - for example, sending binary frames to an endpoint that expects text (JSON), or vice versa.
How to fix it
- Check the API reference to confirm whether the endpoint expects text or binary frames.
- For live transcription, ensure you're sending raw audio as binary frames.
- For control messages, ensure you're sending JSON as text frames.
Abnormal Closure - connection dropped unexpectedly
What happened
The connection was lost without a proper close handshake. This usually means a network interruption, a server crash, or an intermediate proxy killing the connection (e.g. idle timeout).
How to fix it
- Implement automatic reconnection with exponential back-off.
- Send periodic ping frames to keep the connection alive through idle-timeout proxies.
- Check your network stability - this is often a connectivity issue on the client side.
- If it occurs consistently on good networks, contact support.
Invalid Payload Data - message content unreadable
What happened
The server received a text frame that wasn't valid UTF-8, or a binary payload that couldn't be parsed as expected audio data.
How to fix it
- Ensure all JSON control messages are encoded as valid UTF-8 text.
- Confirm audio is being sent in a supported format and encoding.
- Validate JSON payloads against the schema before sending.
Policy Violation - message broke an application rule
What happened
The message was technically valid but violated a server-side policy - for example, sending a message larger than the allowed limit, or sending a command that isn't permitted in the current session state.
How to fix it
- Review the streaming API reference for valid message types and session states.
- Ensure you're sending messages in the correct sequence (e.g.,
startbefore audio data). - Check that individual message sizes are within the documented per-message limit.
Message Too Large - single frame exceeds size limit
What happened
A single WebSocket message exceeded the server's maximum allowed message size. The server closed the connection immediately upon detecting this.
How to fix it
- Send audio in smaller chunks - the recommended chunk size is 100–500 ms of audio at a time.
- Check the API reference for the maximum frame size for your streaming endpoint.
- Reduce your audio buffer size in the client before sending.
Internal Error - unexpected server-side failure
What happened
The server encountered an unexpected condition that prevented it from continuing the session. This is a server-side error and was not caused by your messages.
How to fix it
- Reconnect and retry the session after a short delay.
- If the error recurs consistently, contact support.
- Report the issue to support with timestamps and the session ID if available.
Service Overloaded - server at capacity
What happened
The streaming server is temporarily overloaded and couldn't accept or continue your session. Connections are being shed until load drops.
How to fix it
- Wait 10–30 seconds before attempting to reconnect.
- Use exponential back-off for repeated reconnection attempts.
- Contact support if the error continues.
- If you're hitting this frequently at scale, contact us about dedicated capacity options.