Migration guides / AssemblyAI
AssemblyAI alternative: migrate speech to text to Cartesia
Replace the AssemblyAI API's submit-and-poll loop with one Cartesia batch call that sends the file and gets the transcript back in the same response.
Migrate from AssemblyAI with your coding agent
Paste this into Claude Code, Cursor or Codex in the repo that calls AssemblyAI. It carries the field mapping, the Cartesia request and a rollout that keeps AssemblyAI behind a flag until you switch.
Prompt
Move this codebase from AssemblyAI to Cartesia for speech to text. Keep AssemblyAI working behind a flag until I switch over.
## 1. Find the calls
Search for `api.assemblyai.com` or `ASSEMBLYAI_API_KEY`. The request to replace is `POST /v2/transcript`, then poll for `completed` or receive a webhook. List every call site before you edit anything.
## 2. Target
- Recorded files: `client.stt.transcribe(...)` in the `cartesia` SDK, or `POST https://api.cartesia.ai/stt`, with `model: "ink-whisper"`
- Live audio: `ink-2` over the STT WebSocket
- Headers: `X-API-Key` read from the `CARTESIA_API_KEY` environment variable, and `Cartesia-Version: 2026-08-14`
- Auth swap: AssemblyAI sends the key in `authorization` header holding the raw API key from `ASSEMBLYAI_API_KEY`. Replace it with `X-API-Key` from `CARTESIA_API_KEY` on the Cartesia path only, and keep `ASSEMBLYAI_API_KEY` for the AssemblyAI path. AssemblyAI takes the key with no `Bearer` prefix. Cartesia's SDK reads it from the client constructor and sends `X-API-Key` for you.
- Add `CARTESIA_API_KEY` wherever the project documents its environment (`.env.example`, README, deploy config). Never hardcode the key.
- Concurrency: AssemblyAI allows Pre-recorded: 5 parallel transcriptions on Free, 200+ on paid, with extra jobs queued. Streaming: 5 new sessions a minute on Free, 200 on paid. 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.
- Always pass `language`. Cartesia's batch call doesn't detect it and assumes `en`.
## 3. Field mapping, AssemblyAI → Cartesia
- `POST /v2/transcript`, then poll for `completed` or receive a webhook → `client.stt.transcribe(...)`, one call
- `authorization` header with the raw key → `Cartesia(api_key=...)`
- `audio_url`: a public URL or one from `/v2/upload` → `file`: an open binary file. Cartesia takes no URL input. Download audio that sits behind a URL and send the bytes.
- `speech_models` → `model`: `ink-whisper` for files, `ink-2` for live audio
- `language_code` → `language`. AssemblyAI detects the language when you leave it out. Cartesia batch assumes `en`, so set `language` on every request.
## 4. AssemblyAI fields with no Cartesia equivalent
- `keyterms_prompt`. What to do: Cartesia takes keyterms, up to 100, only on the Ink-2 WebSocket. `ink-whisper` batch has no keyterm parameter.
- `speaker_labels`. What to do: Cartesia returns no speaker labels on batch or streaming. If your product splits speakers, keep a separate diarization step.
- `prompt`. What to do: The batch call has no free-text prompt for steering formatting or style.
- `domain`: `medical-v1`. What to do: Cartesia has no medical mode. Transcribe your clinical recordings on both and compare word error rate before you move them.
- `webhook_url`. What to do: The transcript comes back in the response, so there is no job to be notified about. Call it from a worker if your request path can't wait on long files.
## 5. Reference request
Match the language and HTTP client the codebase already uses. This is the same request in Python:
```python
import os
from cartesia import Cartesia
client = Cartesia(api_key=os.environ["CARTESIA_API_KEY"])
with open("call.wav", "rb") as audio_file:
result = client.stt.transcribe(
file=audio_file,
model="ink-whisper",
language="en",
timestamp_granularities=["word"],
)
print(result.text)
```
## 6. Roll out
1. Choose AssemblyAI or Cartesia per request from one config flag, defaulting to AssemblyAI.
2. Transcribe the same recordings with both and save the transcripts side by side. Compare the words, the word timestamps and the language on each.
3. Leave the AssemblyAI 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
- AssemblyAI submit transcript reference: https://www.assemblyai.com/docs/api-reference/transcripts/submit
- AssemblyAI models and languages: https://www.assemblyai.com/docs/getting-started/models
- AssemblyAI speaker diarization: https://www.assemblyai.com/docs/pre-recorded-audio/speaker-diarization
- Cartesia batch transcribe reference: https://docs.cartesia.ai/api-reference/stt/transcribe
- Cartesia keyterms guide: https://docs.cartesia.ai/use-the-api/stt/keyterms
- Cartesia speech-to-text docs: https://docs.cartesia.ai/use-the-api/stt/compare-endpoints
When you're done, tell me which files changed, which fields you couldn't map, and how to flip the flag.Every AssemblyAI field, mapped to Cartesia
The prompt carries this table. Each row is a field in your AssemblyAI request and the Cartesia field that replaces it.
- AssemblyAI
POST /v2/transcript, then poll forcompletedor receive a webhookCartesiaclient.stt.transcribe(...), one call - AssemblyAI
authorizationheader with the raw keyCartesiaCartesia(api_key=...) - AssemblyAI
audio_url: a public URL or one from/v2/uploadCartesiafile: an open binary fileNoteCartesia takes no URL input. Download audio that sits behind a URL and send the bytes. - AssemblyAI
speech_modelsCartesiamodel:ink-whisperfor files,ink-2for live audio - AssemblyAI
language_codeCartesialanguageNoteAssemblyAI detects the language when you leave it out. Cartesia batch assumesen, so setlanguageon every request.
AssemblyAI 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.
- AssemblyAI
authorizationheader holding the raw API keyCartesiaX-API-KeyplusCartesia-Version: 2026-08-14NoteAssemblyAI takes the key with noBearerprefix. Cartesia's SDK reads it from the client constructor and sendsX-API-Keyfor you. - AssemblyAI
ASSEMBLYAI_API_KEYCartesiaCARTESIA_API_KEY
AssemblyAI API pricing per hour of audio
List prices per hour of audio from the vendor's own pricing page. Plans, regions and volume discounts change what you pay.
- Model or plan
Universal-3.5 Pro, pre-recorded
AssemblyAI$0.21 - Model or plan
Universal-2, pre-recorded
AssemblyAI$0.15 - Model or plan
Universal-3.6 Pro Realtime, streaming
AssemblyAI$0.45 - Model or plan
Universal-Streaming, English or multilingual
AssemblyAI$0.15
On Cartesia, usage draws from your plan's credits: 20,000 credits a month on the Free plan (about 111 minutes of Ink-2 at 3 credits a second). Enterprise pricing is custom.
Cartesia plans and pricingSources
Prices read from each company's pricing page in November 2026.
AssemblyAI 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 111 minutes of Ink-2 at 3 credits a second)AssemblyAI$50 of credit for new accounts, which doesn't expire and doesn't cover LLM Gateway - Limit
Languages
Cartesia5 on Ink-2 (en, es, fr, hi, ja); about 100 on Ink WhisperAssemblyAI99 for pre-recorded audio (18 on Universal-3.5 Pro); 32 for realtime on Universal-3.6 Pro Realtime
Cartesia's figures come from its pricing page and speech to text docs.
Cartesia pricing and plan limitsSources
- AssemblyAI billing and free creditsassemblyai.com
- AssemblyAI pre-recorded rate limitsassemblyai.com
- AssemblyAI streaming rate limitsassemblyai.com
- AssemblyAI models and languagesassemblyai.com
Limits read from each company's documentation in November 2026.
What you get on Cartesia
What changes once the AssemblyAI call is gone.
No job to poll
client.stt.transcribe uploads the file and returns the transcript, so the polling loop or webhook handler goes away. AssemblyAI's own Synchronous API also answers in one call, for audio up to 20 minutes.
Ink-2 for voice agents
Ink-2 streams text while the caller speaks and detects the end of each turn itself.
Speech in and speech out from one vendor
Pair speech to text with Cartesia text to speech, or run the whole call on Managed Agents.
How to migrate from AssemblyAI to Cartesia
The same changes the prompt makes, if you'd rather make them yourself.
Install the SDK with
python -m pip install --upgrade cartesiaand setCARTESIA_API_KEY.Replace the submit-and-poll code with the single call above. Fetch URL-hosted audio into a file first, and pass
languageon every call.If you send
keyterms_prompttoday, measure accuracy on your own product names without it. Only the Ink-2 WebSocket takes keyterms; keyterm prompting has the details.Move live calls to Ink-2 on the WebSocket, following Compare STT endpoints.
AssemblyAISources
Sources
Request shapes checked against vendor documentation in November 2026.
Compare and read next
Frequently asked questions
Does AssemblyAI have a free tier?
New accounts get $50 in free credits for pre-recorded and real-time speech to text, and the credits don't expire. Free accounts can run 5 transcriptions in parallel and open 5 new streaming sessions a minute. LLM Gateway bills from the first request.
What does AssemblyAI cost per minute?
Universal-3.5 Pro is $0.21 an hour, or $0.0035 a minute, and Universal-2 is $0.0025 a minute. For streaming, Universal-3.6 Pro Realtime is $0.0075 a minute and Universal-Streaming $0.0025.
What do add-ons do to AssemblyAI pricing?
They stack on the base rate. Speaker diarization adds $0.02 an hour on pre-recorded audio and $0.12 an hour on streaming, medical mode adds $0.15 an hour, and multichannel files bill per channel. Cartesia's batch call has none of those features, so there is nothing to add.
Does Cartesia do speaker diarization?
No. Neither the batch call nor Ink-2 streaming returns speaker labels, and AssemblyAI has them on pre-recorded audio and on Universal-3.6 Pro Realtime. If you split a call into speakers today, keep that step on AssemblyAI or another diarization service, or record each speaker on its own channel and transcribe the channels separately.
Do I need to upload audio before transcribing?
There is no separate upload step. The batch call takes the file bytes in the same request that returns the transcript. It can't fetch from a URL, so download remote audio first.
Which languages can I transcribe?
ink-whisper covers about 100 languages for recorded files. For live audio in voice agents, Ink-2 covers English, French, Hindi, Japanese and Spanish.
What doesn't carry over?
Batch has no speaker labels, prompt, medical domain, webhooks, keyterms or automatic language detection. Live audio is the bigger gap. Ink-2 streams 5 languages, and AssemblyAI lists 32 for Universal-3.6 Pro Realtime on its models page. Keep live traffic outside those 5 on AssemblyAI for now.
Can I run both while I switch?
Yes. Put the transcription call behind a flag, send a slice of files to each vendor and diff the transcripts on the same audio. Rolling back means flipping the flag, since neither side keeps state you depend on.
Can I try Ink before I migrate?
Yes. The speech-to-text tool transcribes your microphone in Ink's languages with no sign-up.
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 recordings.