Skip to content

Text to Speech (TTS)

Takes a string, returns natural-sounding audio. Compatible with the OpenAI audio/speech format.

Qevron has two local TTS engines: blab-fast (fast) and blab-pro (premium). Every other TTS id is a permanent alias pointing at one of these two.

Available models

ModelEngineSample rateMeasured latency¹PriceUse where
blab-fast (default)Supertonic v344.1 kHz~0.2–0.5 s (median ~0.3)$6 / 1M charsRealtime agents, telephony, streaming, high volume
blab-pro (premium)VoxCPM248 kHz~0.5–0.8 s (median ~0.7)$12 / 1M charsPromos, audiobooks, voice cloning, style direction
tts-1OpenAIOpenAI rateOnly if an OpenAI-keyed channel is configured

¹ Measured on this deployment, from the same host, end-to-end (non-streaming) for a ~50-character Turkish sentence. Longer input takes proportionally longer; use streaming to get first audio sooner.

Aliases

The older model ids were not removed — they keep working as permanent aliases:

What you sendWhat actually runs
blab-stableblab-fast
blab-expressiveblab-pro
blab-ttsblab-pro

Removed Piper models

blab-fast-tr-naz and blab-fast-en-emma were fully removed on 2026-08-10 and now return 404. Migrate any code using those ids to blab-fast plus a voice id.

curl

bash
curl https://app.qevron.ai/v1/audio/speech \
  -H "Authorization: Bearer $QEVRON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "blab-fast",
    "input": "Hello, this audio was produced with Qevron.",
    "voice": "emma"
  }' --output out.wav

Python (openai SDK)

python
from openai import OpenAI

client = OpenAI(api_key="sk-...", base_url="https://app.qevron.ai/v1")

resp = client.audio.speech.create(
    model="blab-fast",
    input="Qevron serves your own models through one API.",
    voice="emma",
)
resp.stream_to_file("out.wav")

Which model when?

  • blab-fast — your default. Phone agents, live chat, streaming reads, bulk generation. Milliseconds-scale synthesis across 30 languages. The quality field (standard / high / max) trades speed for fidelity via the engine's diffusion step count.
  • blab-pro — when quality and voice identity matter. 48 kHz studio grade, context-aware reading, instant voice cloning, prompt-based voice design (voice_description) and natural-language style direction (instruction). Roughly double the latency and double the price.
  • tts-1 — only if an OpenAI-keyed channel exists; the voices are OpenAI's.

Telephony and realtime lanes

blab-stable-voice and blab-stable-live are separate model ids that pin the same Supertonic engine to dedicated GPU lanes for telephony and realtime use, so batch jobs cannot block the queue. For general-purpose integrations use blab-fast.

The voice parameter

voice is a voice id, not a language code. It is optional — omit it and the engine uses its own default voice.

json
{"model": "blab-pro", "input": "Hello world", "voice": "sinan"}
  • The full list of ids: TTS Voice Roster (47 catalogued voices for blab-pro, 40 for blab-fast).
  • Live listing: GET /v1/audio/voices?model=blab-fast → see Audio API.
  • The roster is engine-specific: blab-pro ids are not valid on blab-fast.
  • Voices you clone yourself appear in the same listing and are visible only to your group.

An unknown id behaves DIFFERENTLY on the two engines

A voice that is not in the roster (including the legacy "tr" / "en" language codes):

engineresult
blab-fast (blab-stable)HTTP 200 — no error; silently reads with the engine's default voice
blab-pro (blab-expressive, blab-tts)HTTP 400 — the request is rejected

The silent fallback exists only on blab-fast, and that is the dangerous half: a wrong id still looks like a success, but the speaker is not the one you asked for. Ids are not portable between engines (naz is blab-fast only, nisan is blab-pro only) — always verify against GET /v1/audio/voices for the model you are calling.

Audio format (response_format)

Formatblab-fastblab-pro
wav (default)✓ 44.1 kHz✓ 48 kHz
mp3
pcm✓ raw int16✓ raw int16 (24 kHz stream)
opus / aac / flac✗ — silently returns WAV✗ — returns 400

The two engines differ here: blab-fast silently downgrades an unsupported format to WAV, while blab-pro fails loudly. Choose the file extension from the actual response content, not from what you asked for.

Streaming

python
stream = client.audio.speech.create(
    model="blab-fast",
    input="A long passage of text...",
    voice="emma",
    stream=True,
)
with open("out.wav", "wb") as f:
    for chunk in stream.iter_bytes():
        f.write(chunk)

For realtime agents, response_format: "pcm" gives a raw int16 stream you can feed straight into an audio device or phone leg.

Legacy stream_format parameter

Before v2.2.0 you had to pass OpenAI's original stream_format: "sse" explicitly. As of v2.2.0 qevron auto-bridges stream: true (the SDK shape) → stream_format: "sse". Both work; an explicit stream_format still wins.

Voice cloning

blab-pro clones a voice from a reference clip in seconds:

bash
curl -X POST "https://app.qevron.ai/v1/audio/voices?model=blab-pro" \
  -H "Authorization: Bearer $QEVRON_API_KEY" \
  -F "label=Host Voice" \
  -F "file=@reference.wav"

Put the returned id straight into the voice field. The reference clip must be 3–60 seconds. Passing the clip's exact text as transcript upgrades the clone to prompt-continuation ("ultimate") mode for sharper similarity. Details: Audio API.

Troubleshooting

  • Silent or corrupt file → set Content-Type: application/json; send JSON, not form-data.
  • The voice never changes → the voice id you sent may not exist on that engine, so it silently fell back to the default. Verify with GET /v1/audio/voices?model=<model>.
  • 404 model not found → you are using a removed id (blab-fast-tr-naz, blab-fast-en-emma). Use blab-fast plus a voice.
  • Asked for opus/flac, got WAVblab-fast silently downgrades unsupported formats.
  • MP3 or WAV? → WAV by default. Add "response_format": "mp3" for MP3.

Next: TTS Voice Roster · Audio API · STT — speech to text

Qevron — AI gateway. Arpanet / OpenAI / Anthropic / Gemini compatible.