Request lifecycle
Request lifecycle
Section titled “Request lifecycle”This page traces a POST /v1/audio/speech request and the startup warmup that must
complete before synthesis succeeds.
Startup and warmup
Section titled “Startup and warmup”- The process launches via
python -m api.src.serve, which wires a TLS certificate whenTLS_ENABLEDis set, then starts uvicorn bound to0.0.0.0:8880. - The socket opens and
/healthimmediately answers200withstatus: warming. - A background task loads the Kokoro model and voice packs and runs a short warmup synthesis.
- On success the status flips to
ready(and/readyreturns200); a startup panel is logged. On permanent failure the status is set tofailedand the process exits non-zero so an orchestrator can restart it.
With WARMUP_ON_START=false, steps 3–4 are deferred to the first synthesis request.
A synthesis request
Section titled “A synthesis request”Step by step:
- Authentication — when
API_KEYis set, the bearer token is verified (constant-time); a bad or missing key returns401. - Readiness gate — if the model is warming, the request returns
503withRetry-After: 10and errormodel_warming; if warmup failed,503withmodel_failed. - Validation — the model name is checked, and the
voicestring is parsed and validated (including weighted combinations); invalid input returns400. - Voice resolution — a single voice tensor or a normalized weighted combination is assembled and cached.
- Chunking — long input is split at sentence boundaries using the configured token bounds.
- Synthesis — each chunk is synthesized by the Kokoro pipeline for the resolved language.
- Encoding — frames are encoded by the streaming audio writer into the requested format and either streamed (chunked transfer, default) or returned as one complete response.
Related behavior
Section titled “Related behavior”- Captioned synthesis (
/dev/captioned_speech) follows the same path but returns base64 audio plus word-level timestamps. See Extended API. POST /dev/unloadfrees the model from VRAM between requests; the next request reloads it lazily.