Foreign names in an English voiceover: respell or split the job
Sume TTS takes one language per job. For a few foreign names in an English script, respell them phonetically, or split into jobs and join the audio.

For a few foreign names inside an English narration, keep one English job: send language: "en", an English voice, and spell each name the way it should sound. Sume TTS takes one language and one voice per request, and has no inline language tag, so the engine reads every word with that language's rules. Respelling "Siobhan" as "shi-VAWN" adds a few characters, a fraction of a cent at $0.0475 per 1,000. If a name must sound fully native, split the script into jobs and join the audio with Timeline audio, at $0.01 flat per join.
The request fields and the language rule come from the Sume API reference; the join from Timeline audio, the price from API pricing and the polling steps from Jobs and results, read on 2026-10-03. The voice check is read from Sume's code. Whole sentences in a second language are a different job, covered in mixed-language scripts; this page is about names and short phrases inside one language.
What does Sume do with a foreign name in the script?
Nothing special. In current code, the 409 tts_voice_language_mismatch check compares the voice's primary language with the request's language. It never reads the transcript for foreign words, so an English voice with en and a Spanish name raises no error: the name is read by English rules, and only your ear tells you if it landed.
One trap: when language is omitted, Sume infers ko or ja if Hangul or kana letters outnumber Latin letters. A short English line carrying a long Korean name can flip, then meet an English voice and stop with a 409. Always send language.
Which approach fits which name?
Respelling keeps one voice, one job and one flat read. Splitting changes the voice at each seam, because a voice's language is part of the check, so pick it only when respelling cannot get there.
- The schema also lists an optional
pronunciation_dict_id; the pages read do not say how to create one, so Text to speech pronunciation is the place to look. - In current code Sume's TTS wav output is written as one channel, so two TTS wav parts join cleanly; a mismatch fails as
audio_parts_channel_mismatch.
| Approach | Jobs | Extra cost | Watch for |
|---|---|---|---|
| Respell phonetically | 1 | A few characters | Odd spelling may be read wrongly, so listen |
| Split and join | One per language run, plus one join | $0.01 per join, up to 20 parts | Voice changes at the seam; parts need one channel layout |
How do I respell names in a script?
Keep a map of names to spellings, apply it before you send, and check the language guard offline. This script runs without a key and prints the request body, the character count and the cost.
import json, re
RESPELL = {"Joaquín": "wah-KEEN", "Siobhan": "shi-VAWN", "Niamh": "neev"}
script = "Joaquín and Siobhan met Niamh at noon."
def respell(text):
for name, say in RESPELL.items():
text = re.sub(rf"\b{re.escape(name)}\b", say, text)
return text
def inferred(text):
hangul = len(re.findall("[가-힣]", text))
kana = len(re.findall("[-ヿ]", text))
latin = len(re.findall("[A-Za-z]", text))
return "ko" if hangul > latin else "ja" if kana > latin else None
spoken = respell(script)
assert inferred(spoken) is None # with language omitted this stays English
body = {"transcript": spoken, "language": "en",
"voice": {"id": "voi_0123456789abcdef0123456789abcdef"}}
print(json.dumps(body, ensure_ascii=False))
print(len(spoken), "characters =", round(len(spoken) * 0.0475 / 1000, 5), "USD")How do I check the result?
Generate only the sentence with the name, listen, and adjust the spelling. Every hyphen and capital counts as a character, but a retake of one line is cheap. Check a TTS take with an STT round trip catches dropped words, though not a mispronounced one.
Sources
Related posts
More in Developers
- Format contents PUT 409 format_content_sha_required: send the sha
PUT on a Format file that already exists needs its blob sha. Read the sha with GET, retry, and tell the three 409 codes apart from the package If-Match guard.
- Format 404 format_not_found: five causes, including a pending grant
A Sume 404 format_not_found can mean a typo, an archived Format, the wrong workspace, a team handle you are not in, or a shared Format whose grant is pending.
- 409 previous_run_not_terminal: continue a Format run after it ends
Continuing a Format run with previous_run_id while the first is still running returns 409. Wait for terminal, then continue; a failed create frees its key.
- studio_agent_upstream_unavailable 503: retry, the run keeps going
A Sume 503 studio_agent_upstream_unavailable is a Sume-side outage: retry create with the same Idempotency-Key, and keep polling a run you already hold.
Written by Sume