Concepts

Choose the right speech workflow by input state, result timing, and output type.

Start with two questions: is the input audio or text, and—if it is audio—is the whole unit already available? Those answers choose the processing model. Transport and SDK client come afterward.

Choose the processing model

Starting pointChooseBehaviorDecision boundary
A complete long-form or large recordingBatch transcriptionUpload once, receive a jobId, and poll a jobUse for meetings, podcasts, archives, and other work where asynchronous completion is acceptable.
A complete audio unit whose latency mattersFast transcriptionSend the whole encoded audio unit over Socket.IO, then receive result eventsUse for bounded full-audio work such as one agentic or conversational turn. It is not live audio streaming and is not the long-recording path.
Audio that is still arrivingRealtime transcriptionSend PCM16 chunks and receive provisional and final text while the stream is openUse for calls, captions, microphones, and live media pipelines.
A need to know who spoke whenDiarizationProduce speaker time segments alongside batch audio or from a live PCM streamAdd it to the matching batch or live workflow; it does not produce the transcript itself.
Text that must become audioText-to-speech (TTS)Send text and receive streamed raw PCM samplesUse when speech is the output rather than the input.

The decisive distinction is the input boundary. Batch and fast transcription both start with complete audio; fast result events do not make the input realtime. If audio is still being produced, choose realtime.

Batch is a job

Batch submission returns jobId. Poll the result route until a terminal state or until the app's overall deadline expires.

StatusStateApp decision
queuedNon-terminalWait, then poll again within the deadline.
processingNon-terminalKeep waiting within the same deadline.
doneTerminal successRead the completed result.
failedTerminal failureStop polling and surface the job failure.
clearedTerminal without a stored resultStop polling and treat the result as unavailable.

The published API does not define a retention duration, so do not design around a guaranteed result-availability window. SDK 0.18.0 succeeds on done, raises on failed, and otherwise stops at its configured timeout; a direct poller must handle cleared itself.

Result retrieval defaults to save_result=false. A terminal done or failed read can clear stored fields after building its response, so a lost response can be followed by cleared. Set save_result=true before polling when terminal delivery must be repeatable; that setting still defines no retention duration.

Event results are state, not a transcript log

Fast, realtime, and diarization responses evolve. Reconcile them by request or stream ID instead of appending every event.

SurfaceResult markersState rule
Fast transcriptionid, seq, is_finalTreat non-final responses as provisional and commit the final response once.
Realtime transcriptionid, seq, is_final, is_speech_finalReplace provisional text while both final flags are false; commit when either becomes true.
Live diarizationid, final_segments, active_segments, is_finalAccumulate unseen final additions and replace the revisable active tail.

Fast and Realtime responses contain seq, but their current public contracts do not define ordering or uniqueness semantics for it. Route events by id, process them in observed arrival order, and treat each event's text and words as that event's state. Finish only on the capability's final signal or an error/deadline.

RealtimeSubtitles intentionally ignores provisional responses and deduplicates finalized responses by stream ID and seq. Because the current Realtime wire contract does not promise distinct seq values, do not use that helper to collect multiple final events. Collect finalized words in observed arrival order and render them with Subtitles instead.

End a live input with the documented final frame, wait only to an app deadline, and always clean up the client. A close wait expiring does not prove a final result arrived; inspect the state recorded by callbacks.

Build a speaker timeline

Diarization produces relative speaker labels over time, not real-world speaker identity. Live SDK updates expose the reconciled timeline as update.segments and new final additions as update.newlyFinalized / update.newly_finalized. Closing the SDK stream waits up to five seconds and returns the best-known timeline if no final update arrives in that time.

In the batch V2 response, final_word_segments and diarization_segments are separate. If the app needs speaker-attributed words, document an explicit overlap rule rather than assuming every word already contains speaker.

Audio and transport contracts

SurfaceAudio contractSDK 0.18.0 transport
Batch transcriptionComplete supported audio-file containerREST
Fast transcriptionOne complete AAC, FLAC, MP3, MP4, or WAV fileSocket.IO
Realtime transcription and live diarizationPCM16 little-endian, 16 kHz, monoSocket.IO
TTS through the SDKRaw PCM16 little-endian, 24 kHz, mono outputSocket.IO
Direct HTTP TTSUndelimited protocol capture with conceptual 16 kHz PCM16 service frames; not generically decodable audioNo public SDK wrapper

Raw PCM is not a media-file container. A typical player needs a WAV header with the matching sample rate. Direct integrations can also use the validated Realtime HTTP operations; no public SDK 0.18.0 client wraps them.

Next steps

Concepts explain what to choose. The SDK guides define released client behavior; recipes assemble complete tasks; OpenAPI and AsyncAPI define direct wire contracts.

On this page