> ## Documentation Index
> Fetch the complete documentation index at: https://assemblyai.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Prompting and Keyterms

Use prompting and keyterms to improve Sync STT transcription accuracy.

The Sync API supports two complementary ways to give the model information about your audio, both passed in the optional `config` JSON part alongside the `audio` part:

* **Prompting** (`prompt`) — a custom transcription instruction, optionally including context about the audio: the domain, the scenario, or details of the conversation.
* **Keyterms** (`keyterms_prompt`) — an explicit list of terms you want the model to recognize accurately.

Both improve recognition accuracy for your use case. Neither changes the output format.

## Prompting

The `prompt` field replaces the default transcription instruction with your own. Use it to control transcription behavior — verbatim style, disfluency handling — or to describe the audio so the model better recognizes the vocabulary that context makes likely: a clip described as a cardiology consultation primes the model for medical terminology; one described as an order-status check primes it for order IDs and product names.

* Maximum length: **4096 characters**
* When omitted, the [default prompt](#default-prompt) is applied
* `language_code` is **ignored** when a custom `prompt` is set — the prompt fully controls the model, so state the language inside the prompt if you need both

<Tip>
  **Start with no prompt**

  We strongly recommend testing with no `prompt` first. Universal-3.5 Pro is optimized out of the box, and a custom prompt helps most when your audio contains domain-specific vocabulary the model is getting wrong. Add context when you see those errors, starting with the broadest description that covers your use case.
</Tip>

Guidelines for writing prompts:

* Write plain, complete sentences. A short description of the audio (`Cardiology consultation about chest pain symptoms.`) is often enough.
* Include specifics your application already knows — participant names, products, order identifiers — when the audio contains proper nouns the model can't otherwise know.
* Don't pack lists of keywords into the prompt — that's what [`keyterms_prompt`](#keyterms-prompting) is for.
* The model stays grounded in the audio: context that turns out to be irrelevant does not cause it to insert words that weren't spoken, so you can safely send the same description with every request of a longer interaction.

<Tabs>
  <Tab title="Python" language="python">
    ```python theme={null}
    import json
    import requests

    with open("sample.wav", "rb") as f:
        audio = f.read()

    response = requests.post(
        "https://sync.assemblyai.com/transcribe",
        headers={
            "Authorization": "<YOUR_API_KEY>",
            "X-AAI-Model": "universal-3-5-pro",
        },
        files={
            "audio": ("sample.wav", audio, "audio/wav"),
            "config": (
                None,
                json.dumps({"prompt": "Transcribe verbatim. Preserve disfluencies."}),
                "application/json",
            ),
        },
        timeout=60,
    )
    response.raise_for_status()
    print(response.json()["text"])
    ```
  </Tab>

  <Tab title="JavaScript" language="javascript">
    ```javascript theme={null}
    import { readFileSync } from "fs";

    const audio = readFileSync("sample.wav");
    const form = new FormData();
    form.append("audio", new Blob([audio], { type: "audio/wav" }), "sample.wav");
    form.append(
      "config",
      new Blob(
        [JSON.stringify({ prompt: "Transcribe verbatim. Preserve disfluencies." })],
        { type: "application/json" }
      )
    );

    const response = await fetch("https://sync.assemblyai.com/transcribe", {
      method: "POST",
      headers: {
        Authorization: "<YOUR_API_KEY>",
        "X-AAI-Model": "universal-3-5-pro",
      },
      body: form,
    });

    const result = await response.json();
    console.log(result.text);
    ```
  </Tab>

  <Tab title="cURL" language="bash">
    ```bash theme={null}
    curl -X POST https://sync.assemblyai.com/transcribe \
      -H 'Authorization: <YOUR_API_KEY>' \
      -H 'X-AAI-Model: universal-3-5-pro' \
      -F 'audio=@sample.wav;type=audio/wav' \
      -F 'config={"prompt":"Transcribe verbatim. Preserve disfluencies."};type=application/json'
    ```
  </Tab>
</Tabs>

### Default prompt

When no `prompt` is provided, the following default is applied:

> Transcribe with context and proper nouns preserved, where speech is present in the audio. Each language as spoken. English as English. Non-native speakers.

## Keyterms prompting

The `keyterms_prompt` field biases the model toward specific tokens — useful for proper nouns, product names, technical jargon, or any term the model might otherwise mishear.

* Value: an array of strings
* Maximum total length: **2048 characters** across all terms
* Whitespace is stripped and empty terms are ignored

Keyterms are the right tool when you have an explicit vocabulary list — contact names, product catalogs, medical terms — rather than a description of the conversation. Like prompting, keyterms biasing is robust to terms that don't end up being spoken, so you can pass your full list with every request.

<Tip>
  **Start with no keyterms**

  **We strongly recommend starting with no `keyterms_prompt` and then adding terms as needed** based on important words for your use case that you are consistently seeing the model struggle with.

  Including a large number of terms or common terms that are well represented in the training data could lead to overcorrections and hallucinations.
</Tip>

**Best practices:**

* **Specify unique terminology.** Include proper names, company names, technical terms, or vocabulary specific to your domain that might not be commonly recognized.
* **Exact spelling and capitalization.** Provide keyterms with the precise spelling and capitalization you expect to see in the output transcript.
* **Avoid common words.** Do not include single, common English words (e.g., "information") as keyterms. The system is generally proficient with such words, and adding them as keyterms can be redundant.

<Tabs>
  <Tab title="Python" language="python">
    ```python theme={null}
    import json
    import requests

    with open("sample.wav", "rb") as f:
        audio = f.read()

    response = requests.post(
        "https://sync.assemblyai.com/transcribe",
        headers={
            "Authorization": "<YOUR_API_KEY>",
            "X-AAI-Model": "universal-3-5-pro",
        },
        files={
            "audio": ("sample.wav", audio, "audio/wav"),
            "config": (
                None,
                json.dumps({"keyterms_prompt": ["AssemblyAI", "LeMUR", "U3-Pro"]}),
                "application/json",
            ),
        },
        timeout=60,
    )
    response.raise_for_status()
    print(response.json()["text"])
    ```
  </Tab>

  <Tab title="JavaScript" language="javascript">
    ```javascript theme={null}
    import { readFileSync } from "fs";

    const audio = readFileSync("sample.wav");
    const form = new FormData();
    form.append("audio", new Blob([audio], { type: "audio/wav" }), "sample.wav");
    form.append(
      "config",
      new Blob(
        [JSON.stringify({ keyterms_prompt: ["AssemblyAI", "LeMUR", "U3-Pro"] })],
        { type: "application/json" }
      )
    );

    const response = await fetch("https://sync.assemblyai.com/transcribe", {
      method: "POST",
      headers: {
        Authorization: "<YOUR_API_KEY>",
        "X-AAI-Model": "universal-3-5-pro",
      },
      body: form,
    });

    const result = await response.json();
    console.log(result.text);
    ```
  </Tab>

  <Tab title="cURL" language="bash">
    ```bash theme={null}
    curl -X POST https://sync.assemblyai.com/transcribe \
      -H 'Authorization: <YOUR_API_KEY>' \
      -H 'X-AAI-Model: universal-3-5-pro' \
      -F 'audio=@sample.wav;type=audio/wav' \
      -F 'config={"keyterms_prompt":["AssemblyAI","LeMUR","U3-Pro"]};type=application/json'
    ```
  </Tab>
</Tabs>

## Using prompt and keyterms together

You can combine `prompt` and `keyterms_prompt` in the same `config` part:

<Tabs>
  <Tab title="Python" language="python">
    ```python theme={null}
    import json
    import requests

    with open("sample.wav", "rb") as f:
        audio = f.read()

    config = {
        "prompt": "Transcribe verbatim. Preserve disfluencies.",
        "keyterms_prompt": ["AssemblyAI", "LeMUR", "U3-Pro"],
    }

    response = requests.post(
        "https://sync.assemblyai.com/transcribe",
        headers={
            "Authorization": "<YOUR_API_KEY>",
            "X-AAI-Model": "universal-3-5-pro",
        },
        files={
            "audio": ("sample.wav", audio, "audio/wav"),
            "config": (None, json.dumps(config), "application/json"),
        },
        timeout=60,
    )
    response.raise_for_status()
    print(response.json()["text"])
    ```
  </Tab>

  <Tab title="JavaScript" language="javascript">
    ```javascript theme={null}
    import { readFileSync } from "fs";

    const audio = readFileSync("sample.wav");
    const config = {
      prompt: "Transcribe verbatim. Preserve disfluencies.",
      keyterms_prompt: ["AssemblyAI", "LeMUR", "U3-Pro"],
    };

    const form = new FormData();
    form.append("audio", new Blob([audio], { type: "audio/wav" }), "sample.wav");
    form.append(
      "config",
      new Blob([JSON.stringify(config)], { type: "application/json" })
    );

    const response = await fetch("https://sync.assemblyai.com/transcribe", {
      method: "POST",
      headers: {
        Authorization: "<YOUR_API_KEY>",
        "X-AAI-Model": "universal-3-5-pro",
      },
      body: form,
    });

    const result = await response.json();
    console.log(result.text);
    ```
  </Tab>

  <Tab title="cURL" language="bash">
    ```bash theme={null}
    curl -X POST https://sync.assemblyai.com/transcribe \
      -H 'Authorization: <YOUR_API_KEY>' \
      -H 'X-AAI-Model: universal-3-5-pro' \
      -F 'audio=@sample.wav;type=audio/wav' \
      -F 'config={"prompt":"Transcribe verbatim. Preserve disfluencies.","keyterms_prompt":["AssemblyAI","LeMUR","U3-Pro"]};type=application/json'
    ```
  </Tab>
</Tabs>

## Related features

* **Conversation context** — supply the dialogue that preceded the current clip with the `conversation_context` field, so the model transcribes multi-turn conversations with better continuity and proper-noun consistency. See [Conversation context](/sync-stt/conversation-context).
* **Language selection** — steer the default prompt toward one or more languages with `language_code`. See [Language selection](/sync-stt/language-selection).

## Looking for streaming or async prompting?

This guide covers prompting for **Sync STT (short pre-recorded clips)**. For live audio, see [Prompting and keyterms (Real-time)](/streaming/prompting-and-keyterms). For longer pre-recorded audio, see the [Prompting Guide (Async)](/pre-recorded-audio/universal-3-5-pro/prompting).
