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

# Pronunciation dictionaries

> Create reusable pronunciation dictionaries and attach them to any SLNG TTS request so brand names, acronyms, and domain terms are spoken the way you expect.

export const AudioPlayer = ({src, title = "Audio", description, autoPlay = false, loop = false, variant = "default"}) => {
  const audioId = useId();
  const isCompact = variant === "compact";
  const audioRef = useRef(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const togglePlayback = () => {
    const audio = audioRef.current;
    if (!audio) return;
    if (audio.paused) {
      void audio.play();
      setIsPlaying(true);
      return;
    }
    audio.pause();
    setIsPlaying(false);
  };
  return <div className={`audio-player ${isCompact ? "compact" : ""}`}>
      {!isCompact && <div className="meta">
          <div className="titles">
            <div className="title">{title}</div>
            {description && <div className="description">{description}</div>}
          </div>

          <a className="download" href={src} download>
            Download
          </a>
        </div>}

      {isCompact ? <>
          <button type="button" className="compact-button" onClick={togglePlayback} aria-label={isPlaying ? "Pause audio sample" : "Play audio sample"}>
            <span className="compact-icon" aria-hidden="true">
              {isPlaying ? "❚❚" : "▶"}
            </span>
          </button>
          <audio id={audioId} ref={audioRef} preload="metadata" loop={loop} autoPlay={autoPlay} aria-label={title} src={src} onEnded={() => setIsPlaying(false)}>
            Your browser does not support the audio element.
          </audio>
        </> : <audio id={audioId} className="audio-control" controls preload="metadata" loop={loop} autoPlay={autoPlay} aria-label={title} src={src}>
          Your browser does not support the audio element.
        </audio>}
    </div>;
};

Pronunciation dictionaries let you control how text is spoken before it reaches the selected TTS model. Create a dictionary once, then reference it from HTTP, WebSocket, or Unified TTS requests.

Use them when a voice needs to pronounce acronyms, product names, customer names, jargon, or multilingual terms consistently across TTS models.

## Placeholders

The snippets below use these placeholders. Replace them before running the code.

| Placeholder              | Replace with                                                                |
| ------------------------ | --------------------------------------------------------------------------- |
| `SLNG_API_KEY`           | An SLNG key from [app.slng.ai/api-keys](https://app.slng.ai/api-keys)       |
| `support-pronunciations` | The dictionary `name` you create with `POST /v1/pronunciation/dictionaries` |
| `pd_01abc...`            | A dictionary `dictionary_id` returned at creation time                      |

<Note>
  Pronunciation dictionaries currently support rewrite mode. SLNG rewrites matching words or phrases before synthesis, and the rewritten text is what the selected model receives.
</Note>

## How it works

Each dictionary belongs to the organization resolved from your SLNG key. Requests from another organization cannot read or use it.

The basic flow is:

1. Create a dictionary with rewrite rules.
2. Reference that dictionary by `name` or `dictionary_id`.
3. Send a TTS request with a `pronunciation` object.

Only one active pronunciation dictionary can apply to a request or WebSocket turn.

## Create a dictionary

Create dictionaries with the [pronunciation dictionary API reference](/api-reference/tts/pronunciation-dictionaries/create-pronunciation-dictionary-http):

```bash theme={null}
curl -X POST https://api.slng.ai/v1/pronunciation/dictionaries \
  -H "Authorization: Bearer SLNG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "support-pronunciations",
    "metadata": {
      "language": "en-US",
      "use_case": "support voice agent"
    },
    "modes": {
      "rewrite": {
        "rules": [
          { "match": "SLNG", "replace": "slang" },
          { "match": "QubePay", "replace": "cube pay" },
          { "match": "ACH transfer", "replace": "ay see aitch transfer" },
          { "match": "ACH", "replace": "ay see aitch" }
        ]
      }
    }
  }'
```

A successful response includes the dictionary `id`, normalized name, metadata, modes, content hash, and creation timestamp:

```json theme={null}
{
  "id": "pd_01abc...",
  "org_id": "org_123",
  "name": "support-pronunciations",
  "normalized_name": "support-pronunciations",
  "metadata": {
    "language": "en-US",
    "use_case": "support voice agent"
  },
  "modes": {
    "rewrite": {
      "rules": [
        { "match": "SLNG", "replace": "slang" },
        { "match": "QubePay", "replace": "cube pay" },
        { "match": "ACH transfer", "replace": "ay see aitch transfer" },
        { "match": "ACH", "replace": "ay see aitch" }
      ]
    }
  },
  "content_hash": "sha256:...",
  "created_at": "2026-05-15T12:00:00.000Z"
}
```

Dictionary names must be unique within your organization. Names can contain letters, numbers, `.`, `_`, and `-`, and can be up to 128 characters.

## Hear the difference

Use the same text with and without the dictionary:

```text theme={null}
Thanks for calling SLNG support. I found your QubePay ACH transfer, and the next invoice will arrive on Friday.
```

<AudioPlayer src="/audio/pronunciation-dictionary-without.mp3" title="Without pronunciation dictionary" description="The model guesses how to pronounce acronyms and product names." />

<AudioPlayer src="/audio/pronunciation-dictionary-with.mp3" title="With pronunciation dictionary" description="The same text after rewrite rules are applied." />

## Manage dictionaries

For request and response schemas, see the generated API reference pages for [listing dictionaries](/api-reference/tts/pronunciation-dictionaries/list-pronunciation-dictionaries-http), [reading one dictionary](/api-reference/tts/pronunciation-dictionaries/get-pronunciation-dictionary-http), and [deleting a dictionary](/api-reference/tts/pronunciation-dictionaries/delete-pronunciation-dictionary-http).

List dictionaries:

```bash theme={null}
curl -s https://api.slng.ai/v1/pronunciation/dictionaries \
  -H "Authorization: Bearer SLNG_API_KEY"
```

Get one dictionary by name:

```bash theme={null}
curl -s https://api.slng.ai/v1/pronunciation/dictionaries/support-pronunciations \
  -H "Authorization: Bearer SLNG_API_KEY"
```

Delete a dictionary:

```bash theme={null}
curl -X DELETE https://api.slng.ai/v1/pronunciation/dictionaries/support-pronunciations \
  -H "Authorization: Bearer SLNG_API_KEY"
```

## Use a dictionary with HTTP TTS

Add a `pronunciation` object to the TTS request body:

```bash theme={null}
curl -X POST https://api.slng.ai/v1/tts/slng/deepgram/aura:2-en \
  -H "Authorization: Bearer SLNG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "aura-2-thalia-en",
    "text": "Thanks for calling SLNG support. I found your QubePay ACH transfer, and the next invoice will arrive on Friday.",
    "pronunciation": {
      "mode": "rewrite",
      "name": "support-pronunciations"
    }
  }'
```

You can also reference the dictionary by immutable ID:

```json theme={null}
{
  "pronunciation": {
    "mode": "rewrite",
    "dictionary_id": "pd_01abc..."
  }
}
```

Rules for the request object:

* `mode` must be `"rewrite"`
* provide exactly one of `name` or `dictionary_id`
* use only one active dictionary per request

With the example dictionary above, the selected model receives this rewritten text:

```text theme={null}
Thanks for calling slang support. I found your cube pay ay see aitch transfer, and the next invoice will arrive on Friday.
```

## Use a dictionary with WebSocket TTS

Set a default dictionary when you initialize the session:

```json theme={null}
{
  "type": "init",
  "config": {
    "pronunciation": {
      "mode": "rewrite",
      "name": "support-pronunciations"
    }
  }
}
```

Then send text normally:

```json theme={null}
{
  "type": "text",
  "text": "Thanks for calling SLNG support. I found your QubePay ACH transfer, and the next invoice will arrive on Friday."
}
```

To change dictionaries for a later turn, include `pronunciation` on the `text` message:

```json theme={null}
{
  "type": "text",
  "text": "Use another dictionary for this turn",
  "pronunciation": {
    "mode": "rewrite",
    "name": "finance-pronunciations"
  }
}
```

`init.config.pronunciation` sets the session default. `text.pronunciation` replaces the active dictionary for that turn, and later text turns reuse the most recent active dictionary.

## Use a dictionary with Unified TTS

Use the same `pronunciation` shape with Unified TTS bridge requests:

```json theme={null}
{
  "type": "init",
  "model": "slng/deepgram/aura:2-en",
  "config": {
    "language": "en-US",
    "sample_rate": 24000,
    "encoding": "linear16",
    "pronunciation": {
      "mode": "rewrite",
      "name": "support-pronunciations"
    }
  }
}
```

## Rewrite matching

Rewrite mode is deterministic:

* matching is case-insensitive
* only whole words or whole phrases are matched
* longer phrases win before shorter matches
* rewriting is single-pass and non-recursive

For example, this dictionary prefers `ACH transfer` over the shorter `ACH` match:

```json theme={null}
{
  "modes": {
    "rewrite": {
      "rules": [
        { "match": "ACH", "replace": "ay see aitch" },
        { "match": "ACH transfer", "replace": "ay see aitch transfer" }
      ]
    }
  }
}
```

Input:

```text theme={null}
I found your ACH transfer
```

Rewritten result:

```text theme={null}
I found your ay see aitch transfer
```

## Limits and errors

Current limits:

| Limit                          | Value              |
| ------------------------------ | ------------------ |
| Dictionary name                | 128 characters     |
| Rewrite rules per dictionary   | 256                |
| IPA rules per dictionary       | 256                |
| `match` length                 | 128 characters     |
| `replace` length               | 256 characters     |
| `ipa` length                   | 256 characters     |
| Runtime text input for rewrite | 20,000 characters  |
| Runtime rewritten output       | 100,000 characters |

Pronunciation resolution fails closed. If the dictionary cannot be found or resolved, the request or WebSocket turn is not sent to the selected TTS model.

Common HTTP errors:

| Status and code                     | Meaning                                                                   |
| ----------------------------------- | ------------------------------------------------------------------------- |
| `400 invalid_pronunciation`         | Malformed object, invalid name, unsupported mode, or dictionary not found |
| `401 pronunciation_unauthenticated` | Missing or unresolved organization context                                |
| `409 pronunciation_conflict`        | Dictionary name already exists in the organization                        |
| `503 pronunciation_unavailable`     | Platform storage or dependency failure during dictionary resolution       |

Common WebSocket failures return an error frame:

```json theme={null}
{
  "type": "error",
  "code": "pronunciation_not_found",
  "message": "Pronunciation dictionary not found: support-pronunciations",
  "slng_request_id": "..."
}
```

## Current limitations

* Only `mode: "rewrite"` is executable today.
* `modes.ipa` can be stored but is not executed.
* There is no automatic fallback from IPA to rewrite.
* Provider-native pronunciation dictionary uploads are not supported through SLNG.

## Recommended pattern

For most applications, create a stable dictionary such as `support-pronunciations` and reuse it by name. Use `dictionary_id` only when your application needs an immutable machine reference.

Keep dictionaries scoped to a domain, product line, or voice style. For WebSocket sessions, set the default dictionary in `init`, then override individual turns only when needed.
