Amazon Polly

Migrate Amazon Polly SynthesizeSpeech to Cartesia

Every SynthesizeSpeech parameter has a row below, with the boto3 call and its Cartesia /tts/bytes replacement side by side.

Migrate from Amazon Polly with your coding agent

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

10 fields mapped, with a rollback plan

Prompt

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

## 1. Find the calls
Search for `boto3`. The request to replace is `SynthesizeSpeech` through boto3, signed with AWS credentials. 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: Amazon Polly sends the key in AWS Signature Version 4, which boto3 signs for you from `AWS_ACCESS_KEY_ID`. Replace it with `X-API-Key` from `CARTESIA_API_KEY` on the Cartesia path only, and keep `AWS_ACCESS_KEY_ID` for the Amazon Polly path. boto3 also reads `AWS_SECRET_ACCESS_KEY` or an attached role, and the IAM policy has to allow each `polly:` action you call. Cartesia needs only the key.
- Add `CARTESIA_API_KEY` wherever the project documents its environment (`.env.example`, README, deploy config). Never hardcode the key.
- Request size: Amazon Polly caps a request at 3,000 billed characters (6,000 in total) per SynthesizeSpeech call; 100,000 billed through StartSpeechSynthesisTask. 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: Amazon Polly allows Neural: 8 requests a second, burst 10, up to 18 at once. Standard: 80 a second and 80 at once. Generative and long-form: 26 at once. 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 Amazon Polly 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: Joanna (US English, female) → `db6b0ed5-d5d3-463d-ae85-518a07d3c2b4` (Skylar - Friendly Guide); Matthew (US English, male) → `47c38ca4-5f35-497b-b1a3-415245fb35e1` (Daniel - Modern Assistant); Amy (British English, female) → `62ae83ad-4f6a-430b-af41-a9bede9286ca` (Gemma - Decisive Agent); Brian (British English, male) → `4bc3cb8c-adb9-4bb8-b5d5-cbbef950b991` (George - Composed Consultant).

## 3. Field mapping, Amazon Polly → Cartesia
- `SynthesizeSpeech` through boto3, signed with AWS credentials → `POST /tts/bytes` with `X-API-Key` and `Cartesia-Version: 2026-08-14`. One API key replaces the IAM policy and request signing.
- `Text`, with `TextType: ssml` for markup → `transcript`. `<break time="1s"/>` works as written, and Cartesia needs no `<speak>` wrapper. `<prosody>`, `<say-as>`, `<phoneme>` and `<mark>` have no effect; [SSML tags](https://docs.cartesia.ai/build-with-cartesia/capability-guides/ssml-tags) lists the five Cartesia reads.
- `VoiceId`, such as `Joanna` → `voice`: `{"id": "<voice id>"}`
- `Engine`: `standard`, `neural`, `long-form` or `generative` → `model_id`: `sonic-3.6`. Every Cartesia voice runs on the same model, so there is no engine to pick per voice.
- `LanguageCode`, such as `en-US` → `language`: `en` or `en-US`. Polly reads it only for bilingual voices. Cartesia wants it on every request.
- `OutputFormat`: `mp3`, `pcm`, `mulaw` or `alaw` → `output_format.container` and `encoding`. `mp3` is the `mp3` container. `pcm` is `raw` with `pcm_s16le`, `mulaw` is `pcm_mulaw` and `alaw` is `pcm_alaw`.
- `SampleRate` → `output_format.sample_rate`. Any rate from 8000 to 48000 Hz.
- `OutputFormat: json` with `SpeechMarkTypes` (`word`, `sentence`, `viseme`, `ssml`) → `add_timestamps` on the TTS WebSocket. The WebSocket returns word timestamps, and phoneme timestamps with `add_phoneme_timestamps`. `/tts/bytes` returns neither, and Cartesia has no sentence, viseme or SSML marks.
- `LexiconNames`, up to 5 per request → `pronunciation_dict_id`, one per request. Merge the lexicons you stack today into a single dictionary.
- `StartSpeechSynthesisStream` (generative engine) → The TTS WebSocket. Send text as it arrives and read audio chunks back; the [WebSocket reference](https://docs.cartesia.ai/api-reference/tts/websocket) has the message format.

## 4. Amazon Polly fields with no Cartesia equivalent
- `OutputFormat`: `ogg_vorbis` or `ogg_opus`. What to do: Ask for `mp3` or raw PCM and encode Ogg yourself.

## 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 = "Your package will arrive between two and four this afternoon."
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 Amazon Polly or Cartesia per request from one config flag, defaulting to Amazon Polly.
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 Amazon Polly 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
- Amazon Polly SynthesizeSpeech reference: https://docs.aws.amazon.com/polly/latest/dg/API_SynthesizeSpeech.html
- Amazon Polly StartSpeechSynthesisStream reference: https://docs.aws.amazon.com/polly/latest/dg/API_StartSpeechSynthesisStream.html
- Cartesia TTS bytes API reference: https://docs.cartesia.ai/api-reference/tts/bytes
- Cartesia SSML tags: https://docs.cartesia.ai/build-with-cartesia/capability-guides/ssml-tags
- Amazon Polly quotas: https://docs.aws.amazon.com/polly/latest/dg/limits.html

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

Every Amazon Polly field, mapped to Cartesia

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

  1. Amazon Polly

    SynthesizeSpeech through boto3, signed with AWS credentials

    Cartesia
    POST /tts/bytes with X-API-Key and Cartesia-Version: 2026-08-14
    Note
    One API key replaces the IAM policy and request signing.
  2. Amazon Polly

    Text, with TextType: ssml for markup

    Cartesia
    transcript
    Note
    <break time="1s"/> works as written, and Cartesia needs no <speak> wrapper. <prosody>, <say-as>, <phoneme> and <mark> have no effect; SSML tags lists the five Cartesia reads.
  3. Amazon Polly

    VoiceId, such as Joanna

    Cartesia
    voice: {"id": "<voice id>"}
  4. Amazon Polly

    Engine: standard, neural, long-form or generative

    Cartesia
    model_id: sonic-3.6
    Note
    Every Cartesia voice runs on the same model, so there is no engine to pick per voice.
  5. Amazon Polly

    LanguageCode, such as en-US

    Cartesia
    language: en or en-US
    Note
    Polly reads it only for bilingual voices. Cartesia wants it on every request.
  6. Amazon Polly

    OutputFormat: mp3, pcm, mulaw or alaw

    Cartesia
    output_format.container and encoding
    Note
    mp3 is the mp3 container. pcm is raw with pcm_s16le, mulaw is pcm_mulaw and alaw is pcm_alaw.
  7. Amazon Polly

    SampleRate

    Cartesia
    output_format.sample_rate
    Note
    Any rate from 8000 to 48000 Hz.
  8. Amazon Polly

    OutputFormat: json with SpeechMarkTypes (word, sentence, viseme, ssml)

    Cartesia
    add_timestamps on the TTS WebSocket
    Note
    The WebSocket returns word timestamps, and phoneme timestamps with add_phoneme_timestamps. /tts/bytes returns neither, and Cartesia has no sentence, viseme or SSML marks.
  9. Amazon Polly

    LexiconNames, up to 5 per request

    Cartesia
    pronunciation_dict_id, one per request
    Note
    Merge the lexicons you stack today into a single dictionary.
  10. Amazon Polly

    StartSpeechSynthesisStream (generative engine)

    Cartesia
    The TTS WebSocket
    Note
    Send text as it arrives and read audio chunks back; the WebSocket reference has the message format.

Amazon Polly 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. Amazon Polly

    AWS Signature Version 4, which boto3 signs for you

    Cartesia
    X-API-Key plus Cartesia-Version: 2026-08-14
    Note
    boto3 also reads AWS_SECRET_ACCESS_KEY or an attached role, and the IAM policy has to allow each polly: action you call. Cartesia needs only the key.
  2. Amazon Polly

    AWS_ACCESS_KEY_ID

    Cartesia
    CARTESIA_API_KEY

Amazon Polly 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

    Polly Standard voices

    Amazon Polly
    $0.004
    Note
    $4 per million characters; 5 million characters a month free
  2. Model or plan

    Polly Neural voices

    Amazon Polly
    $0.016
    Note
    $16 per million; 1 million characters a month free for the first 12 months
  3. Model or plan

    Polly Generative voices

    Amazon Polly
    $0.030
    Note
    $30 per million; 100,000 characters a month free for the first 12 months
  4. Model or plan

    Polly Long-Form voices

    Amazon Polly
    $0.100
    Note
    $100 per million; 500,000 characters a month free for the first 12 months

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.

Amazon Polly 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)
    Amazon Polly
    5 million Standard characters a month, plus 1 million Neural characters a month for your first 12 months
  2. Limit

    Request limit

    Cartesia
    No published maximum; stream long text over the TTS WebSocket
    Amazon Polly
    3,000 billed characters (6,000 in total) per SynthesizeSpeech call; 100,000 billed through StartSpeechSynthesisTask
  3. Limit

    Languages

    Cartesia
    44 languages for text to speech
    Amazon Polly
    42 languages and variants across all engines; 36 with Neural voices

What you get on Cartesia

What changes once the Amazon Polly call is gone.

Speed, volume and emotion as request fields

generation_config takes speed from 0.6 to 1.5, volume from 0.5 to 2.0 and an emotion such as calm, on sonic-3 and newer. On Polly these live in SSML <prosody> tags.

Your own voice from a short recording

An instant clone needs 10 seconds of audio you have permission to use, on the Pro plan and up. A professional clone needs 30 minutes, on the Startup plan and up, and ignores speed and volume at request time.

How to migrate from Amazon Polly 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 the secret store that holds the Polly role's credentials today.

  2. Cast a Cartesia voice for each Polly voice and language from the voice library. Names such as Joanna don't exist on Cartesia.

  3. Replace the boto3 call with the request above. Cut the SSML down to <break> tags and fold your lexicons into one pronunciation dictionary.

  4. Set output_format to what your player expects. Polly pcm is 16-bit mono little-endian, which Cartesia calls pcm_s16le in a raw container.

  5. If captions or lip sync read Polly speech marks, move that code to the WebSocket and its add_timestamps events.

Frequently asked questions

Is Amazon Polly free?

Partly. The Polly free tier covers 5 million Standard characters a month, and for the first 12 months 1 million Neural, 500,000 Long-Form and 100,000 Generative characters a month. AWS accounts opened since July 15, 2025 get up to $200 in Free Tier credits, which also apply to Polly. Cartesia's Free plan gives 20,000 credits a month, about 20,000 characters.

Do Amazon Polly alternatives mean leaving AWS?

Not with Cartesia. It is listed on AWS Marketplace and available through Amazon SageMaker; see Cartesia on AWS.

Which Cartesia model matches Polly Neural or Generative?

All of them map to one model_id, currently sonic-3.6. Pick the voice, set the model, and the engine question goes away.

What happens to my Polly lexicons?

Copy the entries from every lexicon you pass into one Cartesia pronunciation dictionary and send its ID as pronunciation_dict_id. Dictionaries work on sonic-3 and newer.

What doesn't carry over?

Most SSML (<prosody>, <say-as>, <phoneme>, <mark>), Ogg output, sentence and viseme speech marks, and stacking several lexicons on one request. Word timestamps carry over, but only on the WebSocket. Cartesia has no pitch control, so cast a voice that already sits at the pitch you want.

Can I keep Polly as a fallback?

Yes. Send synthesis through one function with a flag per voice or per tenant, start Cartesia on a small share of traffic, and flip the flag back if a listening check fails. Keep the Polly IAM role until the last tenant has moved.

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