pyai-speak; the required scope is
speak:synthesize.
Speaker diarization and speech generation
Speak generates audio from text. To identify who spoke when in an existing recording, use speaker diarization with Hear. Hear async jobs produce speaker-labelled transcripts; your application can then use Speak for spoken output.Synthesize your first clip
Install an SDK if you want retries handled for you:Choose a voice from the catalog
Do not hardcode assumptions about voice language, product support, or delivery mode. Read the catalog:voice_idis the canonical input.aliasesare permanent convenience inputs on the advertised surfaces.available_ontells you whether the voice works on Speak, Omni, or both.synthesis_modestells you whichstreamvalues the voice accepts. Every Speak voice accepts both; an empty list means the voice has no Speak surface at all.speak_emotionslists qualified emotion directions for this voice. An empty or absent list means directed emotion is unavailable.tierandpricingdescribe the customer-facing quality tier and its catalog treatment. Check the pricing page for current commercial terms.
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 idstock_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 aliaseshi5–hi8are 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.
available_on is the product contract;
synthesis_modes is the delivery contract.
Emotion direction
Emotion support is specific to each voice. Readspeak_emotions from
GET /v1/voices before sending a direction. When the chosen voice advertises it,
pass emotion with happy, sad, angry, fearful, or surprised. This works
with both streaming and buffered delivery. Omit the field, or use neutral,
for the voice’s ordinary delivery.
x-pyai-emotion with the requested
name and x-pyai-emotion-applied: true. Unsupported voice/direction combinations
return 400 unsupported_parameter; invalid direction names return
400 invalid_emotion. If a qualified direction is temporarily unavailable,
Speak returns 503 emotion_unavailable before returning audio.
Speak does not offer an intensity control. Direction describes delivery;
keep pacing and check-in questions in the script itself.
Streaming vs buffered delivery
stream defaults to true:
- Use
truewhen playback should start as bytes arrive. - Use
falsewhen your client requires a complete body andContent-Length. Every catalog voice accepts both values, so the documented request above works for anyvoice_idyou find inGET /v1/voices. Some voices (today: Hindi and a fewes/fr/derows) 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 withx-pyai-stream: buffered: same status, same body, sameresponse_format, higher time-to-first-byte. Nothing to retry, nothing to branch on unless you are measuring TTFB.
Consume bytes as they arrive
AnArrayBuffer 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.
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 forpyai-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.