Audio formats

The two parameters that decide what bytes come back, and which one wins.

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.

FieldShapeExampleUse when
audio_formatcontainer onlymp3The default sample rate and bitrate are fine.
output_formatcodec_sampleRate_bitratemp3_24000_128You need a specific rate or 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.

CodecValues
PCMpcm_8000, pcm_16000, pcm_22050, pcm_24000, pcm_44100, pcm_48000
µ-lawulaw_8000
MP3 (22.05 kHz)mp3_22050_32, mp3_22050_64, mp3_22050_96, mp3_22050_128, mp3_22050_160, mp3_22050_192
MP3 (24 kHz)mp3_24000_32, mp3_24000_64, mp3_24000_96, mp3_24000_128, mp3_24000_160, mp3_24000_192
Oggogg_24000
AACaac_24000
WAVwav_24000, wav_48000

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

import os
from speechify import Speechify
client = Speechify(token=os.environ["SPEECHIFY_API_KEY"])
# audio_format: the container, at its default rate and bitrate.
basic = client.audio.speech(
input="Hello from the Speechify API.",
voice_id="geffen_32",
model="simba-3.2",
audio_format="mp3",
)
# output_format: container, sample rate and bitrate together. It wins.
explicit = client.audio.speech(
input="Hello from the Speechify API.",
voice_id="geffen_32",
model="simba-3.2",
output_format="mp3_24000_128",
)
# The format actually encoded, which is not always the one requested.
print(explicit.output_format)

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:

ContainerAcceptResponse Content-Type
MP3audio/mpegaudio/mpeg
Opusaudio/oggaudio/ogg
AACaudio/aacaudio/aac
PCMaudio/pcmaudio/L16; rate=…; channels=1

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.