Migration guides / 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.
Prompt
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.

- Amazon Polly
SynthesizeSpeechthrough boto3, signed with AWS credentialsCartesiaPOST /tts/byteswithX-API-KeyandCartesia-Version: 2026-08-14NoteOne API key replaces the IAM policy and request signing. - Amazon Polly
Text, withTextType: ssmlfor markupCartesiatranscriptNote<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. - Amazon Polly
VoiceId, such asJoannaCartesiavoice:{"id": "<voice id>"} - Amazon Polly
Engine:standard,neural,long-formorgenerativeCartesiamodel_id:sonic-3.6NoteEvery Cartesia voice runs on the same model, so there is no engine to pick per voice. - Amazon Polly
LanguageCode, such asen-USCartesialanguage:enoren-USNotePolly reads it only for bilingual voices. Cartesia wants it on every request. - Amazon Polly
OutputFormat:mp3,pcm,mulaworalawCartesiaoutput_format.containerandencodingNotemp3is themp3container.pcmisrawwithpcm_s16le,mulawispcm_mulawandalawispcm_alaw. - Amazon Polly
SampleRateCartesiaoutput_format.sample_rateNoteAny rate from 8000 to 48000 Hz. - Amazon Polly
OutputFormat: jsonwithSpeechMarkTypes(word,sentence,viseme,ssml)Cartesiaadd_timestampson the TTS WebSocketNoteThe WebSocket returns word timestamps, and phoneme timestamps withadd_phoneme_timestamps./tts/bytesreturns neither, and Cartesia has no sentence, viseme or SSML marks. - Amazon Polly
LexiconNames, up to 5 per requestCartesiapronunciation_dict_id, one per requestNoteMerge the lexicons you stack today into a single dictionary. - Amazon Polly
StartSpeechSynthesisStream(generative engine)CartesiaThe TTS WebSocketNoteSend 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.

- Amazon Polly
AWS Signature Version 4, which boto3 signs for you
CartesiaX-API-KeyplusCartesia-Version: 2026-08-14Noteboto3 also readsAWS_SECRET_ACCESS_KEYor an attached role, and the IAM policy has to allow eachpolly:action you call. Cartesia needs only the key. - Amazon Polly
AWS_ACCESS_KEY_IDCartesiaCARTESIA_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.
Per 1,000 characters- Model or plan
Polly Standard voices
Amazon Polly$0.004Note$4 per million characters; 5 million characters a month free - Model or plan
Polly Neural voices
Amazon Polly$0.016Note$16 per million; 1 million characters a month free for the first 12 months - Model or plan
Polly Generative voices
Amazon Polly$0.030Note$30 per million; 100,000 characters a month free for the first 12 months - Model or plan
Polly Long-Form voices
Amazon Polly$0.100Note$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 pricingSources
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.

- Limit
Free tier
Cartesia20,000 credits a month on the Free plan (about 20,000 characters)Amazon Polly5 million Standard characters a month, plus 1 million Neural characters a month for your first 12 months - Limit
Request limit
CartesiaNo published maximum; stream long text over the TTS WebSocketAmazon Polly3,000 billed characters (6,000 in total) per SynthesizeSpeech call; 100,000 billed through StartSpeechSynthesisTask - Limit
Languages
Cartesia44 languages for text to speechAmazon Polly42 languages and variants across all engines; 36 with Neural voices
Cartesia's figures come from its pricing page and voice library.
Cartesia pricing and plan limitsSources
- Amazon Polly pricing and free tieraws.amazon.com
- Amazon Polly quotasdocs.aws.amazon.com
- Amazon Polly available voicesdocs.aws.amazon.com
- Amazon Polly neural voicesdocs.aws.amazon.com
Limits read from each company's documentation in November 2026.
Amazon Polly voices and where to start on Cartesia
AWS Polly voices are named per language and engine, such as Joanna and Matthew for US English or Amy and Brian for British English.
Each card is a starting point for a common Amazon Polly pick, matched by language and use. Listen before you choose.
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.
Create a Cartesia API key and keep it in the secret store that holds the Polly role's credentials today.
Cast a Cartesia voice for each Polly voice and language from the voice library. Names such as
Joannadon't exist on Cartesia.Replace the boto3 call with the request above. Cut the SSML down to
<break>tags and fold your lexicons into one pronunciation dictionary.Set
output_formatto what your player expects. Pollypcmis 16-bit mono little-endian, which Cartesia callspcm_s16lein arawcontainer.If captions or lip sync read Polly speech marks, move that code to the WebSocket and its
add_timestampsevents.
Sources
Request shapes checked against vendor documentation in November 2026.
Compare and read next
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.
Start building.
Create an API key, then hand your coding agent the migration prompt and a few of your own scripts.
