When to use it
Meetings and interviews
More than one voice, and you need to know which is which.
Call review
Both sides of a call, with the timings to jump a player to any line.
Field and shoot audio
The audibility read tells you which takes are usable before anyone tries to
edit them.
One voice only?
Plain transcription is cheaper and returns the
same words.
Getting a diarized transcript
It rides the same endpoint as plain transcription. Pick a model that reportssupports_diarization from GET /v1/audio/models and ask for verbose_json:
Word-level output
words is a flat, OpenAI-shaped array — each entry carries segment_id and
speaker so you can regroup it into turns without a second pass.
Word timing is on by default. Send
timestamp_granularities[]=segment to skip
the alignment pass — worth a few seconds of GPU on a long file.
Audibility: on-mic dialogue vs background talk
Faint off-mic speech — crew direction bleeding into a take, a question from behind the camera — sits 30 dB or more under the dialogue. Whole-file loudness normalization does not recover it, because integrated loudness is dominated by the loud material. This service normalizes adaptively in short frames instead, which does recover it: a −35 dB utterance transcribes word-perfect with the correct speaker. That leaves a problem: after normalization every level looks the same, and the transcript cannot tell you which lines were actually on mic. So the level is measured on the pre-normalization signal, alongside the file’s own noise floor:
In the example above the presenter reads 41.4 dB SNR (
on_mic) and the
off-camera request reads 3.3 dB (faint) — both fully transcribed, and
distinguishable afterwards.
Silence, pace and language
Speaker labels (
S01, S02, …) are consistent within one file but anonymous —
they identify voices, not people, and reset between files.
Two things also happen service-side before decoding: adaptive loudness
normalization (above), and a voice-activity gate that answers silent uploads
(b-roll, room tone) immediately with "text": "", empty segments, and
"no_speech": true — without occupying the GPU.
Sound-event timeline
Alongside the transcript, the whole file is swept with an AudioSet tagger and returned asscene — what sound occurs when, for the entire duration, not one
dominant label per asset.
Events overlap on purpose. Dialogue over a music bed in a room with
traffic outside is three simultaneous answers, and a timeline that reports one
winner per moment throws two of them away — we measured a speech clip mixed
with broadband noise coming back 100%
ambience, the speech erased. So each
bucket gets its own run of events, and music + speech covering the same
seconds is the normal case, not a conflict.
Resolution is 2 s, and each slot is classified with
a full 10 s of surrounding context. There is no duration cap — the sweep runs
over the whole file.
Streaming progress
Long recordings decode for minutes. Withstream=true the response is SSE:
standard transcript.text.delta / transcript.text.done events, interleaved
with a transcript.segment event per finished diarized segment. Each
segment’s end timestamp tells you how far into the audio the model has
gotten, so a progress bar is end / duration.
transcript.text.done event carries the complete verbose_json payload
in a verbose field, words included, so a streaming client never needs a
second request for the authoritative result.
Limits
Going further
Speech to text
Plain batch transcription without speaker labels.