Low-latency multilingual speech-to-text over WebSocket. Covers 25 languages with automatic language identification, with optional speaker labels, word timestamps, and per-utterance language codes.
WSS
/
api
/
velma-2-stt-streaming-multilingual-vfast
Low-latency multilingual speech-to-text over WebSocket. The spoken language is identified automatically, so the client declares no language and uses no per-language endpoint. Interim partial transcripts stream while audio arrives, and a final utterance is emitted for each segment of speech.This endpoint produces no emotion, accent, or PII/PHI data. Use STT Streaming if you need those.
Container or raw PCM format of the audio you will stream
sample_rate
Raw PCM only
Source sample rate in Hz. Required for a raw format; ignored for container formats.
num_channels
Raw PCM only
Number of audio channels (1–8). Required for a raw format; ignored for container formats.
endpointing
No
true or false (default false). When true, speech is segmented into utterances at pauses.
diarize
No
true or false (default false). When true, each final utterance carries speaker fields — see Speaker labels.
time_stamps
No
true or false (default false). When true, each final utterance carries words — see Word timestamps.
detect_language
No
true or false (default false). When true, each final utterance carries language — see Language identification.
endpointing, diarize, time_stamps, and detect_language are independent; every combination is valid.
Worth knowing:diarize=true substantially increases time-to-first-text. Speaker decisions are made over a multi-second window, so the first partial_utterance arrives several seconds later than on a non-diarized connection, and the gap widens under concurrency. Transcript accuracy is unaffected - the cost is latency, not quality. If you are rendering live captions, either size the interface for this or run a second, non-diarized connection for the display text.
The spoken language is identified automatically across these 25 languages:Bulgarian, Croatian, Czech, Danish, Dutch, English, Estonian, Finnish, French, German, Greek, Hungarian, Italian, Latvian, Lithuanian, Maltese, Polish, Portuguese, Romanian, Russian, Slovak, Slovenian, Spanish, Swedish, Ukrainian.Each utterance is transcribed in the language spoken, with auto-capitalization and auto-punctuation already applied. The client declares no language, and recognition quality varies by language.
Worth knowing: this set is smaller and narrower than it sounds. Multilingual Transcription covers 100 languages; these 25 are all European, so Chinese, Japanese, Arabic, Hindi and Korean are not among them. Audio outside the set is still transcribed, but not reliably.
With detect_language=true, each final utterance carries language: the ISO 639-1 code of one of the 25 languages above (es, de, en, and so on). Partials never carry it. With detect_language=false, no message carries a language field.language is null when the utterance is too short to identify reliably. That is a deliberate result, not a dropped field or a low-confidence guess.
Worth knowing: expect null often on short utterances. A single word or a back-channel such as “yes” or “okay” commonly returns null, and with diarize=true speaker changes produce many short utterances. A client that needs the conversation’s language should take it from the longer utterances rather than the most recent one.
With diarize=true, each final utterance carries speaker, a zero-based index identifying who produced it. Partials never carry it, and a label is assigned when an utterance is finalized and never revised.The index is stable for one connection and meaningless outside it: the same person on a new connection may receive a different index, so it is not an identity that can be matched across connections.speaker is null when diarization was requested but no speaker could be determined for that utterance. That is distinct from the field being absent, which means diarize=true was not requested.
Up to four concurrent speakers are labeled per connection. Beyond four, additional speakers are merged into existing labels: their speech is still transcribed, but speaker is wrong for some utterances.
Worth knowing:speakers_capped and speaker_purity are the two signals that a label may be unreliable, and a client acting on speaker identity should check both. The four-speaker ceiling is lower than English Fast Transcription (streaming), which labels ten, so a conversation that diarizes cleanly there can exceed capacity here.
Segments are cut at pauses regardless of diarize. An utterance spanning a fast exchange with no pause carries the speaker who produced most of it, and speaker_purity reports what proportion that was. 1.0 is cleanly single-speaker; lower means the label describes only the majority.
diarize=true&endpointing=false produces one final utterance for the whole stream, so a single speaker cannot describe it. Read n_speakers and treat speaker as indicative only.
With time_stamps=true, each final utterance carries words: one entry per word of text, in order, each with word, start_ms, and end_ms. Partials never carry it.Word times are milliseconds from the start of the stream, the same clock as the utterance’s start_ms, not offsets within the utterance. Each word matches the utterance text, punctuation and casing included.Timings are computed alongside the transcript, so requesting them changes neither the text nor the latency. With time_stamps=false, words is absent rather than an empty array.
A connection can stream for up to six hours. If no audio frame arrives for five minutes, the stream is finalized as though the end-of-stream frame had been sent. Either way the server sends the final utterance for any remaining speech, then done, and closes with 1000. Reaching a limit is not an error.The five-minute limit counts from the last audio frame received, not the last speech, so streaming silence keeps the connection open.
Connect with api_key, audio_format, (for raw formats) sample_rate and num_channels, and any of endpointing, diarize, time_stamps, and detect_language.
Stream audio as binary WebSocket frames.
Receive partial_utterance messages while audio arrives.
Send an empty text frame ("") to signal end of audio.
Receive the final utterance(s), then a done message.
The connection closes.
Worth knowing: step 4 must be a text frame containing the empty string. An empty binary frame is treated as an audio chunk and does not end the stream, so the connection hangs until it times out with no final utterance.
The complete transcript so far for the current scope — the whole connection by default, or the current segment when endpointing=true. Not a delta: replace the displayed text on each message, never append.
Final transcript for this segment, in the language spoken.
utterance.is_final
boolean
Always true
utterance.start_ms
integer
Start of this segment, in milliseconds from the beginning of the stream. Approximate.
utterance.duration_ms
integer
Duration of this segment’s speech, excluding the pause that ended it. Approximate.
utterance.speaker
integer | null
Present only with diarize=true. Zero-based speaker index, null when none could be determined.
utterance.n_speakers
integer
Present only with diarize=true. Distinct speakers detected on the connection so far.
utterance.speakers_capped
boolean
Present only with diarize=true. true once all four speaker slots are in use.
utterance.speaker_purity
number
Present only with diarize=true. Proportion of this utterance attributed to speaker, from 0 to 1.
utterance.words
array
Present only with time_stamps=true. One { word, start_ms, end_ms } entry per word of text, timed from the start of the stream.
utterance.language
string | null
Present only with detect_language=true. ISO 639-1 code of the utterance’s language, null when it is too short to identify.
With diarize=false no speaker field appears in any message. Likewise, words appears only with time_stamps=true and language only with detect_language=true.
Sent if something goes wrong. The connection closes after it; no further messages follow.
{ "type": "error", "error": "diarize=true is not available on this endpoint." }
That second message means speaker labelling is not enabled on the instance that served the connection. Retry once — instances can differ while a deployment is rolling — and if it persists, reconnect without diarize. time_stamps=true is not available on this endpoint. means the same for word timestamps.
Normal closure after the done message, including when a session limit is reached
1003
Invalid query parameters — missing audio_format, invalid sample_rate, invalid endpointing, diarize, time_stamps, or detect_language, unsupported value. Also returned when diarize=true or time_stamps=true is requested but that feature is not enabled on the serving instance; retry once before treating this as permanent.
1011
Internal server error. An error message is sent before the close.
1013
The service is temporarily at capacity. Not an account or billing condition — retry the connection. Diarized connections have a lower concurrency ceiling than plain transcription, so a diarize=true connection can be refused while a plain one succeeds.
4001
The api_key query parameter is missing or invalid
4002
Audio bytes did not match the declared raw format, or the audio could not be decoded mid-stream
4003
The request is not permitted
4004
The API key does not have access to this model
4029
Insufficient credits
4030
Concurrent request limit reached — an account-level limit on simultaneous connections, distinct from the service-capacity 1013. Contact support to raise it.
{
"type": "error",
"error": "Internal server error"
}
{
"type": "done",
"duration_ms": 14253
}
{}
""
query
type:object
Partial Utterance Result
type:object
In-progress transcript snapshot for the CURRENT speech segment. Sent
zero or more times per segment, roughly every 1.5 seconds. The text
field contains the current segment's transcript so far - not a delta,
and not the whole stream - with auto-capitalization and
auto-punctuation already applied. Clients should REPLACE the current
segment's previously displayed partial text, not append. Partials
never carry speaker labels, even with diarize=true, and never
carry word timestamps, even with time_stamps=true.
Final Utterance Result
type:object
The final transcript for one segment of speech, with
auto-capitalization and auto-punctuation applied, plus the segment's
start time and duration. With diarize=true it also carries the
speaker who produced it, with time_stamps=true the start and
end time of every word, and with detect_language=true its
detected language. Sent once per segment (when the segment
ends, and once more for the last segment after end-of-stream), and
supersedes the partial_utterance messages for that segment. The
full transcript is the concatenation of these texts in order.
Error
type:object
An error occurred during transcription. Sent at most once per
connection; the WebSocket closes shortly after. No further
messages follow an error.
Transcription Complete
type:object
Transcription completed successfully. Sent exactly once, immediately
after the final utterance message. After this message the server
closes the WebSocket.
Audio Data Chunk
type:string
Raw audio data chunk for transcription. Sent zero or more times
by the client during the stream lifetime. Each chunk's bytes are
decoded by the server according to the connection's
audio_format query parameter.
End of Audio Stream
type:string
Empty text frame signaling end of audio. Sent exactly once by the
client after the last audio chunk. The server responds with a
final utterance message followed by a done message, then
closes the connection.
{
"type": "error",
"error": "Internal server error"
}
{
"type": "done",
"duration_ms": 14253
}
{}
""
{"docsConfig":{"theme":"sequoia","$schema":"https://mintlify.com/docs.json","name":"Modulate","description":"Build with the modulate.ai models — real-time transcription, deepfake detection, and PII/PHI redaction at scale.","colors":{"primary":"#285FEB","light":"#5B82F0","dark":"#285FEB"},"logo":{"light":"https://mintcdn.com/modulateai/0NHKM9zXEnghoEfZ/images/wordmark-navy.svg?fit=max\u0026auto=format\u0026n=0NHKM9zXEnghoEfZ\u0026q=85\u0026s=7ee7a19111bb0154aa2e6934ebd29607","dark":"https://mintcdn.com/modulateai/0NHKM9zXEnghoEfZ/images/wordmark-white.svg?fit=max\u0026auto=format\u0026n=0NHKM9zXEnghoEfZ\u0026q=85\u0026s=98ae552c2cd0d6bf2268f8374825c88a","href":"https://modulate.ai"},"favicon":"https://mintcdn.com/modulateai/0NHKM9zXEnghoEfZ/images/favicon.svg?fit=max\u0026auto=format\u0026n=0NHKM9zXEnghoEfZ\u0026q=85\u0026s=d8e2a95af577097e3287379354855376","appearance":{"default":"system"},"navbar":{"links":[{"href":"https://platform.modulate.ai/signin","label":"Sign in"}],"primary":{"type":"button","label":"Start building free","href":"https://platform.modulate.ai/signup-request"}},"footer":{"socials":{"website":"https://modulate.ai"},"links":[{"header":"Product","items":[{"label":"Modulate","href":"https://modulate.ai"},{"label":"Velma Preview","href":"https://preview.modulate.ai"}]},{"header":"Support","items":[{"label":"Email support","href":"mailto:support@modulate.ai"},{"label":"Privacy policy","href":"https://www.modulate.ai/privacy-policy"},{"label":"Report a vulnerability","href":"/security"}]}]},"integrations":{"ga4":{"measurementId":"G-0WV1JKWMB3"}},"contextual":{"options":["copy","view","assistant","chatgpt","claude","perplexity"],"display":"header"},"markdown":{"schema":true},"styling":{"latex":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"modulateai","hasAudioNarration":false,"actualSubdomain":"modulateai","customDomains":["docs.modulate.ai"],"gitSource":{"type":"gitlab","owner":"modulate","repo":"modulate-user-docs","projectId":81929608,"deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae8b8d621d86b83cef2b55b","collectionId":"edb8ba97-3e05-4ed6-950a-9032b207844d","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae8b8d621d86b83cef2b55b"},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6ae8b8d621d86b83cef2b55b","clientVersion":"0.0.4045","searchFilterCounts":[{"language":"default","tag":"API Reference","count":31},{"language":"default","tag":"Velma","count":17},{"language":"default","tag":"Get Started","count":16},{"language":"default","tag":"By capability","count":10},{"language":"default","tag":"Speech-to-text Transcription","count":7},{"language":"default","tag":"Detection packages","count":7},{"language":"default","tag":"Benchmarks","count":6},{"language":"default","tag":"Support","count":4},{"language":"default","tag":"Behaviors","count":4},{"language":"default","tag":"AI Music Detection","count":3}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true,"deflection":{"enabled":true,"email":"support@modulate.ai","showHelpButton":true}},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/stt/streaming-multilingual-vfast","slug":"/api-reference/stt/streaming-multilingual-vfast","pageMetadata":{"title":"Multilingual Fast Transcription Streaming","sidebarTitle":"Streaming (Multilingual Fast)","asyncapi":"api/stt_streaming_multilingual_vfast.yaml velma2SttStreamingMultilingualVfast","description":"Low-latency multilingual speech-to-text over WebSocket. Covers 25 languages with automatic language identification, with optional speaker labels, word timestamps, and per-utterance language codes.","href":"/api-reference/stt/streaming-multilingual-vfast"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Low-latency multilingual speech-to-text over WebSocket. Covers 25 languages with automatic language identification, with optional speaker labels, word timestamps, and per-utterance language codes.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,em:`em`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{Accordion,CodeBlock,Heading,Table,Warning}=_components;if(!Accordion)_missingMdxReference(`Accordion`,true);if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Low-latency multilingual speech-to-text over WebSocket. The spoken language is identified automatically, so the client declares no language and uses no per-language endpoint. Interim partial transcripts stream while audio arrives, and a final `,_jsx(_components.code,{children:`utterance`}),` is emitted for each segment of speech.`]}),`\n`,_jsxs(_components.p,{children:[`This endpoint produces no emotion, accent, or PII/PHI data. Use `,_jsx(_components.a,{href:`/api-reference/stt/streaming`,children:`STT Streaming`}),` if you need those.`]}),`\n`,_jsx(Heading,{level:`2`,id:`endpoint`,children:`Endpoint`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`wss://platform.modulate.ai/api/velma-2-stt-streaming-multilingual-vfast`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(Heading,{level:`2`,id:`authentication`,children:`Authentication`}),`\n`,_jsxs(_components.p,{children:[`The API key goes in the query string at connection time, not in a header. See `,_jsx(_components.a,{href:`/guides/authentication`,children:`Authentication and rate limits`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`supported-audio-formats`,children:`Supported audio formats`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Container formats`}),` — `,_jsx(_components.code,{children:`sample_rate`}),` and `,_jsx(_components.code,{children:`num_channels`}),` are ignored if supplied:`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`mp3`}),`, `,_jsx(_components.code,{children:`wav`}),`, `,_jsx(_components.code,{children:`flac`}),`, `,_jsx(_components.code,{children:`m4a`}),`, `,_jsx(_components.code,{children:`mp4`}),`, `,_jsx(_components.code,{children:`ogg`}),`, `,_jsx(_components.code,{children:`opus`}),`, `,_jsx(_components.code,{children:`webm`}),`, `,_jsx(_components.code,{children:`aac`}),`, `,_jsx(_components.code,{children:`aiff`}),`, `,_jsx(_components.code,{children:`wma`}),`, `,_jsx(_components.code,{children:`amr`}),`, and `,_jsx(_components.code,{children:`au`}),`, plus 66 others`]}),`\n`,_jsx(Accordion,{title:`All 79 accepted container values`,id:`all-79-accepted-container-values`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`3g2`}),`, `,_jsx(_components.code,{children:`3ga`}),`, `,_jsx(_components.code,{children:`3gp`}),`, `,_jsx(_components.code,{children:`3gpp`}),`, `,_jsx(_components.code,{children:`8svx`}),`, `,_jsx(_components.code,{children:`aa3`}),`, `,_jsx(_components.code,{children:`aac`}),`, `,_jsx(_components.code,{children:`ac3`}),`, `,_jsx(_components.code,{children:`act`}),`, `,_jsx(_components.code,{children:`adts`}),`, `,_jsx(_components.code,{children:`aif`}),`, `,_jsx(_components.code,{children:`aifc`}),`, `,_jsx(_components.code,{children:`aiff`}),`,\n`,_jsx(_components.code,{children:`amb`}),`, `,_jsx(_components.code,{children:`amr`}),`, `,_jsx(_components.code,{children:`asf`}),`, `,_jsx(_components.code,{children:`at3`}),`, `,_jsx(_components.code,{children:`au`}),`, `,_jsx(_components.code,{children:`avr`}),`, `,_jsx(_components.code,{children:`awb`}),`, `,_jsx(_components.code,{children:`bwf`}),`, `,_jsx(_components.code,{children:`c2`}),`, `,_jsx(_components.code,{children:`caf`}),`, `,_jsx(_components.code,{children:`dss`}),`, `,_jsx(_components.code,{children:`dts`}),`, `,_jsx(_components.code,{children:`dtshd`}),`,\n`,_jsx(_components.code,{children:`eac3`}),`, `,_jsx(_components.code,{children:`ec3`}),`, `,_jsx(_components.code,{children:`f4a`}),`, `,_jsx(_components.code,{children:`f4b`}),`, `,_jsx(_components.code,{children:`flac`}),`, `,_jsx(_components.code,{children:`gsm`}),`, `,_jsx(_components.code,{children:`iff`}),`, `,_jsx(_components.code,{children:`m2a`}),`, `,_jsx(_components.code,{children:`m2ts`}),`, `,_jsx(_components.code,{children:`m4a`}),`, `,_jsx(_components.code,{children:`m4b`}),`, `,_jsx(_components.code,{children:`m4r`}),`, `,_jsx(_components.code,{children:`m4v`}),`,\n`,_jsx(_components.code,{children:`mka`}),`, `,_jsx(_components.code,{children:`mkv`}),`, `,_jsx(_components.code,{children:`mlp`}),`, `,_jsx(_components.code,{children:`mp+`}),`, `,_jsx(_components.code,{children:`mp1`}),`, `,_jsx(_components.code,{children:`mp2`}),`, `,_jsx(_components.code,{children:`mp3`}),`, `,_jsx(_components.code,{children:`mp4`}),`, `,_jsx(_components.code,{children:`mpa`}),`, `,_jsx(_components.code,{children:`mpc`}),`, `,_jsx(_components.code,{children:`mpga`}),`, `,_jsx(_components.code,{children:`mpp`}),`, `,_jsx(_components.code,{children:`mts`}),`,\n`,_jsx(_components.code,{children:`oga`}),`, `,_jsx(_components.code,{children:`ogg`}),`, `,_jsx(_components.code,{children:`ogx`}),`, `,_jsx(_components.code,{children:`oma`}),`, `,_jsx(_components.code,{children:`omg`}),`, `,_jsx(_components.code,{children:`opus`}),`, `,_jsx(_components.code,{children:`paf`}),`, `,_jsx(_components.code,{children:`pvf`}),`, `,_jsx(_components.code,{children:`qcp`}),`, `,_jsx(_components.code,{children:`ra`}),`, `,_jsx(_components.code,{children:`rf64`}),`, `,_jsx(_components.code,{children:`rm`}),`, `,_jsx(_components.code,{children:`rmvb`}),`,\n`,_jsx(_components.code,{children:`snd`}),`, `,_jsx(_components.code,{children:`svx`}),`, `,_jsx(_components.code,{children:`thd`}),`, `,_jsx(_components.code,{children:`ts`}),`, `,_jsx(_components.code,{children:`tta`}),`, `,_jsx(_components.code,{children:`voc`}),`, `,_jsx(_components.code,{children:`vqf`}),`, `,_jsx(_components.code,{children:`w64`}),`, `,_jsx(_components.code,{children:`wav`}),`, `,_jsx(_components.code,{children:`wave`}),`, `,_jsx(_components.code,{children:`weba`}),`, `,_jsx(_components.code,{children:`webm`}),`, `,_jsx(_components.code,{children:`wma`}),`,\n`,_jsx(_components.code,{children:`wmv`})]})}),`\n`,_jsxs(_components.p,{children:[`The MP4-family values (`,_jsx(_components.code,{children:`mp4`}),`, `,_jsx(_components.code,{children:`m4a`}),`, `,_jsx(_components.code,{children:`m4b`}),`, `,_jsx(_components.code,{children:`m4r`}),`, `,_jsx(_components.code,{children:`m4v`}),`, `,_jsx(_components.code,{children:`3gp`}),`, `,_jsx(_components.code,{children:`3gpp`}),`, `,_jsx(_components.code,{children:`3ga`}),`, `,_jsx(_components.code,{children:`3g2`}),`, `,_jsx(_components.code,{children:`f4a`}),`, `,_jsx(_components.code,{children:`f4b`}),`) must be sent in a streamable layout; otherwise the connection ends with an audio-processing error.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Raw PCM formats`}),` — `,_jsx(_components.code,{children:`sample_rate`}),` and `,_jsx(_components.code,{children:`num_channels`}),` are required:`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`s8`}),`, `,_jsx(_components.code,{children:`s16le`}),`, `,_jsx(_components.code,{children:`s16be`}),`, `,_jsx(_components.code,{children:`s24le`}),`, `,_jsx(_components.code,{children:`s24be`}),`, `,_jsx(_components.code,{children:`s32le`}),`, `,_jsx(_components.code,{children:`s32be`}),`, `,_jsx(_components.code,{children:`u8`}),`, `,_jsx(_components.code,{children:`u16le`}),`, `,_jsx(_components.code,{children:`u16be`}),`, `,_jsx(_components.code,{children:`u24le`}),`, `,_jsx(_components.code,{children:`u24be`}),`, `,_jsx(_components.code,{children:`u32le`}),`, `,_jsx(_components.code,{children:`u32be`}),`, `,_jsx(_components.code,{children:`f32le`}),`, `,_jsx(_components.code,{children:`f32be`}),`, `,_jsx(_components.code,{children:`f64le`}),`, `,_jsx(_components.code,{children:`f64be`}),`, `,_jsx(_components.code,{children:`mulaw`}),`, `,_jsx(_components.code,{children:`alaw`}),`, `,_jsx(_components.code,{children:`g722`}),`, `,_jsx(_components.code,{children:`vox`})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`g722`}),` and `,_jsx(_components.code,{children:`vox`}),` are mono-only: `,_jsx(_components.code,{children:`num_channels`}),` must be `,_jsx(_components.code,{children:`1`}),`.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Valid sample rates:`}),` 8000, 11025, 16000, 22050, 32000, 44100, 48000, 96000`]}),`\n`,_jsxs(_components.p,{children:[`For lowest end-to-end latency, send `,_jsx(_components.code,{children:`audio_format=s16le\u0026sample_rate=16000\u0026num_channels=1`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`query-parameters`,children:`Query parameters`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Parameter`}),_jsx(_components.th,{children:`Required`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`api_key`})}),_jsx(_components.td,{children:`Yes`}),_jsx(_components.td,{children:`Your API key`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`audio_format`})}),_jsx(_components.td,{children:`Yes`}),_jsx(_components.td,{children:`Container or raw PCM format of the audio you will stream`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`sample_rate`})}),_jsx(_components.td,{children:`Raw PCM only`}),_jsx(_components.td,{children:`Source sample rate in Hz. Required for a raw format; ignored for container formats.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`num_channels`})}),_jsx(_components.td,{children:`Raw PCM only`}),_jsx(_components.td,{children:`Number of audio channels (1–8). Required for a raw format; ignored for container formats.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`endpointing`})}),_jsx(_components.td,{children:`No`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`true`}),` or `,_jsx(_components.code,{children:`false`}),` (default `,_jsx(_components.code,{children:`false`}),`). When `,_jsx(_components.code,{children:`true`}),`, speech is segmented into utterances at pauses.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`diarize`})}),_jsx(_components.td,{children:`No`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`true`}),` or `,_jsx(_components.code,{children:`false`}),` (default `,_jsx(_components.code,{children:`false`}),`). When `,_jsx(_components.code,{children:`true`}),`, each final `,_jsx(_components.code,{children:`utterance`}),` carries speaker fields — see `,_jsx(_components.a,{href:`#speaker-labels`,children:`Speaker labels`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`time_stamps`})}),_jsx(_components.td,{children:`No`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`true`}),` or `,_jsx(_components.code,{children:`false`}),` (default `,_jsx(_components.code,{children:`false`}),`). When `,_jsx(_components.code,{children:`true`}),`, each final `,_jsx(_components.code,{children:`utterance`}),` carries `,_jsx(_components.code,{children:`words`}),` — see `,_jsx(_components.a,{href:`#word-timestamps`,children:`Word timestamps`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`detect_language`})}),_jsx(_components.td,{children:`No`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`true`}),` or `,_jsx(_components.code,{children:`false`}),` (default `,_jsx(_components.code,{children:`false`}),`). When `,_jsx(_components.code,{children:`true`}),`, each final `,_jsx(_components.code,{children:`utterance`}),` carries `,_jsx(_components.code,{children:`language`}),` — see `,_jsx(_components.a,{href:`#language-identification`,children:`Language identification`}),`.`]})]})]})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`endpointing`}),`, `,_jsx(_components.code,{children:`diarize`}),`, `,_jsx(_components.code,{children:`time_stamps`}),`, and `,_jsx(_components.code,{children:`detect_language`}),` are independent; every combination is valid.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Worth knowing:`}),` `,_jsx(_components.code,{children:`diarize=true`}),` substantially increases time-to-first-text. Speaker decisions are made over a multi-second window, so the first `,_jsx(_components.code,{children:`partial_utterance`}),` arrives several seconds later than on a non-diarized connection, and the gap widens under concurrency. Transcript accuracy is unaffected - the cost is latency, not quality. If you are rendering live captions, either size the interface for this or run a second, non-diarized connection for the display text.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`language-identification`,children:`Language identification`}),`\n`,_jsx(_components.p,{children:`The spoken language is identified automatically across these 25 languages:`}),`\n`,_jsx(_components.p,{children:`Bulgarian, Croatian, Czech, Danish, Dutch, English, Estonian, Finnish, French, German, Greek, Hungarian, Italian, Latvian, Lithuanian, Maltese, Polish, Portuguese, Romanian, Russian, Slovak, Slovenian, Spanish, Swedish, Ukrainian.`}),`\n`,_jsxs(_components.p,{children:[`Each `,_jsx(_components.code,{children:`utterance`}),` is transcribed in the language spoken, with auto-capitalization and auto-punctuation already applied. The client declares no language, and recognition quality varies by language.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Worth knowing:`}),` this set is smaller and narrower than it sounds. Multilingual Transcription covers 100 languages; these 25 are all European, so Chinese, Japanese, Arabic, Hindi and Korean are not among them. Audio outside the set is still transcribed, but not reliably.`]})}),`\n`,_jsx(Heading,{level:`3`,id:`reporting-the-detected-language`,children:`Reporting the detected language`}),`\n`,_jsxs(_components.p,{children:[`With `,_jsx(_components.code,{children:`detect_language=true`}),`, each final `,_jsx(_components.code,{children:`utterance`}),` carries `,_jsx(_components.code,{children:`language`}),`: the ISO 639-1 code of one of the 25 languages above (`,_jsx(_components.code,{children:`es`}),`, `,_jsx(_components.code,{children:`de`}),`, `,_jsx(_components.code,{children:`en`}),`, and so on). Partials never carry it. With `,_jsx(_components.code,{children:`detect_language=false`}),`, no message carries a `,_jsx(_components.code,{children:`language`}),` field.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`language`}),` is `,_jsx(_components.code,{children:`null`}),` when the utterance is too short to identify reliably. That is a deliberate result, not a dropped field or a low-confidence guess.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Worth knowing:`}),` expect `,_jsx(_components.code,{children:`null`}),` often on short utterances. A single word or a back-channel such as “yes” or “okay” commonly returns `,_jsx(_components.code,{children:`null`}),`, and with `,_jsx(_components.code,{children:`diarize=true`}),` speaker changes produce many short utterances. A client that needs the conversation’s language should take it from the longer utterances rather than the most recent one.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`speaker-labels`,children:`Speaker labels`}),`\n`,_jsxs(_components.p,{children:[`With `,_jsx(_components.code,{children:`diarize=true`}),`, each final `,_jsx(_components.code,{children:`utterance`}),` carries `,_jsx(_components.code,{children:`speaker`}),`, a zero-based index identifying who produced it. Partials never carry it, and a label is assigned when an utterance is finalized and never revised.`]}),`\n`,_jsx(_components.p,{children:`The index is stable for one connection and meaningless outside it: the same person on a new connection may receive a different index, so it is not an identity that can be matched across connections.`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`speaker`}),` is `,_jsx(_components.code,{children:`null`}),` when diarization was requested but no speaker could be determined for that utterance. That is distinct from the field being absent, which means `,_jsx(_components.code,{children:`diarize=true`}),` was not requested.`]}),`\n`,_jsx(Heading,{level:`3`,id:`speaker-capacity`,children:`Speaker capacity`}),`\n`,_jsxs(_components.p,{children:[`Up to `,_jsx(_components.strong,{children:`four`}),` concurrent speakers are labeled per connection. Beyond four, additional speakers are merged into existing labels: their speech is still transcribed, but `,_jsx(_components.code,{children:`speaker`}),` is wrong for some utterances.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Worth knowing:`}),` `,_jsx(_components.code,{children:`speakers_capped`}),` and `,_jsx(_components.code,{children:`speaker_purity`}),` are the two signals that a label may be unreliable, and a client acting on speaker identity should check both. The four-speaker ceiling is lower than English Fast Transcription (streaming), which labels ten, so a conversation that diarizes cleanly there can exceed capacity here.`]})}),`\n`,_jsx(Heading,{level:`3`,id:`utterances-that-span-a-speaker-change`,children:`Utterances that span a speaker change`}),`\n`,_jsxs(_components.p,{children:[`Segments are cut at pauses regardless of `,_jsx(_components.code,{children:`diarize`}),`. An utterance spanning a fast exchange with no pause carries the speaker who produced most of it, and `,_jsx(_components.code,{children:`speaker_purity`}),` reports what proportion that was. `,_jsx(_components.code,{children:`1.0`}),` is cleanly single-speaker; lower means the label describes only the majority.`]}),`\n`,_jsx(Heading,{level:`3`,id:`with-endpointing-off`,children:`With endpointing off`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`diarize=true\u0026endpointing=false`}),` produces one final `,_jsx(_components.code,{children:`utterance`}),` for the whole stream, so a single `,_jsx(_components.code,{children:`speaker`}),` cannot describe it. Read `,_jsx(_components.code,{children:`n_speakers`}),` and treat `,_jsx(_components.code,{children:`speaker`}),` as indicative only.`]}),`\n`,_jsx(Heading,{level:`2`,id:`word-timestamps`,children:`Word timestamps`}),`\n`,_jsxs(_components.p,{children:[`With `,_jsx(_components.code,{children:`time_stamps=true`}),`, each final `,_jsx(_components.code,{children:`utterance`}),` carries `,_jsx(_components.code,{children:`words`}),`: one entry per word of `,_jsx(_components.code,{children:`text`}),`, in order, each with `,_jsx(_components.code,{children:`word`}),`, `,_jsx(_components.code,{children:`start_ms`}),`, and `,_jsx(_components.code,{children:`end_ms`}),`. Partials never carry it.`]}),`\n`,_jsxs(_components.p,{children:[`Word times are milliseconds from the start of the stream, the same clock as the utterance’s `,_jsx(_components.code,{children:`start_ms`}),`, not offsets within the utterance. Each `,_jsx(_components.code,{children:`word`}),` matches the utterance text, punctuation and casing included.`]}),`\n`,_jsxs(_components.p,{children:[`Timings are computed alongside the transcript, so requesting them changes neither the text nor the latency. With `,_jsx(_components.code,{children:`time_stamps=false`}),`, `,_jsx(_components.code,{children:`words`}),` is absent rather than an empty array.`]}),`\n`,_jsx(Heading,{level:`2`,id:`session-limits`,children:`Session limits`}),`\n`,_jsxs(_components.p,{children:[`A connection can stream for up to `,_jsx(_components.strong,{children:`six hours`}),`. If no audio frame arrives for `,_jsx(_components.strong,{children:`five minutes`}),`, the stream is finalized as though the end-of-stream frame had been sent. Either way the server sends the final `,_jsx(_components.code,{children:`utterance`}),` for any remaining speech, then `,_jsx(_components.code,{children:`done`}),`, and closes with `,_jsx(_components.code,{children:`1000`}),`. Reaching a limit is not an error.`]}),`\n`,_jsx(_components.p,{children:`The five-minute limit counts from the last audio frame received, not the last speech, so streaming silence keeps the connection open.`}),`\n`,_jsx(Heading,{level:`2`,id:`connection-flow`,children:`Connection flow`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Connect with `,_jsx(_components.code,{children:`api_key`}),`, `,_jsx(_components.code,{children:`audio_format`}),`, (for raw formats) `,_jsx(_components.code,{children:`sample_rate`}),` and `,_jsx(_components.code,{children:`num_channels`}),`, and any of `,_jsx(_components.code,{children:`endpointing`}),`, `,_jsx(_components.code,{children:`diarize`}),`, `,_jsx(_components.code,{children:`time_stamps`}),`, and `,_jsx(_components.code,{children:`detect_language`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Stream audio as `,_jsx(_components.strong,{children:`binary`}),` WebSocket frames.`]}),`\n`,_jsxs(_components.li,{children:[`Receive `,_jsx(_components.code,{children:`partial_utterance`}),` messages while audio arrives.`]}),`\n`,_jsxs(_components.li,{children:[`Send an `,_jsx(_components.strong,{children:`empty text frame`}),` (`,_jsx(_components.code,{children:`\"\"`}),`) to signal end of audio.`]}),`\n`,_jsxs(_components.li,{children:[`Receive the final `,_jsx(_components.code,{children:`utterance`}),`(s), then a `,_jsx(_components.code,{children:`done`}),` message.`]}),`\n`,_jsx(_components.li,{children:`The connection closes.`}),`\n`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Worth knowing:`}),` step 4 must be a `,_jsx(_components.strong,{children:`text`}),` frame containing the empty string. An empty `,_jsx(_components.em,{children:`binary`}),` frame is treated as an audio chunk and does not end the stream, so the connection hangs until it times out with no final `,_jsx(_components.code,{children:`utterance`}),`.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`server-messages`,children:`Server messages`}),`\n`,_jsx(Heading,{level:`3`,id:`partial_utterance`,children:_jsx(_components.code,{children:`partial_utterance`})}),`\n`,_jsxs(_components.p,{children:[`The complete transcript so far for the current scope — the whole connection by default, or the current segment when `,_jsx(_components.code,{children:`endpointing=true`}),`. Not a delta: replace the displayed text on each message, never append.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`4`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"partial_utterance\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"partial_utterance\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"text\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Buenos días, gracias por\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"is_final\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`false`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Partials never carry speaker fields, even with `,_jsx(_components.code,{children:`diarize=true`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`utterance`,children:_jsx(_components.code,{children:`utterance`})}),`\n`,_jsx(_components.p,{children:`The final transcript for one segment. Will not be revised.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`13`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`13`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"utterance\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"utterance\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"text\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Buenos días, gracias por llamar.\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"is_final\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`true`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"start_ms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`0`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"duration_ms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`2360`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"speaker\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`0`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"n_speakers\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`2`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"speakers_capped\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`false`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"speaker_purity\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`1.0`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`With `,_jsx(_components.code,{children:`time_stamps=true`}),` and `,_jsx(_components.code,{children:`detect_language=true`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`16`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`16`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"utterance\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"utterance\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"text\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Hola, ¿cómo estás hoy?\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"is_final\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`true`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"start_ms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`1200`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"duration_ms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`1850`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"language\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"es\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"words\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"word\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Hola,\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"start_ms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`1240`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"end_ms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`1560`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"word\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"¿cómo\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"start_ms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`1640`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"end_ms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`1980`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"word\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"estás\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"start_ms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`2010`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"end_ms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`2480`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"word\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"hoy?\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"start_ms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`2520`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"end_ms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`3010`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ]`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Field`}),_jsx(_components.th,{children:`Type`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`type`})}),_jsx(_components.td,{children:`string`}),_jsxs(_components.td,{children:[`Always `,_jsx(_components.code,{children:`\"utterance\"`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`utterance.text`})}),_jsx(_components.td,{children:`string`}),_jsx(_components.td,{children:`Final transcript for this segment, in the language spoken.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`utterance.is_final`})}),_jsx(_components.td,{children:`boolean`}),_jsxs(_components.td,{children:[`Always `,_jsx(_components.code,{children:`true`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`utterance.start_ms`})}),_jsx(_components.td,{children:`integer`}),_jsx(_components.td,{children:`Start of this segment, in milliseconds from the beginning of the stream. Approximate.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`utterance.duration_ms`})}),_jsx(_components.td,{children:`integer`}),_jsx(_components.td,{children:`Duration of this segment’s speech, excluding the pause that ended it. Approximate.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`utterance.speaker`})}),_jsx(_components.td,{children:`integer | null`}),_jsxs(_components.td,{children:[`Present only with `,_jsx(_components.code,{children:`diarize=true`}),`. Zero-based speaker index, `,_jsx(_components.code,{children:`null`}),` when none could be determined.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`utterance.n_speakers`})}),_jsx(_components.td,{children:`integer`}),_jsxs(_components.td,{children:[`Present only with `,_jsx(_components.code,{children:`diarize=true`}),`. Distinct speakers detected on the connection so far.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`utterance.speakers_capped`})}),_jsx(_components.td,{children:`boolean`}),_jsxs(_components.td,{children:[`Present only with `,_jsx(_components.code,{children:`diarize=true`}),`. `,_jsx(_components.code,{children:`true`}),` once all four speaker slots are in use.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`utterance.speaker_purity`})}),_jsx(_components.td,{children:`number`}),_jsxs(_components.td,{children:[`Present only with `,_jsx(_components.code,{children:`diarize=true`}),`. Proportion of this utterance attributed to `,_jsx(_components.code,{children:`speaker`}),`, from 0 to 1.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`utterance.words`})}),_jsx(_components.td,{children:`array`}),_jsxs(_components.td,{children:[`Present only with `,_jsx(_components.code,{children:`time_stamps=true`}),`. One `,_jsx(_components.code,{children:`{ word, start_ms, end_ms }`}),` entry per word of `,_jsx(_components.code,{children:`text`}),`, timed from the start of the stream.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`utterance.language`})}),_jsx(_components.td,{children:`string | null`}),_jsxs(_components.td,{children:[`Present only with `,_jsx(_components.code,{children:`detect_language=true`}),`. ISO 639-1 code of the utterance’s language, `,_jsx(_components.code,{children:`null`}),` when it is too short to identify.`]})]})]})]}),`\n`,_jsxs(_components.p,{children:[`With `,_jsx(_components.code,{children:`diarize=false`}),` no speaker field appears in any message. Likewise, `,_jsx(_components.code,{children:`words`}),` appears only with `,_jsx(_components.code,{children:`time_stamps=true`}),` and `,_jsx(_components.code,{children:`language`}),` only with `,_jsx(_components.code,{children:`detect_language=true`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`done`,children:_jsx(_components.code,{children:`done`})}),`\n`,_jsxs(_components.p,{children:[`Sent once, immediately after the final `,_jsx(_components.code,{children:`utterance`}),`. The server closes after it.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{ `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"done\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"duration_ms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`14253`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`error`,children:_jsx(_components.code,{children:`error`})}),`\n`,_jsx(_components.p,{children:`Sent if something goes wrong. The connection closes after it; no further messages follow.`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{ `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"error\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"error\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"diarize=true is not available on this endpoint.\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`That second message means speaker labelling is not enabled on the instance that served the connection. Retry once — instances can differ while a deployment is rolling — and if it persists, reconnect without `,_jsx(_components.code,{children:`diarize`}),`. `,_jsx(_components.code,{children:`time_stamps=true is not available on this endpoint.`}),` means the same for word timestamps.`]}),`\n`,_jsx(Heading,{level:`2`,id:`websocket-close-codes`,children:`WebSocket close codes`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Code`}),_jsx(_components.th,{children:`Meaning`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`1000`})}),_jsxs(_components.td,{children:[`Normal closure after the `,_jsx(_components.code,{children:`done`}),` message, including when a `,_jsx(_components.a,{href:`#session-limits`,children:`session limit`}),` is reached`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`1003`})}),_jsxs(_components.td,{children:[`Invalid query parameters — missing `,_jsx(_components.code,{children:`audio_format`}),`, invalid `,_jsx(_components.code,{children:`sample_rate`}),`, invalid `,_jsx(_components.code,{children:`endpointing`}),`, `,_jsx(_components.code,{children:`diarize`}),`, `,_jsx(_components.code,{children:`time_stamps`}),`, or `,_jsx(_components.code,{children:`detect_language`}),`, unsupported value. Also returned when `,_jsx(_components.code,{children:`diarize=true`}),` or `,_jsx(_components.code,{children:`time_stamps=true`}),` is requested but that feature is not enabled on the serving instance; retry once before treating this as permanent.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`1011`})}),_jsxs(_components.td,{children:[`Internal server error. An `,_jsx(_components.code,{children:`error`}),` message is sent before the close.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`1013`})}),_jsxs(_components.td,{children:[`The service is temporarily at capacity. Not an account or billing condition — retry the connection. Diarized connections have a lower concurrency ceiling than plain transcription, so a `,_jsx(_components.code,{children:`diarize=true`}),` connection can be refused while a plain one succeeds.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`4001`})}),_jsxs(_components.td,{children:[`The `,_jsx(_components.code,{children:`api_key`}),` query parameter is missing or invalid`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`4002`})}),_jsx(_components.td,{children:`Audio bytes did not match the declared raw format, or the audio could not be decoded mid-stream`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`4003`})}),_jsx(_components.td,{children:`The request is not permitted`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`4004`})}),_jsx(_components.td,{children:`The API key does not have access to this model`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`4029`})}),_jsx(_components.td,{children:`Insufficient credits`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`4030`})}),_jsxs(_components.td,{children:[`Concurrent request limit reached — an account-level limit on simultaneous connections, distinct from the service-capacity `,_jsx(_components.code,{children:`1013`}),`. Contact support to raise it.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`4031`})}),_jsx(_components.td,{children:`Monthly usage limit reached`})]})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`related`,children:`Related`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/get-started/stt`,children:`Transcription`}),` — parameters, response shape, and audio formats for every transcription endpoint`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.a,{href:`/api-reference/stt/batch-multilingual-vfast`,children:`Multilingual Fast Transcription Batch`}),` — the file-upload counterpart`]}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/guides/which-api`,children:`Which API should I use?`})}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Multilingual Fast Transcription Streaming","sidebarTitle":"Streaming (Multilingual Fast)","asyncapi":"api/stt_streaming_multilingual_vfast.yaml velma2SttStreamingMultilingualVfast","description":"Low-latency multilingual speech-to-text over WebSocket. Covers 25 languages with automatic language identification, with optional speaker labels, word timestamps, and per-utterance language codes.","href":"/api-reference/stt/streaming-multilingual-vfast"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Endpoint","slug":"endpoint","depth":2,"children":[]},{"title":"Authentication","slug":"authentication","depth":2,"children":[]},{"title":"Supported audio formats","slug":"supported-audio-formats","depth":2,"children":[]},{"title":"Query parameters","slug":"query-parameters","depth":2,"children":[]},{"title":"Language identification","slug":"language-identification","depth":2,"children":[{"title":"Reporting the detected language","slug":"reporting-the-detected-language","depth":3,"children":[]}]},{"title":"Speaker labels","slug":"speaker-labels","depth":2,"children":[{"title":"Speaker capacity","slug":"speaker-capacity","depth":3,"children":[]},{"title":"Utterances that span a speaker change","slug":"utterances-that-span-a-speaker-change","depth":3,"children":[]},{"title":"With endpointing off","slug":"with-endpointing-off","depth":3,"children":[]}]},{"title":"Word timestamps","slug":"word-timestamps","depth":2,"children":[]},{"title":"Session limits","slug":"session-limits","depth":2,"children":[]},{"title":"Connection flow","slug":"connection-flow","depth":2,"children":[]},{"title":"Server messages","slug":"server-messages","depth":2,"children":[{"title":"partial_utterance","slug":"partial_utterance","depth":3,"children":[]},{"title":"utterance","slug":"utterance","depth":3,"children":[]},{"title":"done","slug":"done","depth":3,"children":[]},{"title":"error","slug":"error","depth":3,"children":[]}]},{"title":"WebSocket close codes","slug":"websocket-close-codes","depth":2,"children":[]},{"title":"Related","slug":"related","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/modulateai/6f43a4827c59f292/hubspot.js","/_mintlify/custom/modulateai/0bb96afd82713278/swan.js","/_mintlify/custom/modulateai/476f212ab71e7bd6/hubspot-forms.js","/_mintlify/custom/modulateai/06d8e9ccae2eea7a/detection-package-download.js"],"apiReferenceData":{"channel":{"id":"velma2SttStreamingMultilingualVfast","title":"Velma2 stt streaming multilingual vfast","description":"Establish a WebSocket connection for low-latency multilingual\ntranscription. The server emits partial transcripts as audio streams\nin, and a final `utterance` at end-of-stream. With `endpointing=true`,\nspeech is additionally segmented at pauses into one final `utterance`\nper segment. With `diarize=true`, each final `utterance` also carries\nthe speaker who produced it. With `time_stamps=true`, each final\n`utterance` also carries the start and end time of every word. With\n`detect_language=true`, each final `utterance` also carries its\ndetected language.\n\n## Supported Languages\nBulgarian, Croatian, Czech, Danish, Dutch, English, Estonian, Finnish,\nFrench, German, Greek, Hungarian, Italian, Latvian, Lithuanian,\nMaltese, Polish, Portuguese, Romanian, Russian, Slovak, Slovenian,\nSpanish, Swedish, Ukrainian.\n\nThe spoken language is detected from the audio automatically and does\nnot need to be declared by the client - transcript text is returned in\nthe language spoken. Recognition quality varies by language. See\n\"Language Detection\" below for the separate, optional feature that\nreports which of these 25 languages each final utterance was in.\n\n## Connection Flow\n1. Connect with `api_key`, `audio_format`, (for raw formats) `sample_rate` +\n `num_channels`, and optionally `endpointing`, `diarize`,\n `time_stamps`, and `detect_language`\n2. Connection accepted if authentication succeeds and limits are not\n exceeded\n3. Stream audio data as binary WebSocket frames\n4. Receive `partial_utterance` results every ~1.5 seconds while transcription\n is in progress (each is the complete transcript of the current segment\n so far - REPLACE, don't append)\n5. With `endpointing=true`, receive a final `utterance` message each time a\n segment of speech ends, carrying that segment's text, start time, and\n duration\n6. Send empty text frame (`\"\"`) when the audio stream ends\n7. Receive the final `utterance` for any content not already finalized\n mid-stream (the whole stream with endpointing off; with\n `endpointing=true`, this step is skipped when the last segment was\n already finalized mid-stream)\n8. Receive `done` message with total audio duration\n9. Connection closes automatically\n\n## Partial and Segment Semantics\nBy default the connection produces a single final `utterance` at\nend-of-stream, covering the whole stream (`start_ms=0`), and each\n`partial_utterance` reflects the whole stream so far. With\n`endpointing=true`, speech is segmented into utterances: each\n`partial_utterance` reflects the CURRENT segment, and a final\n`utterance` is emitted each time a segment ends, after which the\nfollowing `partial_utterance` messages belong to the next segment; the\nfull transcript is the concatenation of the final `utterance` texts. In\nboth modes a `partial_utterance` is the complete transcript of its\nscope so far (not a delta), and the last few words may be revised in\nsubsequent partials as the model sees more audio context, so clients\nshould replace the displayed partial text rather than append.\n\nWith `endpointing=true` AND `diarize=true`, a segment ends either at a\npause OR when the speaker changes, whichever comes first. This\ngenerally produces more segments than endpointing alone: in fast\nback-and-forth conversation the pauses between turns are often shorter\nthan the silence threshold, so speaker changes are what separate the\nturns.\n\n## Speaker Labels\nWith `diarize=true`, each final `utterance` carries `speaker` - a\nzero-based index that is stable for the lifetime of the connection.\nIt identifies speakers only WITHIN one connection: the same person on\na new connection may get a different index, and indices are not\nidentities that can be matched across connections or sessions.\n\nA maximum of four concurrent speakers is supported. Past that, further\nspeakers are merged into existing labels rather than reported\nseparately - their speech is still transcribed, but its `speaker` will\nbe wrong. `speakers_capped` is `true` once all four slots are in use,\nwhich is the only signal that labels may be unreliable; clients doing\nanything consequential with speaker identity should check it.\n\nSpeaker labels are attached to final `utterance` messages only, never\nto `partial_utterance`. Diarization has no back-patching: a label is\nassigned when the utterance is finalized and is not revised\nafterwards.\n\nWith `diarize=true` and `endpointing=false` there is only one final\n`utterance` for the whole stream, so a single `speaker` cannot\ndescribe it. In that mode read `n_speakers` - how many distinct\nspeakers were detected on the connection - and treat `speaker` as\nindicative only.\n\n## Word Timestamps\nWith `time_stamps=true`, each final `utterance` carries `words` - one\nentry per word of its `text`, in order, each with `start_ms` and\n`end_ms`. Word times are measured on the same clock as the\nutterance's `start_ms`: milliseconds from the beginning of the audio\nstream, not from the start of the utterance.\n\nWord timestamps are attached to final `utterance` messages only,\nnever to `partial_utterance`. They are computed alongside the\ntranscript, so requesting them does not change the transcript text,\nits latency, or any other field of the payload.\n\n`time_stamps` is independent of `endpointing` and `diarize`; every\ncombination is valid.\n\n## Language Detection\nWith `detect_language=true`, each final `utterance` additionally\ncarries `language` - the detected language of that utterance, as one\nof the ISO 639-1 codes in \"Supported Languages\" above.\n\n`language` is `null` when the utterance is too short to identify\nreliably - a deliberate \"not enough information to tell\" result, not\na dropped field or a low-confidence guess. Very short utterances (a\nsingle word, a short back-channel like \"yes\" or \"okay\") commonly\nproduce `null`, especially with `diarize=true`, where speaker\nchanges can produce many short utterances.\n\nLanguage detection is attached to final `utterance` messages only,\nnever to `partial_utterance`, since a partial's text is still\nrevising. `detect_language` is independent of `endpointing`,\n`diarize`, and `time_stamps`; every combination is valid.\n\n## Text Formatting\nBoth `partial_utterance` and `utterance` payloads contain text that\nhas already been auto-capitalized and auto-punctuated by the model, in\nthe language spoken. Clients can render the `text` field directly\nwithout additional casing or punctuation normalization. Note that in\n`partial_utterance` messages, both capitalization and punctuation in\nthe final words may be revised in subsequent partials as the model\nsees more audio context.\n\n## Session Limits\nA connection can stream for up to six hours. If no audio frame\narrives for five minutes, the stream is finalized as if the\nend-of-stream frame had been sent. In both cases the server emits the\nfinal `utterance` for any content not yet finalized, then `done`, and\ncloses normally with `1000`: reaching a limit is not an error.\nSending silent audio keeps the stream active, since the five-minute\nlimit counts from the last audio frame received, not from the last\nspeech.\n\n## Error Handling\nIf an error occurs during transcription, the server sends an error\nmessage and closes the connection. Connection rejections during\nhandshake use WebSocket close codes (see below).\n\n## WebSocket Close Codes\n- `1000`: Normal closure after the `done` message, or after the\n connection completes, including when a session limit is reached\n (see \"Session Limits\").\n- `1003`: Invalid query parameters (missing `audio_format`, invalid\n `sample_rate`, invalid `endpointing`, invalid `diarize`, invalid\n `time_stamps`, invalid `detect_language`, unsupported value, etc.).\n Also returned when `diarize=true` is requested but speaker labelling\n is not enabled on the serving instance, or when `time_stamps=true`\n is requested but word timestamps are not enabled on the serving\n instance.\n- `1011`: Internal server error. An `error` message is sent before the\n close.\n- `1013`: The service is temporarily at capacity and could not accept\n the connection. An `error` message is sent before the close with the\n text \"The service is temporarily unavailable. Please try again later.\"\n This is not an account or billing condition - retry the connection.\n Note that connections requesting `diarize=true` have a lower\n concurrency ceiling than plain transcription, so a `diarize=true`\n connection may be refused while a plain one succeeds.\n- `4001`: The `api_key` query parameter is missing or invalid.\n- `4002`: Audio data didn't match the declared raw format (sent\n container bytes but declared a raw type), or the audio could not\n be decoded mid-stream. The `error` message is\n \"Audio data does not match the declared audio_format.\" for a declared\n raw format mismatch, or\n \"The audio could not be processed. It may be corrupted or in an unsupported format.\"\n for a mid-stream decode failure.\n- `4003`: The request is not permitted.\n- `4004`: The API key does not have access to this model.\n- `4029`: The request could not be completed due to insufficient\n credits.\n- `4030`: Concurrent request limit reached.\n- `4031`: Monthly usage limit reached.\n","servers":[{"id":"production","protocol":"wss","host":"platform.modulate.ai","bindings":[],"variables":[]}],"address":"/api/velma-2-stt-streaming-multilingual-vfast","parameters":[],"bindings":[{"protocol":"ws","version":"latest","value":{"query":{"type":"object","required":["api_key","audio_format"],"properties":{"api_key":{"type":"string","description":"Your API key for authentication. Must be provided as a query\nparameter when establishing the WebSocket connection.\n"},"audio_format":{"type":"string","description":"Container or raw format of the audio data the client will send.\nRequired.\n\nFor container formats, the audio header determines the sample rate\nand channel count, and `sample_rate` / `num_channels` query\nparameters are ignored. The MP4-family values (`mp4`, `m4a`,\n`m4b`, `m4r`, `m4v`, `3gp`, `3gpp`, `3ga`, `3g2`, `f4a`,\n`f4b`) must be sent in a streamable layout;\notherwise the connection ends with an audio-processing error.\n\nFor raw formats, `sample_rate` and `num_channels` are required.\nThe raw `g722` and `vox` formats are additionally mono-only\n(`num_channels` must be `1`).\n\nFor lowest end-to-end latency, send\n`audio_format=s16le\u0026sample_rate=16000\u0026num_channels=1`.\n","enum":["s8","s16le","s16be","s24le","s24be","s32le","s32be","u8","u16le","u16be","u24le","u24be","u32le","u32be","f32le","f32be","f64le","f64be","mulaw","alaw","g722","vox","3g2","3ga","3gp","3gpp","8svx","aa3","aac","ac3","act","adts","aif","aifc","aiff","amb","amr","asf","at3","au","avr","awb","bwf","c2","caf","dss","dts","dtshd","eac3","ec3","f4a","f4b","flac","gsm","iff","m2a","m2ts","m4a","m4b","m4r","m4v","mka","mkv","mlp","mp+","mp1","mp2","mp3","mp4","mpa","mpc","mpga","mpp","mts","oga","ogg","ogx","oma","omg","opus","paf","pvf","qcp","ra","rf64","rm","rmvb","snd","svx","thd","ts","tta","voc","vqf","w64","wav","wave","weba","webm","wma","wmv"]},"sample_rate":{"type":"integer","description":"Source sample rate of the audio data in Hz. Required when\n`audio_format` is a raw type; ignored for container formats.\n","enum":[8000,11025,16000,22050,32000,44100,48000,96000]},"num_channels":{"type":"integer","description":"Number of audio channels in the source data (1-8). Required when\n`audio_format` is a raw type; ignored for container formats.\n","minimum":1,"maximum":8},"endpointing":{"type":"boolean","default":false,"description":"Whether to segment speech into utterances at pauses. Optional;\ndefaults to `false`.\n\nWhen `false` (the default), the connection produces a single\nfinal `utterance` at end-of-stream covering the whole stream\n(`start_ms=0`), and each `partial_utterance` reflects the whole\nstream so far.\n\nWhen `true`, trailing silence after speech closes the current\nutterance and starts a new one: the server emits one final\n`utterance` per speech segment (each with its own `start_ms` /\n`duration_ms`), and each `partial_utterance` reflects the current\nsegment. The full transcript is the concatenation of the final\n`utterance` texts.\n\nIn both modes every connection ends with at least one final\n`utterance`; a stream containing no speech yields a single\nfinal with empty `text`.\n\nIndependent of `diarize`. When both are `true`, a segment ends\nat a pause OR at a speaker change, whichever comes first.\n\nExample:\n`audio_format=s16le\u0026sample_rate=16000\u0026num_channels=1\u0026endpointing=true`.\n"},"diarize":{"type":"boolean","default":false,"description":"Whether to label which speaker produced each utterance.\nOptional; defaults to `false`.\n\nWhen `false` (the default), no speaker fields appear in any\nmessage and the payloads are byte-identical to a\nnon-diarized connection.\n\nWhen `true`, each final `utterance` additionally carries\n`speaker`, `n_speakers`, `speakers_capped`, and\n`speaker_purity`. A maximum of four concurrent speakers is\nsupported; see \"Speaker Labels\" above for what happens\nbeyond that and for the limits of the `speaker` index.\n\nIndependent of `endpointing`; all four combinations are\nvalid. Speaker labels are only meaningful per utterance,\nhowever, so `diarize=true\u0026endpointing=false` yields one\nwhole-stream utterance where `n_speakers` is the useful\nfield rather than `speaker`.\n\nRequesting `diarize=true` where speaker labelling is not\nenabled on the serving instance is rejected during the\nhandshake with close code `1003`.\n\nDiarized connections have a lower concurrency ceiling than\nplain transcription and may be refused with close code\n`1013` when that ceiling is reached.\n\nExample:\n`audio_format=s16le\u0026sample_rate=16000\u0026num_channels=1\u0026endpointing=true\u0026diarize=true`.\n"},"time_stamps":{"type":"boolean","default":false,"description":"Whether to include word-level timestamps on final\nutterances. Optional; defaults to `false`.\n\nWhen `false` (the default), no `words` field appears in any\nmessage and the payloads are byte-identical to a connection\nthat did not pass the parameter.\n\nWhen `true`, each final `utterance` additionally carries\n`words`: one entry per word of `text`, in order, each with\n`word`, `start_ms`, and `end_ms` in milliseconds from the\nbeginning of the audio stream. `partial_utterance` messages\nare unaffected.\n\nIndependent of `endpointing` and `diarize`; all\ncombinations are valid.\n\nRequesting `time_stamps=true` where word timestamps are not\nenabled on the serving instance is rejected during the\nhandshake with close code `1003`.\n\nExample:\n`audio_format=s16le\u0026sample_rate=16000\u0026num_channels=1\u0026endpointing=true\u0026time_stamps=true`.\n"},"detect_language":{"type":"boolean","default":false,"description":"Whether to detect and report the language of each final\nutterance. Optional; defaults to `false`.\n\nWhen `false` (the default), no `language` field appears in\nany message and the payloads are byte-identical to a\nconnection that did not pass the parameter.\n\nWhen `true`, each final `utterance` additionally carries\n`language`: one of the ISO 639-1 codes listed under\n\"Supported Languages\" above, or `null` when the utterance\nis too short to identify reliably. `partial_utterance`\nmessages are unaffected.\n\nIndependent of `endpointing`, `diarize`, and `time_stamps`;\nall combinations are valid.\n\nExample:\n`audio_format=s16le\u0026sample_rate=16000\u0026num_channels=1\u0026endpointing=true\u0026detect_language=true`.\n"}}}},"schemaProperties":[{"name":"query","type":"object","required":false,"properties":[{"name":"api_key","type":"string","description":"Your API key for authentication. Must be provided as a query\nparameter when establishing the WebSocket connection.\n","required":true},{"name":"audio_format","type":"string","description":"Container or raw format of the audio data the client will send.\nRequired.\n\nFor container formats, the audio header determines the sample rate\nand channel count, and `sample_rate` / `num_channels` query\nparameters are ignored. The MP4-family values (`mp4`, `m4a`,\n`m4b`, `m4r`, `m4v`, `3gp`, `3gpp`, `3ga`, `3g2`, `f4a`,\n`f4b`) must be sent in a streamable layout;\notherwise the connection ends with an audio-processing error.\n\nFor raw formats, `sample_rate` and `num_channels` are required.\nThe raw `g722` and `vox` formats are additionally mono-only\n(`num_channels` must be `1`).\n\nFor lowest end-to-end latency, send\n`audio_format=s16le\u0026sample_rate=16000\u0026num_channels=1`.\n","enumValues":["s8","s16le","s16be","s24le","s24be","s32le","s32be","u8","u16le","u16be","u24le","u24be","u32le","u32be","f32le","f32be","f64le","f64be","mulaw","alaw","g722","vox","3g2","3ga","3gp","3gpp","8svx","aa3","aac","ac3","act","adts","aif","aifc","aiff","amb","amr","asf","at3","au","avr","awb","bwf","c2","caf","dss","dts","dtshd","eac3","ec3","f4a","f4b","flac","gsm","iff","m2a","m2ts","m4a","m4b","m4r","m4v","mka","mkv","mlp","mp+","mp1","mp2","mp3","mp4","mpa","mpc","mpga","mpp","mts","oga","ogg","ogx","oma","omg","opus","paf","pvf","qcp","ra","rf64","rm","rmvb","snd","svx","thd","ts","tta","voc","vqf","w64","wav","wave","weba","webm","wma","wmv"],"required":true},{"name":"sample_rate","type":"integer","description":"Source sample rate of the audio data in Hz. Required when\n`audio_format` is a raw type; ignored for container formats.\n","enumValues":[8000,11025,16000,22050,32000,44100,48000,96000],"required":false},{"name":"num_channels","type":"integer","description":"Number of audio channels in the source data (1-8). Required when\n`audio_format` is a raw type; ignored for container formats.\n","required":false},{"name":"endpointing","type":"boolean","description":"Whether to segment speech into utterances at pauses. Optional;\ndefaults to `false`.\n\nWhen `false` (the default), the connection produces a single\nfinal `utterance` at end-of-stream covering the whole stream\n(`start_ms=0`), and each `partial_utterance` reflects the whole\nstream so far.\n\nWhen `true`, trailing silence after speech closes the current\nutterance and starts a new one: the server emits one final\n`utterance` per speech segment (each with its own `start_ms` /\n`duration_ms`), and each `partial_utterance` reflects the current\nsegment. The full transcript is the concatenation of the final\n`utterance` texts.\n\nIn both modes every connection ends with at least one final\n`utterance`; a stream containing no speech yields a single\nfinal with empty `text`.\n\nIndependent of `diarize`. When both are `true`, a segment ends\nat a pause OR at a speaker change, whichever comes first.\n\nExample:\n`audio_format=s16le\u0026sample_rate=16000\u0026num_channels=1\u0026endpointing=true`.\n","required":false},{"name":"diarize","type":"boolean","description":"Whether to label which speaker produced each utterance.\nOptional; defaults to `false`.\n\nWhen `false` (the default), no speaker fields appear in any\nmessage and the payloads are byte-identical to a\nnon-diarized connection.\n\nWhen `true`, each final `utterance` additionally carries\n`speaker`, `n_speakers`, `speakers_capped`, and\n`speaker_purity`. A maximum of four concurrent speakers is\nsupported; see \"Speaker Labels\" above for what happens\nbeyond that and for the limits of the `speaker` index.\n\nIndependent of `endpointing`; all four combinations are\nvalid. Speaker labels are only meaningful per utterance,\nhowever, so `diarize=true\u0026endpointing=false` yields one\nwhole-stream utterance where `n_speakers` is the useful\nfield rather than `speaker`.\n\nRequesting `diarize=true` where speaker labelling is not\nenabled on the serving instance is rejected during the\nhandshake with close code `1003`.\n\nDiarized connections have a lower concurrency ceiling than\nplain transcription and may be refused with close code\n`1013` when that ceiling is reached.\n\nExample:\n`audio_format=s16le\u0026sample_rate=16000\u0026num_channels=1\u0026endpointing=true\u0026diarize=true`.\n","required":false},{"name":"time_stamps","type":"boolean","description":"Whether to include word-level timestamps on final\nutterances. Optional; defaults to `false`.\n\nWhen `false` (the default), no `words` field appears in any\nmessage and the payloads are byte-identical to a connection\nthat did not pass the parameter.\n\nWhen `true`, each final `utterance` additionally carries\n`words`: one entry per word of `text`, in order, each with\n`word`, `start_ms`, and `end_ms` in milliseconds from the\nbeginning of the audio stream. `partial_utterance` messages\nare unaffected.\n\nIndependent of `endpointing` and `diarize`; all\ncombinations are valid.\n\nRequesting `time_stamps=true` where word timestamps are not\nenabled on the serving instance is rejected during the\nhandshake with close code `1003`.\n\nExample:\n`audio_format=s16le\u0026sample_rate=16000\u0026num_channels=1\u0026endpointing=true\u0026time_stamps=true`.\n","required":false},{"name":"detect_language","type":"boolean","description":"Whether to detect and report the language of each final\nutterance. Optional; defaults to `false`.\n\nWhen `false` (the default), no `language` field appears in\nany message and the payloads are byte-identical to a\nconnection that did not pass the parameter.\n\nWhen `true`, each final `utterance` additionally carries\n`language`: one of the ISO 639-1 codes listed under\n\"Supported Languages\" above, or `null` when the utterance\nis too short to identify reliably. `partial_utterance`\nmessages are unaffected.\n\nIndependent of `endpointing`, `diarize`, and `time_stamps`;\nall combinations are valid.\n\nExample:\n`audio_format=s16le\u0026sample_rate=16000\u0026num_channels=1\u0026endpointing=true\u0026detect_language=true`.\n","required":false}]}]}],"operations":[{"id":"streamAudio","title":"Stream audio","description":"Stream audio for low-latency multilingual transcription","type":"send","messages":[{"id":"audioChunk","contentType":"application/octet-stream","payload":[{"type":"string","format":"binary","x-parser-schema-id":"\u003canonymous-schema-1>","name":"Audio Data Chunk","description":"Raw audio data chunk for transcription. Sent zero or more times\nby the client during the stream lifetime. Each chunk's bytes are\ndecoded by the server according to the connection's\n`audio_format` query parameter.\n"}],"headers":[],"jsonPayloadSchema":{"type":"string","format":"binary","x-parser-schema-id":"\u003canonymous-schema-1>"},"title":"Audio Data Chunk","description":"Raw audio data chunk for transcription. Sent zero or more times\nby the client during the stream lifetime. Each chunk's bytes are\ndecoded by the server according to the connection's\n`audio_format` query parameter.\n","example":"{}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"audioChunk"}]},{"id":"endOfStream","contentType":"text/plain","payload":[{"type":"string","const":"","x-parser-schema-id":"\u003canonymous-schema-2>","name":"End of Audio Stream","description":"Empty text frame signaling end of audio. Sent exactly once by the\nclient after the last audio chunk. The server responds with a\nfinal `utterance` message followed by a `done` message, then\ncloses the connection.\n"}],"headers":[],"jsonPayloadSchema":{"type":"string","const":"","x-parser-schema-id":"\u003canonymous-schema-2>"},"title":"End of Audio Stream","description":"Empty text frame signaling end of audio. Sent exactly once by the\nclient after the last audio chunk. The server responds with a\nfinal `utterance` message followed by a `done` message, then\ncloses the connection.\n","example":"\"\"","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"endOfStream"}]}],"bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"velma2SttStreamingMultilingualVfast"}]},{"id":"receiveTranscription","title":"Receive transcription","description":"Receive partial and final transcription results from the server","type":"receive","messages":[{"id":"partialUtteranceResult","contentType":"application/json","payload":[{"name":"Partial Utterance Result","description":"In-progress transcript snapshot for the CURRENT speech segment. Sent\nzero or more times per segment, roughly every 1.5 seconds. The `text`\nfield contains the current segment's transcript so far - not a delta,\nand not the whole stream - with auto-capitalization and\nauto-punctuation already applied. Clients should REPLACE the current\nsegment's previously displayed partial text, not append. Partials\nnever carry speaker labels, even with `diarize=true`, and never\ncarry word timestamps, even with `time_stamps=true`.\n","type":"object","properties":[{"name":"type","type":"string","description":"partial_utterance","required":true},{"name":"partial_utterance","type":"object","required":true,"properties":[{"name":"text","type":"string","description":"The complete transcript built so far for the current scope -\nthe whole connection by default, or the current speech segment\nwhen `endpointing=true` - with auto-capitalization (sentence\ncase, proper nouns, etc.) and auto-punctuation (commas,\nperiods, question marks, and the language's own conventions\nsuch as Spanish `¿`) already applied by the model, in the\nlanguage spoken. This is NOT a delta from the previous partial -\nclients should display this as a replacement for any previously\ndisplayed partial text. The last few words, including their\ncapitalization and punctuation, may be revised in subsequent\npartials as the model sees more audio context.\n","required":true},{"name":"is_final","type":"boolean","description":"Always `false` for `partial_utterance` messages. Use the\nmessage `type` field to distinguish partial from final.\n","required":true}]}]}],"headers":[],"jsonPayloadSchema":{"type":"object","required":["type","partial_utterance"],"properties":{"type":{"type":"string","const":"partial_utterance","x-parser-schema-id":"\u003canonymous-schema-4>"},"partial_utterance":{"type":"object","required":["text","is_final"],"properties":{"text":{"type":"string","description":"The complete transcript built so far for the current scope -\nthe whole connection by default, or the current speech segment\nwhen `endpointing=true` - with auto-capitalization (sentence\ncase, proper nouns, etc.) and auto-punctuation (commas,\nperiods, question marks, and the language's own conventions\nsuch as Spanish `¿`) already applied by the model, in the\nlanguage spoken. This is NOT a delta from the previous partial -\nclients should display this as a replacement for any previously\ndisplayed partial text. The last few words, including their\ncapitalization and punctuation, may be revised in subsequent\npartials as the model sees more audio context.\n","example":"Hola, ¿cómo estás","x-parser-schema-id":"\u003canonymous-schema-5>"},"is_final":{"type":"boolean","const":false,"description":"Always `false` for `partial_utterance` messages. Use the\nmessage `type` field to distinguish partial from final.\n","x-parser-schema-id":"\u003canonymous-schema-6>"}},"x-parser-schema-id":"StreamingPartialUtterance"}},"x-parser-schema-id":"\u003canonymous-schema-3>"},"title":"Partial Utterance Result","description":"In-progress transcript snapshot for the CURRENT speech segment. Sent\nzero or more times per segment, roughly every 1.5 seconds. The `text`\nfield contains the current segment's transcript so far - not a delta,\nand not the whole stream - with auto-capitalization and\nauto-punctuation already applied. Clients should REPLACE the current\nsegment's previously displayed partial text, not append. Partials\nnever carry speaker labels, even with `diarize=true`, and never\ncarry word timestamps, even with `time_stamps=true`.\n","example":"{\n \"type\": \"partial_utterance\",\n \"partial_utterance\": {\n \"text\": \"Hola, ¿cómo estás\",\n \"is_final\": false\n }\n}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"partialUtteranceResult"}]},{"id":"utteranceResult","contentType":"application/json","payload":[{"name":"Final Utterance Result","description":"The final transcript for one segment of speech, with\nauto-capitalization and auto-punctuation applied, plus the segment's\nstart time and duration. With `diarize=true` it also carries the\nspeaker who produced it, with `time_stamps=true` the start and\nend time of every word, and with `detect_language=true` its\ndetected language. Sent once per segment (when the segment\nends, and once more for the last segment after end-of-stream), and\nsupersedes the `partial_utterance` messages for that segment. The\nfull transcript is the concatenation of these texts in order.\n","type":"object","properties":[{"name":"type","type":"string","description":"utterance","required":true},{"name":"utterance","type":"object","required":true,"properties":[{"name":"text","type":"string","description":"The final transcribed text for one segment of speech, with\nauto-capitalization and auto-punctuation already applied by the\nmodel, in the language spoken. This is the authoritative\ntranscript for the segment and will not be revised. The full\ntranscript is the concatenation of the `text` of every\n`utterance` in order.\n","required":true},{"name":"is_final","type":"boolean","description":"Always `true` for `utterance` messages. Use the message `type`\nfield to distinguish partial from final.\n","required":true},{"name":"start_ms","type":"integer","description":"Start time of this segment, in milliseconds from the beginning of\nthe audio stream. Approximate: speech onset is detected at the\nserver's internal processing granularity, so the start may differ\nfrom the first spoken word by a fraction of a second.\n","required":true},{"name":"duration_ms","type":"integer","description":"Duration of this segment's speech, in milliseconds, excluding the\ntrailing pause that ended the segment. Approximate, with the same\nboundary granularity as `start_ms`. With endpointing off, the\nsingle final utterance instead covers the whole stream, including\nany leading and trailing silence.\n","required":true},{"name":"language","type":["string","null"],"description":"Present only when `detect_language=true`. The detected ISO\n639-1 language code of this utterance, one of the codes\nlisted under \"Supported Languages\" above.\n\n`null` means the utterance was too short to identify\nreliably - a deliberate result, not a low-confidence guess.\nCommon on very short utterances, such as a single word or a\nshort back-channel.\n","enumValues":["bg","hr","cs","da","nl","en","et","fi","fr","de","el","hu","it","lv","lt","mt","pl","pt","ro","ru","sk","sl","es","sv","uk"],"required":false},{"name":"speaker","type":"integer","description":"Present only when `diarize=true`. Zero-based index of the\nspeaker who produced this utterance, stable for the lifetime of\nthe connection but meaningless outside it - the same person on a\nnew connection may receive a different index.\n\n`null` means diarization was requested but no speaker could be\ndetermined for this utterance, which happens for very short or\nsilent segments. That is distinct from the field being absent,\nwhich means diarization was not requested at all.\n\nWith `endpointing=false` there is a single whole-stream\nutterance that may contain several speakers, so this field is\nindicative only in that mode - read `n_speakers` instead.\n","required":false},{"name":"n_speakers","type":"integer","description":"Present only when `diarize=true`. Count of distinct speakers\ndetected on the connection so far. This is the meaningful\nspeaker signal when `endpointing=false`, where one `speaker`\nindex cannot describe a whole multi-speaker stream.\n","required":false},{"name":"speakers_capped","type":"boolean","description":"Present only when `diarize=true`. `true` once all four speaker\nslots are in use, meaning the connection may contain more\nspeakers than can be represented. Beyond four, additional\nspeakers are merged into existing labels rather than reported\nseparately - their speech is still transcribed, but `speaker`\nwill be wrong for some utterances and there is no other signal\nthat this happened. Clients that act on speaker identity should\ncheck this field.\n","required":false},{"name":"speaker_purity","type":"number","description":"Present only when `diarize=true`. The proportion of this\nutterance's speech attributed to the speaker named in\n`speaker`. `1.0` means the utterance was cleanly single-speaker.\nA lower value means the utterance spans a speaker change that\nthe segmentation did not split, so its single `speaker` label\ndescribes only the majority of it.\n","required":false},{"name":"words","type":"array","description":"Present only when `time_stamps=true`. One entry per word of\n`text`, in the same order. Absent - not an empty array - when\nword timestamps were not requested, so a client can tell\n\"timestamps off\" from \"no words\".\n","required":false,"properties":[{"name":"word","type":"string","description":"The word as it appears in the utterance `text`, including any\nattached punctuation and casing.\n","required":true},{"name":"start_ms","type":"integer","description":"Start time of the word, in milliseconds from the beginning of\nthe audio stream - the same clock as the utterance's\n`start_ms`, not relative to the utterance.\n","required":true},{"name":"end_ms","type":"integer","description":"End time of the word, in milliseconds from the beginning of the\naudio stream. Always greater than or equal to `start_ms`.\n","required":true}]}]}]}],"headers":[],"jsonPayloadSchema":{"type":"object","required":["type","utterance"],"properties":{"type":{"type":"string","const":"utterance","x-parser-schema-id":"\u003canonymous-schema-8>"},"utterance":{"type":"object","required":["text","is_final","start_ms","duration_ms"],"properties":{"text":{"type":"string","description":"The final transcribed text for one segment of speech, with\nauto-capitalization and auto-punctuation already applied by the\nmodel, in the language spoken. This is the authoritative\ntranscript for the segment and will not be revised. The full\ntranscript is the concatenation of the `text` of every\n`utterance` in order.\n","example":"Hola, ¿cómo estás hoy?","x-parser-schema-id":"\u003canonymous-schema-9>"},"is_final":{"type":"boolean","const":true,"description":"Always `true` for `utterance` messages. Use the message `type`\nfield to distinguish partial from final.\n","x-parser-schema-id":"\u003canonymous-schema-10>"},"start_ms":{"type":"integer","minimum":0,"description":"Start time of this segment, in milliseconds from the beginning of\nthe audio stream. Approximate: speech onset is detected at the\nserver's internal processing granularity, so the start may differ\nfrom the first spoken word by a fraction of a second.\n","example":0,"x-parser-schema-id":"\u003canonymous-schema-11>"},"duration_ms":{"type":"integer","minimum":0,"description":"Duration of this segment's speech, in milliseconds, excluding the\ntrailing pause that ended the segment. Approximate, with the same\nboundary granularity as `start_ms`. With endpointing off, the\nsingle final utterance instead covers the whole stream, including\nany leading and trailing silence.\n","example":2360,"x-parser-schema-id":"\u003canonymous-schema-12>"},"language":{"type":["string","null"],"enum":["bg","hr","cs","da","nl","en","et","fi","fr","de","el","hu","it","lv","lt","mt","pl","pt","ro","ru","sk","sl","es","sv","uk",null],"description":"Present only when `detect_language=true`. The detected ISO\n639-1 language code of this utterance, one of the codes\nlisted under \"Supported Languages\" above.\n\n`null` means the utterance was too short to identify\nreliably - a deliberate result, not a low-confidence guess.\nCommon on very short utterances, such as a single word or a\nshort back-channel.\n","example":"es","x-parser-schema-id":"\u003canonymous-schema-13>"},"speaker":{"type":"integer","nullable":true,"minimum":0,"maximum":3,"description":"Present only when `diarize=true`. Zero-based index of the\nspeaker who produced this utterance, stable for the lifetime of\nthe connection but meaningless outside it - the same person on a\nnew connection may receive a different index.\n\n`null` means diarization was requested but no speaker could be\ndetermined for this utterance, which happens for very short or\nsilent segments. That is distinct from the field being absent,\nwhich means diarization was not requested at all.\n\nWith `endpointing=false` there is a single whole-stream\nutterance that may contain several speakers, so this field is\nindicative only in that mode - read `n_speakers` instead.\n","example":0,"x-parser-schema-id":"\u003canonymous-schema-14>"},"n_speakers":{"type":"integer","minimum":0,"description":"Present only when `diarize=true`. Count of distinct speakers\ndetected on the connection so far. This is the meaningful\nspeaker signal when `endpointing=false`, where one `speaker`\nindex cannot describe a whole multi-speaker stream.\n","example":2,"x-parser-schema-id":"\u003canonymous-schema-15>"},"speakers_capped":{"type":"boolean","description":"Present only when `diarize=true`. `true` once all four speaker\nslots are in use, meaning the connection may contain more\nspeakers than can be represented. Beyond four, additional\nspeakers are merged into existing labels rather than reported\nseparately - their speech is still transcribed, but `speaker`\nwill be wrong for some utterances and there is no other signal\nthat this happened. Clients that act on speaker identity should\ncheck this field.\n","example":false,"x-parser-schema-id":"\u003canonymous-schema-16>"},"speaker_purity":{"type":"number","minimum":0,"maximum":1,"description":"Present only when `diarize=true`. The proportion of this\nutterance's speech attributed to the speaker named in\n`speaker`. `1.0` means the utterance was cleanly single-speaker.\nA lower value means the utterance spans a speaker change that\nthe segmentation did not split, so its single `speaker` label\ndescribes only the majority of it.\n","example":1,"x-parser-schema-id":"\u003canonymous-schema-17>"},"words":{"type":"array","items":{"type":"object","required":["word","start_ms","end_ms"],"properties":{"word":{"type":"string","description":"The word as it appears in the utterance `text`, including any\nattached punctuation and casing.\n","example":"Hola,","x-parser-schema-id":"\u003canonymous-schema-19>"},"start_ms":{"type":"integer","minimum":0,"description":"Start time of the word, in milliseconds from the beginning of\nthe audio stream - the same clock as the utterance's\n`start_ms`, not relative to the utterance.\n","example":1240,"x-parser-schema-id":"\u003canonymous-schema-20>"},"end_ms":{"type":"integer","minimum":0,"description":"End time of the word, in milliseconds from the beginning of the\naudio stream. Always greater than or equal to `start_ms`.\n","example":1560,"x-parser-schema-id":"\u003canonymous-schema-21>"}},"x-parser-schema-id":"WordTimestamp"},"description":"Present only when `time_stamps=true`. One entry per word of\n`text`, in the same order. Absent - not an empty array - when\nword timestamps were not requested, so a client can tell\n\"timestamps off\" from \"no words\".\n","x-parser-schema-id":"\u003canonymous-schema-18>"}},"x-parser-schema-id":"StreamingUtterance"}},"x-parser-schema-id":"\u003canonymous-schema-7>"},"title":"Final Utterance Result","description":"The final transcript for one segment of speech, with\nauto-capitalization and auto-punctuation applied, plus the segment's\nstart time and duration. With `diarize=true` it also carries the\nspeaker who produced it, with `time_stamps=true` the start and\nend time of every word, and with `detect_language=true` its\ndetected language. Sent once per segment (when the segment\nends, and once more for the last segment after end-of-stream), and\nsupersedes the `partial_utterance` messages for that segment. The\nfull transcript is the concatenation of these texts in order.\n","example":"{\n \"type\": \"utterance\",\n \"utterance\": {\n \"text\": \"Hola, ¿cómo estás hoy?\",\n \"is_final\": true,\n \"start_ms\": 0,\n \"duration_ms\": 2360\n }\n}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"utteranceResult"}]},{"id":"errorResult","contentType":"application/json","payload":[{"name":"Error","description":"An error occurred during transcription. Sent at most once per\nconnection; the WebSocket closes shortly after. No further\nmessages follow an `error`.\n","type":"object","properties":[{"name":"type","type":"string","description":"error","required":true},{"name":"error","type":"string","description":"Human-readable error message","required":true}]}],"headers":[],"jsonPayloadSchema":{"type":"object","required":["type","error"],"properties":{"type":{"type":"string","const":"error","x-parser-schema-id":"\u003canonymous-schema-23>"},"error":{"type":"string","description":"Human-readable error message","x-parser-schema-id":"\u003canonymous-schema-24>"}},"x-parser-schema-id":"\u003canonymous-schema-22>"},"title":"Error","description":"An error occurred during transcription. Sent at most once per\nconnection; the WebSocket closes shortly after. No further\nmessages follow an `error`.\n","example":"{\n \"type\": \"error\",\n \"error\": \"Internal server error\"\n}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"errorResult"}]},{"id":"doneResult","contentType":"application/json","payload":[{"name":"Transcription Complete","description":"Transcription completed successfully. Sent exactly once, immediately\nafter the final `utterance` message. After this message the server\ncloses the WebSocket.\n","type":"object","properties":[{"name":"type","type":"string","description":"done","required":true},{"name":"duration_ms","type":"integer","description":"Total duration of audio processed in milliseconds","required":true}]}],"headers":[],"jsonPayloadSchema":{"type":"object","required":["type","duration_ms"],"properties":{"type":{"type":"string","const":"done","x-parser-schema-id":"\u003canonymous-schema-26>"},"duration_ms":{"type":"integer","minimum":0,"description":"Total duration of audio processed in milliseconds","x-parser-schema-id":"\u003canonymous-schema-27>"}},"x-parser-schema-id":"\u003canonymous-schema-25>"},"title":"Transcription Complete","description":"Transcription completed successfully. Sent exactly once, immediately\nafter the final `utterance` message. After this message the server\ncloses the WebSocket.\n","example":"{\n \"type\": \"done\",\n \"duration_ms\": 14253\n}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"doneResult"}]}],"bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"velma2SttStreamingMultilingualVfast"}]}],"sendOperations":[{"id":"receiveTranscription","title":"Receive transcription","description":"Receive partial and final transcription results from the server","type":"receive","messages":[{"id":"partialUtteranceResult","contentType":"application/json","payload":[{"name":"Partial Utterance Result","description":"In-progress transcript snapshot for the CURRENT speech segment. Sent\nzero or more times per segment, roughly every 1.5 seconds. The `text`\nfield contains the current segment's transcript so far - not a delta,\nand not the whole stream - with auto-capitalization and\nauto-punctuation already applied. Clients should REPLACE the current\nsegment's previously displayed partial text, not append. Partials\nnever carry speaker labels, even with `diarize=true`, and never\ncarry word timestamps, even with `time_stamps=true`.\n","type":"object","properties":[{"name":"type","type":"string","description":"partial_utterance","required":true},{"name":"partial_utterance","type":"object","required":true,"properties":[{"name":"text","type":"string","description":"The complete transcript built so far for the current scope -\nthe whole connection by default, or the current speech segment\nwhen `endpointing=true` - with auto-capitalization (sentence\ncase, proper nouns, etc.) and auto-punctuation (commas,\nperiods, question marks, and the language's own conventions\nsuch as Spanish `¿`) already applied by the model, in the\nlanguage spoken. This is NOT a delta from the previous partial -\nclients should display this as a replacement for any previously\ndisplayed partial text. The last few words, including their\ncapitalization and punctuation, may be revised in subsequent\npartials as the model sees more audio context.\n","required":true},{"name":"is_final","type":"boolean","description":"Always `false` for `partial_utterance` messages. Use the\nmessage `type` field to distinguish partial from final.\n","required":true}]}]}],"headers":[],"jsonPayloadSchema":{"type":"object","required":["type","partial_utterance"],"properties":{"type":{"type":"string","const":"partial_utterance","x-parser-schema-id":"\u003canonymous-schema-4>"},"partial_utterance":{"type":"object","required":["text","is_final"],"properties":{"text":{"type":"string","description":"The complete transcript built so far for the current scope -\nthe whole connection by default, or the current speech segment\nwhen `endpointing=true` - with auto-capitalization (sentence\ncase, proper nouns, etc.) and auto-punctuation (commas,\nperiods, question marks, and the language's own conventions\nsuch as Spanish `¿`) already applied by the model, in the\nlanguage spoken. This is NOT a delta from the previous partial -\nclients should display this as a replacement for any previously\ndisplayed partial text. The last few words, including their\ncapitalization and punctuation, may be revised in subsequent\npartials as the model sees more audio context.\n","example":"Hola, ¿cómo estás","x-parser-schema-id":"\u003canonymous-schema-5>"},"is_final":{"type":"boolean","const":false,"description":"Always `false` for `partial_utterance` messages. Use the\nmessage `type` field to distinguish partial from final.\n","x-parser-schema-id":"\u003canonymous-schema-6>"}},"x-parser-schema-id":"StreamingPartialUtterance"}},"x-parser-schema-id":"\u003canonymous-schema-3>"},"title":"Partial Utterance Result","description":"In-progress transcript snapshot for the CURRENT speech segment. Sent\nzero or more times per segment, roughly every 1.5 seconds. The `text`\nfield contains the current segment's transcript so far - not a delta,\nand not the whole stream - with auto-capitalization and\nauto-punctuation already applied. Clients should REPLACE the current\nsegment's previously displayed partial text, not append. Partials\nnever carry speaker labels, even with `diarize=true`, and never\ncarry word timestamps, even with `time_stamps=true`.\n","example":"{\n \"type\": \"partial_utterance\",\n \"partial_utterance\": {\n \"text\": \"Hola, ¿cómo estás\",\n \"is_final\": false\n }\n}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"partialUtteranceResult"}]},{"id":"utteranceResult","contentType":"application/json","payload":[{"name":"Final Utterance Result","description":"The final transcript for one segment of speech, with\nauto-capitalization and auto-punctuation applied, plus the segment's\nstart time and duration. With `diarize=true` it also carries the\nspeaker who produced it, with `time_stamps=true` the start and\nend time of every word, and with `detect_language=true` its\ndetected language. Sent once per segment (when the segment\nends, and once more for the last segment after end-of-stream), and\nsupersedes the `partial_utterance` messages for that segment. The\nfull transcript is the concatenation of these texts in order.\n","type":"object","properties":[{"name":"type","type":"string","description":"utterance","required":true},{"name":"utterance","type":"object","required":true,"properties":[{"name":"text","type":"string","description":"The final transcribed text for one segment of speech, with\nauto-capitalization and auto-punctuation already applied by the\nmodel, in the language spoken. This is the authoritative\ntranscript for the segment and will not be revised. The full\ntranscript is the concatenation of the `text` of every\n`utterance` in order.\n","required":true},{"name":"is_final","type":"boolean","description":"Always `true` for `utterance` messages. Use the message `type`\nfield to distinguish partial from final.\n","required":true},{"name":"start_ms","type":"integer","description":"Start time of this segment, in milliseconds from the beginning of\nthe audio stream. Approximate: speech onset is detected at the\nserver's internal processing granularity, so the start may differ\nfrom the first spoken word by a fraction of a second.\n","required":true},{"name":"duration_ms","type":"integer","description":"Duration of this segment's speech, in milliseconds, excluding the\ntrailing pause that ended the segment. Approximate, with the same\nboundary granularity as `start_ms`. With endpointing off, the\nsingle final utterance instead covers the whole stream, including\nany leading and trailing silence.\n","required":true},{"name":"language","type":["string","null"],"description":"Present only when `detect_language=true`. The detected ISO\n639-1 language code of this utterance, one of the codes\nlisted under \"Supported Languages\" above.\n\n`null` means the utterance was too short to identify\nreliably - a deliberate result, not a low-confidence guess.\nCommon on very short utterances, such as a single word or a\nshort back-channel.\n","enumValues":["bg","hr","cs","da","nl","en","et","fi","fr","de","el","hu","it","lv","lt","mt","pl","pt","ro","ru","sk","sl","es","sv","uk"],"required":false},{"name":"speaker","type":"integer","description":"Present only when `diarize=true`. Zero-based index of the\nspeaker who produced this utterance, stable for the lifetime of\nthe connection but meaningless outside it - the same person on a\nnew connection may receive a different index.\n\n`null` means diarization was requested but no speaker could be\ndetermined for this utterance, which happens for very short or\nsilent segments. That is distinct from the field being absent,\nwhich means diarization was not requested at all.\n\nWith `endpointing=false` there is a single whole-stream\nutterance that may contain several speakers, so this field is\nindicative only in that mode - read `n_speakers` instead.\n","required":false},{"name":"n_speakers","type":"integer","description":"Present only when `diarize=true`. Count of distinct speakers\ndetected on the connection so far. This is the meaningful\nspeaker signal when `endpointing=false`, where one `speaker`\nindex cannot describe a whole multi-speaker stream.\n","required":false},{"name":"speakers_capped","type":"boolean","description":"Present only when `diarize=true`. `true` once all four speaker\nslots are in use, meaning the connection may contain more\nspeakers than can be represented. Beyond four, additional\nspeakers are merged into existing labels rather than reported\nseparately - their speech is still transcribed, but `speaker`\nwill be wrong for some utterances and there is no other signal\nthat this happened. Clients that act on speaker identity should\ncheck this field.\n","required":false},{"name":"speaker_purity","type":"number","description":"Present only when `diarize=true`. The proportion of this\nutterance's speech attributed to the speaker named in\n`speaker`. `1.0` means the utterance was cleanly single-speaker.\nA lower value means the utterance spans a speaker change that\nthe segmentation did not split, so its single `speaker` label\ndescribes only the majority of it.\n","required":false},{"name":"words","type":"array","description":"Present only when `time_stamps=true`. One entry per word of\n`text`, in the same order. Absent - not an empty array - when\nword timestamps were not requested, so a client can tell\n\"timestamps off\" from \"no words\".\n","required":false,"properties":[{"name":"word","type":"string","description":"The word as it appears in the utterance `text`, including any\nattached punctuation and casing.\n","required":true},{"name":"start_ms","type":"integer","description":"Start time of the word, in milliseconds from the beginning of\nthe audio stream - the same clock as the utterance's\n`start_ms`, not relative to the utterance.\n","required":true},{"name":"end_ms","type":"integer","description":"End time of the word, in milliseconds from the beginning of the\naudio stream. Always greater than or equal to `start_ms`.\n","required":true}]}]}]}],"headers":[],"jsonPayloadSchema":{"type":"object","required":["type","utterance"],"properties":{"type":{"type":"string","const":"utterance","x-parser-schema-id":"\u003canonymous-schema-8>"},"utterance":{"type":"object","required":["text","is_final","start_ms","duration_ms"],"properties":{"text":{"type":"string","description":"The final transcribed text for one segment of speech, with\nauto-capitalization and auto-punctuation already applied by the\nmodel, in the language spoken. This is the authoritative\ntranscript for the segment and will not be revised. The full\ntranscript is the concatenation of the `text` of every\n`utterance` in order.\n","example":"Hola, ¿cómo estás hoy?","x-parser-schema-id":"\u003canonymous-schema-9>"},"is_final":{"type":"boolean","const":true,"description":"Always `true` for `utterance` messages. Use the message `type`\nfield to distinguish partial from final.\n","x-parser-schema-id":"\u003canonymous-schema-10>"},"start_ms":{"type":"integer","minimum":0,"description":"Start time of this segment, in milliseconds from the beginning of\nthe audio stream. Approximate: speech onset is detected at the\nserver's internal processing granularity, so the start may differ\nfrom the first spoken word by a fraction of a second.\n","example":0,"x-parser-schema-id":"\u003canonymous-schema-11>"},"duration_ms":{"type":"integer","minimum":0,"description":"Duration of this segment's speech, in milliseconds, excluding the\ntrailing pause that ended the segment. Approximate, with the same\nboundary granularity as `start_ms`. With endpointing off, the\nsingle final utterance instead covers the whole stream, including\nany leading and trailing silence.\n","example":2360,"x-parser-schema-id":"\u003canonymous-schema-12>"},"language":{"type":["string","null"],"enum":["bg","hr","cs","da","nl","en","et","fi","fr","de","el","hu","it","lv","lt","mt","pl","pt","ro","ru","sk","sl","es","sv","uk",null],"description":"Present only when `detect_language=true`. The detected ISO\n639-1 language code of this utterance, one of the codes\nlisted under \"Supported Languages\" above.\n\n`null` means the utterance was too short to identify\nreliably - a deliberate result, not a low-confidence guess.\nCommon on very short utterances, such as a single word or a\nshort back-channel.\n","example":"es","x-parser-schema-id":"\u003canonymous-schema-13>"},"speaker":{"type":"integer","nullable":true,"minimum":0,"maximum":3,"description":"Present only when `diarize=true`. Zero-based index of the\nspeaker who produced this utterance, stable for the lifetime of\nthe connection but meaningless outside it - the same person on a\nnew connection may receive a different index.\n\n`null` means diarization was requested but no speaker could be\ndetermined for this utterance, which happens for very short or\nsilent segments. That is distinct from the field being absent,\nwhich means diarization was not requested at all.\n\nWith `endpointing=false` there is a single whole-stream\nutterance that may contain several speakers, so this field is\nindicative only in that mode - read `n_speakers` instead.\n","example":0,"x-parser-schema-id":"\u003canonymous-schema-14>"},"n_speakers":{"type":"integer","minimum":0,"description":"Present only when `diarize=true`. Count of distinct speakers\ndetected on the connection so far. This is the meaningful\nspeaker signal when `endpointing=false`, where one `speaker`\nindex cannot describe a whole multi-speaker stream.\n","example":2,"x-parser-schema-id":"\u003canonymous-schema-15>"},"speakers_capped":{"type":"boolean","description":"Present only when `diarize=true`. `true` once all four speaker\nslots are in use, meaning the connection may contain more\nspeakers than can be represented. Beyond four, additional\nspeakers are merged into existing labels rather than reported\nseparately - their speech is still transcribed, but `speaker`\nwill be wrong for some utterances and there is no other signal\nthat this happened. Clients that act on speaker identity should\ncheck this field.\n","example":false,"x-parser-schema-id":"\u003canonymous-schema-16>"},"speaker_purity":{"type":"number","minimum":0,"maximum":1,"description":"Present only when `diarize=true`. The proportion of this\nutterance's speech attributed to the speaker named in\n`speaker`. `1.0` means the utterance was cleanly single-speaker.\nA lower value means the utterance spans a speaker change that\nthe segmentation did not split, so its single `speaker` label\ndescribes only the majority of it.\n","example":1,"x-parser-schema-id":"\u003canonymous-schema-17>"},"words":{"type":"array","items":{"type":"object","required":["word","start_ms","end_ms"],"properties":{"word":{"type":"string","description":"The word as it appears in the utterance `text`, including any\nattached punctuation and casing.\n","example":"Hola,","x-parser-schema-id":"\u003canonymous-schema-19>"},"start_ms":{"type":"integer","minimum":0,"description":"Start time of the word, in milliseconds from the beginning of\nthe audio stream - the same clock as the utterance's\n`start_ms`, not relative to the utterance.\n","example":1240,"x-parser-schema-id":"\u003canonymous-schema-20>"},"end_ms":{"type":"integer","minimum":0,"description":"End time of the word, in milliseconds from the beginning of the\naudio stream. Always greater than or equal to `start_ms`.\n","example":1560,"x-parser-schema-id":"\u003canonymous-schema-21>"}},"x-parser-schema-id":"WordTimestamp"},"description":"Present only when `time_stamps=true`. One entry per word of\n`text`, in the same order. Absent - not an empty array - when\nword timestamps were not requested, so a client can tell\n\"timestamps off\" from \"no words\".\n","x-parser-schema-id":"\u003canonymous-schema-18>"}},"x-parser-schema-id":"StreamingUtterance"}},"x-parser-schema-id":"\u003canonymous-schema-7>"},"title":"Final Utterance Result","description":"The final transcript for one segment of speech, with\nauto-capitalization and auto-punctuation applied, plus the segment's\nstart time and duration. With `diarize=true` it also carries the\nspeaker who produced it, with `time_stamps=true` the start and\nend time of every word, and with `detect_language=true` its\ndetected language. Sent once per segment (when the segment\nends, and once more for the last segment after end-of-stream), and\nsupersedes the `partial_utterance` messages for that segment. The\nfull transcript is the concatenation of these texts in order.\n","example":"{\n \"type\": \"utterance\",\n \"utterance\": {\n \"text\": \"Hola, ¿cómo estás hoy?\",\n \"is_final\": true,\n \"start_ms\": 0,\n \"duration_ms\": 2360\n }\n}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"utteranceResult"}]},{"id":"errorResult","contentType":"application/json","payload":[{"name":"Error","description":"An error occurred during transcription. Sent at most once per\nconnection; the WebSocket closes shortly after. No further\nmessages follow an `error`.\n","type":"object","properties":[{"name":"type","type":"string","description":"error","required":true},{"name":"error","type":"string","description":"Human-readable error message","required":true}]}],"headers":[],"jsonPayloadSchema":{"type":"object","required":["type","error"],"properties":{"type":{"type":"string","const":"error","x-parser-schema-id":"\u003canonymous-schema-23>"},"error":{"type":"string","description":"Human-readable error message","x-parser-schema-id":"\u003canonymous-schema-24>"}},"x-parser-schema-id":"\u003canonymous-schema-22>"},"title":"Error","description":"An error occurred during transcription. Sent at most once per\nconnection; the WebSocket closes shortly after. No further\nmessages follow an `error`.\n","example":"{\n \"type\": \"error\",\n \"error\": \"Internal server error\"\n}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"errorResult"}]},{"id":"doneResult","contentType":"application/json","payload":[{"name":"Transcription Complete","description":"Transcription completed successfully. Sent exactly once, immediately\nafter the final `utterance` message. After this message the server\ncloses the WebSocket.\n","type":"object","properties":[{"name":"type","type":"string","description":"done","required":true},{"name":"duration_ms","type":"integer","description":"Total duration of audio processed in milliseconds","required":true}]}],"headers":[],"jsonPayloadSchema":{"type":"object","required":["type","duration_ms"],"properties":{"type":{"type":"string","const":"done","x-parser-schema-id":"\u003canonymous-schema-26>"},"duration_ms":{"type":"integer","minimum":0,"description":"Total duration of audio processed in milliseconds","x-parser-schema-id":"\u003canonymous-schema-27>"}},"x-parser-schema-id":"\u003canonymous-schema-25>"},"title":"Transcription Complete","description":"Transcription completed successfully. Sent exactly once, immediately\nafter the final `utterance` message. After this message the server\ncloses the WebSocket.\n","example":"{\n \"type\": \"done\",\n \"duration_ms\": 14253\n}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"doneResult"}]}],"bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"velma2SttStreamingMultilingualVfast"}]}],"receiveOperations":[{"id":"streamAudio","title":"Stream audio","description":"Stream audio for low-latency multilingual transcription","type":"send","messages":[{"id":"audioChunk","contentType":"application/octet-stream","payload":[{"type":"string","format":"binary","x-parser-schema-id":"\u003canonymous-schema-1>","name":"Audio Data Chunk","description":"Raw audio data chunk for transcription. Sent zero or more times\nby the client during the stream lifetime. Each chunk's bytes are\ndecoded by the server according to the connection's\n`audio_format` query parameter.\n"}],"headers":[],"jsonPayloadSchema":{"type":"string","format":"binary","x-parser-schema-id":"\u003canonymous-schema-1>"},"title":"Audio Data Chunk","description":"Raw audio data chunk for transcription. Sent zero or more times\nby the client during the stream lifetime. Each chunk's bytes are\ndecoded by the server according to the connection's\n`audio_format` query parameter.\n","example":"{}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"audioChunk"}]},{"id":"endOfStream","contentType":"text/plain","payload":[{"type":"string","const":"","x-parser-schema-id":"\u003canonymous-schema-2>","name":"End of Audio Stream","description":"Empty text frame signaling end of audio. Sent exactly once by the\nclient after the last audio chunk. The server responds with a\nfinal `utterance` message followed by a `done` message, then\ncloses the connection.\n"}],"headers":[],"jsonPayloadSchema":{"type":"string","const":"","x-parser-schema-id":"\u003canonymous-schema-2>"},"title":"End of Audio Stream","description":"Empty text frame signaling end of audio. Sent exactly once by the\nclient after the last audio chunk. The server responds with a\nfinal `utterance` message followed by a `done` message, then\ncloses the connection.\n","example":"\"\"","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"endOfStream"}]}],"bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"velma2SttStreamingMultilingualVfast"}]}],"sendMessages":[{"id":"partialUtteranceResult","contentType":"application/json","payload":[{"name":"Partial Utterance Result","description":"In-progress transcript snapshot for the CURRENT speech segment. Sent\nzero or more times per segment, roughly every 1.5 seconds. The `text`\nfield contains the current segment's transcript so far - not a delta,\nand not the whole stream - with auto-capitalization and\nauto-punctuation already applied. Clients should REPLACE the current\nsegment's previously displayed partial text, not append. Partials\nnever carry speaker labels, even with `diarize=true`, and never\ncarry word timestamps, even with `time_stamps=true`.\n","type":"object","properties":[{"name":"type","type":"string","description":"partial_utterance","required":true},{"name":"partial_utterance","type":"object","required":true,"properties":[{"name":"text","type":"string","description":"The complete transcript built so far for the current scope -\nthe whole connection by default, or the current speech segment\nwhen `endpointing=true` - with auto-capitalization (sentence\ncase, proper nouns, etc.) and auto-punctuation (commas,\nperiods, question marks, and the language's own conventions\nsuch as Spanish `¿`) already applied by the model, in the\nlanguage spoken. This is NOT a delta from the previous partial -\nclients should display this as a replacement for any previously\ndisplayed partial text. The last few words, including their\ncapitalization and punctuation, may be revised in subsequent\npartials as the model sees more audio context.\n","required":true},{"name":"is_final","type":"boolean","description":"Always `false` for `partial_utterance` messages. Use the\nmessage `type` field to distinguish partial from final.\n","required":true}]}]}],"headers":[],"jsonPayloadSchema":{"type":"object","required":["type","partial_utterance"],"properties":{"type":{"type":"string","const":"partial_utterance","x-parser-schema-id":"\u003canonymous-schema-4>"},"partial_utterance":{"type":"object","required":["text","is_final"],"properties":{"text":{"type":"string","description":"The complete transcript built so far for the current scope -\nthe whole connection by default, or the current speech segment\nwhen `endpointing=true` - with auto-capitalization (sentence\ncase, proper nouns, etc.) and auto-punctuation (commas,\nperiods, question marks, and the language's own conventions\nsuch as Spanish `¿`) already applied by the model, in the\nlanguage spoken. This is NOT a delta from the previous partial -\nclients should display this as a replacement for any previously\ndisplayed partial text. The last few words, including their\ncapitalization and punctuation, may be revised in subsequent\npartials as the model sees more audio context.\n","example":"Hola, ¿cómo estás","x-parser-schema-id":"\u003canonymous-schema-5>"},"is_final":{"type":"boolean","const":false,"description":"Always `false` for `partial_utterance` messages. Use the\nmessage `type` field to distinguish partial from final.\n","x-parser-schema-id":"\u003canonymous-schema-6>"}},"x-parser-schema-id":"StreamingPartialUtterance"}},"x-parser-schema-id":"\u003canonymous-schema-3>"},"title":"Partial Utterance Result","description":"In-progress transcript snapshot for the CURRENT speech segment. Sent\nzero or more times per segment, roughly every 1.5 seconds. The `text`\nfield contains the current segment's transcript so far - not a delta,\nand not the whole stream - with auto-capitalization and\nauto-punctuation already applied. Clients should REPLACE the current\nsegment's previously displayed partial text, not append. Partials\nnever carry speaker labels, even with `diarize=true`, and never\ncarry word timestamps, even with `time_stamps=true`.\n","example":"{\n \"type\": \"partial_utterance\",\n \"partial_utterance\": {\n \"text\": \"Hola, ¿cómo estás\",\n \"is_final\": false\n }\n}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"partialUtteranceResult"}]},{"id":"utteranceResult","contentType":"application/json","payload":[{"name":"Final Utterance Result","description":"The final transcript for one segment of speech, with\nauto-capitalization and auto-punctuation applied, plus the segment's\nstart time and duration. With `diarize=true` it also carries the\nspeaker who produced it, with `time_stamps=true` the start and\nend time of every word, and with `detect_language=true` its\ndetected language. Sent once per segment (when the segment\nends, and once more for the last segment after end-of-stream), and\nsupersedes the `partial_utterance` messages for that segment. The\nfull transcript is the concatenation of these texts in order.\n","type":"object","properties":[{"name":"type","type":"string","description":"utterance","required":true},{"name":"utterance","type":"object","required":true,"properties":[{"name":"text","type":"string","description":"The final transcribed text for one segment of speech, with\nauto-capitalization and auto-punctuation already applied by the\nmodel, in the language spoken. This is the authoritative\ntranscript for the segment and will not be revised. The full\ntranscript is the concatenation of the `text` of every\n`utterance` in order.\n","required":true},{"name":"is_final","type":"boolean","description":"Always `true` for `utterance` messages. Use the message `type`\nfield to distinguish partial from final.\n","required":true},{"name":"start_ms","type":"integer","description":"Start time of this segment, in milliseconds from the beginning of\nthe audio stream. Approximate: speech onset is detected at the\nserver's internal processing granularity, so the start may differ\nfrom the first spoken word by a fraction of a second.\n","required":true},{"name":"duration_ms","type":"integer","description":"Duration of this segment's speech, in milliseconds, excluding the\ntrailing pause that ended the segment. Approximate, with the same\nboundary granularity as `start_ms`. With endpointing off, the\nsingle final utterance instead covers the whole stream, including\nany leading and trailing silence.\n","required":true},{"name":"language","type":["string","null"],"description":"Present only when `detect_language=true`. The detected ISO\n639-1 language code of this utterance, one of the codes\nlisted under \"Supported Languages\" above.\n\n`null` means the utterance was too short to identify\nreliably - a deliberate result, not a low-confidence guess.\nCommon on very short utterances, such as a single word or a\nshort back-channel.\n","enumValues":["bg","hr","cs","da","nl","en","et","fi","fr","de","el","hu","it","lv","lt","mt","pl","pt","ro","ru","sk","sl","es","sv","uk"],"required":false},{"name":"speaker","type":"integer","description":"Present only when `diarize=true`. Zero-based index of the\nspeaker who produced this utterance, stable for the lifetime of\nthe connection but meaningless outside it - the same person on a\nnew connection may receive a different index.\n\n`null` means diarization was requested but no speaker could be\ndetermined for this utterance, which happens for very short or\nsilent segments. That is distinct from the field being absent,\nwhich means diarization was not requested at all.\n\nWith `endpointing=false` there is a single whole-stream\nutterance that may contain several speakers, so this field is\nindicative only in that mode - read `n_speakers` instead.\n","required":false},{"name":"n_speakers","type":"integer","description":"Present only when `diarize=true`. Count of distinct speakers\ndetected on the connection so far. This is the meaningful\nspeaker signal when `endpointing=false`, where one `speaker`\nindex cannot describe a whole multi-speaker stream.\n","required":false},{"name":"speakers_capped","type":"boolean","description":"Present only when `diarize=true`. `true` once all four speaker\nslots are in use, meaning the connection may contain more\nspeakers than can be represented. Beyond four, additional\nspeakers are merged into existing labels rather than reported\nseparately - their speech is still transcribed, but `speaker`\nwill be wrong for some utterances and there is no other signal\nthat this happened. Clients that act on speaker identity should\ncheck this field.\n","required":false},{"name":"speaker_purity","type":"number","description":"Present only when `diarize=true`. The proportion of this\nutterance's speech attributed to the speaker named in\n`speaker`. `1.0` means the utterance was cleanly single-speaker.\nA lower value means the utterance spans a speaker change that\nthe segmentation did not split, so its single `speaker` label\ndescribes only the majority of it.\n","required":false},{"name":"words","type":"array","description":"Present only when `time_stamps=true`. One entry per word of\n`text`, in the same order. Absent - not an empty array - when\nword timestamps were not requested, so a client can tell\n\"timestamps off\" from \"no words\".\n","required":false,"properties":[{"name":"word","type":"string","description":"The word as it appears in the utterance `text`, including any\nattached punctuation and casing.\n","required":true},{"name":"start_ms","type":"integer","description":"Start time of the word, in milliseconds from the beginning of\nthe audio stream - the same clock as the utterance's\n`start_ms`, not relative to the utterance.\n","required":true},{"name":"end_ms","type":"integer","description":"End time of the word, in milliseconds from the beginning of the\naudio stream. Always greater than or equal to `start_ms`.\n","required":true}]}]}]}],"headers":[],"jsonPayloadSchema":{"type":"object","required":["type","utterance"],"properties":{"type":{"type":"string","const":"utterance","x-parser-schema-id":"\u003canonymous-schema-8>"},"utterance":{"type":"object","required":["text","is_final","start_ms","duration_ms"],"properties":{"text":{"type":"string","description":"The final transcribed text for one segment of speech, with\nauto-capitalization and auto-punctuation already applied by the\nmodel, in the language spoken. This is the authoritative\ntranscript for the segment and will not be revised. The full\ntranscript is the concatenation of the `text` of every\n`utterance` in order.\n","example":"Hola, ¿cómo estás hoy?","x-parser-schema-id":"\u003canonymous-schema-9>"},"is_final":{"type":"boolean","const":true,"description":"Always `true` for `utterance` messages. Use the message `type`\nfield to distinguish partial from final.\n","x-parser-schema-id":"\u003canonymous-schema-10>"},"start_ms":{"type":"integer","minimum":0,"description":"Start time of this segment, in milliseconds from the beginning of\nthe audio stream. Approximate: speech onset is detected at the\nserver's internal processing granularity, so the start may differ\nfrom the first spoken word by a fraction of a second.\n","example":0,"x-parser-schema-id":"\u003canonymous-schema-11>"},"duration_ms":{"type":"integer","minimum":0,"description":"Duration of this segment's speech, in milliseconds, excluding the\ntrailing pause that ended the segment. Approximate, with the same\nboundary granularity as `start_ms`. With endpointing off, the\nsingle final utterance instead covers the whole stream, including\nany leading and trailing silence.\n","example":2360,"x-parser-schema-id":"\u003canonymous-schema-12>"},"language":{"type":["string","null"],"enum":["bg","hr","cs","da","nl","en","et","fi","fr","de","el","hu","it","lv","lt","mt","pl","pt","ro","ru","sk","sl","es","sv","uk",null],"description":"Present only when `detect_language=true`. The detected ISO\n639-1 language code of this utterance, one of the codes\nlisted under \"Supported Languages\" above.\n\n`null` means the utterance was too short to identify\nreliably - a deliberate result, not a low-confidence guess.\nCommon on very short utterances, such as a single word or a\nshort back-channel.\n","example":"es","x-parser-schema-id":"\u003canonymous-schema-13>"},"speaker":{"type":"integer","nullable":true,"minimum":0,"maximum":3,"description":"Present only when `diarize=true`. Zero-based index of the\nspeaker who produced this utterance, stable for the lifetime of\nthe connection but meaningless outside it - the same person on a\nnew connection may receive a different index.\n\n`null` means diarization was requested but no speaker could be\ndetermined for this utterance, which happens for very short or\nsilent segments. That is distinct from the field being absent,\nwhich means diarization was not requested at all.\n\nWith `endpointing=false` there is a single whole-stream\nutterance that may contain several speakers, so this field is\nindicative only in that mode - read `n_speakers` instead.\n","example":0,"x-parser-schema-id":"\u003canonymous-schema-14>"},"n_speakers":{"type":"integer","minimum":0,"description":"Present only when `diarize=true`. Count of distinct speakers\ndetected on the connection so far. This is the meaningful\nspeaker signal when `endpointing=false`, where one `speaker`\nindex cannot describe a whole multi-speaker stream.\n","example":2,"x-parser-schema-id":"\u003canonymous-schema-15>"},"speakers_capped":{"type":"boolean","description":"Present only when `diarize=true`. `true` once all four speaker\nslots are in use, meaning the connection may contain more\nspeakers than can be represented. Beyond four, additional\nspeakers are merged into existing labels rather than reported\nseparately - their speech is still transcribed, but `speaker`\nwill be wrong for some utterances and there is no other signal\nthat this happened. Clients that act on speaker identity should\ncheck this field.\n","example":false,"x-parser-schema-id":"\u003canonymous-schema-16>"},"speaker_purity":{"type":"number","minimum":0,"maximum":1,"description":"Present only when `diarize=true`. The proportion of this\nutterance's speech attributed to the speaker named in\n`speaker`. `1.0` means the utterance was cleanly single-speaker.\nA lower value means the utterance spans a speaker change that\nthe segmentation did not split, so its single `speaker` label\ndescribes only the majority of it.\n","example":1,"x-parser-schema-id":"\u003canonymous-schema-17>"},"words":{"type":"array","items":{"type":"object","required":["word","start_ms","end_ms"],"properties":{"word":{"type":"string","description":"The word as it appears in the utterance `text`, including any\nattached punctuation and casing.\n","example":"Hola,","x-parser-schema-id":"\u003canonymous-schema-19>"},"start_ms":{"type":"integer","minimum":0,"description":"Start time of the word, in milliseconds from the beginning of\nthe audio stream - the same clock as the utterance's\n`start_ms`, not relative to the utterance.\n","example":1240,"x-parser-schema-id":"\u003canonymous-schema-20>"},"end_ms":{"type":"integer","minimum":0,"description":"End time of the word, in milliseconds from the beginning of the\naudio stream. Always greater than or equal to `start_ms`.\n","example":1560,"x-parser-schema-id":"\u003canonymous-schema-21>"}},"x-parser-schema-id":"WordTimestamp"},"description":"Present only when `time_stamps=true`. One entry per word of\n`text`, in the same order. Absent - not an empty array - when\nword timestamps were not requested, so a client can tell\n\"timestamps off\" from \"no words\".\n","x-parser-schema-id":"\u003canonymous-schema-18>"}},"x-parser-schema-id":"StreamingUtterance"}},"x-parser-schema-id":"\u003canonymous-schema-7>"},"title":"Final Utterance Result","description":"The final transcript for one segment of speech, with\nauto-capitalization and auto-punctuation applied, plus the segment's\nstart time and duration. With `diarize=true` it also carries the\nspeaker who produced it, with `time_stamps=true` the start and\nend time of every word, and with `detect_language=true` its\ndetected language. Sent once per segment (when the segment\nends, and once more for the last segment after end-of-stream), and\nsupersedes the `partial_utterance` messages for that segment. The\nfull transcript is the concatenation of these texts in order.\n","example":"{\n \"type\": \"utterance\",\n \"utterance\": {\n \"text\": \"Hola, ¿cómo estás hoy?\",\n \"is_final\": true,\n \"start_ms\": 0,\n \"duration_ms\": 2360\n }\n}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"utteranceResult"}]},{"id":"errorResult","contentType":"application/json","payload":[{"name":"Error","description":"An error occurred during transcription. Sent at most once per\nconnection; the WebSocket closes shortly after. No further\nmessages follow an `error`.\n","type":"object","properties":[{"name":"type","type":"string","description":"error","required":true},{"name":"error","type":"string","description":"Human-readable error message","required":true}]}],"headers":[],"jsonPayloadSchema":{"type":"object","required":["type","error"],"properties":{"type":{"type":"string","const":"error","x-parser-schema-id":"\u003canonymous-schema-23>"},"error":{"type":"string","description":"Human-readable error message","x-parser-schema-id":"\u003canonymous-schema-24>"}},"x-parser-schema-id":"\u003canonymous-schema-22>"},"title":"Error","description":"An error occurred during transcription. Sent at most once per\nconnection; the WebSocket closes shortly after. No further\nmessages follow an `error`.\n","example":"{\n \"type\": \"error\",\n \"error\": \"Internal server error\"\n}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"errorResult"}]},{"id":"doneResult","contentType":"application/json","payload":[{"name":"Transcription Complete","description":"Transcription completed successfully. Sent exactly once, immediately\nafter the final `utterance` message. After this message the server\ncloses the WebSocket.\n","type":"object","properties":[{"name":"type","type":"string","description":"done","required":true},{"name":"duration_ms","type":"integer","description":"Total duration of audio processed in milliseconds","required":true}]}],"headers":[],"jsonPayloadSchema":{"type":"object","required":["type","duration_ms"],"properties":{"type":{"type":"string","const":"done","x-parser-schema-id":"\u003canonymous-schema-26>"},"duration_ms":{"type":"integer","minimum":0,"description":"Total duration of audio processed in milliseconds","x-parser-schema-id":"\u003canonymous-schema-27>"}},"x-parser-schema-id":"\u003canonymous-schema-25>"},"title":"Transcription Complete","description":"Transcription completed successfully. Sent exactly once, immediately\nafter the final `utterance` message. After this message the server\ncloses the WebSocket.\n","example":"{\n \"type\": \"done\",\n \"duration_ms\": 14253\n}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"doneResult"}]}],"receiveMessages":[{"id":"audioChunk","contentType":"application/octet-stream","payload":[{"type":"string","format":"binary","x-parser-schema-id":"\u003canonymous-schema-1>","name":"Audio Data Chunk","description":"Raw audio data chunk for transcription. Sent zero or more times\nby the client during the stream lifetime. Each chunk's bytes are\ndecoded by the server according to the connection's\n`audio_format` query parameter.\n"}],"headers":[],"jsonPayloadSchema":{"type":"string","format":"binary","x-parser-schema-id":"\u003canonymous-schema-1>"},"title":"Audio Data Chunk","description":"Raw audio data chunk for transcription. Sent zero or more times\nby the client during the stream lifetime. Each chunk's bytes are\ndecoded by the server according to the connection's\n`audio_format` query parameter.\n","example":"{}","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"audioChunk"}]},{"id":"endOfStream","contentType":"text/plain","payload":[{"type":"string","const":"","x-parser-schema-id":"\u003canonymous-schema-2>","name":"End of Audio Stream","description":"Empty text frame signaling end of audio. Sent exactly once by the\nclient after the last audio chunk. The server responds with a\nfinal `utterance` message followed by a `done` message, then\ncloses the connection.\n"}],"headers":[],"jsonPayloadSchema":{"type":"string","const":"","x-parser-schema-id":"\u003canonymous-schema-2>"},"title":"End of Audio Stream","description":"Empty text frame signaling end of audio. Sent exactly once by the\nclient after the last audio chunk. The server responds with a\nfinal `utterance` message followed by a `done` message, then\ncloses the connection.\n","example":"\"\"","bindings":[],"extensions":[{"id":"x-parser-unique-object-id","value":"endOfStream"}]}],"extensions":[{"id":"x-parser-unique-object-id","value":"velma2SttStreamingMultilingualVfast"}],"securitySchemes":[]},"channelId":"velma2SttStreamingMultilingualVfast","metadata":{"id":30804,"subdomain":"modulateai","eTag":"\"39f73236ffc38c4797f65c101c3fdf0d\"","originalFileLocation":"api/stt_streaming_multilingual_vfast.yaml","uuid":"53b4ae32-e003-48b1-90da-591094542953","source":"LOCAL_FILE","createdAt":"2026-09-15T15:07:08.178Z","updatedAt":"2026-10-16T13:48:39.348Z","deletedAt":null,"retiredAt":null,"retiredByDeploymentHistoryId":null}},"subdomain":"modulateai","siteName":"Modulate","title":"Multilingual Fast Transcription Streaming - Modulate","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-19T19:30:51.522Z","originalFileLocation":"api-reference/stt/streaming-multilingual-vfast.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Low-latency multilingual speech-to-text over WebSocket. Covers 25 languages with automatic language identification, with optional speaker labels, word timestamps, and per-utterance language codes.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Modulate\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/modulateai/DjDAyeOufX95soiv/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/modulateai/DjDAyeOufX95soiv/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/modulateai/DjDAyeOufX95soiv/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/modulateai/DjDAyeOufX95soiv/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/modulateai/DjDAyeOufX95soiv/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/modulateai/DjDAyeOufX95soiv/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/modulateai/DjDAyeOufX95soiv/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/modulateai/DjDAyeOufX95soiv/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/modulateai/DjDAyeOufX95soiv/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Multilingual Fast Transcription Streaming - Modulate\">\u003cmeta data-mint-head property=\"og:description\" content=\"Low-latency multilingual speech-to-text over WebSocket. Covers 25 languages with automatic language identification, with optional speaker labels, word timestamps, and per-utterance language codes.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Modulate\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.modulate.ai/api-reference/stt/streaming-multilingual-vfast\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://modulateai.mintlify.app/_mintlify/api/og/v2?division=Speech-to-text+Transcription\u0026amp;title=Multilingual+Fast+Transcription+Streaming\u0026amp;description=Low-latency+multilingual+speech-to-text+over+WebSocket.+Covers+25+languages+with+automatic+language+identification%2C+with+optional+speaker+labels%2C+word+timestamp\u0026amp;theme=5b1c5018c22e2de339bbf72b\u0026amp;signature=2eb4920817c3c167189b2307d2fd5d8a6532afd3364c644fcf1ac12dbb41d034\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Multilingual Fast Transcription Streaming - Modulate\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Low-latency multilingual speech-to-text over WebSocket. Covers 25 languages with automatic language identification, with optional speaker labels, word timestamps, and per-utterance language codes.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://modulateai.mintlify.app/_mintlify/api/og/v2?division=Speech-to-text+Transcription\u0026amp;title=Multilingual+Fast+Transcription+Streaming\u0026amp;description=Low-latency+multilingual+speech-to-text+over+WebSocket.+Covers+25+languages+with+automatic+language+identification%2C+with+optional+speaker+labels%2C+word+timestamp\u0026amp;theme=5b1c5018c22e2de339bbf72b\u0026amp;signature=2eb4920817c3c167189b2307d2fd5d8a6532afd3364c644fcf1ac12dbb41d034\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/modulateai/DjDAyeOufX95soiv/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Modulate\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#285FEB\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.modulate.ai/api-reference/stt/streaming-multilingual-vfast\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/stt/streaming-multilingual-vfast.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.modulate.ai/#organization\",\"name\":\"Modulate\",\"url\":\"https://docs.modulate.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/modulateai/0NHKM9zXEnghoEfZ/images/wordmark-navy.svg?fit=max\u0026auto=format\u0026n=0NHKM9zXEnghoEfZ\u0026q=85\u0026s=7ee7a19111bb0154aa2e6934ebd29607\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.modulate.ai#website\",\"name\":\"Modulate\",\"url\":\"https://docs.modulate.ai\",\"publisher\":{\"@id\":\"https://docs.modulate.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.modulate.ai/api-reference/stt/streaming-multilingual-vfast#webpage\",\"url\":\"https://docs.modulate.ai/api-reference/stt/streaming-multilingual-vfast\",\"name\":\"Multilingual Fast Transcription Streaming\",\"description\":\"Low-latency multilingual speech-to-text over WebSocket. Covers 25 languages with automatic language identification, with optional speaker labels, word timestamps, and per-utterance language codes.\",\"dateModified\":\"2026-10-19T19:30:51.522Z\",\"isPartOf\":{\"@id\":\"https://docs.modulate.ai#website\"},\"breadcrumb\":{\"@id\":\"https://docs.modulate.ai/api-reference/stt/streaming-multilingual-vfast#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.modulate.ai/api-reference/stt/streaming-multilingual-vfast#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Speech-to-text Transcription\",\"item\":\"https://docs.modulate.ai/api-reference/stt/overview\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Multilingual Fast Transcription Streaming\",\"item\":\"https://docs.modulate.ai/api-reference/stt/streaming-multilingual-vfast\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.modulate.ai/api-reference/stt/streaming-multilingual-vfast#apireference\",\"headline\":\"Multilingual Fast Transcription Streaming\",\"name\":\"Multilingual Fast Transcription Streaming\",\"description\":\"Low-latency multilingual speech-to-text over WebSocket. Covers 25 languages with automatic language identification, with optional speaker labels, word timestamps, and per-utterance language codes.\",\"url\":\"https://docs.modulate.ai/api-reference/stt/streaming-multilingual-vfast\",\"mainEntityOfPage\":{\"@id\":\"https://docs.modulate.ai/api-reference/stt/streaming-multilingual-vfast#webpage\"},\"dateModified\":\"2026-10-19T19:30:51.522Z\",\"publisher\":{\"@id\":\"https://docs.modulate.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.modulate.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Modulate\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Modulate","nav":{"global":null,"tabs":[{"tab":"Get Started","pages":[{"title":"Get Started","href":""}]},{"tab":"Velma","pages":[{"title":"Velma","href":"/velma/overview"}]},{"tab":"API Reference","groups":[{"group":"Velma","icon":"comments","pages":[{"title":"Velma","sidebarTitle":"Overview","href":"/api-reference/velma/overview"},{"title":"Velma Batch","sidebarTitle":"Batch","openapi":"api/velma_2_batch.yaml POST /api/velma-2-batch","href":"/api-reference/velma/batch"},{"title":"List behavior presets","sidebarTitle":"Behavior presets","openapi":"api/velma_2_batch.yaml GET /api/velma-2-batch/list-presets","href":"/api-reference/velma/presets"},{"title":"Velma Streaming","sidebarTitle":"Streaming","asyncapi":"api/velma_2_streaming.yaml velma2Streaming","href":"/api-reference/velma/streaming"}]},{"group":"Speech-to-text Transcription","icon":"microphone","pages":[{"title":"Speech-to-text Transcription","sidebarTitle":"Overview","href":"/api-reference/stt/overview"},{"title":"Speech-to-Text Transcription Batch Multilingual","sidebarTitle":"Batch Multilingual","openapi":"api/velma_2_stt_batch.yaml POST /api/velma-2-stt-batch","href":"/api-reference/stt/batch"},{"title":"Speech-to-Text Transcription Streaming Multilingual","sidebarTitle":"Streaming Multilingual","asyncapi":"api/velma_2_stt_streaming.yaml velma2SttStreaming","href":"/api-reference/stt/streaming"},{"title":"Speech-to-Text Transcription Batch English VFast","sidebarTitle":"Batch English VFast","openapi":"api/velma_2_stt_batch_english_vfast.yaml POST /api/velma-2-stt-batch-english-vfast","href":"/api-reference/stt/batch-english-vfast"},{"title":"Speech-to-Text Streaming English","sidebarTitle":"Streaming English","asyncapi":"api/velma_2_stt_streaming_english_v2.yaml velma2SttStreamingEnglishV2","href":"/api-reference/stt/streaming-vfast"},{"title":"Multilingual Fast Transcription Batch","sidebarTitle":"Batch Multilingual VFast","description":"Fast multilingual batch transcription. Optionally declare the spoken language for the fastest path; otherwise the language is detected automatically.","openapi":"api/velma_2_stt_batch_multilingual_vfast.yaml POST /api/velma-2-stt-batch-multilingual-vfast","href":"/api-reference/stt/batch-multilingual-vfast"},{"title":"Multilingual Fast Transcription Streaming","sidebarTitle":"Streaming (Multilingual Fast)","asyncapi":"api/stt_streaming_multilingual_vfast.yaml velma2SttStreamingMultilingualVfast","href":"/api-reference/stt/streaming-multilingual-vfast"}]},{"group":"Deepfake Detection","icon":"shield-halved","pages":[{"title":"Deepfake Detection","sidebarTitle":"Overview","description":"Synthetic voice detection — deepfake detection on pre-recorded files (batch) or live audio (streaming).","href":"/api-reference/svd/overview"},{"title":"Deepfake Detection Batch","sidebarTitle":"Batch","openapi":"api/velma_2_synthetic_voice_detection_batch.yaml POST /api/velma-2-synthetic-voice-detection-batch","href":"/api-reference/svd/batch"},{"title":"Deepfake Detection Streaming","sidebarTitle":"Streaming","asyncapi":"api/velma_2_synthetic_voice_detection_streaming.yaml streaming-detection","href":"/api-reference/svd/streaming"}]},{"group":"Emotion Detection","icon":"face-smile","pages":[{"title":"Emotion Detection","sidebarTitle":"Overview","href":"/api-reference/emotion/overview"},{"title":"Emotion Detection Batch","sidebarTitle":"Batch","openapi":"api/velma_2_emotion_batch.yaml POST /api/velma-2-emotion-batch","href":"/api-reference/emotion/batch"}]},{"group":"Accent Detection","icon":"globe","pages":[{"title":"Accent Detection","sidebarTitle":"Overview","href":"/api-reference/accent/overview"},{"title":"Accent Detection Batch","sidebarTitle":"Batch","openapi":"api/velma_2_accent_batch.yaml POST /api/velma-2-accent-batch","href":"/api-reference/accent/batch"}]},{"group":"PII/PHI Redaction","icon":"eye-slash","pages":[{"title":"PII/PHI Redaction","sidebarTitle":"Overview","href":"/api-reference/redaction/overview"},{"title":"PII/PHI Redaction Batch","sidebarTitle":"Batch","openapi":"api/velma_2_pii_phi_redaction_batch.yaml POST /api/velma-2-pii-phi-redaction-batch","href":"/api-reference/redaction/batch"},{"title":"PII/PHI Redaction Streaming","sidebarTitle":"Streaming","asyncapi":"api/velma_2_pii_phi_redaction_streaming.yaml velma2PiiPhiRedactionStreaming","href":"/api-reference/redaction/streaming"}]},{"group":"Music Detection","icon":"music","pages":[{"title":"Music Detection","sidebarTitle":"Overview","href":"/api-reference/music-detection/overview"},{"title":"Music Detection Batch","sidebarTitle":"Batch","openapi":"api/velma_2_music_detection_batch.yaml POST /api/velma-2-music-detection-batch","href":"/api-reference/music-detection/batch"},{"title":"Music Detection Streaming","sidebarTitle":"Streaming","asyncapi":"api/velma_2_music_detection_streaming.yaml streaming-detection","href":"/api-reference/music-detection/streaming"}]},{"group":"AI Music Detection","icon":"robot","pages":[{"title":"AI Music Detection","sidebarTitle":"Overview","href":"/api-reference/ai-music-detection/overview"},{"title":"AI Music Detection Batch","sidebarTitle":"Batch","openapi":"api/velma_2_ai_music_detection_batch.yaml POST /api/velma-2-ai-music-detection-batch","href":"/api-reference/ai-music-detection/batch"},{"title":"AI Music Detection Streaming","sidebarTitle":"Streaming","asyncapi":"api/velma_2_ai_music_detection_streaming.yaml streaming-detection","href":"/api-reference/ai-music-detection/streaming"}]},{"group":"Language Detection","icon":"language","pages":[{"title":"Language Detection","sidebarTitle":"Overview","href":"/api-reference/language-detection/overview"},{"title":"Language Detection Batch","sidebarTitle":"Batch","openapi":"api/velma_2_language_detection_batch.yaml POST /api/velma-2-language-detection-batch","href":"/api-reference/language-detection/batch"}]},{"group":"Audio Event Detection","icon":"waveform-lines","pages":[{"title":"Audio Event Detection","sidebarTitle":"Overview","href":"/api-reference/audio-event-detection/overview"},{"title":"Audio Event Detection Batch","sidebarTitle":"Batch","openapi":"api/velma_2_audio_event_classifier.yaml POST /api/velma-2-audio-event-classifier","href":"/api-reference/audio-event-detection/batch"}]}]},{"tab":"Benchmarks","pages":[{"title":"Benchmarks","href":"/benchmarks/overview"}]},{"tab":"Support","pages":[{"title":"Support","href":"/support"}]}]},"basePath":"","title":"Multilingual Fast Transcription Streaming - Modulate","buildId":"dpl_36EDyZCDfRuoUD9af5CH4M1bqY2h","deploymentId":"dpl_36EDyZCDfRuoUD9af5CH4M1bqY2h","dynamics":["a4b48b4bee","a9bb46feb3","3b021dca80"],"chunks":["Page-DSYy6aK3.js","utils-ME8dDnLe.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","getPastedJson-u6QiPzNZ.js","icon-Bb-CBSxO.js","MethodPill-F7l5AI7V.js","DuplicateIcon-IiAXkdSg.js","createIcon-FliI8EBc.js","DynamicMarkdown-B62XqCSI.js","getApiPlaygroundDisplay-BnYQO2Ss.js","MessageExamples-DJblhcCE.js","CodeSnippet-RKKOc8c_.js","Markdown-BOgQCTwD.js","clsx-BIWXJmsZ.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-DKZWslLH.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-UDqbR6xh.js"]}