voice-sdk
Providers

Cartesia

Configuration, behaviour, and format support for the Cartesia provider.

pnpm add @swungstudent/voice @swungstudent/cartesia
import { Voice } from "@swungstudent/voice";
import { CartesiaProvider } from "@swungstudent/cartesia";

const voice = new Voice({
  provider: new CartesiaProvider({ defaultVoice: "a0e99841-438c-4a64-b679-ae501e7d6091" }),
});

const { audio } = await voice.speak({ text: "Hello there." });

Configuration

new CartesiaProvider({
  apiKey: "...", // defaults to CARTESIA_API_KEY
  baseUrl: "https://...",
  defaultVoice: "a0e99841-...",
  defaultModel: "sonic-3.5",
  defaultSTTModel: "ink-whisper",
  defaultRealtimeSTTModel: "ink-2",
  defaultFormat: { container: "wav", sampleRate: 44100 },

  retries: 2,
  timeout: 30_000,
  logger: console,
  rateLimit: { concurrency: 4 },
  middleware: [],
});

Model defaults are pinned to specific versions instead of -latest, so output does not change between releases of this package. A per-call request context overrides retries and timeout.

Voice selection

Synthesis requires a voice id. Set defaultVoice on the provider or pass voice on each call. Without either, speak() throws a ValidationError.

listVoices() pages through the voice catalogue and returns the full list.

Realtime transcription

Two endpoints are available, selected by turnDetection:

turnDetectionEndpointDefault modelTurn handling
{ mode: "vad" } (default)/stt/turns/websocketink-2Provider detects and emits turns
{ mode: "manual" }/stt/websocketink-whisperNo turn detection; flush() finalizes

Both are normalised to the same event stream. Requesting automatic turns with ink-whisper throws a ValidationError when the session opens. defaultRealtimeSTTModel overrides the default that each mode would otherwise select.

Connection behaviour

openTTSSession() and openSTTSession() resolve after the WebSocket connection is established, so an invalid key or an unreachable host rejects the promise instead of failing later during iteration.

Realtime synthesis

The SSE and WebSocket endpoints accept the raw container only. Requesting wav or mp3 throws a ValidationError. Use speak() for container formats.

Prosody controls

speed accepts values between 0.6 and 1.5, and volume between 0.5 and 2. Values outside those ranges throw a ValidationError before the request is sent. stability, similarity, and instructions have no Cartesia equivalent and are ignored.

Audio formats

ContainerEncodingSample rates
rawpcm_s16le, pcm_f32le, mulaw, alaw8000, 16000, 22050, 24000, 44100, 48000
wavAs aboveAs above
mp3—As above, bitrate 32/64/96/128/192 kbps

Mono only. Other combinations throw a ValidationError naming the field.

Cartesia prefixes codec names on the wire, so mulaw is sent as pcm_mulaw. The provider package handles this; use the core encoding names in your code.

On this page