Before you start
An API key, kept server-side
An API key, kept server-side
Create one under Developer → API keys in the
console. See
Authentication.
A diarizing model this deployment serves
A diarizing model this deployment serves
GET /v1/audio/models and take an id with supports_diarization: true.
The examples use nur-stt-v1, which is that model.A recording under about twenty minutes
A recording under about twenty minutes
The model handles roughly ninety minutes in one pass, but the production
GPU sets the real ceiling nearer twenty. Split longer recordings at silence
boundaries — see the last section.
The recipe
Speaker labels, word timings and the audibility read only come back inverbose_json. json, text, srt and vtt carry the words alone.
What comes back
Word
confidence, where it appears, is acoustic support at the aligned
position — how strongly the audio backs a word that was already transcribed —
not the recognizer’s probability that the word is right. The two differ
measurably. If word timings could not be produced at all, the payload says so
with words_unavailable: true rather than omitting the key, because an
absent key is indistinguishable from an older backend.Save the run, then name the speakers
The OpenAI-compatible route above is a pure relay: it returns the transcript and keeps nothing.POST /v1/speech/transcriptions does the same work and
keeps it — one upload, because sending a ninety-minute file twice is the thing
worth avoiding.
stream defaults to true, which streams diarized
segments back as server-sent events as the file decodes — good for a progress
bar, more work for a script, so this recipe turns it off.
Now replace S01 and S02 with real names. Operator names are kept apart from
the model’s own labels, so renaming never edits the transcript:
Playback returns a short-lived signed URL rather than redirecting to one,
because a browser will not replay a bearer token onto a media request — an
<audio src> needs the URL itself. It lasts an hour.
Where diarization gets it wrong
Speaker separation needs enough continuous speech per voice to be confident. Two failures are worth expecting rather than discovering:- One person split in two. On short fragments — a meeting of one-word interjections, a heavily cut recording — the same voice can land under two labels. More continuous speech per person fixes it; nothing in the request does.
- Labels do not carry across files. Speakers are numbered by order of first
appearance in this upload, so whoever talks first is
S01here and might beS02in the next file. If you split a recording, do not assumeS01is the same person in part two — reconcile by listening, or by the names you set on each run.
Recordings longer than one pass
Split at silence boundaries, not at a fixed clock time: a cut mid-word costs you a word in both halves and can invent a speaker change at the seam. The response’sgaps array from a first short pass, or any silence detector, gives
you the boundaries.
The upload caps are 25 MB on an ordinary transcription model and 1 GB on a
diarizing one, and a long-form request may decode for up to 30 minutes before
it answers — set your client’s read timeout above that or the request is cut
after you have paid for the pass. Over the cap you get
413 content_size_limit_exceeded, whose message names the alternative model if
this deployment serves one.
What it costs
$0.001 per minute of audio, metered on the recording’s duration. A twenty-minute meeting is two credits, which rounds to two cents. See Pricing and limits. Saving a run stores the audio, which creates a retention duty that is yours rather than the platform’s —DELETE is a real erasure path. See
Compliance.
Next
Audio intelligence
Every field in the diarized response, in full.
Speech to text
The plain transcription path, and the language hint.
Errors
The
413, and what to do about it.Compliance
Recording consent, and the deletion routes.