August 30, 2026 · 5 min read
Everything a Thai voice model decides before it makes a sound
Thai text carries no word spaces and no reliable letter-to-sound rule. Four decisions a text to speech model has to settle before there is any audio.
An English speech model can get a long way on the surface of the text. Words arrive separated, letters map to sounds with a manageable number of exceptions, and stress is a property of the word. A Thai sentence hands a model none of that.
ผมกินข้าวที่ร้านอาหารไทย is one string with no spaces inside it. Four things have to be settled before the first sample of audio exists. Where the phrases break, which letters group into a syllable, what tone each syllable carries, and how a number or an abbreviation is read aloud.
ผมกินข้าวที่ร้านอาหารไทย 1 where the phrases break 2 which letters make one syllable 3 which of five tones each carries 4 how digits and abbreviations read the string states none of the four
Where a phrase begins and ends#
Thai runs its words together and spends the space character on something else. A space in Thai marks a clause or phrase boundary, the job a comma does in English, and it appears far less often than an English reader expects. A model that pauses on spaces would read a whole paragraph in two breaths.
A splitter over spaces therefore returns clauses. It returns them reliably and it returns nothing about words, and the word is the unit that tells a reader where one syllable can end and the next begin. The same absence reaches the translation half of the API, which an earlier post works through.
Phrasing therefore has to come from the sentence itself. A listener hears the difference at once, because a pause dropped inside a Thai clause sounds like a stutter.
Which letters make one syllable#
Thai spelling does not map cleanly from character to sound. กด is read kot, with a vowel that is never written anywhere in the string. ปลา and ปลัด open on the same two letters, one as a consonant cluster and one as two syllables. รัฐศาสตร์ grows a linking syllable that no letter announces, and จันทร์ deletes two letters at the end through a cancellation mark.
Every one of those is a lookahead problem. The doubled -รร reads un at the end of a word and um in front of a final consonant. สรร and กรรม therefore diverge on a letter that comes later. จักรยาน and จักรี share their first four letters and cut into syllables differently. The word decides, and the word is only known once it has been found in a string that marks no boundaries.
The full set of these cases, each with the reading a Thai speaker produces, sits on the text to speech page.
Which of five tones the syllable carries#
Thai is tonal, and the tone of a syllable is written nowhere directly. It follows from the class of the initial consonant, the length of the vowel, whether the syllable ends live or dead, and the tone mark when there is one. Four properties resolve together into one of five tones.
A tone mark on its own settles nothing. The same mark over a mid-class initial and over a low-class initial produces two different tones, which is why a table that copies the mark straight across lands on the wrong one. This is the most common way a Thai reading goes wrong, and it is invisible in the spelling.
Get one of the four wrong and the model produces a different real Thai word. A mispronunciation in Thai speech synthesis usually lands on a word that exists.
What a number or an abbreviation says out loud#
A run of digits has no single reading. A quantity ending in one takes เอ็ด, a postal code goes digit by digit, and ๑๖.๓๐ น. is a clock time. กรุงเทพฯ restores the six syllables its abbreviation mark hides. ก.พ. carries two accepted readings, the full word and the letter names.
Repetition marks behave the same way. ๆ repeats one word in เด็กเล็ก ๆ, two syllables in ในวันหนึ่ง ๆ, and a whole phrase in แต่ละวัน ๆ. The character is identical in all three and the span it covers comes from the meaning.
Every one of those readings is chosen from context. The model resolves the whole word and the whole sentence first and speaks second.
Which language the next word is in#
Thai product copy, support scripts, and chat messages carry English inside Thai sentences constantly. Tracking codes, product names, and complete English clauses appear between Thai words with no marker of any kind. A model that hands English to a second speaker changes voice mid-sentence, which a listener hears as two people reading one line.
Flash keeps one speaker across both languages within a single request.
What each decision costs when it goes wrong#
The four are separate failures with four separate sounds, and only one of them is the mispronunciation people expect.
| Decision | A per-character reader | What a listener hears |
|---|---|---|
| Phrase boundary | Breaks on spaces and punctuation | A paragraph read in two long breaths |
| Syllable grouping | Reads ปลัด the way it reads ปลา | A word the language does not have |
| Tone | Takes the tone from the mark | A different real Thai word |
| Digit reading | Gives every number one reading | A postal code spoken as a quantity |
What this means at the API#
All four decisions happen inside the model, and a request stays a string of text and a voice id. There is nothing to annotate, no phoneme markup to supply, and no pronunciation dictionary to maintain on the caller's side.
A dictionary would close only part of the gap in any case. It can hold the reading of รัฐศาสตร์. It cannot hold the tone of a syllable whose class and final it has not seen, and it cannot hold where a clause breaks in a sentence written this morning. Both of those are properties of the sentence.
The endpoint is POST /v1/tts. It takes up to 5,000 characters per request, streams audio while synthesis is still running, and returns word, sentence, or utterance timestamps on request. The free speech tool reads a short line with no account, and the text to speech guide covers the request shape.