Audio · Synthesis
Text-to-Speech (OpenAI)
A drop-in replacement for OpenAI's /v1/audio/speech: the same request body, the same streamed audio response, spoken in natural Cantonese by our streaming text-to-speech engine. Point an OpenAI SDK at https://cantonese.ai/api/v1 with your cantonese.ai API key and nothing else in your code has to change.
POSThttps://cantonese.ai/api/v1/audio/speech
| Field | Behaviour |
|---|---|
| input | The text to speak (up to 500 characters). Cantonese by default; add "language": "English" for English text. |
| voice | A cantonese.ai voice_id, or the name of a public voice. The OpenAI names alloy, echo, fable, onyx, nova and shimmer all exist, so unchanged code keeps working. |
| response_format | mp3 (default), opus, aac, flac, wav or pcm (raw 16-bit little-endian, 24 kHz, mono, the lowest-latency option). |
| stream_format | audio (default, chunked bytes) or sse (server-sent speech.audio.delta events carrying base64 audio, then speech.audio.done). |
| speed | 0.25 to 4.0, default 1.0. |
| model, instructions | Accepted and ignored: the streaming service serves a single model, V8.2. Ignored fields are listed in the X-Ignored-Fields response header. |
| billing | Characters count 4x against your monthly text-to-speech quota, exactly like the streaming endpoint. An exhausted quota answers 429 with code insufficient_quota; the X-Characters-Charged header reports what each request deducted. |
Errors use OpenAI's envelope ({ "error": { "message", "type", "param", "code" } }): 401 authentication_error for a bad key, 429 rate_limit_error when your plan's per-minute budget is spent, 404 voice_not_found for an unknown voice name.
to auto-fill your API key in the code examples below.
curl -N https://cantonese.ai/api/v1/audio/speech \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"tts-1","voice":"alloy","input":"你好,今日想食啲咩呀?","response_format":"mp3"}' \
--output speech.mp3