| Endpoint | Returns | Granularity |
|---|---|---|
GET /api/tts/generate/{id}/stream.mp3 | MP3 byte stream | Entire generation task |
GET /api/tts/generate/{id}/{contentIndex}/stream.mp3 | MP3 byte stream | Single content |
GET /api/tts/generate/{id}/stream | JSON containing the full URL of the first endpoint above | Entire generation task (URL lookup only) |
GET /api/tts/generate/{id}/{contentIndex}/pseudo/stream.mp3 | 302 redirect to the finished audio | Single content (pseudo-streaming) |
metadata.audio already exists (finished audio has landed in storage) → 302 redirect to the finished audio URL; the streaming pipeline is not used.processing or generated → return an MP3 byte stream.STREAM_NOT_READY.{id} + {i} share one stream session: the generation pipeline runs globally once, output is appended into the session cache, and every HTTP request reads from the cache.Range / If-Range / HEAD / 206 / 416 (iOS AVPlayer depends on this semantics).ETag changes.Content-Type: audio/mpeg); the endpoint does not accept format / bitrate / sampleRate parameters.libmp3lame pipeline and re-encoded at a fixed bitrate of 320 kbps (routes/generate/streaming.js:220-221). That pipeline does not explicitly set a sample rate; sample rate is inherited from the upstream segments.routes/generate/streaming.js:861-869). That path requests 24 kHz MP3 from upstream (routes/generate/streaming.js:842), so this path's output is neither 320 kbps nor 44.1 kHz.interval silence-fill segments are encoded separately from 44.1 kHz / stereo PCM into 320 kbps MP3 (routes/generate/streaming.js:391-394,421).X-Reecho-Audio-Id / X-Reecho-Response-Datadirect_stream: true direct-return branch of POST /api/tts/generate (routes/generate/tts.js:1789-1798)routes/generate/tts.js:1321-1322). Those are the only two write sites in the whole repo; they do not exist in routes/generate/streaming.js,credit_used / billing / estimatedDuration) cannot be obtained from this endpoint's response headers — use the generation-task detail endpoint instead.app.js:261; both express-jwt and API-key middleware are skipped; only the ?auth= static token is accepted.{ status, code, message, requestId? }. code is always the parent code — sub codes only change message and never appear in the body. requestId is present only on reportable-tier errors, so use the X-Vocu-App-Request-Id response header when troubleshooting (it is written unconditionally on every response). See the "Errors" document for the full code reference.