# WebSocket API URL: /api-reference/stt/websocket-api Learn how to use and integrate Soniox Speech-to-Text WebSocket API. import { Badge } from "@openapi/ui/components/method-label"; ## Overview The **Soniox WebSocket API** provides real-time **transcription and translation** of live audio with ultra-low latency. It supports advanced features like **speaker diarization, context customization,** and **manual finalization** — all over a persistent WebSocket connection. Ideal for live scenarios such as meetings, broadcasts, multilingual communication, and voice interfaces. *** ## WebSocket endpoint Connect to the API using: ```text wss://stt-rt.soniox.com/transcribe-websocket ``` *** ## Authentication Send your API key with the connection, in the Authorization header or the protocols list. See [WebSocket authentication](/guides/websocket-authentication). The key sent with the connection is the connection's key for its whole life. The `api_key` field of the start request is **deprecated**. From **15 January 2027** a connection that sends its key only there is refused. See [Migrate WebSocket authentication](/guides/migrate-websocket-authentication). *** ## Configuration Before streaming audio, configure the transcription session by sending a JSON message such as: ```json { "model": "stt-rt-v5", "audio_format": "auto", "language_hints": ["en", "es"], "context": { "general": [ { "key": "domain", "value": "Healthcare" }, { "key": "topic", "value": "Diabetes management consultation" }, { "key": "doctor", "value": "Dr. Martha Smith" }, { "key": "patient", "value": "Mr. David Miller" }, { "key": "organization", "value": "St John's Hospital" } ], "text": "Mr. David Miller visited his healthcare provider last month for a routine follow-up related to diabetes care. The clinician reviewed his recent test results, noted improved glucose levels, and adjusted his medication schedule accordingly. They also discussed meal planning strategies and scheduled the next check-up for early spring.", "terms": [ "Celebrex", "Zyrtec", "Xanax", "Prilosec", "Amoxicillin Clavulanate Potassium" ], "translation_terms": [ { "source": "Mr. Smith", "target": "Sr. Smith" }, { "source": "St John's", "target": "St John's" }, { "source": "stroke", "target": "ictus" } ] }, "enable_speaker_diarization": true, "enable_language_identification": true, "translation": { "type": "two_way", "language_a": "en", "language_b": "es" } } ``` *** ### Parameters **Deprecated.** Send the API key with the connection instead; see [Authentication](#authentication) and [Migrate WebSocket authentication](/guides/migrate-websocket-authentication). Real-time model to use. See [models](/stt/models).
Example: `"stt-rt-v5"`
Audio format of the stream. See [audio formats](/stt/rt/real-time-transcription#audio-formats). Required for raw audio formats. See [audio formats](/stt/rt/real-time-transcription#audio-formats). Required for raw audio formats. See [audio formats](/stt/rt/real-time-transcription#audio-formats). See [language hints](/stt/concepts/language-hints). See [language restrictions](/stt/concepts/language-restrictions). See [context](/stt/concepts/context). See [speaker diarization](/stt/concepts/speaker-diarization). See [language identification](/stt/concepts/language-identification). See [endpoint detection](/stt/rt/endpoint-detection). Must be between 500 and 3000. Default value is 2000. See [endpoint detection](/stt/rt/endpoint-detection). Must be between -1.0 and 1.0. Default value is 0.0. Supported only by the Soniox v5 model. See [endpoint detection](/stt/rt/endpoint-detection). Must be between 0 and 3. Default value is 0. Supported only by the Soniox v5 model. See [endpoint detection](/stt/rt/endpoint-detection). Optional client-defined identifier recorded with this request in [usage logs](/guides/usage-logs). Does not need to be unique. Ignored if the request authenticates with a [temporary API key](/guides/temporary-api-keys). See [real-time translation](/stt/rt/real-time-translation).

**One-way translation**

Must be set to `one_way`. Language to translate the transcript into.

**Two-way translation**

Must be set to `two_way`. First language for two-way translation. Second language for two-way translation.
*** ## Connection timeouts There is no deadline for the start request, but send a [keepalive](/stt/rt/connection-keepalive) control message at least every **40 seconds** until it, or the connection is closed as idle with WebSocket status `1001`. The connection counts against your connection limit the whole time. After the start request, the keepalive rules apply as usual. Open connections, including idle ones, count against a connection limit, a multiple of your concurrent requests limit; see [Limits & quotas](/stt/rt/limits-and-quotas). Full details in [WebSocket authentication](/guides/websocket-authentication). Still sending `api_key` in the start request? Different timeouts apply; see [Migrate WebSocket authentication](/guides/migrate-websocket-authentication). *** ## Audio streaming After configuration, start streaming audio: * Send audio as binary WebSocket frames. * Each stream supports up to 300 minutes of audio. *** ## Ending the stream To gracefully close a streaming session: * Send an **empty text frame**, an empty string. An empty binary frame is an empty audio chunk and does not end the stream. * The server will return one or more responses, including [finished response](#finished-response), and then close the connection. *** ## Response Soniox returns **responses** in JSON format. A typical successful response looks like: ```json { "tokens": [ { "text": "Hello", "start_ms": 600, "end_ms": 760, "confidence": 0.97, "is_final": true, "speaker": "1" } ], "final_audio_proc_ms": 760, "total_audio_proc_ms": 880 } ``` ### Field descriptions List of processed tokens (words or subwords). Each token may include: Token text. Start timestamp of the token (in milliseconds). Not included if `translation_status` is `translation`. End timestamp of the token (in milliseconds). Not included if `translation_status` is `translation`. Confidence score (`0.0`–`1.0`). Whether the token is finalized. Speaker label (if diarization enabled). See [real-time translation](/stt/rt/real-time-translation). Language of the `token.text`. See [real-time translation](/stt/rt/real-time-translation). Audio processed into final tokens. Audio processed into final + non-final tokens. *** ## Finished response At the end of a stream, Soniox sends a **final message** to indicate the session is complete: ```json { "tokens": [], "final_audio_proc_ms": 1560, "total_audio_proc_ms": 1680, "finished": true } ``` After this, the server closes the WebSocket connection. *** ## Error response If an error occurs, the server returns an **error message** and immediately closes the connection: ```json { "tokens": [], "error_code": 503, "error_type": "service_unavailable", "error_message": "Cannot continue request (code 11). Please restart the request. Refer to: https://soniox.com/url/cannot-continue-request (request ID 3d37a3bd-5078-47ee-a369-b204e3bbedda)", "more_info": "https://soniox.com/docs/api-reference/errors#service-unavailable", "request_id": "3d37a3bd-5078-47ee-a369-b204e3bbedda" } ``` Standard HTTP status code of the error. Stable, machine-readable identifier of the error. Branch on this, not on `error_message`. See the [Errors reference](/api-reference/errors) for the full catalog and recovery steps. Human-readable description of the error. Link to the section on the [Errors](/api-reference/errors) page describing this `error_type`. Unique identifier of this request. Include it when contacting [support@soniox.com](mailto:support@soniox.com); server logs are keyed on it. For the full catalog of `error_type` values across all Soniox APIs, see the [Errors reference](/api-reference/errors). Full list of possible error codes and messages: 400 Bad request } > The request is malformed or contains invalid parameters. `error_type` is one of [`invalid_request`](/api-reference/errors#invalid-request) or [`model_not_available`](/api-reference/errors#model-not-available). * `Audio data channels must be specified for PCM formats` * `Audio data sample rate must be specified for PCM formats` * `Audio decode error` * `Audio is too long.` * `Audio frame is not valid base64. Send audio as either a binary WebSocket frame, or a text frame containing standard base64-encoded bytes.` * `` `client_reference_id` is N characters, which exceeds the maximum allowed length of 256. `` * `Context is too long.` * `Context is too long: N tokens, the maximum is 8000 tokens.` * `Control request body is not valid JSON.` * `Control request type is invalid. Valid values: "finalize", "keepalive".` * `Field endpoint_latency_adjustment_level must be between 0 and N.` * `Field endpoint_sensitivity cannot be less than -1.` * `Field endpoint_sensitivity cannot be more than 1.` * `Field max_non_final_tokens_duration_ms cannot be less than N.` * `Field max_non_final_tokens_duration_ms cannot be more than N.` * `Field translation.exclude_source_languages is not supported by model X.` * `Field translation.source_languages cannot be empty.` * `Field translation.source_languages for model X should be empty or it can be one element list having string '*'.` * `Invalid audio data format: avi` * `Invalid language hint.` * `Invalid language in translation.exclude_source_languages: X.` * `Invalid language in translation.language_a.` * `Invalid language in translation.language_b.` * `Invalid language in translation.source_languages: X.` * `Invalid language in translation.target_language.` * `Language hints must be unique.` * `Languages in translation.exclude_source_languages must be unique.` * `Languages in translation.source_languages must be unique.` * `Missing audio format. Specify a valid audio format (e.g. s16le, f32le, wav, ogg, flac...) or "auto" for auto format detection.` * `Model does not support endpoint_latency_adjustment_level.` * `Model does not support endpoint_sensitivity.` * `Model does not support language_hints_strict.` * `Model does not support max_endpoint_delay_ms.` * `Model does not support one way translation.` * `Model does not support two way translation.` * `No audio received.` * `Prompt too long for model` * `Received too much audio data in total.` * `Specified model X does not support real-time transcription. If you wish to use real-time transcription, specify model Y.` * `Send the API key either in the Authorization header or in the WebSocket protocols list, not both.` * `Authorization header must be "Bearer ".` * `soniox-api-key must be sent in the WebSocket protocols list together with exactly one other entry, the API key.` * `The api_key in the start request does not match the API key sent with the connection. Send the same key or omit it.` * `Start request is malformed.` * `Start request must be a text message.` * `The requested model is not available. See https://soniox.com/docs/stt/models for the list of supported models.` * `translation.language_a and translation.language_b must be different (both are X).` * `translation.language_a must be present if translation.language_b is present.` * `translation.language_b must be present if translation.language_a is present.` * `Two way translation between translation.language_a=X and translation.language_b=Y is not supported.` 401 Unauthorized } > Authentication is missing or incorrect. Ensure a valid API key is provided before retrying. `error_type`: [`unauthenticated`](/api-reference/errors#unauthenticated). * `Incorrect API key provided. You can get an API key at https://console.soniox.com` * `Invalid or expired temporary API key. Create a new temporary API key and retry. See https://soniox.com/docs/guides/temporary-api-keys for details.` * `Missing API key. Provide API key as a header (i.e. Authorization: Bearer ). You can get an API key at https://console.soniox.com` * `Missing API key. Send it with the connection: the Authorization header "Bearer ", or soniox-api-key and the key in the WebSocket protocols list.` (from 15 January 2027, for a connection that sends no key with the connection; see [Migrate WebSocket authentication](/guides/migrate-websocket-authentication)) * ``The temporary API key cannot be used for this action. Each temporary API key is scoped to a specific `usage_type`; create a new key with the correct usage type.`` 402 Payment required } > The organization's balance or monthly usage limit has been reached. Additional credits are required before making further requests. `error_type` is one of [`organization_balance_exhausted`](/api-reference/errors#organization-balance-exhausted), [`organization_monthly_budget_exhausted`](/api-reference/errors#organization-monthly-budget-exhausted), or [`project_monthly_budget_exhausted`](/api-reference/errors#project-monthly-budget-exhausted). * `Organization balance exhausted. Please either add funds manually or enable autopay.` * `Organization monthly budget exhausted. Please increase it.` * `Project monthly budget exhausted. Please increase it.` 403 Forbidden } > The API key does not have the permission for real-time speech-to-text, or the temporary API key in use was created with a `max_session_duration_seconds` cap and that duration has elapsed for the current session. `error_type` is one of [`permission_denied`](/api-reference/errors#permission-denied) or [`temp_api_key_session_expired`](/api-reference/errors#temp-api-key-session-expired). * `The API key does not have permission for this product. Edit the key's permissions at https://console.soniox.com` * `Temporary API key session duration limit exceeded. Create a new temporary API key to start a new session.` 408 Request timeout } > A backend call exceeded its deadline before completing. Retry the request. `error_type`: [`request_timeout`](/api-reference/errors#request-timeout). * `Audio data decode timeout` * `Input too slow` * `Request timeout.` * `Timed out while waiting for the first audio chunk` 413 Content too large } > The connection reached the maximum allowed session duration and was closed. Open a new WebSocket connection to continue streaming. `error_type`: [`max_duration_reached`](/api-reference/errors#max-duration-reached). * `This WebSocket connection has reached the maximum allowed duration and was closed. Please open a new WebSocket connection to continue transcribing.` 429 Too many requests } > A usage or rate limit has been exceeded. You may retry after a delay or request an increase in limits via the Soniox Console. `error_type` is one of [`limit_exceeded`](/api-reference/errors#limit-exceeded) or [`max_concurrent_connections_reached`](/api-reference/errors#max-concurrent-connections-reached). * `Concurrent requests limit for real-time transcription has been exceeded for your organization.` * `Concurrent requests limit for real-time transcription has been exceeded for your project.` * `Requests per minute limit for real-time transcription has been exceeded for your organization.` * `Requests per minute limit for real-time transcription has been exceeded for your project.` * `Concurrent WebSocket connections limit for real-time transcription has been exceeded for your organization. Close connections you are not using, or start streams on the ones you hold: the limit is a multiple of your concurrent streams limit.` * `Concurrent WebSocket connections limit for real-time transcription has been exceeded for your project. Close connections you are not using, or start streams on the ones you hold: the limit is a multiple of your concurrent streams limit.` 500 Internal server error } > An unexpected server-side error occurred. The request may be retried. `error_type`: [`internal_error`](/api-reference/errors#internal-error). * `The server had an error processing your request. Sorry about that! You can retry your request, or contact us through our support email support@soniox.com if you keep seeing this error.` 503 Service unavailable } > The service cannot accept the request right now (upstream overload, cache exhausted, shutdown). Retry with backoff. The numeric `(code N)` in the message identifies the sub-cause for support triage. `error_type`: [`service_unavailable`](/api-reference/errors#service-unavailable). * `Cannot continue request (code N). Please restart the request. Refer to: https://soniox.com/url/cannot-continue-request`