sonixdocs

Text to speech

POST /v1/audio/speech is OpenAI-compatible speech synthesis. The response is binary audio with a content type derived from response_format.

curl "$SONIX_URL/v1/audio/speech" \
  -H "Authorization: Bearer $SONIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kokoro-82m",
    "input": "Hello from sonix.",
    "voice": "af_heart",
    "response_format": "wav",
    "speed": 1.0
  }' --output hello.wav

Request fields

FieldRequiredNotes
modelyesA speech-capable model ID. See Models.
inputyesThe text to synthesize.
voiceyesA voice ID or OpenAI-style name (alloy, …), or an object like { "id": "af_heart" }. See Voices.
response_formatnomp3 (default), opus, aac, flac, wav, or pcm.
speedno0.25 to 4.0. Defaults to 1.0.
instructionsnoForwarded to the model as synthesis metadata. Not delivered to qwen3-tts-0.6b; see below.
stream_formatnoaudio (default). sse is rejected until event streaming ships.

wav responses are wrapped in a WAV container server-side; other formats are returned as produced by the model. Unsupported parameters are rejected with a validation error rather than silently ignored.

Format support varies by model. qwen3-tts-0.6b produces pcm and wav only: an omitted response_format returns wav there, an explicit mp3, opus, aac or flac returns a validation error. On that model speed is accepted but currently unapplied; the x-zzz-speed-applied response header reports the speed actually used. instructions is not delivered to that model either; only input, voice, response_format and speed reach it.

Using the OpenAI SDK

Any OpenAI SDK works by overriding the base URL:

from openai import OpenAI

client = OpenAI(base_url=f"{SONIX_URL}/v1", api_key=SONIX_API_KEY)

speech = client.audio.speech.create(
    model="kokoro-82m",
    voice="af_heart",
    input="Hello from sonix.",
    response_format="wav",
)
speech.write_to_file("hello.wav")