Audio
The audio endpoints offer four operations: text-to-speech (TTS), voice management, speech-to-text (STT) and speech-to-English translation.
Text-to-speech (TTS)
Converts text into a spoken audio file.
Request parameters (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
model | string | ✓ | TTS model (blab-fast, blab-pro, or one of their aliases) |
input | string | ✓ | Text to speak |
voice | string | A voice id (not a language code). Omit it for the engine default — see the Voice Roster | |
response_format | string | wav (default), mp3, pcm | |
speed | number | Speed between 0.25–4.0 | |
quality | string | blab-fast only: standard / high / max | |
instruction | string | blab-pro only: natural-language style direction (e.g. "cheerful, slightly faster") | |
stream_format | string | For streamed output ("sse"); auto-bridged from stream: true |
voice is not validated
An unrecognised voice id raises no error — the request returns 200 with the engine's default voice. Verify ids with the listing endpoint below. opus / aac / flac are not supported by these engines: blab-fast silently falls back to WAV, blab-pro returns 400.
Example
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 generated with Qevron.",
"voice": "emma"
}' --output output.wavresp = client.audio.speech.create(
model="blab-fast",
input="Hello, this audio was generated with Qevron.",
voice="emma",
)
resp.stream_to_file("output.wav")The response is binary audio data (Content-Type: audio/wav by default). When streaming, audio chunks arrive as SSE speech.audio.delta events.
Listing voices
Returns the voices a TTS model can use: the engine's built-in roster plus your own clones. Other tenants' clones are never listed.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
model | string | ✓ | TTS model name (blab-fast, blab-pro, or an alias) |
Example
curl -H "Authorization: Bearer $QEVRON_API_KEY" \
"https://app.qevron.ai/v1/audio/voices?model=blab-fast"Response
{
"supports_custom": true,
"voices": [
{
"id": "emma",
"label": "Emma",
"builtin": true,
"lang": "en",
"lang_key": "en",
"label_en": "Emma",
"gender": "F",
"age": "adult",
"category": "audiobooks",
"categories": ["audiobooks"],
"tags": ["warm", "narrative", "smooth", "calm", "mature"],
"description": "Emma, uzun dinlemeler için sıcak ve sürükleyici bir anlatıcı.",
"description_en": "Emma is a warm, immersive narrator for long-form listening."
},
{ "id": "M1", "label": "Kerem — Genç", "builtin": true, "lang": null }
]
}The two entries above are both verbatim from the live endpoint and show the two shapes you must handle: a fully catalogued roster voice, and an uncatalogued one (here blab-fast's generic default style M1 — note it carries no status, no lang_key and no catalogue fields).
Field dictionary
| Field | Type | On every record? | Description |
|---|---|---|---|
supports_custom | bool | ✓ (root field) | Whether the engine can create custom (cloned) voices |
id | string | ✓ | What you put in the voice field of /v1/audio/speech |
label | string | ✓ | Display name (in its own language) |
builtin | bool | ✓ | true = engine roster voice, false = tenant clone |
status | string | no | "ready". Coverage is inconsistent — see the caveat below |
lang | string | no | Language the voice was curated for (tr / en). Absent or null on uncatalogued records |
lang_key | string | no | Same value and same coverage as lang |
label_en | string | no | English display name (currently identical to label on every record) |
gender | string | no | M (male) or F (female) |
age | string | no | young / adult / mature |
category | string | no | Use case it was curated for (e.g. news, audiobooks) |
categories | string[] | no | Array form of category; currently always exactly one element |
tags | string[] | no | Exactly five character tags (e.g. warm, crisp) |
description | string | no | Short blurb (in its own language) |
description_en | string | no | English blurb (best-effort; a few records still return Turkish text) |
The full set of values, with every id: TTS Voice Roster.
Coverage caveat — catalogued vs uncatalogued records
Not every listed voice carries a catalogue card. Only the curated roster has gender / age / category / tags / description (blab-pro: 47 of 91 records; blab-fast: 40 of 60). The rest are tenant clones and blab-fast's generic M1–F5 default styles, which carry only id, label, builtin (plus status if the engine supplies it).
When you write code against this:
langandlang_keyhave identical coverage — both are populated only on the catalogued roster. "lang_keyis always populated" is not true; a language filter built onlang_keydrops exactly the same voices as one built onlang(i.e. it hides the user's own clones). The only difference is cosmetic: for uncataloguedblab-fastrecordslangis sent asnull, whilelang_keyis not sent at all.- Your language filter must handle "unknown" — do not discard a voice because
langis missing. - Do not rely on
status—blab-prosends it on every record (91/91),blab-faston only 10 of 60. Do not build a "ready" badge on it; if the field is absent, treat the voice as usable.
Errors
| Case | Response |
|---|---|
model not supplied | 400 — {"error": {"message": "query param 'model' is required"}} |
| Model is not a local TTS model | 404 |
| Engine unreachable | 502 |
Cloning a custom voice
Creates a custom voice for your group from a reference clip. Uses multipart/form-data. Instant cloning is available on blab-pro.
| Field | In | Required | Description |
|---|---|---|---|
model | query or form | ✓ | TTS model name |
label | form | ✓ | Display name of the voice |
file | form | ✓ | Reference audio clip (3–60 s) |
transcript | form | The clip's exact text. Supplied, it upgrades blab-pro to prompt-continuation ("ultimate") cloning for sharper similarity; other engines ignore it |
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"The created voice's id is namespaced to your group (g<group>__<label>), so tenants can neither see nor collide with each other's voices. Use the returned id verbatim in the voice field — not the label you sent.
Deleting a voice
Deletes a custom voice you created. The model query parameter is required. You may only delete your own group's voices; built-ins and other tenants' voices return 403. Use it to reap ephemeral clones (for example the per-speaker clones created during dubbing).
curl -X DELETE "https://app.qevron.ai/v1/audio/voices/gacme__host_voice?model=blab-pro" \
-H "Authorization: Bearer $QEVRON_API_KEY"Speech-to-text (STT)
Transcribes an audio file into text. Uses multipart/form-data.
Form fields
| Field | Type | Required | Description |
|---|---|---|---|
model | string | ✓ | STT model (e.g. solab-stt) |
file | file | ✓ | Audio file (wav, mp3, m4a, ...) |
language | string | Language code (e.g. tr, en) | |
response_format | string | json (default), verbose_json, text |
Example
curl https://app.qevron.ai/v1/audio/transcriptions \
-H "Authorization: Bearer $QEVRON_API_KEY" \
-F "model=solab-stt" \
-F "file=@recording.wav" \
-F "language=en"with open("recording.wav", "rb") as f:
resp = client.audio.transcriptions.create(
model="solab-stt",
file=f,
language="en",
)
print(resp.text)Response
{ "text": "Hello, this is a test recording." }With verbose_json you additionally get language, duration and segments.
Speech-to-English translation
Uses the same form fields as transcriptions, but the output text is translated into English. The language field is not needed.