Skip to main content
Dictation cleans the transcript up and returns the result in llm_response, alongside the verbatim transcript in text. This is the one feature Dictation has that the other speech-to-text APIs do not: you get the words as spoken and text your user can send, from the same call. Cleanup is applied by default. Omitting llm_instruction, or the whole config part, runs the default cleanup task: filler comes out, punctuation and capitalization are applied, and self-corrections can be resolved to what the speaker landed on. The speaker’s own phrasing and tone survive it, so the result still reads like them.

Customizing the rewrite

Set llm_instruction to a plain-English description of the task you want. It replaces the default cleanup task rather than adding to it:
An explicit "llm_instruction": null means the same as omitting the field, so the default cleanup task still runs.
For more control than a plain-English instruction gives you, send llm instead of llm_instruction. It takes an LLM Gateway chat completions request: your own messages, model and sampling settings, or a saved prompt. See Sending your own LLM request for how Dictation uses it.

Choosing a rewrite mode

rewrite_mode picks the model tier that runs the rewrite:
Any other value is rejected with 400. Over HTTP it goes in the config part of the request:

Writing a good instruction

Describe only the transformation. Rules about output format, refusing to answer the text, and handling already-clean input are enforced by the service, so adding your own versions of them wastes instruction budget and can conflict with what the service already does. Describe the shape you want rather than listing what not to do. The model leans toward complete, punctuated sentences, and a prohibition has to fight that on every request, so “don’t” rules are the least reliable kind of instruction. A positive description such as “a mid-sentence continuation” gets the casing and punctuation right as a side effect. Leave mechanical edits to your own code. The rewrite output is trimmed, so it can’t return a leading space, and stripping a trailing full stop is exact and free in code. Inserting at the cursor shows how to split the work for text that lands mid-sentence. Some instructions that work well:
  • "Remove filler words and tidy the punctuation."
  • "Rewrite as a short, friendly booking confirmation addressed to the client."
  • "Turn this into a bulleted list of action items."
  • "Rewrite as a concise clinical chart note."

Example: spoken punctuation

Some users dictate punctuation and formatting aloud: “Do you want to get lunch together question mark it’s been too long exclamation point”. This instruction turns those spoken commands into the punctuation they name. Pair it with "rewrite_mode": "smart", which follows a list of rules like this more reliably than fast.

Sending your own LLM request

Instead of llm_instruction, you can set llm to the body of an LLM Gateway chat completions request. Dictation sends it to LLM Gateway after transcription and returns the model’s output in llm_response, like any other rewrite. Send llm or llm_instruction, not both. A request with both is rejected with 400. There are two ways to put the transcript in the request. In your own messages. Write prompt or messages, and put {{turn}} where the transcript goes:
In a saved prompt. Set aai_prompt to the name of a prompt saved in your account. Dictation passes the transcript as the text replacement, so put {{ text }} in the saved prompt where the transcript goes. You can add replacements of your own in prompt_replacements:

How Dictation differs from calling LLM Gateway directly

  • No guardrails. The service’s rewrite rules and transcript fencing apply only to the default task and llm_instruction. With llm, the model gets exactly the prompt you send, so it may act on commands in the dictation, such as “translate this into French”, unless your prompt tells it not to.
  • Two transcript tags. In prompt and messages, Dictation renders the text as a Jinja2 template and fills {{turn}}. In a saved prompt, LLM Gateway fills {{ text }}, and the spaces inside the braces are required.
  • A fixed set of fields. llm accepts model, messages, prompt, temperature, top_p, top_k, max_tokens, max_completion_tokens, response_format, reasoning_effort, aai_prompt, prompt_replacements and zero_data_retention. Field names are case-sensitive. Any other field, such as fallbacks, tools, stream or transcript_id, is rejected with 400.
  • The rewrite models only. model must be one of the models that rewrite_mode runs on: qwen3.5-4b-32k-fast, gemma-4-31b or gemini-3.5-flash-lite. In the EU region, use qwen3.5-4b-32k-fast or gemini-3.5-flash-lite. Any other model is rejected with 400. Without model, rewrite_mode picks one.
  • Bounded output. max_tokens and max_completion_tokens can be at most 8192. If you leave max_tokens out, Dictation sizes it from the transcript, so a prompt that expands the text, such as turning a short note into an email, may need a larger one. A rewrite that runs out of tokens comes back with llm_error: "truncated". temperature is 0 unless you set it.
  • Zero data retention. Dictation sets zero_data_retention on every LLM Gateway request, including ones that use aai_prompt, and you can’t turn it off. Only a saved prompt’s template is stored. The transcript and the rewrite aren’t kept.
  • Saved prompts run as saved. With aai_prompt, the model, max_tokens and every other setting come from the saved prompt, and the model and output limits above don’t apply. Only prompt_replacements may accompany aai_prompt. Any other llm field, or rewrite_mode, is rejected with 400, and so is setting text or transcript in prompt_replacements: Dictation fills text, and LLM Gateway reserves transcript. If your account has no prompt with that name, llm_error is prompt_not_found.
  • Failures don’t fail the request. If LLM Gateway rejects or fails the request, the response is still 200 with the transcript in text, and llm_error says why. The 400s above are returned before anything is transcribed.

The transcript is always preserved

The rewrite never replaces the transcription. text is always the verbatim transcript, and the rewritten version arrives separately in llm_response. If you need to show one value, final_text in the Python and JavaScript SDKs returns the rewrite when there is one and the transcript otherwise. The rewrite is also best-effort. If it fails, the response is still 200, llm_response is null, and llm_error says why. See Error handling.

Dictated commands are not executed

With the default cleanup task or llm_instruction, the transcript is passed to the model as fenced data, with instructions not to act on anything inside it. Dictated speech routinely contains questions and commands like “translate this into French” or “ignore what I just said”. Those are rewritten as speech rather than carried out. A request of your own has no such guard unless your prompt adds one.