IronStratum

POST /v1/audio/speech

Generate audio from text (unit-billed, chars)

Task #15 specialty route (route_type: speech); per-alias input caps added task #17. The response is BINARY audio via chunked transfer: bytes leave the gateway as they arrive from the card (flush per read — no idle gap past load-balancer walls), never a Content-Length. Content-Type forwards from the upstream (default audio/mpeg); no other upstream header crosses. No stream param — chunked transfer is the only mode. Input is length-capped per alias where the card does not cap itself (400 invalid_param param=input, refused before any upstream connection, unbilled; values in the gateway's models.yaml, sized so buffered synthesis fits the card host's ~55-60 s no-byte edge await and the gateway's per-alias first-byte wall: chatterbox-tts 400 (measured 2026-09-09: 0.085 s/char buffered synthesis — 600 chars reached 53.6 s to first byte; the stub-era 20000 is gone) · kokoro-tts 3500 (F-3 measured 0.0149 s/char — ~52.8 s at cap; 4000 would run ~60 s, an edge kill) · pocket-tts 2500 (F-3 measured 0.0188 s/char — ~48 s at cap) · audio8-tts 250 runes (review F-2 2026-09-09: ~0.22 s/char measured × 250 = ~56 s under the edge kill — the old 400 derived from a ~100 s wall that does not exist)). The card synthesizes BEFORE the first byte crosses — first-byte latency of tens of seconds is normal at the caps (chatterbox ~41 s at 400 chars); text longer than a cap is the client's to chunk (one request per chunk, concatenated at playback). Metering: unit_type='chars' = rune count of input, counted at the gateway. Idempotency-Key is accepted with NO replay semantics on this route (§8 route-scope) — a retrying client re-executes and re-bills. Client contract: do not set client read timeouts below the expected generation time.

Request

Request body fields for createSpeech
Field Type Required Description
model string yes An IronStratum alias whose route_type is speech.
input string yes The text to synthesize (billed per rune).
voice string yes An upstream catalog voice id (GET /v1/audio/voices).
response_format string no
speed number no

Responses

400 400

400 response fields for createSpeech
Field Type Required Description
error object yes

401 401

401 response fields for createSpeech
Field Type Required Description
error object yes

402 402

402 response fields for createSpeech
Field Type Required Description
error object yes

403 403

403 response fields for createSpeech
Field Type Required Description
error object yes

404 404

404 response fields for createSpeech
Field Type Required Description
error object yes

500 500

500 response fields for createSpeech
Field Type Required Description
error object yes

502 502

502 response fields for createSpeech
Field Type Required Description
error object yes

503 503

503 response fields for createSpeech
Field Type Required Description
error object yes

Status codes

  • 200 — Chunked binary audio. Content-Type is the upstream's declared audio type (default audio/mpeg); a mid-generation upstream death ends the transfer abruptly — delivered bytes stand, the turn is not billed.

Example

curl -X POST https://api.ironstratum.com/v1/audio/speech \
  -H "Authorization: Bearer $IRONSTRATUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"<model>","input":"<input>","voice":"<voice>"}'

All operations · interactive reference · openapi.yaml