AI voice reads Spanish with an English accent: two causes to check
Spanish read with an English accent usually means the language field was omitted or the voice is tagged for another language. How Sume's TTS 409 works.

If an AI voice reads Spanish, German or Portuguese with an English accent, one of two things happened: the request never said which language to speak, or the voice you picked belongs to another language. On Sume's TTS 1.0 the first is silent and the second is a warning, so you can ship a bad take without noticing unless you know where each one hides.
Both checks come from the Sume API reference for POST /v1/tts-1.0/generate, read 2026-10-03. Neither fix costs anything extra: you resend the same request with the field filled in.
Cause 1: the language field was left out
The request schema describes language as the language the voice speaks the transcript in, a BCP-47 or ISO-639 code such as ko, ja or en. It says to set it for every non-English transcript, and that an omitted value defaults to English at the provider. The only fallback Sume adds is a guess for Korean and Japanese: it infers ko from a transcript that is mostly Hangul and ja from one that is mostly kana.
That means a Spanish script sent with no language is read by an English-defaulted engine. Nothing errors, the job completes, you are billed per character, and the audio sounds like an English speaker reading Spanish. French, German, Portuguese and Hindi behave the same way, and so does Chinese, because the fallback only recognises Hangul and kana.
Cause 2: the voice is tagged for another language
When you pick a voice from your workspace's Voices library, Sume compares that voice's primary language with the language you asked for. If they differ, the request is refused with 409 and the code tts_voice_language_mismatch. The message says pronunciation may sound unnatural and asks whether to proceed. No job is created and nothing is charged at that point.
To go ahead anyway, resend the same request and the same idempotency key with confirm_language_mismatch: true. The flag does not change the voice or the language; it only records that a person accepted the risk. Over Sume's hosted MCP the same check is named tts_voice_language_warning, and the tool description tells an agent to ask the user before confirming rather than switch the voice itself.
The check is advisory and only as good as the tag. If the voice id is not found in the library, for example a raw voice UUID you pasted in, the lookup returns nothing and no warning fires. In that case the only protection is your own listening test.
Which symptom points at which cause?
| What you did | What Sume does | What you hear |
|---|---|---|
Spanish script, no language | Defaults to English at the provider; no warning | English-accented Spanish |
Spanish script, language: "es", voice tagged English | 409 tts_voice_language_mismatch, no job, no charge | Nothing until you confirm |
Same request plus confirm_language_mismatch: true | Runs with the voice you chose | Possibly an accent; test a line |
Korean script, language: "ko", no Hangul in the text | 400 tts_language_script_mismatch | Nothing; check the text encoding |
| Raw voice UUID not in the library | No tag to compare, so no warning | Whatever the voice does |
A request that sets the language
Set language on every non-English request, and pick a voice whose library tag matches it. Replace the voice id with one from your workspace.
curl -X POST https://api.sume.com/v1/tts-1.0/generate \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: es-intro-001" \
-d '{
"transcript": "Hola, esta es la versión en español de nuestro anuncio.",
"language": "es",
"voice": { "id": "'"$VOICE_ID"'" },
"mode": "async"
}'What happens over Sume's hosted MCP?
An agent that calls TTS through Sume's hosted MCP meets the same rule under the name tts_voice_language_warning. The tool description tells the agent to surface the warning to the person and wait, instead of swapping the voice on its own or confirming silently. That is the right default for dubbing, because a wrong voice on a customer-facing video is a decision about brand, not a retry.
If you run batches unattended, move the decision upstream: keep a table of language to voice id that a person approved, and have the batch refuse to run a language that has no entry. Then the 409 becomes a bug in your table, which is easier to catch than a quiet accent in a published video.
A confirmed mismatch is still a normal paid job once it runs. The warning exists before the job is created, so the saving is in not paying for a take you would throw away.
A quick routine before a batch
Sume's TTS schema publishes no list of supported languages and no count, only the language field, so the first test line per language is the real answer for your script. For picking voices per language, see the multilingual TTS post.
- Generate one short line per language first and listen to it, since a tag mismatch and a missing field sound alike.
- Keep a map of language to voice id in your own code and send both fields from it, so a language is never sent without its voice.
- Treat a
409as a decision, not an error to retry blindly: change the voice, or confirm once and keep the same idempotency key. - Do not translate a non-English request into English to make it pass; the schema says never to.
Sources
Related posts
More in Developers
- Are Claude Code mods safe with a Sume API key in your env?
Claude Code mods run unsandboxed and can read env vars and settings files. What that means for a Sume API key, the CLI config file and an OAuth session.
- Cancel a GPT Image 2.5 job: only possible before it starts
Sume's POST /v1/jobs/{id}/cancel works only before generation work starts. How to read cancelable, what the 409 means, and what a client timeout does not do.
- Chinese text to speech API: set language zh or it reads as English
Sume TTS only guesses Korean and Japanese when the language is missing. For Mandarin send language zh and pick a voice tagged zh, then test one line.
- allowManagedModsOnly in Claude Code: does hosted Sume MCP still load?
allowManagedModsOnly keeps users' own Claude Code mods from loading. What it leaves alone, how a policy mod reviews the rest, and the Sume MCP connection.
Written by Sume