Move Deepgram Aura-2 TTS to Cartesia

Every Aura-2 setting that rides in Deepgram's query string moves into the JSON body on Cartesia.

Migrate from Deepgram with your coding agent

Paste this into Claude Code, Cursor or Codex in the repo that calls Deepgram. It carries the field mapping, the Cartesia request and a rollout that keeps Deepgram behind a flag until you switch.

11 fields mapped, with a rollback plan

Prompt

Connect MCP
Move this codebase from Deepgram to Cartesia for text to speech. Keep Deepgram working behind a flag until I switch over.

## 1. Find the calls
Search for `api.deepgram.com` or `DEEPGRAM_API_KEY`. The request to replace is `POST https://api.deepgram.com/v1/speak`. 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: Deepgram sends the key in `Authorization: Token <key>` from `DEEPGRAM_API_KEY`. Replace it with `X-API-Key` from `CARTESIA_API_KEY` on the Cartesia path only, and keep `DEEPGRAM_API_KEY` for the Deepgram path. Deepgram also accepts a short-lived token sent as `Bearer`.
- Add `CARTESIA_API_KEY` wherever the project documents its environment (`.env.example`, README, deploy config). Never hardcode the key.
- Request size: Deepgram caps a request at 2,000 characters per request on Aura-2 and Aura-1. 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: Deepgram allows 15 concurrent REST requests on Pay as you go and Growth; 45 and 60 streaming. 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 Deepgram 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: aura-2-thalia-en (clear, energetic; customer service and IVR) → `f786b574-daa5-4673-aa0c-cbe3e8534c02` (Katie - Friendly Fixer); aura-2-andromeda-en (casual, expressive; customer service) → `9626c31c-bec5-4cca-baa8-f8ba9e84c8bc` (Jacqueline - Reassuring Agent); aura-2-apollo-en (confident, casual) → `86e30c1d-714b-4074-a1f2-1cb6b552fb49` (Carson - Curious Conversationalist); aura-2-orion-en (calm, polite; informative) → `47c38ca4-5f35-497b-b1a3-415245fb35e1` (Daniel - Modern Assistant).

## 3. Field mapping, Deepgram → Cartesia
- `POST https://api.deepgram.com/v1/speak` → `POST /tts/bytes`
- `Authorization: Token <key>` → `X-API-Key` and `Cartesia-Version: 2026-08-14`
- `model=aura-2-thalia-en` (model, voice and language in one name) → `model_id`: `sonic-3.6`, `voice`: `{"id": "<voice id>"}` and `language`: `en`. Split the name in three. The voice becomes an ID and the suffix becomes `language`.
- `text` in the JSON body (2,000 characters at most) → `transcript`
- `encoding`: `linear16`, `mulaw` or `alaw` → `output_format.encoding`: `pcm_s16le`, `pcm_mulaw` or `pcm_alaw`
- `container`: `wav` or `none` → `output_format.container`: `wav` or `raw`
- `encoding`: `mp3`, with `bit_rate` → `container`: `mp3`, with `bit_rate` and `sample_rate`. Deepgram fixes MP3 at 22050 Hz. Cartesia takes 8000 to 48000.
- `sample_rate` (default 24000) → `output_format.sample_rate`
- `speed` (0.7 to 1.5) → `generation_config.speed` (0.6 to 1.5)
- Inline IPA pronunciation objects in `text` → `pronunciation_dict_id` (one dictionary). Move each override into a Cartesia pronunciation dictionary and drop the inline objects from the text.
- `wss://api.deepgram.com/v1/speak` → TTS WebSocket. Set `add_timestamps` there to get word timings with each audio chunk.

## 4. Deepgram fields with no Cartesia equivalent
- `encoding`: `opus`, `flac` or `aac`. What to do: Request `mp3` or raw PCM and transcode.
- `callback` and `callback_method`. What to do: Call `/tts/bytes` from a background worker and post the audio to your own webhook.
- `tag`, `mip_opt_out`. What to do: Drop them. Keep your own request log if you used `tag` for reporting.

## 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 = "You're booked for Tuesday at 3 p.m. Press 1 to confirm or 2 to reschedule."
VOICE_ID = "f786b574-daa5-4673-aa0c-cbe3e8534c02"  # 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_mulaw",
            "sample_rate": 8000,
        },
    },
)
response.raise_for_status()
open("out.ulaw", "wb").write(response.content)
```

## 6. Roll out
1. Choose Deepgram or Cartesia per request from one config flag, defaulting to Deepgram.
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 Deepgram 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
- Deepgram speak request reference: https://developers.deepgram.com/reference/text-to-speech/speak-request
- Deepgram text-to-speech docs: https://developers.deepgram.com/docs/text-to-speech
- Deepgram TTS voice controls: https://developers.deepgram.com/docs/tts-voice-controls
- Deepgram TTS models: https://developers.deepgram.com/docs/tts-models
- 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

When you're done, tell me which files changed, which fields you couldn't map, and how to flip the flag.

Every Deepgram field, mapped to Cartesia

The prompt carries this table. Each row is a field in your Deepgram request and the Cartesia field that replaces it.

  1. Deepgram

    POST https://api.deepgram.com/v1/speak

    Cartesia
    POST /tts/bytes
  2. Deepgram

    Authorization: Token <key>

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

    model=aura-2-thalia-en (model, voice and language in one name)

    Cartesia
    model_id: sonic-3.6, voice: {"id": "<voice id>"} and language: en
    Note
    Split the name in three. The voice becomes an ID and the suffix becomes language.
  4. Deepgram

    text in the JSON body (2,000 characters at most)

    Cartesia
    transcript
  5. Deepgram

    encoding: linear16, mulaw or alaw

    Cartesia
    output_format.encoding: pcm_s16le, pcm_mulaw or pcm_alaw
  6. Deepgram

    container: wav or none

    Cartesia
    output_format.container: wav or raw
  7. Deepgram

    encoding: mp3, with bit_rate

    Cartesia
    container: mp3, with bit_rate and sample_rate
    Note
    Deepgram fixes MP3 at 22050 Hz. Cartesia takes 8000 to 48000.
  8. Deepgram

    sample_rate (default 24000)

    Cartesia
    output_format.sample_rate
  9. Deepgram

    speed (0.7 to 1.5)

    Cartesia
    generation_config.speed (0.6 to 1.5)
  10. Deepgram

    Inline IPA pronunciation objects in text

    Cartesia
    pronunciation_dict_id (one dictionary)
    Note
    Move each override into a Cartesia pronunciation dictionary and drop the inline objects from the text.
  11. Deepgram

    wss://api.deepgram.com/v1/speak

    Cartesia
    TTS WebSocket
    Note
    Set add_timestamps there to get word timings with each audio chunk.

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

    Authorization: Token <key>

    Cartesia
    X-API-Key plus Cartesia-Version: 2026-08-14
    Note
    Deepgram also accepts a short-lived token sent as Bearer.
  2. Deepgram

    DEEPGRAM_API_KEY

    Cartesia
    CARTESIA_API_KEY

Deepgram 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

    Aura-2, Pay as you go

    Deepgram
    $0.030
  2. Model or plan

    Aura-2, Growth

    Deepgram
    $0.027
    Note
    Growth starts at $4,000 a year
  3. Model or plan

    Aura-1, Pay as you go

    Deepgram
    $0.015

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.

Deepgram 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)
    Deepgram
    $200 in credit, no card needed, and it doesn't expire
  2. Limit

    Request limit

    Cartesia
    No published maximum; stream long text over the TTS WebSocket
    Deepgram
    2,000 characters per request on Aura-2 and Aura-1
  3. Limit

    Voices

    Cartesia
    1,022 voices in the library, plus instant clones
    Deepgram
    90 Aura-2 voices
  4. Limit

    Languages

    Cartesia
    44 languages for text to speech
    Deepgram
    7 languages on Aura-2

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 Deepgram call is gone.

No 2,000-character ceiling to split around

Aura-2 rejects text over 2,000 characters with a 413. Cartesia publishes no maximum for /tts/bytes; for long passages, stream the text over the TTS WebSocket.

Languages beyond Aura-2's seven

Aura-2 voices cover 7 languages, and speed and pronunciation controls work in English and Spanish only. Sonic 3.6 speaks 44, each set with the language field.

Emotion and volume per request

Aura-2's voice controls are speed and pronunciation. Cartesia adds generation_config.emotion and volume (0.5 to 2.0) on each call.

How to migrate from Deepgram to Cartesia

The same changes the prompt makes, if you'd rather make them yourself.

  1. Create a Cartesia API key and keep it in CARTESIA_API_KEY beside DEEPGRAM_API_KEY.

  2. List every aura-2-* model name you send. For each one, pick a library voice in the same language and role, using the pairs below as a start.

  3. Move the query parameters into the body as in the code above. Keep the same encoding and sample rate so your telephony or playback code doesn't change.

  4. If you call the Deepgram TTS WebSocket, move that path to Cartesia's TTS WebSocket.

  5. Ship behind a flag on a share of calls, then remove the Aura-2 request once Cartesia carries all of them.

Frequently asked questions

How much does Deepgram TTS cost?

Deepgram's pricing page lists Aura-2 at $0.030 per 1,000 characters on Pay as you go and $0.027 on Growth, and Aura-1 at $0.015. Cartesia's plans and volume pricing are on /pricing.

Is the Deepgram API free?

New Deepgram accounts get $200 of credit with no card required, and Deepgram says it doesn't expire. After that, usage bills at the Pay as you go rates. Cartesia's Free plan includes 20,000 credits a month, about 20,000 characters.

Can I move Deepgram Nova-3 transcription to Cartesia too?

Yes, as a separate step. Cartesia's Ink Whisper transcribes recorded files in about 100 languages, and Ink-2 handles live audio in English, Spanish, French, Hindi and Japanese. Cartesia's batch API has no speaker diarization, so keep Nova-3 for calls where you need speaker labels. Start with the Cartesia STT docs.

What doesn't carry over from Aura-2?

Opus, FLAC and AAC output, the callback webhook, tag and mip_opt_out. Voice names don't map. Aura-2's inline IPA overrides move into a Cartesia pronunciation dictionary, one per request.

Can I fall back to Deepgram if a call goes wrong?

Keep both clients and pick one per call from a flag. Because the two produce the same mu-law bytes at 8 kHz in the example above, your phone stack doesn't care which one answered, so flipping a voice back to Aura-2 is a config change.

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