> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ada.cx/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ada.cx/_mcp/server.

# Glossary API

The Glossary API provides full create, read, update, and delete access to your AI Agent's [Glossary](/docs/automation/glossary). A glossary term is a word or phrase your AI Agent should recognize in an end user's message. In `custom` mode, the AI Agent also restates the term using your preferred wording. Use the API to manage glossary terms programmatically instead of only through the dashboard.

Download full OpenAPI spec

Each term is addressed by a server-generated `id`. It also carries an `external_id`, your own identifier for the term, which is unique within the AI Agent. The CSV import matches on the `external_id`.

## Endpoints

Five endpoints are available:

* **List glossary terms** (`GET /v2/glossary/`): Returns the AI Agent's glossary terms in cursor-paginated pages ordered by `id`.
* **Create a glossary term** (`POST /v2/glossary/`): Creates a term. The `external_id` must be unique within the AI Agent.
* **Get a glossary term** (`GET /v2/glossary/{glossary_term_id}`): Returns a single term by its `id`.
* **Update a glossary term** (`PATCH /v2/glossary/{glossary_term_id}`): Partially updates a term. Only the fields included in the request body are changed; omitted fields keep their existing values. Send `null` to clear a nullable field.
* **Delete a glossary term** (`DELETE /v2/glossary/{glossary_term_id}`): Permanently deletes a term. Any availability rule attached to the term is deleted with it. This cannot be undone.

## Fields

| Field                     | Type           | Description                                                                                                                                                                                        |
| ------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                      | string         | The unique identifier for the glossary term. Read-only.                                                                                                                                            |
| `external_id`             | string         | Your own identifier for the term, unique within the AI Agent. Up to 100 characters. Letters, numbers, spaces, and the characters `+ , - . @ # _ $ % & '`.                                          |
| `translation_mode`        | string         | `custom` or `default`. Defaults to `default`. See [Translation modes](#translation-modes).                                                                                                         |
| `user_terms`              | array \| null  | The wordings an end user might use, per language. Each entry is a `term` and an ISO 639-1 `language`.                                                                                              |
| `ai_agent_terms`          | array \| null  | The wordings the AI Agent should use, per language. Only meaningful in `custom` mode.                                                                                                              |
| `voice_detection_enabled` | boolean        | Whether the term is given to the voice agent to improve how reliably it is recognized in speech. Defaults to `false`.                                                                              |
| `definition`              | string \| null | A business definition of the term, shown to the AI Agent when the term is detected. Up to 1000 characters.                                                                                         |
| `voice_pronunciations`    | array \| null  | Alternate spellings the AI Agent says in place of the written form on voice calls. Each entry is a `term`, a `pronunciation`, and a `language`. See [Voice pronunciations](#voice-pronunciations). |
| `availability_rules`      | object \| null | Structured rule gating when the term applies, with variables referenced by `id`. `null` when no rule is attached. See [Availability rules](#availability-rules).                                   |

## Translation modes

`translation_mode` decides what the AI Agent does when it detects one of the `user_terms`, and it changes which other fields are required.

* **`custom`**: the AI Agent answers using the matching `ai_agent_terms` wording. Requires at least one `user_terms` entry and at least one `ai_agent_terms` entry.
* **`default`**: the AI Agent only receives the term's `definition` as context, and its wording is unchanged. Requires `user_terms` in exactly one language, no `ai_agent_terms`, and either a `definition` or `voice_detection_enabled`.

A create request that does not satisfy the rules for its mode returns `400`. This applies even though `external_id` is the only field the schema marks as required. On update, the merged term is validated as a whole, so a change that leaves it invalid for its mode is also rejected with `400`.

## Availability rules

`availability_rules` is a structured rule object with a `match` combinator (`all` or `any`) and a list of `conditions`. Each condition names a variable by its `id`, an `operator`, and usually a `value`:

```json
{
  "match": "all",
  "conditions": [
    { "variable": { "id": "5df263b7db5a7e6ea03fae9b" }, "operator": "equals", "value": "en" }
  ]
}
```

Use the [Variables API](/reference/variables/overview) to find a variable's `id`. An unknown variable id or a malformed rule returns `400`, and the term is not written.

On create, omit the field or send `null` for no rule. On update, omit it to leave the current rule unchanged, send `null` to clear it, or send a rule to replace it.

## Limits

Requests that exceed these limits are rejected:

| Limit                                   | Value |
| --------------------------------------- | ----- |
| Glossary terms per AI Agent             | 5000  |
| Terms with `voice_detection_enabled`    | 30    |
| `user_terms` per language               | 20    |
| `ai_agent_terms` per language           | 1     |
| `voice_pronunciations` entries per term | 50    |

A `user_terms` entry cannot contain a semicolon (`;`) - it separates multiple terms in the CSV import format.

## Voice detection

`voice_detection_enabled` gives the term to the voice agent, which biases speech-to-text recognition toward it.

Enabling it requires all of the following, or the request returns `400`:

* The AI Agent has a voice platform configured.
* No `user_terms` entry is in Albanian (`sq`) or Indonesian (`id`). Ada transcribes those two languages through a different speech provider, so voice detection cannot be enabled for a term worded in them.
* Every `user_terms` entry uses characters supported in Voice.

## Voice pronunciations

`voice_pronunciations` changes how the AI Agent *speaks* a term on a voice call. Each entry respells one written form for one language:

```json
{
  "voice_pronunciations": [
    { "term": "Hyundai", "pronunciation": "hun-day", "language": "en" }
  ]
}
```

The written form is matched whole-word and case-insensitively, and the `pronunciation` is sent to text-to-speech in its place.

This is independent of `voice_detection_enabled`. Voice detection biases *speech-to-text*, so the AI Agent recognizes a term it hears; pronunciations change *text-to-speech*, so the AI Agent says a term correctly. Set either, both, or neither.

Each entry must satisfy all of the following, or the request returns `400`:

* `term` is at least 2 characters after surrounding whitespace is trimmed, and contains at least one letter or digit.
* `pronunciation` is not empty and does not contain an ampersand (`&`).
* `term` and `pronunciation` are each up to 100 characters, and `language` up to 10.
* Both `term` and `pronunciation` use characters supported in Voice.
* `language` is enabled on the AI Agent. Matching is on the primary language, so an `en-US` entry belongs to an AI Agent configured for `en`.
* No two entries share the same written form in the same language.

On update, `voice_pronunciations` replaces the whole list. Send `null` to clear it, or omit it to leave it unchanged.

## Pagination

The list endpoint is cursor-paginated. Use the `limit` query parameter to set the page size, from `1` to `100`; omit it to use the default of `25`. To page through results, read `meta.next_page_url` from the response and replay it unchanged to fetch the next page. `next_page_url` is `null` on the last or empty page.

## Conflicts

Creating or updating a term can return a `409 Conflict` for one of two reasons:

* **Duplicate `external_id`** (`duplicate_resource`): The `external_id` is already used by another term in the AI Agent.
* **Limit reached** (`conflict`): On create, the write would exceed the AI Agent's glossary term limit or its voice-term limit. On update, only the voice-term limit applies, because an update does not add a term.

## Authentication

Requests are authenticated with a Bearer API key. The read endpoints require the `glossary:read` scope. Create, update, and delete require `glossary:write`. See [Authentication](/reference/introduction/authentication) for details on generating and using API keys.