| name | cartesia-api |
| description | Integrate Cartesia speech APIs (TTS, STT, voices) in application code or coding-agent workflows. Use when the user asks about Cartesia REST/WebSocket APIs, SDKs, API keys, Sonic TTS, Ink STT, voice IDs, access tokens, or embedding voice in an app. For Cartesia Line deployed agents, CLI deploy, and telephony, use the line-voice-agent skill instead. |
| compatibility | Requires a Cartesia API key from https://play.cartesia.ai/keys for server-side calls. Client apps must use short-lived access tokens, not raw API keys. Optional cartesia-mcp requires Python 3.13+. |
Cartesia Voice & Speech APIs
Cartesia provides text-to-speech (Sonic), speech-to-text (Ink), voices (library, clone, localize), and related HTTPS and WebSocket APIs. This skill covers application integration and agent-assisted coding. For Cartesia Line (managed voice agents, cartesia CLI, telephony, Line SDK), use line-voice-agent.
Core directives
- HTTPS only: All HTTP endpoints use
https://api.cartesia.ai. WebSockets use wss://
- HTTP may be unsupported; keys used over HTTP can be auto-rotated
- API version: Cartesia's API is dated (
Cartesia-Version: YYYY-MM-DD). Pin one version across your services and treat bumping it like a major dependency upgrade — a new version can carry breaking changes — so it's a fixed choice, not a runtime/per-call variable.
- With an SDK (recommended): the SDK already pins a
Cartesia-Version it was built and tested against. Let it manage that — do not override it (e.g. via default_headers) with your own date, since the SDK may not work against an arbitrary version. To move to a newer API version, upgrade the SDK.
- Calling the API directly (no SDK): you must send
Cartesia-Version yourself. Browser WebSockets can't set handshake headers, so pass it as ?cartesia_version=... (query wins if both are present).
- Optional:
GET https://api.cartesia.ai/ returns {"ok":true,"version":"..."} (the gateway's current default), useful when wiring a new client.
- Server-side auth: Use
Authorization: Bearer <api_key> with your Cartesia API key (sk_car_...).
- Client apps (browser / mobile): Never embed API keys. Have your backend mint a short-lived access token and use
Authorization: Bearer <access_token>
- For WebSockets from browsers, pass the token as
?access_token=<token> (headers are not available on WS handshake)
- The JS/TS SDK (v3+) runs in the browser with an access token — prefer it over hand-rolling the WebSocket (see its Browser Examples below); don't assume the SDK is server-only
- See Access Token API
- Errors: For
Cartesia-Version 2026-03-01 and newer, errors are structured JSON (error_code, title, message, request_id, optional doc_url)
- Source of truth: Prefer docs since they are updated first before SDKs / plugins / integrations
- Fetch docs as Markdown: append
.md to any docs.cartesia.ai page to get the agent-readable Markdown (e.g. https://docs.cartesia.ai/api-reference/stt/transcribe.md); the bare URL is the human HTML page. Prefer the .md form when fetching docs programmatically
- For machine index:
llms.txt and llms-full.txt
- Optional MCP: cartesia-mcp helps in Cursor / Claude (files, voice tools)
- MCP does NOT replace API / SDKs for production
- Requires Python 3.13+
- See MCP docs
Text-to-speech with Sonic (generating audio)
- Choosing a TTS model: See TTS models for current model IDs, supported languages, and features. Don't trust a model ID from memory — training data goes stale (e.g.
sonic-2 is no longer current)
- Voice IDs: Don't invent a voice ID — a made-up UUID won't resolve. Real voice IDs are stable, so hardcoding a real one as a constant is fine and common; copy one from the playground or List Voices. Use List Voices to discover/choose a voice, not as a required call on every request
- Choosing an endpoint — bytes vs WebSocket: if the text is known up front (a fixed string, a button press), use
POST /tts/bytes — it streams audio back as it's generated and is simpler. Reach for the WebSocket only when the input text arrives incrementally (e.g. piping an LLM's token stream) — the continuations case. Don't default to WebSockets; compare them in TTS endpoints
- Output audio format: See TTS output audio format for containers/encodings/sample rates (
wav + pcm_s16le @ 44.1 kHz is a safe, self-contained default; mp3 carries no separate encoding)
Speech-to-text with Ink (transcribing audio)
- Choosing an STT model: see STT models for current models and supported languages
- Choosing an API endpoint: see Compare STT Endpoints
- Input audio: see STT input encodings for supported formats (self-contained files like
.wav carry their own header)
- Before you write any STT code: read Common STT Pitfalls
- Don't assume model or API behavior without grounding it in the docs — small client-side mistakes cause obscure but severe accuracy degradation
- Common client-side errors:
- Stripping or inserting whitespace in transcripts (read the model's text verbatim — no
.strip(), no normalization)
- Improperly concatenating transcript pieces
- Not following the API spec
Cartesia Python SDK
pip install cartesia
Replace /heads/main/ with /tags/vX.X.X/ (e.g. /tags/v3.2.0/) to source code specific to your SDK version.
Cartesia TypeScript / JavaScript SDK
npm i @cartesia/cartesia-js
Replace /heads/main/ with /tags/vX.X.X/ (e.g. /tags/v3.2.0/) to source code specific to your SDK version.
When to use which path
| Goal | Path |
|---|
| App or backend calling REST/WebSocket | Python SDK, JS/TS SDK, or native API requests / fetch |
| IDE agent with MCP | cartesia-mcp + docs fallback |
| Deployed voice agent, Line, telephony | line-voice-agent |
| OpenClaw bootstrap | https://cartesia.sh/openclaw.md then docs / llms.txt |
Quick start (HTTP TTS, one-shot)
Shape only: confirm field names and enums against the API reference for your Cartesia-Version:
curl -X POST "https://api.cartesia.ai/tts/bytes" \
-H "Authorization: Bearer $CARTESIA_API_KEY" \
-H "Cartesia-Version: 2026-03-01" \
-H "Content-Type: application/json" \
-d '{
"model_id": "sonic-3",
"transcript": "Hello from Cartesia.",
"voice": { "id": "f786b574-daa5-4673-aa0c-cbe3e8534c02" },
"output_format": {
"container": "wav",
"encoding": "pcm_s16le",
"sample_rate": 44100
},
"language": "en"
}' \
--output /tmp/out.wav
Mental model (for LLMs)
- Sonic = TTS Model used to generate speech
- Ink = STT Model used to transcribe audio
- Line = separate product: you deploy your Python agent; Cartesia runs STT/TTS/telephony around it, different from "call TTS API from my server."
- Concurrency / quota: Handle
429-class and structured concurrency_limited / quota_exceeded per API errors.
Related material in this repo
Common mistakes
- Overriding the SDK's
Cartesia-Version: with an SDK, don't set or override the version — it pins one it's tested against; upgrade the SDK to move versions. Only raw HTTP/WS callers send the date themselves, and then keep one date everywhere (wrong date → subtle breakage or legacy error shapes).
- API keys in frontend code: use short-lived access tokens minted by your backend.
- Wrong auth header style: examples use
Authorization: Bearer; match current docs, not old snippets.
- Stale SDK / model code from memory: training data lags the API. Model IDs drift (e.g.
sonic-2), and the JS SDK's named import { CartesiaClient } is deprecated and won't run in browsers — use import Cartesia from "@cartesia/cartesia-js" (or the default import). Confirm models against the models docs and SDK usage against the linked README / examples.
- Using this skill for
cartesia deploy / Line: switch to line-voice-agent.