Skip to main content
A brand glossary holds your terms and how HeyGen should treat them: how the voice pronounces them, and whether translation keeps or replaces them. Pass its brand_glossary_id on a video or translation request to apply it. Glossaries can be authored in the HeyGen app under Brand Kit or over the API; the API is how you give each of your own customers their own vocabulary.

Three lists

Translation rules take effect only through a translation feature; plain video generation and text-to-speech use terms alone. Matching is case-insensitive. A translation is inserted verbatim with no inflection, so pick a form that reads correctly on its own. If a term is in both do_not_translate_terms and forced_translations, it stays untranslated.

Create

POST /v3/brand-glossaries takes a name (1–64 characters, unique per workspace) and any of the three lists. The 201 response is the full glossary, usable immediately.
A pronunciation is a respelling, written the way you would coach someone to say it: hey-jen, hyper frames, twenty twenty-four. Add a term once you have heard it come out wrong.

Language-specific rules

A pronunciation or forced translation can apply to one language. Add pronunciation_language to a terms entry or target_language to a forced_translations entry:
Here French videos say ak-may and every other language says ack-mee.
  • Omit the field, or send { "scope": "all" }, for a rule that applies to all languages.
  • code is a base language code: fr, es, de.
  • A language-specific rule takes precedence over an all-languages rule for that language.
  • The same term can appear once per language in each list.
  • do_not_translate_terms always applies to all languages.
Responses include the language field only on language-specific rules, so all-languages entries keep their existing shape.

Update

PATCH /v3/brand-glossaries/{brand_glossary_id} replaces each field independently. Omit a field to leave it alone, send a list to replace it in full, send [] to clear it. Send at least one field. A list replaces that kind of rule across every language, so send language-specific entries back with their language fields. A term repeated for the same language within one list returns 409 conflict. To add a single entry, read the glossary, append, and send the whole list back:
Tone settings are managed in the HeyGen app under Brand Kit and are untouched by PATCH.

Read

GET /v3/brand-glossaries lists names, IDs, and timestamps, paged with limit and token. GET /v3/brand-glossaries/{brand_glossary_id} returns the full glossary; do_not_translate_terms and forced_translations appear whenever the glossary has rules of that kind, including rules set in the app. Read it when a video pronounces or translates a term unexpectedly.

Delete

DELETE /v3/brand-glossaries/{brand_glossary_id} removes a glossary. Videos and translations already created with it are unaffected. This cannot be undone.

Apply

Pass brand_glossary_id at the top level of the request, one glossary per call:
On Brand lists every endpoint that accepts the field. On POST /v3/video-agents it is set once per session. In a translation batch or video batch it is set per item. Scenes with their own audio_url or audio_asset_id have no synthesis step, so terms leaves them unchanged. An unknown brand_glossary_id fails the request with 400 before rendering, so no credits are spent. Glossaries are workspace-scoped: an ID visible in the app is rejected if the API key belongs to another workspace.

Errors

Migrating from v1 brand voice

brand_voice_id is the deprecated former name of brand_glossary_id. It is still accepted on POST /v3/templates/{template_id}, POST /v3/video-translations, and POST /v3/video-translations/proofreads. POST /v3/videos accepts brand_glossary_id only. The legacy POST /v1/brand_voice/{brand_voice_id} lists map to the v3 glossary as follows, ahead of the October 31, 2026 v1/v2 sunset: