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

# Dictionaries

> Per-project pronunciation and replacement lists for brand names and domain vocabulary

Custom dictionaries are per-project pronunciation and replacement lists.
Each entry maps a written word to the text or IPA the TTS pipeline should
pronounce instead. Use them for brand names, product names, acronyms, and
domain vocabulary that should sound consistent across requests.

Changes are available to synthesis after the dictionary mutation finishes.
Pass the dictionary's `projectId` on `GenerateOptions`; omission loads no
project dictionary. With `projectId`, omit `dictionaryIds` to apply all active
project dictionaries or pass a list to select exact IDs. JavaScript streaming
configs currently lack `projectId`, so dictionary-backed streaming requires
the raw WebSocket protocol.

For the full HTTP contract, field limits, master-key `project_id` rules,
and error codes, see the [Dictionaries API reference](/api-reference/endpoints/dictionaries).

## Create a Dictionary

```typescript theme={null}
import { KugelAudio } from 'kugelaudio';

const client = new KugelAudio({ apiKey: 'YOUR_API_KEY' });

const dictionary = await client.dictionaries.create({
  name: 'Brand names',
  description: 'Product and company names',
  language: 'en',
});

console.log(dictionary.id);
```

## Manage Dictionaries

```typescript theme={null}
// List every dictionary in the project
const dictionaries = await client.dictionaries.list();

// Fetch one
const dict = await client.dictionaries.get(dictionary.id);

// Update name / description / language / isActive (only provided fields change)
await client.dictionaries.update(dictionary.id, {
  description: 'Updated description',
  isActive: false,
});

// Delete a dictionary (cascades to its entries)
await client.dictionaries.delete(dictionary.id);
```

<Note>
  Every `dictionaries.*` and `dictionaries.entries.*` method accepts an optional
  final `{ projectId }` argument. It is required **only** for master-key callers
  acting on a specific project; with a normal API key, omit it.
</Note>

## Add and Manage Entries

Use `replacement` for normal spelling-based fixes. Use `ipa` when you need
an exact phonetic pronunciation; IPA takes precedence over `replacement`.

```typescript theme={null}
const createdEntry = await client.dictionaries.entries.add(dictionary.id, {
  word: 'Postgres',
  replacement: 'post-gres',
});

const page = await client.dictionaries.entries.list(dictionary.id, {
  search: 'post',
  limit: 50,
});

for (const entry of page.entries) {
  console.log(`${entry.word} → ${entry.replacement}`);
}

await client.dictionaries.entries.update(
  dictionary.id,
  page.entries[0].id,
  { replacement: 'postgres' }
);

await client.dictionaries.entries.delete(dictionary.id, createdEntry.id);
```

## Atomic Bulk Sync

`replaceAll` upserts every entry in one transaction and deletes entries
currently in the dictionary whose `word` is not in the payload. Use it to
sync from a CMS, PIM, or internal glossary.

<Warning>
  `replaceAll` is intentionally destructive for omitted words. Only call it
  with the complete desired contents of that dictionary.
</Warning>

```typescript theme={null}
const result = await client.dictionaries.entries.replaceAll(dictionary.id, [
  { word: 'Postgres', replacement: 'post-gres' },
  { word: 'Kubernetes', replacement: 'koo-ber-net-eez' },
]);

console.log(`upserted=${result.upserted} deleted=${result.deleted}`);
```

## Generate With Dictionaries

Keep `normalize` enabled unless you have a specific reason to bypass text
normalization.

```typescript theme={null}
const audio = await client.tts.generate({
  text: 'Postgres runs our product analytics.',
  modelId: 'kugel-3',
  voiceId: 1071,
  language: 'en',
  normalize: true,
  projectId: dictionary.projectId,
  dictionaryIds: [dictionary.id],
});
```

## Dictionary types

```typescript theme={null}
interface Dictionary {
  id: number;
  projectId: number;
  name: string;
  description?: string;
  language?: string;
  isActive: boolean;
  createdAt: string;
  updatedAt: string;
}

interface DictionaryEntry {
  id: number;
  dictionaryId: number;
  word: string;
  replacement: string;
  ipa?: string;
  caseSensitive: boolean;
  createdAt: string;
  updatedAt: string;
}

interface DictionaryEntryInput {     // payload for add() / replaceAll()
  word: string;
  replacement: string;
  ipa?: string;
  caseSensitive?: boolean;
}

interface DictionaryEntryListResponse {  // returned by entries.list()
  entries: DictionaryEntry[];
  total: number;
  limit: number;
  offset: number;
}

interface BulkReplaceResult {        // returned by entries.replaceAll()
  upserted: number;
  deleted: number;
  total: number;
}

interface CreateDictionaryOptions { name: string; description?: string; language?: string; }
interface UpdateDictionaryOptions { name?: string; description?: string; language?: string; isActive?: boolean; }
interface UpdateDictionaryEntryOptions { word?: string; replacement?: string; ipa?: string; caseSensitive?: boolean; }
```

***

For automatic handling of numbers, dates, and spelled-out text, see [Text Normalization](/sdks/javascript/text-normalization).
