API Docs

Complete Error Code Reference

Table of Contents


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
  }
}
FieldTypeDescription
error_codestringError code (for programmatic handling)
severitystringSeverity level: fatal / error / warning
messagestringHuman-readable error message
contextstringError source category
sidintOptional. Sentence number for sentence-level errors (e.g., when a sentence fails to translate); not included for non-sentence-level errors
request_idstringRequest tracking ID
timestampstringTime the error occurred (ISO 8601)
detailsobjectAdditional debugging information; common keys in translation scenarios: provider, translation_language, source_lang

Severity Levels

severityDescriptionRecommended Handling
fatalFatal errorStop the service and require reconnection
errorOperation failedShow an error prompt and allow retry
warningWarningShow a warning without blocking the operation

Sentence-level error rule (important): When an error message includes the sid field, regardless of the severity, 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. A fatal + sid combination 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 fatal errors without sid do not close the connection (for example, auth_quota_exceeded and plan_feature_not_allowed); whether you need to reconnect depends on the description of each error code.


Authentication Errors

Error CodeHTTPseverityDescriptionRecommended Handling
auth_missing_api_key401fatalAPI Key is missingMake sure the request includes an API Key
auth_invalid_api_key401fatalInvalid API keyMake sure the API Key is correct
auth_invalid_key_format401fatalInvalid API key formatMake sure the API Key starts with vas_
auth_key_expired401fatalAPI Key has expiredRequest a new API Key
auth_key_disabled401fatalAPI Key is disabledContact technical support
auth_user_disabled403fatalAccount is disabledContact technical support
auth_account_blocked403fatalAccount is blockedContact technical support
auth_ip_not_allowed403fatalSource IP not allowedAccess from an authorized IP address
auth_insufficient_credit402fatalInsufficient creditTop up your credit balance
auth_quota_exceeded402fatalAvailable 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_expired401fatalThe account's service has expired. Not currently returned by any endpoint; reserved for future useContact technical support or renew
auth_service_error500fatalAuthentication 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 CodeHTTPseverityDescriptionRecommended Handling
plan_feature_not_allowed403fatalThe plan does not include the feature in useUse features included in your plan, or upgrade the plan; query GET /api/v1/me/plan for the plan contents
concurrency_limit_reached—errorThis API Key has reached its concurrent recording limitThe 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—errorThe plan's usage threshold was reached; the current recording was stoppedYou may start a new recording immediately (when restarting on the same connection, session_started arrives after the previous recording finishes processing)
daily_limit_reached—fatalUsage has reached the plan's limitAvailable again after the plan's reset (daily limits reset the next day)
plan_daily_limit_reached402errorThe 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):

  • start rejected: when the plan does not include a feature enabled in the request, the start is rejected; the connection is not closed — adjust the parameters and start again.
  • 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-token and subtitle-share (plan without floating subtitles), and POST /api/v1/imports (plan without audio import).

plan_daily_limit_reached (HTTP 402) occurs on POST /api/v1/auth/ticket and 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 the data.reason of POST /api/v1/imports/check-quota; that endpoint is a read-only query and returns HTTP 200, not an error.

too_many_languages semantics extended (v1.9.0): details.max may come from the plan's cap on simultaneously recognized transcription languages, in addition to the system-wide limit (10 transcription languages); details carries max and received.


Ticket Authentication Errors

Error CodeHTTPseverityDescriptionRecommended Handling
ticket_invalid401fatalTicket invalid or expiredObtain a new Ticket
ticket_expired401fatalTicket has expiredObtain a new Ticket
ticket_already_used401fatalTicket already usedEach Ticket can be used only once
ticket_validation_failed401fatalTicket validation failedMake sure the Ticket format is correct

Session Errors

Error CodeHTTPseverityDescriptionRecommended Handling
session_not_found404errorSession not foundMake sure the session ID is correct
session_expired400errorSession expiredCreate a new session
session_not_started400errorRecording 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_paused400warningAlready pausedYou can ignore this error
session_not_paused400warningNot pausedYou can ignore this error
service_shutdown—warningService shutting down, please reconnectBroadcast 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—errorResume token invalid or not foundSession 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—errorResume grace period expiredSame as above
resume_ownership_mismatch—errorResume token ownership mismatchSame as above
resume_unavailable—errorResume 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_failed400errorFailed to change speaking speed (rebuilding recognition failed)Retry later

Speech Recognition Errors

Error CodeHTTPseverityDescriptionRecommended Handling
stt_init_failed503fatalService initialization failedRetry later
stt_start_failed500fatalUnable to start speech recognitionRetry later
stt_auth_failed500fatalService authentication failedContact technical support
stt_quota_exceeded402fatalAvailable 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_lost500fatalConnection lostStop the service and reconnect
stt_silence_timeout-fatalNo 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 SilenceCheck 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-warningNo 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 continuesAlert 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, or daily_limit_disconnect, you can send start on the same connection immediately, but session_started arrives only after the previous recording finishes processing (after status: "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 CodeHTTPseverityDescriptionRecommended Handling
audio_invalid_format400errorInvalid audio data formatMake sure the audio format is correct
audio_process_failed500errorAudio processing failedRetry later
audio_format_unsupported400errorUnsupported audio formatUse a supported format
audio_decode_failed500errorAudio decoding failedVerify 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 CodeHTTPseverityDescriptionRecommended Handling
diarization_init_failed503fatalDiarization service initialization failedRetry later
diarization_start_failed500fatalDiarization session failed to startRetry later
diarization_failed500errorDiarization processing failedRetry later
diarization_unavailable503fatalDiarization service unavailableVerify the service status
diarization_multilang_conflict400errorSpeaker diarization does not support multiple languages (start rejected); two-way translation (conversation) is exempt as of v1.7.2Provide 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 CodeHTTPseverityDescriptionRecommended Handling
channel_mode_required—errorMulti-channel mode requires channel_modeSend channel_mode (per_channel or shared)
invalid_channel_mode—errorInvalid channel_modeAllowed 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—errorMulti-channel mode requires channelsProvide 1–8 channels (including the main speaker, channel_id: 1 by convention)
too_many_channels—errorToo many channelsReduce the channel count; the limit is 8. details carries max / received
invalid_channel_id—errorInvalid or duplicate channel_idchannel_id must be an integer from 1 to 8 and must not repeat
channel_language_required—errorEach channel must specify exactly one languageProvide exactly 1 language in each channel's transcription_languages
channel_language_not_allowed—errorshared mode does not support per-channel languagesIn 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—errorChannel languages do not match transcription_languagesThe union of all channels' languages must match the session-level transcription_languages
channel_id_required—errorMulti-channel mode requires channel_idIn multi-channel mode every audio frame must carry channel_id; channel operations must carry it as well
unknown_channel_id—errorUnknown channel_idMake sure the channel was declared in start or add_channel and has not been removed
multichannel_tts_not_allowed—errorMulti-channel mode does not support speech synthesisDisable tts_enabled
multichannel_broadcast_not_allowed—errorBroadcast does not support multi-channel modeUse a different recognition mode for broadcasts
multichannel_requires_pcm—errorMulti-channel mode only supports the PCM audio formatUse "pcm" for audio_format (16kHz / 16-bit / mono)
multichannel_switch_language_not_allowed—errorMulti-channel mode does not support switch_languageLanguages are bound to channels; use set_channel_language instead
channel_id_in_use—errorThis channel_id has already been used and cannot be reusedChannel IDs are never reused (including removed channels); pick a new ID for add_channel
channel_remove_not_allowed—errorThis channel cannot be removedThe last remaining channel cannot be removed; use stop to end the recording
channel_action_while_paused—errorChannels cannot be added or removed while paused; resume the recording firstresume first, then perform the channel operation
not_multi_channel_session—errorThis recording is not in multi-channel modeChannel operations only apply to recordings with recognition_mode: "multi_channel"
channel_rebuild_too_frequent—errorSettings on this channel are being changed too frequently; try again laterOnly 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, a start with recognition_mode: "multi_channel" returns this error; details carries field: "recognition_mode" and received_value.
  • invalid_parameter: returned on conflicting parameter combinations — multi_channel combined with speaker_diarization (multi-channel is itself a form of speaker separation); type: "conversation" combined with multi_channel; a set_channel_language that switches to the channel's current language, carries more than one language in transcription_languages, or provides both transcription_languages and language inconsistently; a channels[].speaker_name that is too long or contains control characters.
  • plan_feature_not_allowed (details.field: "max_stt_streams"): the channel count in start or add_channel exceeds the unlimited plan's channel limit; details also carries max and the current count.
  • too_many_languages: add_channel / set_channel_language introduces a new language that pushes the number of simultaneously recognized languages past the platform limit (10) or the plan's cap; details carries max / 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 CodeHTTPseverityDescriptionRecommended Handling
speaker_not_found422errorThe specified speaker was not foundMake sure the speaker ID is correct
speaker_sid_not_found422errorThe specified sentence was not foundMake sure the sentence ID is correct
speaker_name_empty422errorSpeaker name cannot be emptyProvide a speaker name
speaker_name_duplicate422errorSpeaker name already in useUse a different name
merge_speakers_same_id400errorSource and target speaker cannot be the sameProvide different speaker IDs
speaker_op_not_allowed_multi_channel422errorThis 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 CodeHTTPseverityDescriptionRecommended Handling
config_empty400errorNo 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_long400errorTerm exceeds 100 charactersShorten the term
config_too_many_entries400errorMore 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 fieldRemove terms or correction rules
config_too_many_dict_entries400errorMore than 3000 dictionary entries for a single language (details.language names it)Reduce the entries for that language
config_invalid_entry400errorA 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 reasonFix the entry at the position given in details
config_ignored_in_start-warningThe glossary sent inside start was ignored; use the config action instead (details.ignored_fields lists what was dropped). start still succeedsSend the glossary with the config action
config_too_many_languages400errorA glossary block carries more language codes than allowed (details carries field / count / max). Used by the Glossary Validation API onlyReduce the number of language codes in that block
config_payload_too_large413errorThe request body exceeds the size limit. Used by the Glossary Validation API onlySend 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 CodeHTTPseverityDescriptionRecommended Handling
record_translation_not_allowed400errorTranslation is not supported for record typeRemove translation_languages, or use the transcribe type
record_tts_not_allowed400errorText-to-speech is not supported for record typeRemove tts_enabled, or use a type that supports TTS
record_summary_requires_template400errorEnabling summary for record type requires a templateProvide summary_template or use summary_mode=custom

record_translation_not_allowed is also returned when calling retranslation endpoints (transcript retranslation, summary translation) on a record recording afterward.


Translation Service Errors

Error CodeHTTPseverityDescriptionRecommended Handling
llm_init_failed503fatalTranslation service initialization failedRetry later
llm_timeout504errorTranslation timeoutRetry later
llm_rate_limit429warningRequests too frequentReduce the request frequency
llm_request_failed500errorTranslation request failedRetry later
llm_provider_error503errorTranslation service temporarily unavailableRetry later
llm_content_filtered400warningContent cannot be translatedModify the input content
llm_auth_failed500fatalTranslation service authentication failedContact technical support
llm_deployment_not_found500fatalTranslation service configuration errorContact technical support
llm_quota_exceeded402fatalTranslation usage limit reachedRetry later
translation_service_unavailable-errorTranslation 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: error or WebSocket type: 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. Read error_code and severity; do not match this column against the status code you actually receive.

translation_service_unavailable trigger rules:

  • Cumulative escalation: escalates after llm_timeout / llm_provider_error / llm_rate_limit / llm_request_failed fail repeatedly in a row
  • Immediate escalation: llm_auth_failed / llm_deployment_not_found / llm_quota_exceeded escalate 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", without sid; details contains provider, 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 CodeHTTPseverityDescriptionRecommended Handling
tts_init_failed503fatalTTS service initialization failedRetry later
tts_not_enabled400warningTTS not enabledMake sure tts_enabled is set on start
tts_invalid_language400errorTTS language invalidMake sure the language is in translation_languages
tts_invalid_voice400errorInvalid 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 startsVerify the voice name with GET /api/v1/tts/voices before sending
sentence_not_found—warningThe specified sentence was not foundMake sure the SID exists
translation_not_found—warningNo translation found for that languageMake sure a translation exists for that language
tts_translation_not_found—errorIn TTS SSE Streaming, the sentence has no translation for the language. Delivered as a tts_error event; aborts the whole streamConfirm the translation has completed and is non-empty
tts_connection_failed—errorSpeech synthesis connection failedRetry shortly
tts_timeout—errorSpeech synthesis timed outRetry shortly
tts_synthesis_failed500errorTTS synthesis failedRetry later
tts_voice_not_found404errorThe specified voice was not found, or its language cannot be used as a TTS targetUse only voices listed by GET /api/v1/tts/voices
tts_sample_generation_failed500errorVoice sample generation failedRetry later

An HTTP column of — means the code is not returned as an HTTP status. It is delivered after the connection is established, through an error or tts_error event on the stream.


Recording Errors

Error CodeHTTPseverityDescriptionRecommended Handling
recording_not_found404errorRecording not foundMake sure the taskId is correct
recording_unauthorized403errorNot authorized to operate on this recordingMake sure the task belongs to the user
recording_audio_not_ready422errorAudio file not ready yetRetry later
recording_transcript_not_ready422errorTranscript not yet generated or emptyMake sure processing_status = completed before exporting
recording_not_completed422errorRecording has not finished processing; retranslation/editing/summary regeneration is not allowed while in progressWait until processing_status = completed, then retry
entry_not_found404errorThe specified sentence was not found (sid does not exist in the transcript)Make sure the sid is correct
entry_text_empty422errorSentence source text is empty (whitespace-only counts as empty)Provide a non-empty original_text
entry_text_too_long422errorSentence source text exceeds the 2000-character limitShorten the content and retry
transcript_revision_conflict409errorTranscript was modified by another request, or another write is in progressRe-read the transcript to get the latest revision, then retry
retranslate_segmentation_required422errorFull 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 chargeSend segmented=1 to retranslate in segments; see Retranslate SSE
task_already_processing409errorAnother processing run for the same task has not finished yet; this request was not appliedSend the same request again later
invalid_processing_status422errorProcessing status does not meet the operation requirementSee 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.

FieldDescription
remaining_budgetThe 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_scopeStates whose credit the number above refers to. There are currently two values, listed below
budget_scopeMeaningremaining_budget in the same details
api_key_creditThe API key used for this request is on pay-as-you-go, and the number is the credit that key can currently draw ona number
api_key_unlimitedThe API key used for this request is bound to a plan, so "remaining credit" does not applynull

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:

EndpointTrigger ConditionFields in detailsRecommended Handling
force-failRecording is already in a terminal state (completed / failed)current_status, messageFor completed tasks, use DELETE /api/v1/tasks/{taskId} instead; failed tasks do not need to be force-failed again
DELETETask is still being processed (not completed / failed), or the task's import is still being processedtask_id, current_status, messageWait 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
retryRecording is not in the failed statecurrent_status, messageOnly failed tasks can be retried
retryAudio file or transcript has not finished uploadingcurrent_status, audio_status, transcript_status, messageMake 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.

EndpointTrigger ConditionFields in detailsRecommended Handling
retryAnother processing run for the same task has not finished yettask_id, messageSend 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 CodeHTTPseverityDescriptionRecommended Handling
import_not_found404errorImport task not foundMake sure the import_id is correct
import_file_too_large413errorFile size exceeds the limitCompress or split the file
import_invalid_format415errorUnsupported audio formatUse mp3/wav/m4a format
import_recognition_mode_unsupported422errorThis recognition_mode is not supported for file imports; use single or multi_speaker. details carries field and supportedModesUse single or multi_speaker
import_duration_out_of_range-errorAudio duration is outside the allowed range (minimum 1 second, maximum 10 hours). Reported through the failed event of import progressUse audio within the allowed length, or split it and import in parts
import_download_failed500errorDownload failedRetry later
import_conversion_failed500errorConversion failedVerify the integrity of the audio file
import_stt_timeout504errorSpeech recognition timeoutRetry later
import_stt_failed500errorSpeech recognition failedRetry later
import_translation_failed500errorTranslation processing failedRetry later
import_summary_failed500warningSummary generation failedRetry later
import_upload_failed500errorResult upload failedRetry later
import_callback_failed500warningFailed to report progressDoes not affect processing; can be ignored
import_invalid_request500errorInvalid request formatMake sure the request format is correct
go_service_error-errorThe processing service is temporarily unavailableImport again later
dispatch_failed-errorThe processing job could not be dispatchedImport again later
job_failed-errorThe processing job failedImport again later
PROCESSING_TIMEOUT-errorThe import waited or ran too long and was marked as failedImport again later
unknown_error-errorImport processing failedImport 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_credit error (HTTP 402) is returned.

Codes with - in the HTTP column are not returned as HTTP status codes; they appear as the error_code of a failed import: in the import query API, in the failed event of the Import Progress SSE, and in the import.failed Webhook. The matching error_message is a fixed, general description without internal details; provide the import_id when you need troubleshooting.


Storage Errors

Error CodeHTTPseverityDescriptionRecommended Handling
storage_connection_failed503errorStorage service connection failedRetry later
storage_upload_failed500errorUpload failedRetry later
storage_download_failed500errorDownload failedRetry later
storage_queue_full500warningUpload queue fullRetry later

SSE Errors

Error CodeHTTPseverityDescriptionRecommended Handling
sse_transcript_not_found404errorTranscript not foundThe recording may not have finished processing
sse_translation_failed500errorTranslation failedRetry later
sse_summary_not_found404errorSummary not foundThis recording has no summary
sse_summary_translation_failed500errorSummary translation failed (Retranslate Summary, Summary Translation). details.original_error of Translation timed out means the request timed outRetry later
sse_summary_regeneration_failed500errorSummary regeneration failedRetry later
sse_template_not_found404errorSummary template not foundMake sure the template slug is correct

Broadcast Errors

Error CodeHTTPseverityDescriptionRecommended Handling
broadcast_not_enabled500errorBroadcast not enabled for the sessionVerify the broadcast settings
broadcast_token_invalid401fatalInvalid share linkStop the service and verify the share link
broadcast_token_revoked401fatalShare link revokedStop the service and create a new broadcast
broadcast_token_already_used422errorToken already used by another SessionClose the other tabs and retry
broadcast_token_required400errorBroadcast mode requires broadcast_tokenProvide the broadcast_token parameter
broadcast_session_not_found404errorBroadcast session not foundMake sure the broadcast Token is correct
broadcast_session_not_started503errorBroadcast not started yetWait for the host to start the broadcast
broadcast_not_ready503warningLive translation service not started yetRetry later
broadcast_session_ended410errorBroadcast session endedWait for the host to start again
broadcast_capacity_exceeded503warningMaximum number of viewers exceededWait in the queue or retry later
broadcast_queue_timeout—errorQueue timeoutTry reconnecting
broadcast_viewer_kicked403errorRemoved by the hostContact the host
broadcast_unauthorized401errorUnauthorized access to the viewer management APIVerify your authentication information
broadcast_password_required401errorThis broadcast requires password verificationProvide the correct password
broadcast_password_incorrect401errorIncorrect passwordVerify the password and retry
broadcast_not_in_standby500warningNot currently in the standby phaseWait for the host to switch to the standby phase
broadcast_standby_warning—warningThe standby phase is about to reach its time limit (30 minutes by default; details carries standbySeconds, remainingSeconds, limitSeconds); the broadcast continuesPrompt the host to go live or start again
broadcast_standby_timeout—fatalThe standby phase reached its time limit and the session ended automatically (details carries standbySeconds, limitSeconds). No recording exists during standby, so no task_complete followsGet a new Ticket and send start; see the Broadcast Guide
broadcast_cannot_revoke422errorOnly broadcasts in the pending state can be revokedStop the broadcast before revoking
broadcast_cannot_start422errorCannot start the broadcastMake sure the broadcast status is pending
broadcast_already_live422errorA broadcast is already liveStop the current broadcast first
broadcast_not_live422errorNo broadcast currently liveStart a broadcast first
validation_failed422errormax_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 an error or tts_error event on the stream.


Conversation Errors

Error CodeHTTPseverityDescriptionRecommended Handling
conversation_requires_two_languages400errorConversation mode requires exactly two languagesProvide exactly 2 transcription_languages
conversation_languages_identical400errorThe two conversation languages cannot be the sameProvide two different languages
conversation_invalid_language400errorInvalid conversation languageMake sure the language is one of the transcription_languages
conversation_same_language400warningAlready the current languageYou can ignore this warning
conversation_speaking400errorCurrently speaking; cannot perform this actionCall stop_speaking to finish speaking first
conversation_not_speaking400warningNot currently speakingYou can ignore this warning
conversation_invalid_speaker400errorInvalid speaker numberUse 1 or 2
conversation_invalid_mode400errorInvalid conversation modeUse auto or manual
conversation_not_manual_mode400errorThis action requires manual modeSwitch to manual mode first
conversation_missing_speakers400errorNo longer returned since V1.24.0, because speakers is now optionalNo action needed
conversation_invalid_speakers400errorInvalid speakers formatMake sure exactly 2 speaker configurations are provided
conversation_language_change_failed500errorLanguage change failed (STT rebuild failed)Retry later
conversation_language_same_as_peer400errorNew language is the same as the other user'sThe two users cannot use the same language

Handling strategy:

Error CodeRetry?Handling
conversation_requires_two_languagesNoShow "Please provide exactly 2 languages"
conversation_languages_identicalNoShow "The two languages cannot be the same"
conversation_invalid_languageNoShow "Invalid language" and use the language from start
conversation_same_languageNoCan be ignored; already the current language
conversation_speakingNoShow "Please finish speaking first"
conversation_not_speakingNoCan be ignored; not currently speaking
conversation_invalid_speakerNoShow "Invalid speaker number"
conversation_invalid_modeNoShow "Invalid mode"
conversation_not_manual_modeNoShow "Please switch to manual mode first"
conversation_missing_speakersNoNo longer returned since V1.24.0; no action needed
conversation_invalid_speakersNoShow "Invalid speakers format"
conversation_language_change_failedYesRetry later; if it keeps failing, reconnect
conversation_language_same_as_peerNoShow "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 CodeHTTPseverityDescriptionRecommended Handling
summary_text_empty400errorText content cannot be emptyProvide text content
summary_text_too_long400errorText content exceeds the limit (200,000 characters)Shorten the text content
summary_failed500errorSummary generation failedRetry later
summary_timeout504errorSummary generation timeoutRetry later
summary_prompt_too_long400errorsummary_prompt exceeds the 3000-character limitShorten the summary_prompt length
summary_prompt_slug_too_long400errorsummary_prompt_slug exceeds the 64-character limitShorten the summary_prompt_slug length
summary_prompt_slug_invalid400errorsummary_prompt_slug contains control charactersRemove control characters such as line breaks / Tab / NULL
summary_mode_field_mismatch400/422errorThe 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 providedAdjust summary_template, summary_prompt, and summary_prompt_slug to the mode's rules; see Summary Customization
template_not_found404errorThe summary template with the specified slug does not exist or is disabledUse GET /api/v1/summary-templates to list available templates
summary_idempotency_key_conflict409errorThe 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—warningAvailable 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 CodeHTTPseverityDescriptionRecommended Handling
retranslate_session_not_active400errorSession not startedVerify the session status
retranslate_no_target_lang400errorNo target language providedProvide the target_lang parameter
retranslate_no_text400errorNo text to translate providedProvide text content
retranslate_llm_not_ready503errorTranslation service not readyRetry later
retranslate_llm_failed500errorTranslation failedRetry later
retranslate_failed500errorRetranslation failedRetry later

Language Switch Errors

Error CodeHTTPseverityDescriptionRecommended Handling
switch_language_no_target400errorNo target language providedProvide the target language parameter
switch_language_in_progress400warningLanguage switch in progressWait for the switch to complete
switch_language_same_target400warningTarget language unchangedYou can ignore this warning
switch_language_op_required400errorop is missing in a multi-language session (v1.6.7)Provide op: "add" or op: "remove"
switch_language_already_exists400warningThe language to add is already in the translation list (v1.6.7)You can ignore this warning
switch_language_not_in_session400errorThe language to remove is not in the translation list (v1.6.7)Check the language code
switch_language_last_language400errorAt least one translation language must remain (v1.6.7)The last language cannot be removed
batch_retranslate_partial_failed500warningSome sentences failed to retranslateCan be ignored; does not affect the main flow
batch_retranslate_failed500warningA 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 CodeHTTPseverityDescriptionRecommended Handling
set_name_empty400errorRecording name cannot be emptyProvide a name
set_name_too_long400errorName exceeds the length limitShorten the name

General Errors

Error CodeHTTPseverityDescriptionRecommended Handling
invalid_json400 / 422errorInvalid JSON format. Endpoints on the realtime service domain return 400; the rest return 422Make sure the JSON format is correct
invalid_data422errorInvalid data formatMake sure the data conforms to the API specification
validation_failed422errorRequest validation failedMake sure required parameters are provided
invalid_parameter400errorA 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-errorAn 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_languages400errorNo speech recognition language providedProvide transcription_languages
invalid_transcription_language400errorInvalid language codeUse a valid BCP 47 language code
invalid_translation_language400errorInvalid translation language codetranslation_languages must use supported BCP 47 codes (see languages.md)
too_many_languages400errorToo 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_type400errorInvalid recording typeUse a valid type
invalid_summary_template400errorInvalid summary templateVerify the template identifier
method_not_allowed405errorThe 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_action400 / 405errorWebSocket: 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_error4xxerrorAnother HTTP-level error; the actual status code is the one on the responseHandle according to the HTTP status code
too_many_requests429errorToo many requests. The response carries the X-RateLimit-* and Retry-After headersWait for the period given in Retry-After, then retry
invalid_service-errorUnsupported service typeCheck 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

Copyright © 2026