Skip to main content

v0.4.1 — Per-request length & body-size limits

  • Maximum input length — a request is rejected if its transcript predicts more than ~46.5 s of generated audio (the generator’s hard ceiling), checked before synthesis so nothing is billed on a rejection. The limit is on predicted duration, not characters: it’s digit-aware and per-language, so a rough en-US guide is ~900 characters of prose but only ~130 digits (number-heavy text hits it with far less text). Over the limit returns input_too_long400 on /tts/bytes and /tts/sse, or a per-context error frame (the socket stays open) on /tts/websocket. Split longer content across requests/turns.
  • Request body cap/tts/bytes and /tts/sse reject a body larger than 64 KB (65536 bytes) with 413 payload_too_large. Normal requests are nowhere near this.
  • Unknown voice ids return 404 — a misspelled or unknown voice.id returns voice_not_found (404) instead of falling back to a default; voice.id must reference an existing voice.

v0.4.0 — Required voice & strict clone language

  • voice is now required on /tts/bytes, /tts/sse, and /tts/websocket (per message) — there is no default voice anymore. A request that doesn’t resolve to a voice returns an error instead of silently synthesizing a default. The only accepted form is the nested object { "mode": "id", "id": "<voice-id>" }; a top-level voice_id is not supported and mode must be "id".
  • New voice/transcript error codesmissing_voice, missing_voice_id, unknown_voice_mode (400), voice_not_found (404), and missing_transcript (400). HTTP errors now use a { error, error_code, message, detail } envelope (error_code is canonical).
  • WebSocket is stricter — a message that omits transcript returns a missing_transcript error frame instead of a silent done. The end-of-turn terminator (transcript: "" with continue: false) remains valid.
  • Voice-clone language must be a valid BCP-47 tagPOST /voices/clone rejects malformed tags (en_US, en-USA, 123) with invalid_language (400). Send the full dialect (en-US); values are canonicalized on save (en-usen-US).

v0.3.0 — Strict output formats, telephony & clearer limits

  • output_format is now strictly validated — unsupported values return 400 instead of silently falling back. Supported: container raw/wav, encoding pcm_s16le/pcm_mulaw/pcm_alaw, sample_rate 8000/16000/22050.
  • Telephony encodings added — 8 kHz μ-law (pcm_mulaw) and A-law (pcm_alaw) for Twilio/SIP media streams.
  • Removed formatsmp3, pcm_f32le, and sample rates 24000/44100/48000 are no longer accepted.
  • Streaming is raw-onlywav is available on /tts/bytes only; /tts/sse and /tts/websocket require raw.
  • Limits clarified as per-org — rate and concurrency limits are shared across all of an org’s API keys; extra keys don’t add capacity. Concurrency is measured per active-speech turn, not per call.
  • Dutch voices are now tagged nl-NL (BCP-47 dialect) instead of bare nl.

v0.2.0 — Cartesia-compatible API

  • Cartesia-compatible surface: POST /tts/bytes, POST /tts/sse, GET /tts/websocket, /voices CRUD, POST /voices/clone
  • Model: gepard-1.0
  • Real-time WebSocket streaming with per-transcript billing
  • Voice cloning and the full Cartesia voice library
  • API keys now use the sk_996_<prefix>_<secret> format, scoped to a project
  • Prepaid credits: 1 credit per character, $5 per 1M characters, credits never expire
  • Per-project tiers (rate + concurrency): tier1 / tier2 / tier3, with auto-upgrade to tier2 at $50 lifetime spend

v0.1.0 — Initial Release

  • OpenAI-compatible TTS API (deprecated; replaced by the Cartesia-compatible surface above)