Skip to main content
Send a customLexicon list with a Coda request, and Coda speaks each listed word or phrase with the X-SAMPA pronunciation you supply. The lexicon works in English, German, Spanish, French, Italian, and Portuguese. Send it over HTTP, WebSocket, or gRPC. Each lexicon entry pairs a spelling with the pronunciation that Coda uses for it:

Draft pronunciations with an AI assistant

An AI assistant, such as Claude or ChatGPT, can draft pronunciations from your language’s phoneme table. Give it this prompt, with your language, its page from Supported languages, and your words in place of the English examples:
A draft gets close, but it is not always right. Send it, and fix any entry that the API rejects with Fix a rejected request. Then listen to each word. If a word still sounds wrong, contact support@rime.ai.

Before you start

Keep these points in mind:
  • Coda only. Mist v3 rejects a request that carries a custom lexicon.
  • Send it to the Coda API. Use https://coda.api.rime.ai/ for HTTP, wss://coda.api.rime.ai/ws for WebSocket, or coda.api.rime.ai:443 for gRPC.
  • Six languages. Coda accepts a lexicon in the six supported languages. A lexicon on an Arabic, Dutch, Hindi, or Japanese request fails with 400.
  • One bad entry fails the whole request. The API checks every entry before synthesis starts and names each ill-formed one. It never falls back to the default pronunciation.
  • At most 500 entries per request.
  • The API stores nothing. Send the lexicon with every request, or once per WebSocket connection.
  • Coda follows a pronunciation closely. A pronunciation that sounds natural in the request’s language works best. Listen to the result before you ship it.

Supported languages

The API checks each pronunciation against the phoneme inventory of the request language, so a string that one language accepts can fail in another.

Write a pronunciation

Use these rules to check a draft or to write a pronunciation yourself. A pronunciation is a single word written in X-SAMPA, a plain-ASCII encoding of the International Phonetic Alphabet. Separate every phoneme and every mark with a space. The API reads an unspaced string such as h@lo as one unknown phoneme and rejects it. For example, English hello is h E . " l oU: two syllables, with primary stress on the second. A pronunciation must also follow these rules:
  • Use only the language’s phonemes. Each language page lists them. Diphthongs such as English aI and oU are single phonemes.
  • Mark exactly one primary stress, with " at the start of a syllable. French has no lexical stress, so a French pronunciation carries no " or %.
  • Give each syllable one vowel. Separate adjacent vowels with .: the API rejects two full vowels in one syllable.
  • Do not stress a reduced vowel such as English @ when a full vowel in the word could carry the stress.
  • Start each syllable with a consonant cluster the language allows. English accepts " t r\ i but rejects " S b eI, because no English syllable begins with S b.
The invented brand name Velkora shows how the inventory and stress rule change with the language:
Escape " and \ inside a JSON string. Write English r\ as "r\\" and primary stress as \". English Velkora becomes "v E l . \" k oU . r\\ @".

How entries match your text

Spellings match your text by these rules:
  • Whole words and phrases, ignoring case. Aoife matches aoife and AOIFE, but not the aoife inside aoifestudio. Write a phrase such as San Jose with one space between its words. The phrase then matches those words with one or more spaces between them, but not across a tab or line break.
  • Spellings match the words Coda reads. The API expands abbreviations, numbers, and symbols before it looks for your entries. So write each spelling the way Coda reads it: Doctor for Dr., and forty-two for 42. A written form such as Dr., AT&T, C++, or 42 never matches, and the request still succeeds. The Text Normalization API returns the words that Coda reads.
  • Entries still apply inside URLs and email addresses. Coda reads www.velkora.com as a web address and speaks velkora the way your entry says.
  • Every occurrence. Coda uses the pronunciation each time the spelling appears.
  • The longest spelling wins. If you list both San and San Jose, San Jose takes the phrase and San covers the other occurrences.
  • The last duplicate wins. If you list a spelling twice, the API uses the later entry.
  • Coda speaks a phrase as one word. Write its pronunciation with one primary stress: San Jose is % s { n . h oU . " z eI.

Send a custom lexicon

Every transport carries the same list of {spelling, pronunciation} entries: customLexicon in JSON and custom_lexicon in the Protobuf schema. Set the request language to a supported language and choose a voice that speaks it. The language field is lang over HTTP and language over WebSocket and gRPC.

HTTP

This request synthesizes one sentence with the kubectl entry and writes the audio to output.wav:
Play output.wav and listen for “kube control” where the text says kubectl. To hear the difference, run the request again without customLexicon. If the API rejects the request, curl exits with an error and output.wav holds the JSON error body. Fix a rejected request explains each message.

WebSocket

A WebSocket context takes its lexicon from start.customLexicon. To apply one lexicon to every context on a connection, send it in config.defaults.customLexicon. You can send config only once, before the first start. A non-empty customLexicon in a start replaces the connection default for that context. Install the ws package with npm install ws. Save this example as lexicon.mjs, and run it with Node.js 22 or later. It sends your API key in the upgrade header, sets the lexicon in config, and writes output.wav after the API sends done:
The API checks the connection-level lexicon against each context’s language when the context starts. A context that fails a lexicon check gets an error event, and the connection stays open. Keep each config and start message under the 64 KiB message limit. A larger message closes the socket without an error event. See the Coda WebSocket API for the full context lifecycle.

gRPC

Add customLexicon to the SynthesisRequest for Synthesize, or to the header for SynthesizeStreaming. Use the schema from the rime-api Python package, version 0.3.0 or later. Its schema directory holds the Rime schema and the Google protos it imports. These commands install the package and print the directory:
This command sends your API key as authorization metadata and prints the streamed response messages with base64 audio fields. Replace ./rime-protos with the schema path:
A generated client sets the repeated custom_lexicon field with PronunciationEntry messages. To call a self-hosted Coda engine, send the same request to the engine’s gRPC address, as Protocols shows.

Fix a rejected request

A rejected request produces no audio. Over HTTP, the API returns 400 with kind set to invalid_input. Over a WebSocket, the context gets an error event with the same kind and message. Over gRPC, the call fails with INVALID_ARGUMENT and the same message. The message names each ill-formed entry, starting with custom-lexicon entry, and lists its failed checks.
The last row of this table applies only to a WebSocket connection: