Migrating Text-to-Speech from ElevenLabs to Sarvam
Migrating Text-to-Speech from ElevenLabs to Sarvam
This guide covers migrating ElevenLabs text-to-speech API calls to Sarvam. If you’re building a full voice agent rather than replacing individual TTS calls, start from the LiveKit or Pipecat voice agent build guides instead: they aren’t a 1:1 API swap and aren’t covered here.
In short: swap voice_id for speaker, add a required target_language_code, and change your response handling: ElevenLabs returns raw audio bytes, Sarvam returns JSON with base64-encoded audio in an audios array. Sarvam’s structured response is what makes it easy to pair audio with per-request metadata; that decode step is the change most migrations look for first.
Quick start
Base URL and auth header change the same way for every ElevenLabs migration, so they’re folded in here rather than in a separate page:
With that, replace the synthesis call and add the required language code:
Before (ElevenLabs)
After (Sarvam)
ElevenLabs’ Python and JavaScript SDKs hand back an iterable/stream of audio chunks you can write directly. Sarvam’s convert() returns a JSON object; the audio lives in response.audios as a list of base64 strings, one per input text. Join and decode before writing to disk, or use the Python SDK’s sarvamai.play.save() helper, which does this for you.
The REST response is JSON with a base64 audios array, not a file. Decode .audios[0] before writing it out; see the REST API guide for the full decode snippet.
The rest of this page covers the full endpoint and parameter mapping, streaming, pronunciation dictionaries, and common mistakes.
Endpoint map
The tables below aren’t a checklist to apply field-by-field: Quick Start above already shows the whole call swapped over in one go. Use these tables as a reference for what changed and why, not as a sequence of edits to make yourself.
Parameter concept map
pitch and loudness give you fine-grained tone and volume control on bulbul:v2. On bulbul:v3, which adds a larger voice set and stronger code-mixed handling, tone comes from speaker choice instead, so pick a speaker whose baseline delivery already fits rather than reaching for these two params.
Streaming
Pronunciation dictionary
Both platforms let you fix mispronounced brand names and acronyms without retraining a model, but the mechanism differs:
If your ElevenLabs dictionary relies on IPA phoneme rules for precise pronunciation control, plan to rewrite it: Sarvam dictionaries use plain word-to-word text replacements (e.g. "NAIC": "N A I C"), which are simpler to author and audit than phonetic transcriptions. See the Pronunciation Dictionary guide for the full format and upload flow.
What’s different by design
- Ready-to-use voices, no cloning step. Sarvam ships a curated, named set of 30+ Bulbul v3 voices, professionally tuned and ready to call immediately, with no per-request cloning or training step to manage.
- Explicit language targeting. Every Sarvam request carries
target_language_code, so pronunciation and prosody are correct by design on every call, especially valuable for Hindi, Hinglish, and other code-mixed Indian-language text where auto-detection is prone to guessing wrong. - A simpler tuning surface. Tone and delivery come from picking the right speaker plus
pace(andpitch/loudnesson v2), instead of calibratingstability,similarity_boost,style, anduse_speaker_boostseparately. Fewer knobs, less trial and error to land on a voice that sounds right. - Indian language depth is Sarvam’s specific strength. Sarvam covers Hindi plus 9 other Indian languages (Bengali, Tamil, Telugu, Kannada, Malayalam, Marathi, Gujarati, Punjabi, Odia), natively tuned for code-mixed input like Hinglish. If your product needs those languages, this is the reason to migrate, not just a side effect of it.
- Instant voice discovery. Every speaker is listed with audio previews on the Voices page: no API call, no pagination, nothing to query.
Full example
A small wrapper function, before and after, showing the complete set of changes together:
Before (ElevenLabs)
After (Sarvam)
Common mistakes
Writing the response body directly as an audio file
The single most common migration bug. ElevenLabs’ REST response is the audio file itself; Sarvam’s is JSON. Code that does f.write(response.content) unmodified will produce a file full of JSON text, not audio. Decode response.audios[0] from base64 first.
Forgetting target_language_code
It’s required on every request, by design: this is what guarantees Sarvam applies the correct pronunciation and prosody instead of guessing from the speaker name. Include it from the start rather than treating it as optional.
Trying to tune pace/pitch instead of picking the right speaker
pace and pitch aren’t drop-in replacements for stability or style. Rather than compensating with those params, pick a speaker whose baseline delivery already matches what you need; see the Voices page for per-speaker tone descriptions.
Reusing pitch/loudness on bulbul:v3
Both params are accepted syntactically but only take effect on bulbul:v2. If output sounds unchanged after setting them, confirm which model version the request is actually using.
Porting an IPA-based pronunciation dictionary as-is
Sarvam’s dictionary format is plain word-to-word substitution, not phoneme rules. An ElevenLabs dictionary built on IPA transcriptions needs to be rewritten as text replacements, not just re-uploaded.
See also
- Migration overview: base URL, auth, and SDK client changes
- Migrating Speech-to-Text
- Which Text-to-Speech API to Use
- TTS Best Practices
- Voices
- Pronunciation Dictionary
- Errors & Troubleshooting