Skip to main content
Speak turns text into audio with one OpenAI-compatible endpoint:
The canonical model is pyai-speak; the required scope is speak:synthesize.

Synthesize your first clip

Install an SDK if you want retries handled for you:
Success is a WAV file at the voice’s native 24 kHz. Audio bytes are delivered incrementally by default.

Choose a voice from the catalog

Do not hardcode assumptions about voice language, product support, or delivery mode. Read the catalog:
For each row:
  • voice_id is the canonical input.
  • aliases are permanent convenience inputs on the advertised surfaces.
  • available_on tells you whether the voice works on Speak, Omni, or both.
  • synthesis_modes tells you which stream values the voice accepts. Every Speak voice accepts both; an empty list means the voice has no Speak surface at all.
  • tier and pricing describe the customer-facing quality tier and its catalog treatment. Check the pricing page for current commercial terms.
Designed voices appear in the same catalog with source: "design". Cloned voices are managed separately under /v1/voice/clones.

Natural voices

Natural is a selectable customer-facing voice tier, not a different endpoint:
  • English en1 (canonical id stock_aria_en) works on Speak in both streaming and buffered modes. The same id is available on Omni. It is the only Natural-tier voice in the catalog today; the former Hindi Natural aliases hi5hi8 are retired. Hindi is served by the Standard-tier voices, which work on both Speak and Omni.
  • Check the pricing page for current voice-tier treatment.
Always inspect the live catalog. available_on is the product contract; synthesis_modes is the delivery contract.

Streaming vs buffered delivery

stream defaults to true:
  • Use true when playback should start as bytes arrive.
  • Use false when your client requires a complete body and Content-Length. Every catalog voice accepts both values, so the documented request above works for any voice_id you find in GET /v1/voices. Some voices (today: Hindi and a few es / fr / de rows) are served from a fleet that has no streaming lane. Those are rendered on the blocking lane whichever value you send, and the response says so with x-pyai-stream: buffered: same status, same body, same response_format, higher time-to-first-byte. Nothing to retry, nothing to branch on unless you are measuring TTFB.

Consume bytes as they arrive

An ArrayBuffer read followed by playback demonstrates buffered application behavior even when the server is incremental. Consume the response body and pass each chunk to your audio pipeline as it arrives. Abort a synthesis when the caller interrupts, and do not retry after any audible bytes without a policy for repeated speech.
Node streaming consumption

Input length

input is capped at 2000 characters per request. Longer text answers 400 input_too_long, naming the limit and the length you sent — split the script and concatenate the audio, or use Cast for long-form work, which is built for it.

Output formats and sample rates

For pcm, choose sample_rate from 8 kHz through 48 kHz. G.711 is always 8 kHz; omit sample_rate or pass exactly 8000. A conflicting G.711 sample rate is rejected. The telephony audio reference explains companding, resampling, and the exact format to send to common phone transports.

Stock, cloned, or designed

  • Stock: select a row from GET /v1/voices; no enrollment required.
  • Clone: enroll a voice you have explicit permission to use. See Clone.
  • Design: create a new synthetic voice from a text description with /v1/voice/design, preview candidates, and save one into your voice library.
Voice is biometric data when it represents a real person. Establish consent before cloning; prompt-designed synthetic voices are a separate workflow. Start a design job with a stable idempotency key:
Poll GET /v1/voice/design/{design_id} until candidates are ready, preview their signed URLs, then save one with POST /v1/voice/design/{design_id}/save. Voice design requires speak:design; cloning uses the separate speak:clone scope.

Compatibility and unsupported controls

OpenAI model names are accepted as aliases for pyai-speak: tts-1, tts-1-hd, tts-1-1106, tts-1-hd-1106, and gpt-4o-mini-tts. So are the preset voice names alloy, echo, fable, onyx, nova, and shimmer. An alias is a name and nothing else: it never changes the engine, the lane, or the voice you would otherwise get. New integrations should prefer pyai-speak and canonical catalog voice IDs. speed, seed, and temperature are not active Speak controls. Sending them returns 400 unsupported_parameter; do not assume they were silently applied.

Browse voices

Filter the live catalog and inspect surface/mode support.

Clone

Enroll, test, use, and delete a consented voice.

Telephony audio

PCM and G.711 formats, rates, and resampling.

Language support

Choose a voice that matches the required language and product.