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 overview

Migrate 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.

13 fields mapped, with a rollback plan

Prompt

Connect MCP
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.

  1. ElevenLabs

    POST /v1/text-to-speech/{voice_id}

    Cartesia
    POST /tts/bytes
    Note
    The voice moves from the path into the body.
  2. ElevenLabs

    xi-api-key header

    Cartesia
    X-API-Key and Cartesia-Version: 2026-08-14
  3. ElevenLabs

    voice_id in the path

    Cartesia
    voice: {"id": "<voice id>"}
    Note
    Voice IDs are specific to each vendor and never carry over.
  4. ElevenLabs

    text

    Cartesia
    transcript
  5. ElevenLabs

    model_id: eleven_multilingual_v2, eleven_flash_v2_5 or eleven_v4

    Cartesia
    model_id: sonic-3.6
  6. ElevenLabs

    language_code

    Cartesia
    language, such as en or en-GB
    Note
    eleven_multilingual_v2 rejects language_code, so many ElevenLabs requests leave it out. Set language on every Cartesia request.
  7. ElevenLabs

    voice_settings.speed

    Cartesia
    generation_config.speed (0.6 to 1.5)
  8. ElevenLabs

    voice_settings: stability, similarity_boost, style

    Cartesia
    generation_config.emotion, plus the voice you pick
    Note
    These knobs have no one-to-one match. Render the same script on both vendors and judge by ear.
  9. ElevenLabs

    Audio tags such as [whispering] or [laughing] (v3 and v4)

    Cartesia
    An <emotion> tag in the transcript
    Note
    An <emotion> tag shifts the tone mid-line. Sound effects such as [applause] have no match.
  10. ElevenLabs

    output_format query parameter, such as pcm_16000 or ulaw_8000

    Cartesia
    output_format object in the body, such as raw with pcm_mulaw at 8000
  11. ElevenLabs

    POST /v1/text-to-speech/{voice_id}/with-timestamps (character alignment)

    Cartesia
    TTS WebSocket with add_timestamps or add_phoneme_timestamps
    Note
    /tts/bytes returns no timing. Cartesia times words and phonemes, and has no character-level alignment.
  12. ElevenLabs

    previous_text, next_text, previous_request_ids, next_request_ids

    Cartesia
    One WebSocket context_id with continue: true
    Note
    /tts/bytes has no stitching fields. Send a long passage as chunks in one context so the prosody carries across.
  13. ElevenLabs

    pronunciation_dictionary_locators (up to 3)

    Cartesia
    pronunciation_dict_id (one dictionary)
    Note
    Merge 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.

  1. ElevenLabs

    xi-api-key header

    Cartesia
    X-API-Key plus Cartesia-Version: 2026-08-14
    Note
    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.
  2. ElevenLabs

    ELEVENLABS_API_KEY

    Cartesia
    CARTESIA_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.

  1. Model or plan

    Eleven v4, Eleven v3 and Multilingual v2

    ElevenLabs
    $0.08
  2. 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 pricing

Sources

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.

  1. Limit

    Free tier

    Cartesia
    20,000 credits a month on the Free plan (about 20,000 characters)
    ElevenLabs
    10,000 credits a month on the Free plan; the commercial license starts on Starter at $6 a month
  2. Limit

    Request limit

    Cartesia
    No published maximum; stream long text over the TTS WebSocket
    ElevenLabs
    10,000 characters per request on Eleven v4 and Multilingual v2, 5,000 on v3, 40,000 on Flash v2.5
  3. Limit

    Voices

    Cartesia
    1,022 voices in the library, plus instant clones
    ElevenLabs
    Over 10,000 community voices in the Voice Library, plus your own clones and Voice Design voices
  4. Limit

    Languages

    Cartesia
    44 languages for text to speech
    ElevenLabs
    90+ 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 limits

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.

  1. Create a Cartesia API key. Listen through the voice library and shortlist a voice for each role you cover on ElevenLabs today.

  2. To rebuild a cloned voice, upload its original recording to Cartesia. Instant clones need 10 seconds, and the cloning guide walks through it.

  3. Move voice_id out of the URL and output_format out of the query string, both into the body, and rename text to transcript.

  4. Swap stability and similarity_boost for speed, volume and emotion, then render one script on both vendors before cutover.

  5. Port any /with-timestamps calls, and any request chains stitched with previous_text, to the TTS WebSocket.

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.

Contact Sales

Start building.

Create an API key, then hand your coding agent the migration prompt and a few of your own scripts.

Try Cartesia