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

# Recognition settings

> Set the language, choose written or word-for-word mode, and add context terms for names and phrases, in the SDK or the WebSocket and gRPC APIs.

Set `language` on every request, because Rime does not detect the language. Rime transcribes in the language that you select, so if you send Spanish speech as `en`, you get a poor transcript, not an error. Two more settings are optional: the mode sets the form of the text, and context terms help the model recognize names.

| Setting | Required | Values | Default |
| - | - | - | - |
| [Language](#language) | Yes | `en` for English or `es` for Spanish | No default. Set it on every request. |
| [Mode](#word-for-word-mode) | No | Written or word-for-word | Written |
| [Context terms](#context-terms) | No | Names and phrases that you expect to hear | No terms |

The three settings work the same way in the SDK, the WebSocket API, and both gRPC methods.

## Word-for-word mode

The mode tells the model what form of text to write.

| | Written mode (default) | Word-for-word mode |
| - | - | - |
| Numbers | As digits. Codes are in compact form. | As spoken words |
| Fillers, repetitions, and false starts | The mode does not ask the model to keep them or to remove them. | The mode asks the model for each one. |
| Choose it for | Text that you show, or send to a language model | An exact record of the words. Examples are calls that you review for quality or compliance, and speech analytics. |

The [quickstart](/docs/stt/quickstart) transcribed the same synthesized call in both modes:

| Mode | Final transcript |
| - | - |
| Written (default) | `Hi! I'm calling about flight 247 to Denver. Can I, move it to Friday?` |
| Word-for-word | `Uh hi. I'm calling about flight two four seven to Denver, can I um move it to Friday?` |

Word-for-word mode kept "Uh", "um", and the spoken "two four seven". Written mode wrote `247`, and on this recording it also left out both fillers. Even so, the mode guides the model but does not guarantee the form of each word. Test the mode on recordings like the ones that your application will get.

Phone audio is one such case. When callers read out ZIP codes, phone numbers, or account numbers, use word-for-word mode. In Rime's tests on phone audio, it kept every digit.

Set word-for-word mode in the stream call:

**Python**

```python theme={null}
from rimelabs_sdk import TranscriptionMode

transcript = client.stt.stream(audio, language="en", mode=TranscriptionMode.VERBATIM)
```

**Node.js**

```javascript theme={null}
const transcript = client.stt.stream(audio, { language: "en", mode: "verbatim" });
```

**Go**

```go theme={null}
transcript, err := client.STT.Stream(ctx, source, rime.TranscriptionOptions{
    Language: "en",
    Mode:     rime.TranscriptionVerbatim,
})
```

**Rust**

```rust theme={null}
use rimelabs_sdk::{TranscriptionMode, TranscriptionOptions};

let transcript = client
    .stt()
    .stream(source, TranscriptionOptions::new("en").mode(TranscriptionMode::Verbatim))?;
```

> **Wire values for direct API calls**
>
> Set `mode` to `TRANSCRIPTION_MODE_VERBATIM` in the WebSocket `start` message, or in the gRPC `config` or `options`.
>
> `TRANSCRIPTION_MODE_WRITTEN` is the default. If you omit `mode` or send `TRANSCRIPTION_MODE_UNSPECIFIED`, the service uses written mode. An unknown value fails with `invalid_input` over WebSocket or `INVALID_ARGUMENT` over gRPC.

## Language

Use `en` for English or `es` for Spanish, and choose the language from what you already know about the speaker. For example, use the caller's menu choice or account settings.

> **Language errors and confirmation**
>
> The service checks the tag before it accepts audio. Each of these values fails with `invalid_input` over WebSocket or `INVALID_ARGUMENT` over gRPC:
>
> | You send | Why it fails |
> | - | - |
> | No `language`, or `und` | A language is required |
> | A supported tag in the wrong form, such as `en_US` | It is not a valid BCP 47 tag |
> | Another language, such as `fr` | Only `en` and `es` are supported |
>
> The SDKs send `language` without changes, and the service checks it.
>
> The direct API returns the confirmed language in `started.accepted.language` over WebSocket and in `accepted.language` over gRPC. The final result also has it in `language`. Its `source` is always `LANGUAGE_SOURCE_SELECTED`.

## Context terms

Context terms tell the model which names and phrases to expect in this utterance. For example, an agent for flight changes can send the caller's surname from the booking, such as `Okonkwo`. The agent can also send its own airline and fare names, such as `Northwind Air` and `FlexPlus`. Terms are hints without weights, so they make a match more likely, but they do not force a match.

Add the terms to the stream call:

**Python**

```python theme={null}
transcript = client.stt.stream(
    audio,
    language="en",
    context_terms=["Northwind Air", "FlexPlus", "Okonkwo"],
)
```

**Node.js**

```javascript theme={null}
const transcript = client.stt.stream(audio, {
  language: "en",
  contextTerms: ["Northwind Air", "FlexPlus", "Okonkwo"],
});
```

**Go**

```go theme={null}
transcript, err := client.STT.Stream(ctx, source, rime.TranscriptionOptions{
    Language:     "en",
    ContextTerms: []string{"Northwind Air", "FlexPlus", "Okonkwo"},
})
```

**Rust**

```rust theme={null}
let terms = vec!["Northwind Air".into(), "FlexPlus".into(), "Okonkwo".into()];
let transcript = client
    .stt()
    .stream(source, TranscriptionOptions::new("en").context_terms(terms))?;
```

Test terms on your own recordings, and keep the terms that change the result. Terms share the [model's context](/docs/stt/errors#limits) with the audio, so a long list leaves less space for a long utterance.

> **Context term rules**
>
> * If you omit the list or send an empty list, the service adds no hints. A term that is empty or has only whitespace fails with `invalid_input`.
> * The service keeps the order and the text of each term, including spaces and commas in the term. It joins the terms with a comma and a space.
> * The joined list, with its separators, must fit in the [limit](/docs/stt/errors#limits) of 1,024 UTF-8 bytes, not characters. There is no limit on the number of terms.
> * A term cannot contain the control markers of the model, such as text between `<|` and `|>`. A term with a control marker fails with `invalid_input`.
> * The service rejects input that is too large with `invalid_input`. It never truncates the input.

## Field names in the direct APIs

Direct API calls use these fields for the three settings:

| API | Language | Mode | Context terms |
| - | - | - | - |
| [WebSocket `start`](/api-reference/stt/websockets#start) | `language` | `mode: "TRANSCRIPTION_MODE_VERBATIM"` | `contextTerms` |
| [gRPC `config` or `options`](/api-reference/stt/grpc) | `language` | `mode: TRANSCRIPTION_MODE_VERBATIM` | `context_terms` |

Each SDK documents its options and their defaults in the rime-sdk repository: [Python](https://github.com/rimelabs/rime-sdk/blob/main/python/docs/stt.md#options), [Node.js](https://github.com/rimelabs/rime-sdk/blob/main/typescript/docs/stt.md#options), [Go](https://github.com/rimelabs/rime-sdk/blob/main/go/README.md#transcription-options), and [Rust](https://github.com/rimelabs/rime-sdk/blob/main/rust/README.md#transcription-options).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.