API reference

View raw .md

Batch TTS API

POST /tts/speak synthesises speech from text and streams the audio back — standalone, no call required. Same API key, same balance as your agents. No agent required — you pick the provider and voice directly.

Synthesise speech

POST /tts/speak
{
  "text": "Your appointment is confirmed for Friday at 2pm.",
  "voice_id": "autumn",
  "provider": "groq",
  "model": null,
  "language": "en",
  "rate": 1.0,
  "volume": 1.0,
  "format": "mp3"
}
fieldtypenotes
textstringrequired — 1–8000 characters
voice_idstringrequired — a voice id from GET /tts/voices
providerstringgroq (default), edge, elevenlabs, deepgram, inworld, voxtral. Unknown → 422
modelstringoptional — defaults to the provider's primary model
languagestringen or fr
ratenumber0.52.0, applied by providers that support it
volumenumber0.02.0, applied by providers that support it
formatstringmp3 (default), wav, or flac

The response is a chunked audio stream with the matching Content-Type (audio/mpeg for mp3, etc.). Two response headers:

headermeaning
X-Wakili-Cachehit or miss — was this served from the cache?
X-Wakili-Cost-Usdamount charged for this request (0 on a cache hit)

Caching (not determinism)

TTS providers do not guarantee byte-identical audio for the same input across calls, so Wakili does not promise deterministic output. Instead it caches: the first synthesis for a given (provider, model, voice_id, rate, volume, format, text) tuple is stored, and every later request with the exact same tuple replays the stored audio. A cache hit is not billed (X-Wakili-Cache: hit, X-Wakili-Cost-Usd: 0). If you need the same audio twice, request it with identical parameters and the second call is free.

List voices

GET /tts/voices?language=en
{
  "language": "en",
  "voices": {
    "groq": ["autumn", "diana", "hannah", "austin", "daniel", "troy"],
    "elevenlabs": ["21m00Tcm4TlvDq8ikWAM", "..."]
  }
}

Omit language for the full list. Providers whose model is multilingual are always included; single-language voices are filtered to the requested language.

Billing

You pay the provider's list price for the character count, plus a flat 10% routing fee:

cost_usd = upstream_cost_usd × 1.10

upstream_cost_usd is the per-1000-character list price for the chosen provider. Debited from the same balance as calls. 402 with code: "insufficient_balance" if the balance can't cover it (checked before synthesis). A cache hit skips billing entirely.

Errors

statuswhen
401missing/invalid API key
402insufficient balance
422invalid body (text length, missing voice_id, unknown provider, bad format)
502upstream TTS provider error