Migration guides / OpenAI TTS
Migrate the OpenAI TTS API to Cartesia
Moving a POST /v1/audio/speech call to Cartesia's POST /tts/bytes changes about ten lines of Python.
Why migrate from OpenAI TTS now
Dated changes on the OpenAI TTS side, each linked to the page that announces it.
OpenAI deprecates its text-to-speech models
OpenAI's deprecation notice marks tts-1, tts-1-hd and every gpt-4o-mini-tts snapshot as deprecated, with at least three months' notice before removal.
tts-1, tts-1-hd and gpt-4o-mini-tts shut down
The named replacement, gpt-realtime-2.1-mini, runs only on the Realtime API and isn't a supported model for /v1/audio/speech. Staying on OpenAI means rebuilding speech output around a realtime session.
Migrate from OpenAI TTS with your coding agent
Paste this into Claude Code, Cursor or Codex in the repo that calls OpenAI TTS. It carries the field mapping, the Cartesia request and a rollout that keeps OpenAI TTS behind a flag until you switch.
Prompt
Move this codebase from OpenAI TTS to Cartesia for text to speech. Keep OpenAI TTS working behind a flag until I switch over.
Deadline (Shutdown announced): January 6, 2027. OpenAI's text-to-speech guide gives January 6, 2027 as the shutdown date for `tts-1`, `tts-1-hd` and `gpt-4o-mini-tts`, including its `2025-03-20` and `2025-12-15` snapshots. Existing Speech API integrations keep working until that day.
October 1, 2026: OpenAI deprecates its text-to-speech models. OpenAI's deprecation notice marks `tts-1`, `tts-1-hd` and every `gpt-4o-mini-tts` snapshot as deprecated, with at least three months' notice before removal. (https://developers.openai.com/api/docs/deprecations#2026-10-01-text-to-speech-models)
## 1. Find the calls
Search for `api.openai.com` or `OPENAI_API_KEY`. The request to replace is `POST /v1/audio/speech`. 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: OpenAI TTS sends the key in `Authorization: Bearer` header from `OPENAI_API_KEY`. Replace it with `X-API-Key` from `CARTESIA_API_KEY` on the Cartesia path only, and keep `OPENAI_API_KEY` for the OpenAI TTS path.
- Add `CARTESIA_API_KEY` wherever the project documents its environment (`.env.example`, README, deploy config). Never hardcode the key.
- Request size: OpenAI TTS caps a request at 4,096 characters of `input` per request. 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.
- Voice IDs don't carry over. Keep each voice ID in one named constant or config value, put a placeholder where each OpenAI TTS 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: `marin` or `cedar` on a support assistant → `f786b574-daa5-4673-aa0c-cbe3e8534c02` (Katie - Friendly Fixer); Order, delivery and account notifications → `25d7abcb-4d6d-4aca-adce-8a1c85620c8b` (Jessica - Clear Communicator); An in-app digital assistant → `47c38ca4-5f35-497b-b1a3-415245fb35e1` (Daniel - Modern Assistant); Read-aloud for articles and long posts → `98a34ef2-2140-4c28-9c71-663dc4dd7022` (Clyde - Calm Narrator).
## 3. Field mapping, OpenAI TTS → Cartesia
- `POST /v1/audio/speech` → `POST /tts/bytes`. Use the WebSocket when you need audio before the text is complete.
- `Authorization: Bearer $OPENAI_API_KEY` → `X-API-Key` and `Cartesia-Version: 2026-08-14`. Requests without the version header fail.
- `model`: `gpt-4o-mini-tts`, `tts-1`, `tts-1-hd` → `model_id`: `sonic-3.6`
- `input` (up to 4,096 characters) → `transcript`
- `voice`: a built-in name such as `marin`, or a custom voice `{"id": "voice_..."}` → `voice`: `{"id": "<voice id>"}`. OpenAI's built-in names and custom `voice_...` IDs both stay on OpenAI. Pick a library voice, or clone again from the consented source recording.
- `instructions`: free-text style guidance → `generation_config`: `emotion`, `speed`, `volume`. Structured fields take the place of the prompt. Rewrite each instruction as an emotion and a speed, then listen.
- `speed`: 0.25 to 4.0 → `generation_config.speed`: 0.6 to 1.5. Clamp anything outside 0.6 to 1.5, since Cartesia has no setting for it.
- `response_format`: `mp3`, `wav`, `pcm` → `output_format`: a `container` of `mp3`, `wav` or `raw`, plus `encoding` and `sample_rate`. OpenAI's `pcm` is 24 kHz `pcm_s16le`. Set `raw`, `pcm_s16le` and `24000` to match it byte for byte.
- `stream_format`: `sse` or `audio` → TTS WebSocket. `/tts/bytes` streams the response body as it generates. The WebSocket also accepts text in pieces.
## 4. OpenAI TTS fields with no Cartesia equivalent
- `response_format`: `opus`, `aac`, `flac`. What to do: Request `mp3` or raw PCM and transcode to the container you need.
## 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 order has shipped and should arrive on Thursday."
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": "wav",
"encoding": "pcm_s16le",
"sample_rate": 44100,
},
},
)
response.raise_for_status()
open("out.wav", "wb").write(response.content)
```
## 6. Roll out
1. Choose OpenAI TTS or Cartesia per request from one config flag, defaulting to OpenAI TTS.
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 OpenAI TTS 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
- OpenAI text-to-speech guide: https://developers.openai.com/api/docs/guides/text-to-speech
- OpenAI deprecations: https://developers.openai.com/api/docs/deprecations
- OpenAI create speech API reference: https://developers.openai.com/api/reference/resources/audio/subresources/speech/methods/create
- 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 OpenAI TTS field, mapped to Cartesia
The prompt carries this table. Each row is a field in your OpenAI TTS request and the Cartesia field that replaces it.
- OpenAI TTS
POST /v1/audio/speechCartesiaPOST /tts/bytesNoteUse the WebSocket when you need audio before the text is complete. - OpenAI TTS
Authorization: Bearer $OPENAI_API_KEYCartesiaX-API-KeyandCartesia-Version: 2026-08-14NoteRequests without the version header fail. - OpenAI TTS
model:gpt-4o-mini-tts,tts-1,tts-1-hdCartesiamodel_id:sonic-3.6 - OpenAI TTS
input(up to 4,096 characters)Cartesiatranscript - OpenAI TTS
voice: a built-in name such asmarin, or a custom voice{"id": "voice_..."}Cartesiavoice:{"id": "<voice id>"}NoteOpenAI's built-in names and customvoice_...IDs both stay on OpenAI. Pick a library voice, or clone again from the consented source recording. - OpenAI TTS
instructions: free-text style guidanceCartesiageneration_config:emotion,speed,volumeNoteStructured fields take the place of the prompt. Rewrite each instruction as an emotion and a speed, then listen. - OpenAI TTS
speed: 0.25 to 4.0Cartesiageneration_config.speed: 0.6 to 1.5NoteClamp anything outside 0.6 to 1.5, since Cartesia has no setting for it. - OpenAI TTS
response_format:mp3,wav,pcmCartesiaoutput_format: acontainerofmp3,wavorraw, plusencodingandsample_rateNoteOpenAI'spcmis 24 kHzpcm_s16le. Setraw,pcm_s16leand24000to match it byte for byte. - OpenAI TTS
stream_format:sseoraudioCartesiaTTS WebSocketNote/tts/bytesstreams the response body as it generates. The WebSocket also accepts text in pieces.
OpenAI TTS 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.
- OpenAI TTS
Authorization: BearerheaderCartesiaX-API-KeyplusCartesia-Version: 2026-08-14 - OpenAI TTS
OPENAI_API_KEYCartesiaCARTESIA_API_KEY
OpenAI TTS 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
tts-1
OpenAI TTS$0.015Note$15 per million characters; shuts down January 6, 2027 - Model or plan
tts-1-hd
OpenAI TTS$0.03Note$30 per million characters; shuts down January 6, 2027 - Model or plan
gpt-4o-mini-tts
OpenAI TTSNot publishedNoteBilled per token, $0.60 per million text input tokens and $12 per million audio output tokens. OpenAI lists no per-character rate.
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.
OpenAI TTS limits compared with Cartesia
Published limits from both companies. Plans change them, so check both pages before you size a rollout.
- Limit
Request limit
CartesiaNo published maximum; stream long text over the TTS WebSocketOpenAI TTS4,096 characters ofinputper request - Limit
Voices
Cartesia1,022 voices in the library, plus instant clonesOpenAI TTS13 built-in voices ongpt-4o-mini-ttsand 9 ontts-1andtts-1-hd, plus custom voices made through OpenAI's consent flow - Limit
Languages
Cartesia44 languages for text to speechOpenAI TTSFollows Whisper's language list; OpenAI says its voices are optimized for English
Cartesia's figures come from its pricing page and voice library.
Cartesia pricing and plan limitsSources
- OpenAI create speech API referencedevelopers.openai.com
- OpenAI text-to-speech guidedevelopers.openai.com
Limits read from each company's documentation in November 2026.
OpenAI TTS voices and where to start on Cartesia
13 built-in voices by name: alloy, ash, ballad, coral, echo, fable, nova, onyx, sage, shimmer, verse, marin and cedar. OpenAI recommends marin or cedar for quality, and tts-1 takes only 9 of the 13.
Each card is a starting point for a common OpenAI TTS pick, matched by language and use. Listen before you choose.
What you get on Cartesia
What changes once the OpenAI TTS call is gone.
A TTS endpoint that stays a TTS endpoint
/tts/bytes takes text and returns audio, the same shape as /v1/audio/speech. Keeping speech output does not mean rebuilding around a realtime session.
Phone-ready output formats
output_format accepts pcm_mulaw and pcm_alaw at 8000 Hz, so audio for a phone line skips a conversion step on your side.
Word timestamps over the WebSocket
Set add_timestamps on the TTS WebSocket and each audio chunk arrives with its words and their start and end times. /v1/audio/speech returns audio only.
How to migrate from OpenAI TTS to Cartesia
The same changes the prompt makes, if you'd rather make them yourself.
Create a Cartesia API key and store it in
CARTESIA_API_KEY.Choose a voice in the voice library and copy its ID. Run your three hardest scripts through it before you touch the code.
Swap the endpoint, headers and body as shown above, and turn each
instructionsstring you send today into anemotionand aspeed.Match the audio format your player or phone line expects. Raw PCM has no header, so declare the same
encodingandsample_rateon playback.Ship behind a flag for a share of traffic, then delete the OpenAI call.
Sources
Sources
Request shapes checked against vendor documentation in November 2026.
Compare and read next
Frequently asked questions
How much does OpenAI TTS cost?
OpenAI TTS pricing depends on the model. tts-1 costs $15 per million characters and tts-1-hd costs $30. gpt-4o-mini-tts bills by token, $0.60 per million text tokens in and $12 per million audio tokens out, so OpenAI publishes no per-character rate for it. All three stop working on January 6, 2027.
What replaces tts-1?
OpenAI points tts-1, tts-1-hd and gpt-4o-mini-tts users to gpt-realtime-2.1-mini, which runs on the Realtime API and not on /v1/audio/speech. On Cartesia, /tts/bytes keeps the plain request that returns audio, and the WebSocket is there when you want text in and audio out during a live call.
When does the OpenAI text to speech API shut down?
January 6, 2027, for tts-1, tts-1-hd and both gpt-4o-mini-tts snapshots. OpenAI's deprecations page carries the current notice. Whatever OpenAI TTS alternative you choose has to be serving production traffic by then.
Can I keep my OpenAI voice?
No. Built-in voices such as marin exist only on OpenAI's API, and a custom voice from OpenAI's consent flow keeps a voice_... ID no other vendor reads. On Cartesia you pick a voice ID from the voice library, or clone a voice from the recording behind your OpenAI custom voice. Instant clones need 10 seconds of audio and a Pro plan or higher.
What doesn't carry over from OpenAI TTS?
Free-text instructions become a fixed set of emotion, speed and volume controls, so a prompt like "sound like a sports announcer" has no direct match. speed narrows from 0.25 to 4.0 down to 0.6 to 1.5. Opus, AAC and FLAC output are gone, so transcode from MP3 or PCM. Cartesia has no pitch control.
Can I run OpenAI and Cartesia side by side before the shutdown?
Yes, until January 6, 2027. Put both request builders behind one interface and send a percentage of synthesis calls to Cartesia from a feature flag. Rolling back means setting that percentage to zero. Delete the OpenAI path once it gets no traffic.
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.