Audio formats
Two request fields control the audio you receive. They are not alternatives — one names a container, the other names a container and a sample rate and a bitrate.
output_format takes precedence over audio_format on
POST /v1/audio/speech, and over the Accept header on
POST /v1/audio/stream. Setting both is not an error; the more specific one
wins.
audio_format accepts wav, mp3, ogg, aac and pcm, and defaults to
wav. The default is not guaranteed to stay wav — pass the value you
expect rather than relying on it.
Every output_format value
All 23 values, as the API accepts them. Streaming takes the same set minus the
two wav_* entries. An invalid value returns 400 and lists what is accepted,
so this table is a convenience rather than the contract.
pcm_* and ulaw_8000 are headerless: raw samples with nothing to tell a
player the rate. Whatever consumes them has to be told.
160 kbps is the ceiling an MP3 carries at 22.05 and 24 kHz, so mp3_22050_160
and mp3_24000_160 are the maximum-fidelity MP3 formats — there is no higher
MP3 to ask for. mp3_22050_192 and mp3_24000_192 were always encoded at
160 kbps, and the response reports the mp3_*_160 it actually delivered
rather than echoing the 192 back. The two mp3_*_160 formats are produced by
the Simba 3 models; pairing one with a legacy Simba 1.6 model returns 400.
wav_* is not available on the streaming routes. Use
POST /v1/audio/speech for WAV.
Setting a format
Python
TypeScript
cURL
Telephony
Twilio and LiveKit SIP expect 8 kHz µ-law or 16 kHz PCM, so ulaw_8000 and
pcm_16000 are the two formats worth reaching for. Match the rate your
transport expects — a mismatch is not an error, it is audio that plays at the
wrong speed and pitch.
Check your pinned API version before using pcm_16000. On a workspace
pinned before 2026-09-30, the Simba 3 models answer pcm_16000 with 24 kHz
samples labelled rate=16000, so a 16 kHz pipeline plays them 1.5x slow and
pitched down.
A workspace created on or after 2026-09-30 is already correct — new
workspaces start at the newest version — and so is any workspace that has
moved its pin. An older pin keeps the bytes it has always received, because an
integration built against 24 kHz breaks the moment they change.
On an older pin, either move the pin, or use ulaw_8000, or keep playing the
audio at 24 kHz until you move. See the
changelog and the
API Versioning guide for reading and
setting your version.
Streaming and the Accept header
On POST /v1/audio/stream the Accept header selects a container when
output_format is absent:
Those default to 24 kHz mono, and MP3 without a named bitrate resolves to
128 kbps. Send output_format when you need anything else — it overrides the
header. The resolved default is not part of the contract, so name the
output_format you want if your pipeline depends on it.
Streaming has no JSON envelope to report the format back in: the response body
is the audio, and the Content-Type is what tells you the format that was
served. It follows the Accept header, except raw PCM, which returns
audio/L16 with rate and channels parameters, and µ-law, which returns
audio/basic.
POST /v1/audio/speech does report it. Its JSON response echoes
output_format when — and only when — the request set one, and reports the
format actually encoded — which is the requested
value unless the request named a bitrate above the MP3 ceiling, where it names
the bitrate delivered. Read the delivered format from there, not from what you
sent.