Cartesia
Text-to-speech with CartesiaTTSService (WebSocket, word timestamps) and CartesiaHttpTTSService (HTTP), configured with GenerationConfig.
Overview
Cartesia's Sonic models turn text into speech. pipedog ports both of Pipecat's Cartesia text-to-speech services:
CartesiaTTSService: streams over Cartesia's WebSocket API. Audio arrives as it is generated, with word-level timestamps that keep the spoken text in step with playback.CartesiaHttpTTSService: posts each request to Cartesia's/tts/bytesHTTP endpoint and gets the audio back in one piece, without word timestamps.GenerationConfig: volume, speed and emotion for sonic-3 series models, shared by both.
Upstream page
Pipecat's documentation for the same services.
Source
packages/cartesia/src/tts.ts.
Cartesia docs
Voices, models, SSML tags and pronunciation dictionaries.
Installation
bun add @pipedog/cartesiaimport {
CartesiaEmotion,
CartesiaHttpTTSService,
CartesiaTTSService,
GenerationConfig,
} from "@pipedog/cartesia/tts";Prerequisites
- A Cartesia account and an API key from the Cartesia playground.
- A voice id from the Cartesia voice library. There is no default voice.
- Pass the key as
apiKey. The examples read it fromCARTESIA_API_KEY.
CartesiaTTSService
Configuration
Prop
Type
Settings
Runtime-updatable settings, passed as settings: new CartesiaTTSService.Settings({...}). Both
services use the same settings class.
| Setting | Type | Default | Description |
|---|---|---|---|
model | string | "sonic-3.6" | Cartesia TTS model. |
voice | string | null | null | Voice id. Set one: there is no default. |
language | Language | Language.EN | Synthesis language. |
accent | string | null | null | Accent a multilingual voice speaks the language with, from the accents of Cartesia's Get Voice response. null lets Cartesia pick. |
generationConfig | GenerationConfig | null | null | Volume, speed and emotion. See below. |
pronunciationDictId | string | null | null | Cartesia pronunciation dictionary id. |
GenerationConfig
Prop
Type
Fields left null are not sent. CartesiaEmotion lists the emotion names Cartesia supports.
Usage
import {
CartesiaEmotion,
CartesiaHttpTTSService,
CartesiaTTSService,
GenerationConfig,
} from "@pipedog/cartesia/tts";
import { TTSUpdateSettingsFrame } from "@pipedog/core/frames/frames";
import { TextAggregationMode } from "@pipedog/core/services/tts_service";
import { Language } from "@pipedog/core/transcriptions/language";
const tts = new CartesiaTTSService({
apiKey: process.env.CARTESIA_API_KEY ?? "",
settings: new CartesiaTTSService.Settings({
voice: "your-voice-id",
model: "sonic-3.6",
language: Language.EN,
}),
});Token streaming and a generation config:
const expressive = new CartesiaTTSService({
apiKey: process.env.CARTESIA_API_KEY ?? "",
// Stream LLM tokens straight to Cartesia instead of waiting for whole sentences.
textAggregationMode: TextAggregationMode.TOKEN,
settings: new CartesiaTTSService.Settings({
voice: "your-voice-id",
generationConfig: new GenerationConfig({ speed: 1.1, emotion: CartesiaEmotion.EXCITED }),
}),
});SSML tag helpers and IPA pronunciations:
// Helpers that build Cartesia SSML tags, for use in text transforms.
const spelled = CartesiaTTSService.SPELL("A1B2");
const tagged = `${CartesiaTTSService.EMOTION_TAG(CartesiaEmotion.CALM)} One moment.${CartesiaTTSService.PAUSE_TAG(0.5)}`;
// Say words as IPA describes. Register it last in textTransforms.
const pronounce = CartesiaTTSService.pronunciationTransformIpa({ Metformin: "mɛtˈfɔɹmɪn" });
const withPronunciations = new CartesiaTTSService({
apiKey: process.env.CARTESIA_API_KEY ?? "",
settings: new CartesiaTTSService.Settings({ voice: "your-voice-id" }),
textTransforms: [["*", pronounce]],
});Change settings mid-call with a TTSUpdateSettingsFrame:
// Queue it on the worker, or push it from a processor upstream of the service.
const update = new TTSUpdateSettingsFrame({
delta: new CartesiaTTSService.Settings({ voice: "another-voice-id", language: Language.ES }),
});Event handlers
Inherited from TTSService:
| Event | Description |
|---|---|
on_connected | Connected to Cartesia. |
on_disconnected | Disconnected from Cartesia. |
on_connection_error | The connection failed. |
on_tts_request | A text chunk is about to be sent for synthesis. |
Notes
- The service does not push the LLM's text frames itself. It builds
TTSTextFrames from Cartesia's word timestamps, so the context only records words the user actually heard. - Text is aggregated into sentences by default.
TextAggregationMode.TOKENstreams tokens directly for lower latency. maxBufferDelayMssets Cartesia's server-side buffer. Leftnull, it is0in sentence mode (no double buffering) and unset in token mode (Cartesia's 3000 ms default).- A
voice,modelorlanguagechange takes effect from the next sentence, which opens a new Cartesia context. - Static helpers build Cartesia SSML tags for text transforms:
SPELL,EMOTION_TAG,PAUSE_TAG,VOLUME_TAGandSPEED_TAG. Text inside<spell>tags is never split across aggregates. pronunciationTransformIpa()turns IPA into Cartesia inline phonemes. Register it last intextTransformsso later transforms don't rewrite its markup.
CartesiaHttpTTSService
Configuration
Prop
Type
Settings
Same as CartesiaTTSService, with the same defaults.
Usage
const httpTts = new CartesiaHttpTTSService({
apiKey: process.env.CARTESIA_API_KEY ?? "",
settings: new CartesiaHttpTTSService.Settings({ voice: "your-voice-id" }),
});Notes
- Each request returns its audio in one piece. Use it when streaming does not matter.
baseUrldefaults to"https://api.cartesia.ai".
Runtime notes
| Runtime | Works | What it needs |
|---|---|---|
| Bun | ✅ yes | Nothing. |
| Node.js | ✅ yes | Nothing. |
| Deno | ✅ yes | Nothing. |
| Cloudflare Workers | ✅ yes | Nothing. |
Generated from pipecat.runtimes and pipecat.compat in packages/cartesia/package.json: ✅ means the compat smoke test passes on that runtime.
CartesiaTTSServiceuses the globalWebSocketand sends the key as anX-API-Keyheader on the handshake. The Bun, Node and DenoWebSocketsupport handshake headers, and on Cloudflare Workers the socket is opened throughfetch.CartesiaHttpTTSServiceuses the globalfetchunless you passfetch. That option replaces upstream'saiohttp_session.- The Cartesia API version header is pinned to
2026-03-01. Upstream'scartesia_versionoption is not ported. - Not ported: the deprecated
voiceId,model,params(InputParams) andaggregateSentencesconstructor options. UsesettingsandtextAggregationMode.
pipedog is an unofficial community TypeScript port of Pipecat. It is not affiliated with or endorsed by Daily or the Pipecat project.
Portions adapted from the Pipecat documentation, Copyright (c) 2024–2025 Daily, BSD-2-Clause (see apps/docs/LICENSE-pipecat-docs).