sphoroVOICEdocs
Markdown

Language and voice

An agent speaks one language or several, and every language it speaks is one entry in languages: what it listens for, what it says, and which voice says it. The first entry is the language calls open in. Set the list on the agent, and choose one of its languages per call when the language depends on who you are dialling.

Step 1 · Set the languages on the agent

Send languages when you create the agent, or patch it later. Each entry carries that language's voice, greeting and, optionally, its own prompt and speech vendors — there is no language, voice_id or greeting field on the agent itself. The usual case is one entry.

PATCH/v1/agents/{id}
Shell
curl -s -X PATCH https://voice.sphoro.com/v1/agents/$AGENT_ID \
  -H "Authorization: Bearer $SPHORO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"languages":[{"code":"hi","greeting":"नमस्ते, एक्मे क्लिनिक।"}]}'

An agent created without one gets en-IN — Indian English. Sending the list replaces it whole, and the order is the meaning: put the language calls should open in first.

Step 2 · Speak several

Add an entry per language, each with a voice that can pronounce it. Every entry after the first needs a voice; the first may leave it empty and take the deployment's default. Set language_detection to follow and the agent moves into whichever of its languages the caller speaks — voice, prompt and all.

Shell
curl -s -X PATCH https://voice.sphoro.com/v1/agents/$AGENT_ID \
  -H "Authorization: Bearer $SPHORO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "languages": [
      {"code": "en-IN", "greeting": "Thanks for calling Acme Clinic."},
      {"code": "hi", "voice_id": "hindi-voice", "greeting": "नमस्ते, एक्मे क्लिनिक।"},
      {"code": "ta", "voice_id": "tamil-voice", "greeting": "வணக்கம், ஆக்மி கிளினிக்."}
    ],
    "language_detection": "follow"
  }'

Step 3 · Or choose one for a single call

language on POST /v1/calls opens that call in one of the agent's languages and changes nothing about the agent. This is what you want when the language comes from your own customer record. It has to be a language the agent speaks — anything else is refused with validation_error, because nothing is invented for a language with no voice that can pronounce it and no greeting written in it.

POST/v1/calls
Shell
curl -s -X POST https://voice.sphoro.com/v1/calls \
  -H "Authorization: Bearer $SPHORO_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d "{
    \"agent_id\": \"$AGENT_ID\",
    \"to\": \"+919876543210\",
    \"language\": \"ta\"
  }"

The call record carries the language it actually ran in, so a transcript can be read back knowing which one that was.

Every language you can send

Send the code. The instruction column is what we add to your prompt on your behalf — it is shown because it is the difference between an agent that listens in a language and one that speaks it, and you can see exactly what your prompt is being asked to do.

CodeLanguageWhat we add to your prompt
enEnglishNothing — English is what a prompt written in English already produces.
en-INIndian EnglishSpeak Indian English. Use Indian conventions for numbers and money — say "twelve thousand five hundred rupees", and lakhs and crores where they fit.
hiHindiहिंदीबातचीत हिंदी में करें। Speak Hindi throughout, including the greeting. Use everyday spoken Hindi, not formal written Hindi.
bnBengaliবাংলাবাংলায় কথা বলুন। Speak Bengali throughout, including the greeting.
mrMarathiमराठीमराठीत बोला. Speak Marathi throughout, including the greeting.
teTeluguతెలుగుతెలుగులో మాట్లాడండి. Speak Telugu throughout, including the greeting.
taTamilதமிழ்தமிழில் பேசுங்கள். Speak Tamil throughout, including the greeting.
guGujaratiગુજરાતીગુજરાતીમાં વાત કરો. Speak Gujarati throughout, including the greeting.
urUrduاردواردو میں بات کریں۔ Speak Urdu throughout, including the greeting.
knKannadaಕನ್ನಡಕನ್ನಡದಲ್ಲಿ ಮಾತನಾಡಿ. Speak Kannada throughout, including the greeting.
mlMalayalamമലയാളംമലയാളത്തിൽ സംസാരിക്കുക. Speak Malayalam throughout, including the greeting.
orOdiaଓଡ଼ିଆଓଡ଼ିଆରେ କଥା ହୁଅନ୍ତୁ। Speak Odia throughout, including the greeting.
paPunjabiਪੰਜਾਬੀਪੰਜਾਬੀ ਵਿੱਚ ਗੱਲ ਕਰੋ। Speak Punjabi throughout, including the greeting.
asAssameseঅসমীয়াঅসমীয়াত কথা কওক। Speak Assamese throughout, including the greeting.
esSpanishEspañolHabla en español. Speak Spanish throughout, including the greeting.
frFrenchFrançaisParlez en français. Speak French throughout, including the greeting.
deGermanDeutschSprich Deutsch. Speak German throughout, including the greeting.
ptPortuguesePortuguêsFale em português. Speak Portuguese throughout, including the greeting.
arArabicالعربيةتحدث بالعربية. Speak Arabic throughout, including the greeting.

What choosing a language actually does

Three things at once, which is worth knowing because getting one of them and not the others is the classic way a voice agent sounds broken.

StageEffect
ListeningSpeech recognition is told which language to expect, so it stops trying to hear the caller as English.
ThinkingThe instruction from the table above is prepended to your system prompt — before it, not after, so it frames everything that follows rather than being one more line at the end of two thousand characters.
SpeakingThe voice is asked for that language, so the words come out with the right sounds instead of being read phonetically by an English voice.
Your prompt does not need translating. Write it in English and set language; the instruction is what carries the language through. Translating the prompt as well is fine and changes nothing — what you must not do is translate the prompt instead of setting the field, which leaves recognition and the voice still set to English.

Regional tags fall back to their base language

hi-IN, ta-IN, es-MX — anything with a region is resolved to the language before the dash, so they behave identically to hi, ta and es. Sending the regional form is not an error and does not need avoiding; it simply does not do anything extra. The one exception is en-IN, which is its own entry above because Indian English differs from English in idiom rather than in vocabulary.

A code we do not know is left in English

An unrecognised value is not rejected, and it is not guessed at either: the agent keeps working and speaks English. Inventing an instruction for a language the model may not speak well produces a worse call than leaving it alone. If an agent you set to a language is answering in English, check the code against the table above first — that is nearly always what happened.

Write the greeting in the language too

A language's greeting, and the agent's filler_phrase, are spoken verbatim; they are not passed through the model, so the language instruction never reaches them. That is why the greeting lives on the language entry: a Hindi agent with an English greeting opens every call in English and then switches, which sounds exactly as odd as it reads.

JSON
{
  "languages": [
    {
      "code": "hi",
      "system_prompt": "You are a warm, efficient receptionist for Acme Clinic. Keep every answer to one or two sentences.",
      "greeting": "नमस्ते, एक्मे क्लिनिक में आपका स्वागत है। मैं आपकी क्या मदद कर सकता हूँ?"
    }
  ],
  "filler_phrase": "एक मिनट, मैं देखता हूँ।"
}

The prompt stays in English on purpose here — the model reads it, nobody hears it, and English is what these models follow instructions in most reliably. It sits on the Hindi language entry because that is where an agent's instructions live, not because it has to be written in Hindi. The two spoken lines are the ones that have to be.

Choosing a voice

voice_id on a language entry names which voice speaks it. Leave it empty on the first language and you get this deployment's default voice, which is the right answer until somebody has actually listened to alternatives and preferred one. Every language after the first needs one, because the previous language's voice cannot pronounce it.

Shell
curl -s -X PATCH https://voice.sphoro.com/v1/agents/$AGENT_ID \
  -H "Authorization: Bearer $SPHORO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"languages":[{"code":"hi","voice_id":"21m00Tcm4TlvDq8ikWAM"}]}'

The value is the identifier used by the speech provider configured on this deployment, so the catalogue of available voices — and the format of the id — comes from that provider rather than from us. Your account manager can tell you which is configured and what it offers; the portal's agent screen is the fastest place to try two and compare.

An unavailable voice does not fail the call. If no provider can produce the voice you named, the call goes ahead in the default voice and the substitution is logged. A different voice is a far better outcome than a silent call — but it does mean a typo in voice_id is something you hear rather than something you are told, so check the first call after changing one.

Speed and pitch

FieldRangeDefaultNotes
speed0.25 – 41Anything under about 0.8 sounds laboured and anything over about 1.2 sounds rushed on a phone line, which is narrower and noisier than a laptop speaker. 0.95 is a common small adjustment for an older audience.
pitch0.25 – 41Small moves only. Past roughly ±0.15 a voice stops sounding like a person.

Both are validated on write: outside the range you get 422 and validation_error naming the field, rather than a call that sounds wrong.

A complete example

An agent that greets in Hindi, thinks in a prompt written in English, and speaks a little slower than default:

Shell
curl -s -X POST https://voice.sphoro.com/v1/agents \
  -H "Authorization: Bearer $SPHORO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Clinic reception (Hindi)",
    "languages": [
      {
        "code": "hi",
        "system_prompt": "You are a warm, efficient receptionist for Acme Clinic. Answer questions about opening hours and appointments. Keep every answer to one or two sentences.",
        "greeting": "नमस्ते, एक्मे क्लिनिक। मैं आपकी क्या मदद कर सकता हूँ?"
      }
    ],
    "filler_phrase": "एक मिनट, मैं देखता हूँ।",
    "speed": 0.95
  }'

Check it before you move on

  • The language code is one from the table, not a guess.
  • greeting and filler_phrase are written in that language.
  • You have heard one real call end to end, not just read the transcript — a transcript looks correct whether or not the voice was.

Next: step 5 tells your server when a call ends, so you stop polling for it.