Overview
Send an audio clip in a single HTTP call and get back the verbatim transcript together with an LLM-rewritten version of it. The rewrite is on by default: with no configuration, it removes disfluencies and leaves every other word exactly as spoken. Setllm_instruction to reshape the transcript into something else instead — a chart note, a booking confirmation, or whatever shape you describe. The verbatim transcript always comes back alongside the rewrite.
Dictation accepts up to 120 seconds of audio per call. You can send the audio
after the recording finishes, or upload it as it is captured so most of the
transfer happens while the user is still speaking — see Uploading while
recording.
- Python SDK
- Python
- JavaScript
- cURL
Dictation is a separate service from Sync, Pre-recorded, and Streaming STT.
It has its own hostname (
dictation.assemblyai.com) and its own request
shape. The Python SDK
wraps it as DictationTranscriber from version 1.5.1; in every other
language, call it over HTTP.Before you begin
To call the Dictation API, you need:- An API key — browse to API Keys in your dashboard and copy your key.
- An audio clip in WAV format, or raw 16-bit PCM. Maximum 120 seconds.
- A client — either the AssemblyAI Python SDK (
pip install "assemblyai>=1.5.1"), or any HTTP client: cURL, Python 3.8+ withrequestsorhttpx, or Node.js 18+ withfetch.
Endpoint
config first, then audio. The endpoint reads the
body as it arrives, so you can start the request while the user is still
speaking and upload the audio as it is captured; see Uploading while
recording.
/v1/transcribe/stream is the path this endpoint shipped under and still
reaches the same handler. There is no unversioned alias.
Authentication
Pass your AssemblyAI API key in theAuthorization header as the raw key, with no Bearer prefix:
An invalid API key returns
404 Not Found with {"detail": "Invalid API key"}, not 401. Treat any 404 from this endpoint as an auth failure.Request
The body ismultipart/form-data with two parts, in this order:
Config comes first, and is required, because the server starts transcribing
the audio as it arrives and cannot begin without it. An
audio part that
arrives before config, or a request with no config part at all, is
rejected with 400.
WAV and raw PCM only. Compressed formats — MP3, M4A, FLAC, OGG, WebM —
are rejected with 415.
Config parameters
Every field exceptllm_instruction controls transcription. llm_instruction customizes the transcript rewrite, which is applied by default — see Rewriting the transcript.
Over HTTP, unknown fields are forwarded to the transcription engine as-is, so transcription parameters added in the future work without dictation-side changes.
DictationConfig in the Python SDK is stricter: it accepts exactly the
fields in the table above and rejects anything else with a validation error,
rather than passing it through. That turns a typo, or a Sync-only option
used by mistake, into an error instead of a setting that quietly does
nothing. To send a field the SDK does not know about yet, build the config
part over HTTP.Rewriting the transcript
The rewrite is applied by default. Omittingllm_instruction — or the whole config part — runs the default cleanup task, which removes disfluencies only (filler sounds and phrases, false starts, stammered repeats). Every kept word, its spelling, and its punctuation stay exactly as spoken.
To customize the rewrite, set llm_instruction to a plain-English description of the task you want (max 2048 characters). It replaces the default cleanup task:
text is always the verbatim transcript, and the rewritten version arrives separately in llm_response.
See Transcript rewriting for how to write a good instruction, what the service enforces for you, and why dictated commands are never carried out.
Uploading while recording
The endpoint transcribes the audio it has while the rest is still arriving, so a client that uploads during the recording gets its transcript sooner. What the user waits for after they stop speaking is the last stretch of audio rather than the whole clip. The saving grows with clip length; on a clip of a few seconds there is little uploaded-but-unprocessed audio to save. Three rules apply to a chunked upload:- The
configpart must arrive before the first audio byte. - Don’t let the connection go silent for long stretches mid-body — an abandoned upload is timed out rather than held open.
- A chunked body can’t be replayed. Keep the audio in memory if you want to retry a failed request.
sample_rate and channels in config and send frames as they come
off the microphone.
The Python SDK does the framing for you. transcribe_live() takes an iterator
of audio chunks, and open_live() takes audio pushed in from a callback — a
microphone library, a WebRTC track, a telephony media stream:
- Pull — an iterator of chunks
- Push — audio from a callback
AsyncDictationTranscriber is the asyncio counterpart, with the same two
methods. Call transcriber.warm() when you know audio is coming — as the user
reaches for the record button — to pay the DNS, TCP and TLS setup before the
first byte rather than in front of it.
Without the SDK, frame the multipart body yourself:
data= makes requests send the body with chunked
transfer encoding, which is what lets the upload start before the audio is
complete. A body with a Content-Length is also accepted, and still streams —
the server does not wait for the full body before it begins.
Response
A successful call returns200 with JSON:
Rewrites are best-effort. A rewrite failure still returns
200 with the
transcription. If llm_response is null and text is present, use
text. Never treat a non-null llm_error as a failed request.Errors
Most errors return{"error": "...", "error_code": "..."}. The ones relayed
from the transcription service, an invalid API key (404) and an unsupported
audio format (415), use a {"status", "title", "detail"} body instead, so
read both shapes. Note that an invalid API key returns 404 rather than 401.
Set the HTTP client timeout to 90 seconds. Typical short clips respond in under
one second. The rewrite has a 5-second internal deadline, after which the
response returns with llm_error: "timeout" and the transcription intact.
See Error handling for the full status code table
and retry guidance.
Examples
The knobs do different jobs.stt_prompt and keyterms_prompt steer the ASR model while it writes the transcript down — the first describes the situation, the second lists the exact terms to expect. llm_instruction tells the LLM what to do with that transcript after it is written.
Clinical dictation
A doctor dictating a visit note.stt_prompt tells the model what kind of audio this is, keyterms_prompt pins the exact drug names, and llm_instruction turns the spoken rambling into a chart-ready note.
- Python SDK
- Python
- JavaScript
- cURL
Travel booking summary
A travel agent dictating a client booking summary.keyterms_prompt pins the specific destination and airline names, and llm_instruction reshapes the transcript into a confirmation the client can read.
- Python SDK
- Python
- JavaScript
- cURL
Next steps
- Transcript rewriting — reshape the transcript with
llm_instruction - Prompting and keyterms — steer the transcript with context and exact terms
- Language selection — transcribe in one or more of 19 languages
- Audio requirements — duration, sample width, and format constraints
- Error handling — status codes and retry guidance
- Cloud endpoints & data residency — global routing and the US/EU data zones
- Connection pre-warming — take the TLS handshake off the critical path
- API reference — the full request and response schema