Migration guides / ElevenLabs
Migrate your ElevenLabs TTS to Cartesia
Cartesia takes the same text-to-speech request as ElevenLabs, with the voice ID and output format moved into the JSON body.
Why migrate from ElevenLabs now
Dated changes on the ElevenLabs side, each linked to the page that announces it.
ElevenLabs Default voices expire
ElevenLabs says every Default voice expires on this date and stops being accessible. If your app calls a Default voice ID, you have to choose a new voice before then on either platform.
ElevenLabs voices overviewMigrate from ElevenLabs with your coding agent
Paste this into Claude Code, Cursor or Codex in the repo that calls ElevenLabs. It carries the field mapping, the Cartesia request and a rollout that keeps ElevenLabs behind a flag until you switch.
Prompt
Move this codebase from ElevenLabs to Cartesia for text to speech. Keep ElevenLabs working behind a flag until I switch over.
December 31, 2026: ElevenLabs Default voices expire. ElevenLabs says every Default voice expires on this date and stops being accessible. If your app calls a Default voice ID, you have to choose a new voice before then on either platform. (https://elevenlabs.io/docs/overview/capabilities/voices)
## 1. Find the calls
Search for `api.elevenlabs.io` or `ELEVENLABS_API_KEY`. The request to replace is `POST /v1/text-to-speech/{voice_id}`. List every call site before you edit anything.
## 2. Target
- Request: `POST https://api.cartesia.ai/tts/bytes`
- Model: `model_id: "sonic-3.6"`
- Headers: `X-API-Key` read from the `CARTESIA_API_KEY` environment variable, and `Cartesia-Version: 2026-08-14`
- Auth swap: ElevenLabs sends the key in `xi-api-key` header from `ELEVENLABS_API_KEY`. Replace it with `X-API-Key` from `CARTESIA_API_KEY` on the Cartesia path only, and keep `ELEVENLABS_API_KEY` for the ElevenLabs path. An ElevenLabs API key can be scoped to certain endpoints, given a credit quota or locked to allowlisted IPs. Write those rules down before you retire the key.
- Add `CARTESIA_API_KEY` wherever the project documents its environment (`.env.example`, README, deploy config). Never hardcode the key.
- Request size: ElevenLabs caps a request at 10,000 characters per request on Eleven v4 and Multilingual v2, 5,000 on v3, 40,000 on Flash v2.5. Cartesia publishes no per-request maximum, so keep any chunking the code already does and split at sentence boundaries; for long text, stream over the Cartesia TTS WebSocket.
- Concurrency: ElevenLabs allows Multilingual v2 allows 2 concurrent requests on Free, 3 on Starter, 5 on Creator, 10 on Pro and 15 on Scale or Business; Flash allows twice that. Look up the Cartesia plan's concurrent request limit at https://www.cartesia.ai/pricing, cap parallel requests at it, and retry rate-limit errors with backoff.
- Voice IDs don't carry over. Keep each voice ID in one named constant or config value, put a placeholder where each ElevenLabs voice was, and list them for me so I can pick replacements at https://www.cartesia.ai/voices.
- Suggested starting points to put in those placeholders, for me to confirm by ear: Audiobook or long-form narration, male → `ed82c17b-4704-4d34-be43-5d19065acdf1` (Carl - Steady Storyteller); Audiobook or long-form narration, female → `a33f7a4c-100f-41cf-a1fd-5822e8fc253f` (Lauren - Lively Narrator); Support agent on a call, female → `9626c31c-bec5-4cca-baa8-f8ba9e84c8bc` (Jacqueline - Reassuring Agent); Onboarding or support agent, male → `a5136bf9-224c-4d76-b823-52bd5efcffcc` (Jameson - Easygoing Support).
## 3. Field mapping, ElevenLabs → Cartesia
- `POST /v1/text-to-speech/{voice_id}` → `POST /tts/bytes`. The voice moves from the path into the body.
- `xi-api-key` header → `X-API-Key` and `Cartesia-Version: 2026-08-14`
- `voice_id` in the path → `voice`: `{"id": "<voice id>"}`. Voice IDs are specific to each vendor and never carry over.
- `text` → `transcript`
- `model_id`: `eleven_multilingual_v2`, `eleven_flash_v2_5` or `eleven_v4` → `model_id`: `sonic-3.6`
- `language_code` → `language`, such as `en` or `en-GB`. `eleven_multilingual_v2` rejects `language_code`, so many ElevenLabs requests leave it out. Set `language` on every Cartesia request.
- `voice_settings.speed` → `generation_config.speed` (0.6 to 1.5)
- `voice_settings`: `stability`, `similarity_boost`, `style` → `generation_config.emotion`, plus the voice you pick. These knobs have no one-to-one match. Render the same script on both vendors and judge by ear.
- Audio tags such as `[whispering]` or `[laughing]` (v3 and v4) → An `<emotion>` tag in the `transcript`. An `<emotion>` tag shifts the tone mid-line. Sound effects such as `[applause]` have no match.
- `output_format` query parameter, such as `pcm_16000` or `ulaw_8000` → `output_format` object in the body, such as `raw` with `pcm_mulaw` at 8000
- `POST /v1/text-to-speech/{voice_id}/with-timestamps` (character alignment) → TTS WebSocket with `add_timestamps` or `add_phoneme_timestamps`. `/tts/bytes` returns no timing. Cartesia times words and phonemes, and has no character-level alignment.
- `previous_text`, `next_text`, `previous_request_ids`, `next_request_ids` → One WebSocket `context_id` with `continue: true`. `/tts/bytes` has no stitching fields. Send a long passage as chunks in one context so the prosody carries across.
- `pronunciation_dictionary_locators` (up to 3) → `pronunciation_dict_id` (one dictionary). Merge your dictionaries into one before you upload it.
## 4. ElevenLabs fields with no Cartesia equivalent
- `voice_settings.use_speaker_boost`. What to do: Drop the field and choose a voice that already sits close to the original speaker.
## 5. Reference request
Match the language and HTTP client the codebase already uses. This is the same request in Python:
```python
import os
import requests
text = "Chapter one. The lighthouse keeper had not seen a ship in eleven days."
VOICE_ID = "6ccbfb76-1fc6-48f7-b71d-91ac6298247b" # from /voices
response = requests.post(
"https://api.cartesia.ai/tts/bytes",
headers={
"X-API-Key": os.environ["CARTESIA_API_KEY"],
"Cartesia-Version": "2026-08-14",
},
json={
"model_id": "sonic-3.6",
"transcript": text,
"voice": {"id": VOICE_ID},
"language": "en",
"output_format": {
"container": "raw",
"encoding": "pcm_s16le",
"sample_rate": 16000,
},
},
)
response.raise_for_status()
open("out.pcm", "wb").write(response.content)
```
## 6. Roll out
1. Choose ElevenLabs or Cartesia per request from one config flag, defaulting to ElevenLabs.
2. Run the same scripts through both and save the clips side by side for me to listen to. Check that the container, encoding and sample rate match what downstream code expects.
3. Leave the ElevenLabs client, call and key in place so rollback is flipping the flag. Don't delete them in this change.
4. Run the existing tests, and add one that checks the Cartesia request body.
## Docs
- ElevenLabs text-to-speech convert reference: https://elevenlabs.io/docs/api-reference/text-to-speech/convert
- ElevenLabs convert with timestamps reference: https://elevenlabs.io/docs/api-reference/text-to-speech/convert-with-timestamps
- ElevenLabs models: https://elevenlabs.io/docs/models
- ElevenLabs API authentication: https://elevenlabs.io/docs/api-reference/authentication
- ElevenLabs text-to-speech best practices (SSML and audio tags): https://elevenlabs.io/docs/overview/capabilities/text-to-speech/best-practices
- Cartesia TTS bytes API reference: https://docs.cartesia.ai/api-reference/tts/bytes
- Cartesia TTS WebSocket API reference: https://docs.cartesia.ai/api-reference/tts/websocket
- Cartesia SSML tags: https://docs.cartesia.ai/build-with-cartesia/capability-guides/ssml-tags
When you're done, tell me which files changed, which fields you couldn't map, and how to flip the flag.Every ElevenLabs field, mapped to Cartesia
The prompt carries this table. Each row is a field in your ElevenLabs request and the Cartesia field that replaces it.
- ElevenLabs
POST /v1/ text-to-speech/ {voice_id} CartesiaPOST /tts/bytesNoteThe voice moves from the path into the body. - ElevenLabs
xi-api-keyheaderCartesiaX-API-KeyandCartesia-Version: 2026-08-14 - ElevenLabs
voice_idin the pathCartesiavoice:{"id": "<voice id>"}NoteVoice IDs are specific to each vendor and never carry over. - ElevenLabs
textCartesiatranscript - ElevenLabs
model_id:eleven_multilingual_v2,eleven_flash_v2_5oreleven_v4Cartesiamodel_id:sonic-3.6 - ElevenLabs
language_codeCartesialanguage, such asenoren-GBNoteeleven_multilingual_v2rejectslanguage_code, so many ElevenLabs requests leave it out. Setlanguageon every Cartesia request. - ElevenLabs
voice_settings.speedCartesiageneration_config.speed(0.6 to 1.5) - ElevenLabs
voice_settings:stability,similarity_boost,styleCartesiageneration_config.emotion, plus the voice you pickNoteThese knobs have no one-to-one match. Render the same script on both vendors and judge by ear. - ElevenLabs
Audio tags such as
[whispering]or[laughing](v3 and v4)CartesiaAn<emotion>tag in thetranscriptNoteAn<emotion>tag shifts the tone mid-line. Sound effects such as[applause]have no match. - ElevenLabs
output_formatquery parameter, such aspcm_16000orulaw_8000Cartesiaoutput_formatobject in the body, such asrawwithpcm_mulawat 8000 - ElevenLabs
POST /(character alignment)v1/ text-to-speech/ {voice_id}/ with-timestamps CartesiaTTS WebSocket withadd_timestampsoradd_phoneme_timestampsNote/tts/bytesreturns no timing. Cartesia times words and phonemes, and has no character-level alignment. - ElevenLabs
previous_text,next_text,previous_request_ids,next_request_idsCartesiaOne WebSocketcontext_idwithcontinue: trueNote/tts/byteshas no stitching fields. Send a long passage as chunks in one context so the prosody carries across. - ElevenLabs
pronunciation_dictionary_locators(up to 3)Cartesiapronunciation_dict_id(one dictionary)NoteMerge your dictionaries into one before you upload it.
ElevenLabs API key and auth, mapped to Cartesia
Cartesia reads the key from the X-API-Key header and pins the API version with Cartesia-Version on every request.
- ElevenLabs
xi-api-keyheaderCartesiaX-API-KeyplusCartesia-Version: 2026-08-14NoteAn ElevenLabs API key can be scoped to certain endpoints, given a credit quota or locked to allowlisted IPs. Write those rules down before you retire the key. - ElevenLabs
ELEVENLABS_API_KEYCartesiaCARTESIA_API_KEY
ElevenLabs API pricing per 1,000 characters
List prices per 1,000 characters from the vendor's own pricing page. Plans, regions and volume discounts change what you pay.
- Model or plan
Eleven v4, Eleven v3 and Multilingual v2
ElevenLabs$0.08 - Model or plan
Eleven v4 Turbo, v3 Conversational and Flash/Turbo
ElevenLabs$0.04
On Cartesia, usage draws from your plan's credits: 20,000 credits a month on the Free plan (about 20,000 characters). Enterprise pricing is custom.
Cartesia plans and pricingSources
Prices read from each company's pricing page in November 2026.
ElevenLabs limits compared with Cartesia
Published limits from both companies. Plans change them, so check both pages before you size a rollout.
- Limit
Free tier
Cartesia20,000 credits a month on the Free plan (about 20,000 characters)ElevenLabs10,000 credits a month on the Free plan; the commercial license starts on Starter at $6 a month - Limit
Request limit
CartesiaNo published maximum; stream long text over the TTS WebSocketElevenLabs10,000 characters per request on Eleven v4 and Multilingual v2, 5,000 on v3, 40,000 on Flash v2.5 - Limit
Voices
Cartesia1,022 voices in the library, plus instant clonesElevenLabsOver 10,000 community voices in the Voice Library, plus your own clones and Voice Design voices - Limit
Languages
Cartesia44 languages for text to speechElevenLabs90+ on Eleven v4, 70+ on v3, 32 on Flash v2.5 and 29 on Multilingual v2
Cartesia's figures come from its pricing page and voice library.
Cartesia pricing and plan limitsSources
- ElevenLabs models, limits and concurrencyelevenlabs.io
- ElevenLabs planselevenlabs.io
- ElevenLabs voices overviewelevenlabs.io
Limits read from each company's documentation in November 2026.
ElevenLabs voices and where to start on Cartesia
Voice IDs from your ElevenLabs library: community voices from the Voice Library, your clones and Voice Design voices.
Each card is a starting point for a common ElevenLabs pick, matched by language and use. Listen before you choose.
What you get on Cartesia
What changes once the ElevenLabs call is gone.
Clone a voice from 10 seconds of audio
An instant clone needs 10 seconds of a recording you have permission to use and a Pro plan or higher. A professional clone takes 30 minutes of audio and a Startup plan or higher.
Volume per request
generation_config.volume scales loudness from 0.5 to 2.0 on each request. ElevenLabs voice_settings has no volume field, so a gain step you run in post can go.
How to migrate from ElevenLabs to Cartesia
The same changes the prompt makes, if you'd rather make them yourself.
Create a Cartesia API key. Listen through the voice library and shortlist a voice for each role you cover on ElevenLabs today.
To rebuild a cloned voice, upload its original recording to Cartesia. Instant clones need 10 seconds, and the cloning guide walks through it.
Move
voice_idout of the URL andoutput_formatout of the query string, both into the body, and renametexttotranscript.Swap
stabilityandsimilarity_boostforspeed,volumeandemotion, then render one script on both vendors before cutover.Port any
/with-timestampscalls, and any request chains stitched withprevious_text, to the TTS WebSocket.
Sources
Sources
Request shapes checked against vendor documentation in November 2026.
Compare and read next
Frequently asked questions
How does ElevenLabs API pricing work?
ElevenLabs pricing for the API is a flat rate per character on every plan. Multilingual v2, v3 and v4 cost $0.08 per 1,000 characters, and Flash or Turbo costs $0.04. A bigger plan buys a larger prepaid allowance at that rate, such as 3,738,000 Multilingual characters on the $299 Scale plan.
Is ElevenLabs free?
There is a free plan with 10,000 credits a month, which ElevenLabs puts at about 10 minutes of audio. Its pricing page lists the commercial license from the Starter plan up, at $6 a month after a $1 first month. Cartesia's Free plan gives 20,000 credits a month at 1 credit per character.
Can I bring my ElevenLabs cloned voice to Cartesia?
Not the voice ID. With the original recording and permission to use it, Cartesia makes an instant clone from 10 seconds of audio on a Pro plan or higher. Professional clones take 30 minutes of audio and lock speed and volume at training time (cloning guide).
Does ElevenLabs support SSML, and does it carry over?
Pauses do. ElevenLabs reads <break time="1.5s" /> up to 3 seconds on its older models, though Eleven v4 and v3 ignore break tags, and phoneme tags work only on eleven_flash_v2. Cartesia reads <break>, <spell>, <emotion>, <speed> and <volume> inside the transcript (SSML tags). Phoneme overrides belong in a pronunciation dictionary.
Where does the output format go?
ElevenLabs reads output_format from the query string. Cartesia wants an object in the JSON body with a container, an encoding and a sample_rate.
What doesn't carry over from ElevenLabs?
stability, similarity_boost, style and use_speaker_boost have no matching fields, and audio-tag sound effects have no match. Character alignment turns into word and phoneme timestamps, served only over the WebSocket. /tts/bytes has no previous_text or next_text, and a request takes one pronunciation dictionary where ElevenLabs takes three.
How do I switch without a hard cutover?
Keep both clients in your code and pick one per request from a flag, starting with a small share of traffic. Log which vendor produced each clip so complaints trace back. If a voice sounds wrong on Cartesia, flip that voice back to ElevenLabs while you audition a better match.
Get started today
Talk to an expert.
Connect with a member of our team and learn how Cartesia can help you build world-class voice experiences.
Start building.
Create an API key, then hand your coding agent the migration prompt and a few of your own scripts.