Complete Error Code Reference
Table of Contents
- Error Response Format
- Severity Levels
- Authentication Errors
- Plan and Usage Limit Errors
- Ticket Authentication Errors
- Session Errors
- Speech Recognition Errors
- Audio Processing Errors
- Speaker Diarization Errors
- Multi-Channel Errors
- Speaker Errors
- Configuration Errors
- Record Type Restriction Errors
- Translation Service Errors
- TTS Synthesis Errors
- Recording Errors
- File Import Errors
- Storage Errors
- SSE Errors
- Broadcast Errors
- Conversation Errors
- Summary Errors
- Retranslation Errors
- Language Switch Errors
- Recording Name Errors
- General Errors
- Frontend Error Handling Example
Error Response Format
All API errors use a unified format:
{
"type": "error",
"data": {
"error_code": "auth_invalid_api_key",
"severity": "fatal",
"message": "Invalid API key",
"context": "auth",
"request_id": "req_abc123xyz789",
"timestamp": "2025-12-25T10:30:45.123Z",
"details": null
}
}
| Field | Type | Description |
|---|---|---|
error_code | string | Error code (for programmatic handling) |
severity | string | Severity level: fatal / error / warning |
message | string | Human-readable error message |
context | string | Error source category |
sid | int | Optional. Sentence number for sentence-level errors (e.g., when a sentence fails to translate); not included for non-sentence-level errors |
request_id | string | Request tracking ID |
timestamp | string | Time the error occurred (ISO 8601) |
details | object | Additional debugging information; common keys in translation scenarios: provider, translation_language, source_lang |
Severity Levels
| severity | Description | Recommended Handling |
|---|---|---|
fatal | Fatal error | Stop the service and require reconnection |
error | Operation failed | Show an error prompt and allow retry |
warning | Warning | Show a warning without blocking the operation |
Sentence-level error rule (important): When an error message includes the
sidfield, regardless of theseverity, it should be treated as a sentence-level error (a single sentence failed). The client only needs to mark that sentence as failed and continue; it should not disconnect. Afatal+sidcombination only means "this sentence failed severely"; the session as a whole can still continue operating.In other words, the "stop the service / require reconnection" recommendation applies only to session-level fatal errors that do not include
sid.Also note that some
fatalerrors withoutsiddo not close the connection (for example,auth_quota_exceededandplan_feature_not_allowed); whether you need to reconnect depends on the description of each error code.
Authentication Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
auth_missing_api_key | 401 | fatal | API Key is missing | Make sure the request includes an API Key |
auth_invalid_api_key | 401 | fatal | Invalid API key | Make sure the API Key is correct |
auth_invalid_key_format | 401 | fatal | Invalid API key format | Make sure the API Key starts with vas_ |
auth_key_expired | 401 | fatal | API Key has expired | Request a new API Key |
auth_key_disabled | 401 | fatal | API Key is disabled | Contact technical support |
auth_user_disabled | 403 | fatal | Account is disabled | Contact technical support |
auth_account_blocked | 403 | fatal | Account is blocked | Contact technical support |
auth_ip_not_allowed | 403 | fatal | Source IP not allowed | Access from an authorized IP address |
auth_insufficient_credit | 402 | fatal | Insufficient credit | Top up your credit balance |
auth_quota_exceeded | 402 | fatal | Available credits are insufficient; the recording did not start (checked on WebSocket start: less than one minute for real-time recording, depleted for broadcasts; the connection is not closed; see "Available Credit Fields" below for details.remaining_budget and details.budget_scope) | Top up and send start again, or wait for the quota period to reset |
auth_account_expired | 401 | fatal | The account's service has expired. Not currently returned by any endpoint; reserved for future use | Contact technical support or renew |
auth_service_error | 500 | fatal | Authentication service temporarily unavailable (when it occurs on WebSocket start, the recording does not start and the connection is not closed) | Retry later |
Plan and Usage Limit Errors
Applies to API Keys on an "unlimited plan" (added in v1.9.0; see Pricing — Unlimited Plans). When blocked by any of the errors below, use GET /api/v1/me/plan to look up "what does my plan include, how far am I from a limit, and when does the restriction lift".
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
plan_feature_not_allowed | 403 | fatal | The plan does not include the feature in use | Use features included in your plan, or upgrade the plan; query GET /api/v1/me/plan for the plan contents |
concurrency_limit_reached | — | error | This API Key has reached its concurrent recording limit | The connection is not closed; the slot is released when the server sends task_complete, so you can start the next recording once you receive it |
daily_limit_disconnect | — | error | The plan's usage threshold was reached; the current recording was stopped | You may start a new recording immediately (when restarting on the same connection, session_started arrives after the previous recording finishes processing) |
daily_limit_reached | — | fatal | Usage has reached the plan's limit | Available again after the plan's reset (daily limits reset the next day) |
plan_daily_limit_reached | 402 | error | The plan's daily usage limit has been reached (REST pre-check gate) | Obtain a Ticket or upload the import again after the plan's reset |
The two occurrence points of
plan_feature_not_allowed(WebSocket):
startrejected: when the plan does not include a feature enabled in the request, thestartis rejected; the connection is not closed — adjust the parameters andstartagain.- Detected while recording: for example, a feature not in the plan is turned on mid-session; once the check before the next minute detects it, the current recording is stopped.
For real-time recording, usage limits are checked before each minute begins; once a limit is reached, the next minute does not start and is not counted toward usage. When the same API Key runs several recordings at once, after the periodic-stop threshold is reached, each recording stops before its own next minute begins.
REST scenarios returning HTTP 403:
POST /api/v1/broadcasts(creating a broadcast with a plan-bound key — broadcasts are never included in unlimited plans),POST /api/v1/auth/tasks/{taskId}/subtitle-feed-tokenandsubtitle-share(plan without floating subtitles), andPOST /api/v1/imports(plan without audio import).
plan_daily_limit_reached(HTTP 402) occurs onPOST /api/v1/auth/ticketand the import upload: when the plan's daily hard limit has been reached, new recordings / imports are blocked up front. The same string also appears as thedata.reasonofPOST /api/v1/imports/check-quota; that endpoint is a read-only query and returns HTTP 200, not an error.
too_many_languagessemantics extended (v1.9.0):details.maxmay come from the plan's cap on simultaneously recognized transcription languages, in addition to the system-wide limit (10 transcription languages);detailscarriesmaxandreceived.
Ticket Authentication Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
ticket_invalid | 401 | fatal | Ticket invalid or expired | Obtain a new Ticket |
ticket_expired | 401 | fatal | Ticket has expired | Obtain a new Ticket |
ticket_already_used | 401 | fatal | Ticket already used | Each Ticket can be used only once |
ticket_validation_failed | 401 | fatal | Ticket validation failed | Make sure the Ticket format is correct |
Session Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
session_not_found | 404 | error | Session not found | Make sure the session ID is correct |
session_expired | 400 | error | Session expired | Create a new session |
session_not_started | 400 | error | Recording not started yet, or this recording has already ended (including while it is still being processed after ending) | Call start first if it has not started; if this was a duplicate stop, the error can be ignored |
session_already_paused | 400 | warning | Already paused | You can ignore this error |
session_not_paused | 400 | warning | Not paused | You can ignore this error |
service_shutdown | — | warning | Service shutting down, please reconnect | Broadcast to all active connections when the service shuts down normally (for example, for a maintenance update). A connection that is not recording is closed about 2 seconds after the notice; a connection that is recording can finish the recording, still receives task_complete after stop, and is closed after that. A start sent while the service is shutting down also receives this error: no recording is started, and the connection is closed afterwards. Clients should display a maintenance notice and, once the connection closes, reconnect after a brief backoff; if a start was rejected, send start again after reconnecting |
resume_token_invalid | — | error | Resume token invalid or not found | Session resume failed; obtain a new Ticket and send a fresh start, but do not automatically start a new recording if the user has already ended the recording (see Connection - Session Resume) |
resume_grace_expired | — | error | Resume grace period expired | Same as above |
resume_ownership_mismatch | — | error | Resume token ownership mismatch | Same as above |
resume_unavailable | — | error | Resume temporarily unavailable (this connection cannot resume the original session; also returned when the original session has been sent stop or has been ended and is still being processed) | Same as above |
set_speaking_speed_failed | 400 | error | Failed to change speaking speed (rebuilding recognition failed) | Retry later |
Speech Recognition Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
stt_init_failed | 503 | fatal | Service initialization failed | Retry later |
stt_start_failed | 500 | fatal | Unable to start speech recognition | Retry later |
stt_auth_failed | 500 | fatal | Service authentication failed | Contact technical support |
stt_quota_exceeded | 402 | fatal | Available credits are insufficient (real-time recording: the recording has ended, checked before the next minute begins, and see "Available Credit Fields" below for details.remaining_budget and details.budget_scope; imports, retranslation, summary regeneration, and similar: the request was not carried out, see each endpoint) | Top up and try again |
stt_connection_lost | 500 | fatal | Connection lost | Stop the service and reconnect |
stt_silence_timeout | - | fatal | No speech was detected for a continuous period (15 minutes by default, adjustable with silenceTimeoutSeconds in start), so the recording ended automatically (details.silence_seconds is the threshold in seconds). The count does not run while paused, while waiting to resume after a disconnect, or for broadcasts; see Automatic End After a Long Silence | Check that the microphone is picking up sound; to continue, start a new recording. This is a WebSocket event and has no HTTP status code |
stt_silence_warning | - | warning | No speech has been detected for a while and the recording will end automatically soon (details.silenceSeconds is how long the silence has lasted, details.remainingSeconds is the time remaining). The recording continues | Alert the user; recognized text or resuming the recording restarts the count. This is a WebSocket event and has no HTTP status code |
Starting again after a recording is ended: after an error that ends the recording, such as
stt_quota_exceeded,stt_silence_timeout,plan_feature_not_allowed, ordaily_limit_disconnect, you can sendstarton the same connection immediately, butsession_startedarrives only after the previous recording finishes processing (afterstatus: "ended"), which can take from a few seconds to a few tens of seconds depending on the summary length. Do not treat this as a timeout.
Audio Processing Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
audio_invalid_format | 400 | error | Invalid audio data format | Make sure the audio format is correct |
audio_process_failed | 500 | error | Audio processing failed | Retry later |
audio_format_unsupported | 400 | error | Unsupported audio format | Use a supported format |
audio_decode_failed | 500 | error | Audio decoding failed | Verify the integrity of the audio file. During a live recording: The recording continues; for WebM, send a new container (with its header) to recover. Time that cannot be decoded is not billed |
Speaker Diarization Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
diarization_init_failed | 503 | fatal | Diarization service initialization failed | Retry later |
diarization_start_failed | 500 | fatal | Diarization session failed to start | Retry later |
diarization_failed | 500 | error | Diarization processing failed | Retry later |
diarization_unavailable | 503 | fatal | Diarization service unavailable | Verify the service status |
diarization_multilang_conflict | 400 | error | Speaker diarization does not support multiple languages (start rejected); two-way translation (conversation) is exempt as of v1.7.2 | Provide only one source language, or disable speaker diarization |
Multi-Channel Errors
Applies to multi-channel mode (recognition_mode: "multi_channel", added in v1.10.0; see WebSocket API Reference – Voice Translation for the parameters and channel operations, and Pricing for billing). All errors below are WebSocket errors with no corresponding HTTP status code.
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
channel_mode_required | — | error | Multi-channel mode requires channel_mode | Send channel_mode (per_channel or shared) |
invalid_channel_mode | — | error | Invalid channel_mode | Allowed values are per_channel and shared; if shared is not enabled in this environment, this error is also returned with a message — use per_channel instead |
channels_required | — | error | Multi-channel mode requires channels | Provide 1–8 channels (including the main speaker, channel_id: 1 by convention) |
too_many_channels | — | error | Too many channels | Reduce the channel count; the limit is 8. details carries max / received |
invalid_channel_id | — | error | Invalid or duplicate channel_id | channel_id must be an integer from 1 to 8 and must not repeat |
channel_language_required | — | error | Each channel must specify exactly one language | Provide exactly 1 language in each channel's transcription_languages |
channel_language_not_allowed | — | error | shared mode does not support per-channel languages | In shared mode the language is shared by the whole session: channels in start / add_channel must not carry transcription_languages, and it cannot be changed with set_channel_language during the recording |
channel_language_mismatch | — | error | Channel languages do not match transcription_languages | The union of all channels' languages must match the session-level transcription_languages |
channel_id_required | — | error | Multi-channel mode requires channel_id | In multi-channel mode every audio frame must carry channel_id; channel operations must carry it as well |
unknown_channel_id | — | error | Unknown channel_id | Make sure the channel was declared in start or add_channel and has not been removed |
multichannel_tts_not_allowed | — | error | Multi-channel mode does not support speech synthesis | Disable tts_enabled |
multichannel_broadcast_not_allowed | — | error | Broadcast does not support multi-channel mode | Use a different recognition mode for broadcasts |
multichannel_requires_pcm | — | error | Multi-channel mode only supports the PCM audio format | Use "pcm" for audio_format (16kHz / 16-bit / mono) |
multichannel_switch_language_not_allowed | — | error | Multi-channel mode does not support switch_language | Languages are bound to channels; use set_channel_language instead |
channel_id_in_use | — | error | This channel_id has already been used and cannot be reused | Channel IDs are never reused (including removed channels); pick a new ID for add_channel |
channel_remove_not_allowed | — | error | This channel cannot be removed | The last remaining channel cannot be removed; use stop to end the recording |
channel_action_while_paused | — | error | Channels cannot be added or removed while paused; resume the recording first | resume first, then perform the channel operation |
not_multi_channel_session | — | error | This recording is not in multi-channel mode | Channel operations only apply to recordings with recognition_mode: "multi_channel" |
channel_rebuild_too_frequent | — | error | Settings on this channel are being changed too frequently; try again later | Only one settings change per channel is accepted every 5 seconds; details carries cooldown_seconds |
Multi-channel semantics of existing error codes:
invalid_recognition_mode: when the multi-channel feature is not enabled in this environment, astartwithrecognition_mode: "multi_channel"returns this error;detailscarriesfield: "recognition_mode"andreceived_value.invalid_parameter: returned on conflicting parameter combinations —multi_channelcombined withspeaker_diarization(multi-channel is itself a form of speaker separation);type: "conversation"combined withmulti_channel; aset_channel_languagethat switches to the channel's current language, carries more than one language intranscription_languages, or provides bothtranscription_languagesandlanguageinconsistently; achannels[].speaker_namethat is too long or contains control characters.plan_feature_not_allowed(details.field: "max_stt_streams"): the channel count instartoradd_channelexceeds the unlimited plan's channel limit;detailsalso carriesmaxand the current count.too_many_languages:add_channel/set_channel_languageintroduces a new language that pushes the number of simultaneously recognized languages past the platform limit (10) or the plan's cap;detailscarriesmax/received/language.There is also
speaker_op_not_allowed_multi_channel(HTTP 422 on REST): for multi-channel recordings the speakers are determined by the channels, so speaker operations are limited to renaming; reassign and merge return this error both during recording (WebSocket) and afterwards (REST) — see Speaker Errors.
Speaker Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
speaker_not_found | 422 | error | The specified speaker was not found | Make sure the speaker ID is correct |
speaker_sid_not_found | 422 | error | The specified sentence was not found | Make sure the sentence ID is correct |
speaker_name_empty | 422 | error | Speaker name cannot be empty | Provide a speaker name |
speaker_name_duplicate | 422 | error | Speaker name already in use | Use a different name |
merge_speakers_same_id | 400 | error | Source and target speaker cannot be the same | Provide different speaker IDs |
speaker_op_not_allowed_multi_channel | 422 | error | This speaker operation is not supported for multi-channel recordings (added in v1.10.0) | In multi-channel mode the speakers are determined by the channels; only rename is available — reassign / merge return this error |
Configuration Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
config_empty | 400 | error | No configuration provided. An empty object {} does not count as "provided" | Provide at least one setting that has content; to clear a glossary, send {"lang": []} |
config_term_too_long | 400 | error | Term exceeds 100 characters | Shorten the term |
config_too_many_entries | 400 | error | More than 500 terminology entries, or more than 4000 fuzzy correction rules (both across all languages combined, not per language). details carries count and max; fuzzy correction also carries field | Remove terms or correction rules |
config_too_many_dict_entries | 400 | error | More than 3000 dictionary entries for a single language (details.language names it) | Reduce the entries for that language |
config_invalid_entry | 400 | error | A field on one terminology entry or correction rule is invalid. details carries language, index, field and reason to locate it (some cases also carry variant_index), plus max_length or count/max depending on reason | Fix the entry at the position given in details |
config_ignored_in_start | - | warning | The glossary sent inside start was ignored; use the config action instead (details.ignored_fields lists what was dropped). start still succeeds | Send the glossary with the config action |
config_too_many_languages | 400 | error | A glossary block carries more language codes than allowed (details carries field / count / max). Used by the Glossary Validation API only | Reduce the number of language codes in that block |
config_payload_too_large | 413 | error | The request body exceeds the size limit. Used by the Glossary Validation API only | Send it in batches, or reduce the glossary content |
Record Type Restriction Errors
record (plain recording) is a lightweight speech-recognition-only type: translation and TTS are not supported, and summary is opt-in (generated only when summary_template or summary_mode=custom is provided). The following error codes are returned during the start phase when these restrictions are violated (since v1.7.0).
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
record_translation_not_allowed | 400 | error | Translation is not supported for record type | Remove translation_languages, or use the transcribe type |
record_tts_not_allowed | 400 | error | Text-to-speech is not supported for record type | Remove tts_enabled, or use a type that supports TTS |
record_summary_requires_template | 400 | error | Enabling summary for record type requires a template | Provide summary_template or use summary_mode=custom |
record_translation_not_allowedis also returned when calling retranslation endpoints (transcript retranslation, summary translation) on arecordrecording afterward.
Translation Service Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
llm_init_failed | 503 | fatal | Translation service initialization failed | Retry later |
llm_timeout | 504 | error | Translation timeout | Retry later |
llm_rate_limit | 429 | warning | Requests too frequent | Reduce the request frequency |
llm_request_failed | 500 | error | Translation request failed | Retry later |
llm_provider_error | 503 | error | Translation service temporarily unavailable | Retry later |
llm_content_filtered | 400 | warning | Content cannot be translated | Modify the input content |
llm_auth_failed | 500 | fatal | Translation service authentication failed | Contact technical support |
llm_deployment_not_found | 500 | fatal | Translation service configuration error | Contact technical support |
llm_quota_exceeded | 402 | fatal | Translation usage limit reached | Retry later |
translation_service_unavailable | - | error | Translation service has failed consecutively up to the threshold (session-level, no sid) | Show a global notice that translation is temporarily unavailable; no need to disconnect; STT continues to run |
The HTTP column in this table is a semantic annotation, not the status code you will receive. Translation service errors are delivered almost entirely as stream events (SSE
event: erroror WebSockettype: error), and the stream itself always returns HTTP 200. This column indicates which class the error belongs to so you can choose a retry strategy: 4xx means the input needs to change, while 5xx and 429 mean you can retry later. Readerror_codeandseverity; do not match this column against the status code you actually receive.
translation_service_unavailabletrigger rules:
- Cumulative escalation: escalates after
llm_timeout/llm_provider_error/llm_rate_limit/llm_request_failedfail repeatedly in a row- Immediate escalation:
llm_auth_failed/llm_deployment_not_found/llm_quota_exceededescalate on the first occurrence (configuration/billing issues)- Not counted:
llm_content_filtered(a content issue, not a service issue)- Deduplication: each session is notified only once; any successful sentence translation resets the counter, and the event can be triggered again
- payload:
type: "error", withoutsid;detailscontainsprovider,last_error_code,fail_count- Viewer notification: in broadcast mode, all viewers (regardless of language) also receive this event (through the SSE/WS broadcast channel)
TTS Synthesis Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
tts_init_failed | 503 | fatal | TTS service initialization failed | Retry later |
tts_not_enabled | 400 | warning | TTS not enabled | Make sure tts_enabled is set on start |
tts_invalid_language | 400 | error | TTS language invalid | Make sure the language is in translation_languages |
tts_invalid_voice | 400 | error | Invalid voice name. Returned only by the realtime voice channel — voice names are not validated when a broadcast is created, so an invalid value surfaces only when the broadcast starts | Verify the voice name with GET /api/v1/tts/voices before sending |
sentence_not_found | — | warning | The specified sentence was not found | Make sure the SID exists |
translation_not_found | — | warning | No translation found for that language | Make sure a translation exists for that language |
tts_translation_not_found | — | error | In TTS SSE Streaming, the sentence has no translation for the language. Delivered as a tts_error event; aborts the whole stream | Confirm the translation has completed and is non-empty |
tts_connection_failed | — | error | Speech synthesis connection failed | Retry shortly |
tts_timeout | — | error | Speech synthesis timed out | Retry shortly |
tts_synthesis_failed | 500 | error | TTS synthesis failed | Retry later |
tts_voice_not_found | 404 | error | The specified voice was not found, or its language cannot be used as a TTS target | Use only voices listed by GET /api/v1/tts/voices |
tts_sample_generation_failed | 500 | error | Voice sample generation failed | Retry later |
An HTTP column of
—means the code is not returned as an HTTP status. It is delivered after the connection is established, through anerrorortts_errorevent on the stream.
Recording Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
recording_not_found | 404 | error | Recording not found | Make sure the taskId is correct |
recording_unauthorized | 403 | error | Not authorized to operate on this recording | Make sure the task belongs to the user |
recording_audio_not_ready | 422 | error | Audio file not ready yet | Retry later |
recording_transcript_not_ready | 422 | error | Transcript not yet generated or empty | Make sure processing_status = completed before exporting |
recording_not_completed | 422 | error | Recording has not finished processing; retranslation/editing/summary regeneration is not allowed while in progress | Wait until processing_status = completed, then retry |
entry_not_found | 404 | error | The specified sentence was not found (sid does not exist in the transcript) | Make sure the sid is correct |
entry_text_empty | 422 | error | Sentence source text is empty (whitespace-only counts as empty) | Provide a non-empty original_text |
entry_text_too_long | 422 | error | Sentence source text exceeds the 2000-character limit | Shorten the content and retry |
transcript_revision_conflict | 409 | error | Transcript was modified by another request, or another write is in progress | Re-read the transcript to get the latest revision, then retry |
retranslate_segmentation_required | 422 | error | Full retranslation: the transcript is too long to translate in one request (details.sentenceCount is the number of sentences to translate, details.maxSentences is the limit). Returned before the stream starts; no charge | Send segmented=1 to retranslate in segments; see Retranslate SSE |
task_already_processing | 409 | error | Another processing run for the same task has not finished yet; this request was not applied | Send the same request again later |
invalid_processing_status | 422 | error | Processing status does not meet the operation requirement | See the "Processing Status Mismatch (invalid_processing_status)" section below |
Available Credit Fields (remaining_budget and budget_scope)
The details of auth_quota_exceeded and stt_quota_exceeded carry these two fields.
| Field | Description |
|---|---|
remaining_budget | The available credit as of the most recent settlement; before any settlement has happened, it is the value at connection time. It is always null when budget_scope is api_key_unlimited |
budget_scope | States whose credit the number above refers to. There are currently two values, listed below |
budget_scope | Meaning | remaining_budget in the same details |
|---|---|---|
api_key_credit | The API key used for this request is on pay-as-you-go, and the number is the credit that key can currently draw on | a number |
api_key_unlimited | The API key used for this request is bound to a plan, so "remaining credit" does not apply | null |
Important: remaining_budget is the credit available to the API key that made this request — not the end user's balance.
If you call this service on behalf of other users, do not show this number directly to your end users;
it reflects the state of your own key.
Note: Broadcasts are billed separately: even when a key is bound to a plan, broadcasts are charged by actual usage.
So for a broadcast session these two codes carry budget_scope: api_key_credit and a real remaining_budget.
Processing Status Mismatch (invalid_processing_status)
This error code is used by POST /api/v1/tasks/{taskId}/force-fail, POST /api/v1/tasks/{taskId}/retry, and DELETE /api/v1/tasks/{taskId}, returned when the recording status does not meet the operation's prerequisites. The details field helps further identify the trigger reason:
| Endpoint | Trigger Condition | Fields in details | Recommended Handling |
|---|---|---|---|
force-fail | Recording is already in a terminal state (completed / failed) | current_status, message | For completed tasks, use DELETE /api/v1/tasks/{taskId} instead; failed tasks do not need to be force-failed again |
DELETE | Task is still being processed (not completed / failed), or the task's import is still being processed | task_id, current_status, message | Wait until the task completes or fails; for a stuck recording, use force-fail first. If the import is still being processed, wait until it finishes. Batch deletion does not return this error; skipped tasks are listed in skipped_task_ids instead |
retry | Recording is not in the failed state | current_status, message | Only failed tasks can be retried |
retry | Audio file or transcript has not finished uploading | current_status, audio_status, transcript_status, message | Make sure the source file is complete; if the recording source is corrupted, use force-fail to close it out instead |
Task Already Processing (task_already_processing)
POST /api/v1/tasks/{taskId}/retry returns this code when another processing run for the same task has not finished yet. Unlike invalid_processing_status, this condition is temporary: the request does not change the task status, and the same request succeeds once the previous run finishes.
| Endpoint | Trigger Condition | Fields in details | Recommended Handling |
|---|---|---|---|
retry | Another processing run for the same task has not finished yet | task_id, message | Send the same request again later; no parameter changes are needed |
Note: After a task fails, the system retries it automatically a few times. During that period processing_status may already read failed while a retry request still returns 409 — this means the automatic retries have not finished. No action is needed; send the same request again a few minutes later.
File Import Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
import_not_found | 404 | error | Import task not found | Make sure the import_id is correct |
import_file_too_large | 413 | error | File size exceeds the limit | Compress or split the file |
import_invalid_format | 415 | error | Unsupported audio format | Use mp3/wav/m4a format |
import_recognition_mode_unsupported | 422 | error | This recognition_mode is not supported for file imports; use single or multi_speaker. details carries field and supportedModes | Use single or multi_speaker |
import_duration_out_of_range | - | error | Audio duration is outside the allowed range (minimum 1 second, maximum 10 hours). Reported through the failed event of import progress | Use audio within the allowed length, or split it and import in parts |
import_download_failed | 500 | error | Download failed | Retry later |
import_conversion_failed | 500 | error | Conversion failed | Verify the integrity of the audio file |
import_stt_timeout | 504 | error | Speech recognition timeout | Retry later |
import_stt_failed | 500 | error | Speech recognition failed | Retry later |
import_translation_failed | 500 | error | Translation processing failed | Retry later |
import_summary_failed | 500 | warning | Summary generation failed | Retry later |
import_upload_failed | 500 | error | Result upload failed | Retry later |
import_callback_failed | 500 | warning | Failed to report progress | Does not affect processing; can be ignored |
import_invalid_request | 500 | error | Invalid request format | Make sure the request format is correct |
go_service_error | - | error | The processing service is temporarily unavailable | Import again later |
dispatch_failed | - | error | The processing job could not be dispatched | Import again later |
job_failed | - | error | The processing job failed | Import again later |
PROCESSING_TIMEOUT | - | error | The import waited or ran too long and was marked as failed | Import again later |
unknown_error | - | error | Import processing failed | Import again later; if it keeps failing, contact support with the import_id |
Note: If the account has insufficient credit at upload time, the
auth_insufficient_crediterror (HTTP 402) is returned.Codes with
-in the HTTP column are not returned as HTTP status codes; they appear as theerror_codeof a failed import: in the import query API, in thefailedevent of the Import Progress SSE, and in theimport.failedWebhook. The matchingerror_messageis a fixed, general description without internal details; provide theimport_idwhen you need troubleshooting.
Storage Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
storage_connection_failed | 503 | error | Storage service connection failed | Retry later |
storage_upload_failed | 500 | error | Upload failed | Retry later |
storage_download_failed | 500 | error | Download failed | Retry later |
storage_queue_full | 500 | warning | Upload queue full | Retry later |
SSE Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
sse_transcript_not_found | 404 | error | Transcript not found | The recording may not have finished processing |
sse_translation_failed | 500 | error | Translation failed | Retry later |
sse_summary_not_found | 404 | error | Summary not found | This recording has no summary |
sse_summary_translation_failed | 500 | error | Summary translation failed (Retranslate Summary, Summary Translation). details.original_error of Translation timed out means the request timed out | Retry later |
sse_summary_regeneration_failed | 500 | error | Summary regeneration failed | Retry later |
sse_template_not_found | 404 | error | Summary template not found | Make sure the template slug is correct |
Broadcast Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
broadcast_not_enabled | 500 | error | Broadcast not enabled for the session | Verify the broadcast settings |
broadcast_token_invalid | 401 | fatal | Invalid share link | Stop the service and verify the share link |
broadcast_token_revoked | 401 | fatal | Share link revoked | Stop the service and create a new broadcast |
broadcast_token_already_used | 422 | error | Token already used by another Session | Close the other tabs and retry |
broadcast_token_required | 400 | error | Broadcast mode requires broadcast_token | Provide the broadcast_token parameter |
broadcast_session_not_found | 404 | error | Broadcast session not found | Make sure the broadcast Token is correct |
broadcast_session_not_started | 503 | error | Broadcast not started yet | Wait for the host to start the broadcast |
broadcast_not_ready | 503 | warning | Live translation service not started yet | Retry later |
broadcast_session_ended | 410 | error | Broadcast session ended | Wait for the host to start again |
broadcast_capacity_exceeded | 503 | warning | Maximum number of viewers exceeded | Wait in the queue or retry later |
broadcast_queue_timeout | — | error | Queue timeout | Try reconnecting |
broadcast_viewer_kicked | 403 | error | Removed by the host | Contact the host |
broadcast_unauthorized | 401 | error | Unauthorized access to the viewer management API | Verify your authentication information |
broadcast_password_required | 401 | error | This broadcast requires password verification | Provide the correct password |
broadcast_password_incorrect | 401 | error | Incorrect password | Verify the password and retry |
broadcast_not_in_standby | 500 | warning | Not currently in the standby phase | Wait for the host to switch to the standby phase |
broadcast_standby_warning | — | warning | The standby phase is about to reach its time limit (30 minutes by default; details carries standbySeconds, remainingSeconds, limitSeconds); the broadcast continues | Prompt the host to go live or start again |
broadcast_standby_timeout | — | fatal | The standby phase reached its time limit and the session ended automatically (details carries standbySeconds, limitSeconds). No recording exists during standby, so no task_complete follows | Get a new Ticket and send start; see the Broadcast Guide |
broadcast_cannot_revoke | 422 | error | Only broadcasts in the pending state can be revoked | Stop the broadcast before revoking |
broadcast_cannot_start | 422 | error | Cannot start the broadcast | Make sure the broadcast status is pending |
broadcast_already_live | 422 | error | A broadcast is already live | Stop the current broadcast first |
broadcast_not_live | 422 | error | No broadcast currently live | Start a broadcast first |
validation_failed | 422 | error | max_viewers exceeds the account viewer limit (the message carries the effective limit) | Lower max_viewers |
An HTTP column of
—means the code is not returned as an HTTP status. It is delivered after the connection is established, through anerrorortts_errorevent on the stream.
Conversation Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
conversation_requires_two_languages | 400 | error | Conversation mode requires exactly two languages | Provide exactly 2 transcription_languages |
conversation_languages_identical | 400 | error | The two conversation languages cannot be the same | Provide two different languages |
conversation_invalid_language | 400 | error | Invalid conversation language | Make sure the language is one of the transcription_languages |
conversation_same_language | 400 | warning | Already the current language | You can ignore this warning |
conversation_speaking | 400 | error | Currently speaking; cannot perform this action | Call stop_speaking to finish speaking first |
conversation_not_speaking | 400 | warning | Not currently speaking | You can ignore this warning |
conversation_invalid_speaker | 400 | error | Invalid speaker number | Use 1 or 2 |
conversation_invalid_mode | 400 | error | Invalid conversation mode | Use auto or manual |
conversation_not_manual_mode | 400 | error | This action requires manual mode | Switch to manual mode first |
conversation_missing_speakers | 400 | error | No longer returned since V1.24.0, because speakers is now optional | No action needed |
conversation_invalid_speakers | 400 | error | Invalid speakers format | Make sure exactly 2 speaker configurations are provided |
conversation_language_change_failed | 500 | error | Language change failed (STT rebuild failed) | Retry later |
conversation_language_same_as_peer | 400 | error | New language is the same as the other user's | The two users cannot use the same language |
Handling strategy:
| Error Code | Retry? | Handling |
|---|---|---|
conversation_requires_two_languages | No | Show "Please provide exactly 2 languages" |
conversation_languages_identical | No | Show "The two languages cannot be the same" |
conversation_invalid_language | No | Show "Invalid language" and use the language from start |
conversation_same_language | No | Can be ignored; already the current language |
conversation_speaking | No | Show "Please finish speaking first" |
conversation_not_speaking | No | Can be ignored; not currently speaking |
conversation_invalid_speaker | No | Show "Invalid speaker number" |
conversation_invalid_mode | No | Show "Invalid mode" |
conversation_not_manual_mode | No | Show "Please switch to manual mode first" |
conversation_missing_speakers | No | No longer returned since V1.24.0; no action needed |
conversation_invalid_speakers | No | Show "Invalid speakers format" |
conversation_language_change_failed | Yes | Retry later; if it keeps failing, reconnect |
conversation_language_same_as_peer | No | Show "Cannot use the same language as the other user" |
conversation_requires_two_languages error details:
This error occurs in the start action of type: "conversation" when the number of transcription_languages is not 2.
{
"type": "error",
"data": {
"error_code": "conversation_requires_two_languages",
"severity": "error",
"message": "Conversation mode requires exactly 2 languages",
"context": "session",
"request_id": "req_abc123xyz",
"timestamp": "2026-03-04T10:30:45.123Z",
"details": {
"received_count": 1,
"expected_count": 2
}
}
}
conversation_languages_identical error details:
This error occurs in the start action of type: "conversation" when the two provided transcription_languages are the same.
{
"type": "error",
"data": {
"error_code": "conversation_languages_identical",
"severity": "error",
"message": "Conversation languages must be different",
"context": "session",
"request_id": "req_abc123xyz",
"timestamp": "2026-03-04T10:30:45.123Z",
"details": {
"languages": ["zh-TW", "zh-TW"]
}
}
}
conversation_invalid_language error details:
This error occurs during switch_language when the specified language is not in the conversation language pair.
{
"type": "error",
"data": {
"error_code": "conversation_invalid_language",
"severity": "error",
"message": "Language not in conversation languages",
"context": "session",
"request_id": "req_abc123xyz",
"timestamp": "2026-03-04T10:30:45.123Z",
"details": {
"language": "ja-JP",
"conversation_languages": ["zh-TW", "en-US"]
}
}
}
Summary Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
summary_text_empty | 400 | error | Text content cannot be empty | Provide text content |
summary_text_too_long | 400 | error | Text content exceeds the limit (200,000 characters) | Shorten the text content |
summary_failed | 500 | error | Summary generation failed | Retry later |
summary_timeout | 504 | error | Summary generation timeout | Retry later |
summary_prompt_too_long | 400 | error | summary_prompt exceeds the 3000-character limit | Shorten the summary_prompt length |
summary_prompt_slug_too_long | 400 | error | summary_prompt_slug exceeds the 64-character limit | Shorten the summary_prompt_slug length |
summary_prompt_slug_invalid | 400 | error | summary_prompt_slug contains control characters | Remove control characters such as line breaks / Tab / NULL |
summary_mode_field_mismatch | 400/422 | error | The summary mode (summary_mode) does not match the summary fields: a required field is missing (over WebSocket, a value with only whitespace counts as missing), or a field not allowed in that mode was provided | Adjust summary_template, summary_prompt, and summary_prompt_slug to the mode's rules; see Summary Customization |
template_not_found | 404 | error | The summary template with the specified slug does not exist or is disabled | Use GET /api/v1/summary-templates to list available templates |
summary_idempotency_key_conflict | 409 | error | The same idempotency_key was already used with a different request — content or any parameter differs (Ad-hoc Summary, added in v1.9.1; also used by Summary Translation from v1.17.0) | Use a new idempotency_key; retries must carry exactly the same fields as the original request |
summary_insufficient_credit | — | warning | Available credits are insufficient; no summary was generated (a real-time recording ended because the available credits ran out, or the available credits at the end could not cover the summary fee; notified through the summary_error event, and the transcript and audio are still saved) | After topping up, get a summary through Regenerate Summary |
Retranslation Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
retranslate_session_not_active | 400 | error | Session not started | Verify the session status |
retranslate_no_target_lang | 400 | error | No target language provided | Provide the target_lang parameter |
retranslate_no_text | 400 | error | No text to translate provided | Provide text content |
retranslate_llm_not_ready | 503 | error | Translation service not ready | Retry later |
retranslate_llm_failed | 500 | error | Translation failed | Retry later |
retranslate_failed | 500 | error | Retranslation failed | Retry later |
Language Switch Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
switch_language_no_target | 400 | error | No target language provided | Provide the target language parameter |
switch_language_in_progress | 400 | warning | Language switch in progress | Wait for the switch to complete |
switch_language_same_target | 400 | warning | Target language unchanged | You can ignore this warning |
switch_language_op_required | 400 | error | op is missing in a multi-language session (v1.6.7) | Provide op: "add" or op: "remove" |
switch_language_already_exists | 400 | warning | The language to add is already in the translation list (v1.6.7) | You can ignore this warning |
switch_language_not_in_session | 400 | error | The language to remove is not in the translation list (v1.6.7) | Check the language code |
switch_language_last_language | 400 | error | At least one translation language must remain (v1.6.7) | The last language cannot be removed |
batch_retranslate_partial_failed | 500 | warning | Some sentences failed to retranslate | Can be ignored; does not affect the main flow |
batch_retranslate_failed | 500 | warning | A single sentence failed during batch retranslation (persisted in transcript.translation_errors) | Failed sids are reported in the failed_sids summary; individual sentences can be retried later |
Recording Name Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
set_name_empty | 400 | error | Recording name cannot be empty | Provide a name |
set_name_too_long | 400 | error | Name exceeds the length limit | Shorten the name |
General Errors
| Error Code | HTTP | severity | Description | Recommended Handling |
|---|---|---|---|---|
invalid_json | 400 / 422 | error | Invalid JSON format. Endpoints on the realtime service domain return 400; the rest return 422 | Make sure the JSON format is correct |
invalid_data | 422 | error | Invalid data format | Make sure the data conforms to the API specification |
validation_failed | 422 | error | Request validation failed | Make sure required parameters are provided |
invalid_parameter | 400 | error | A parameter value or combination is invalid; details.field names the parameter. Examples: an invalid silenceTimeoutSeconds or broadcast_phase value in the WebSocket start, broadcast_token sent with a type other than broadcast, name longer than 60 characters, summary_language longer than 20 characters, or a value outside the accepted list for options.speaking_speed, options.profanity_handling, conversation_mode, or tts_mode (details.valid_values lists the accepted values) | Fix the parameter indicated by details.field |
internal_error | - | error | An unexpected internal error occurred while processing a single WebSocket message (the connection is unaffected) | The connection is kept; it should not disconnect; treat it as a failure of that message and optionally retry the operation. details.message_type and details.action indicate the specific failed operation (see WebSocket API: Per-Message Errors) |
missing_transcription_languages | 400 | error | No speech recognition language provided | Provide transcription_languages |
invalid_transcription_language | 400 | error | Invalid language code | Use a valid BCP 47 language code |
invalid_translation_language | 400 | error | Invalid translation language code | translation_languages must use supported BCP 47 codes (see languages.md) |
too_many_languages | 400 | error | Too many languages (details carries max / received; max may be the system limit or the plan's cap on simultaneously recognized transcription languages) | Up to 10 transcription languages and 12 translation languages; on an unlimited plan, reduce the language count per details.max or upgrade the plan |
invalid_recording_type | 400 | error | Invalid recording type | Use a valid type |
invalid_summary_template | 400 | error | Invalid summary template | Verify the template identifier |
method_not_allowed | 405 | error | The path is correct but the HTTP method is not supported (the response carries an Allow header listing the supported methods) | Use one of the methods listed in Allow |
invalid_action | 400 / 405 | error | WebSocket: this action does not apply to the current recording mode. REST endpoints on the realtime service domain: the HTTP method is not supported (405, with an Allow header on the response) | Use the correct action or HTTP method for the situation |
http_error | 4xx | error | Another HTTP-level error; the actual status code is the one on the response | Handle according to the HTTP status code |
too_many_requests | 429 | error | Too many requests. The response carries the X-RateLimit-* and Retry-After headers | Wait for the period given in Retry-After, then retry |
invalid_service | - | error | Unsupported service type | Check the type field of the WebSocket message |
Frontend Error Handling Example
function handleError(error) {
const { error_code, severity, message } = error.data;
switch (severity) {
case 'fatal':
// Fatal error: stop the service and show an error page
showErrorPage(message);
disconnectWebSocket();
break;
case 'error':
// Operation failed: show an error prompt and allow retry
showErrorToast(message);
break;
case 'warning':
// Warning: show a warning without blocking the operation
showWarningToast(message);
break;
}
// Log the error for debugging
console.error(`[${error_code}] ${message}`);
}
Version: V1.24.1 Last Updated: 2026-10-07