IronStratum

POST /v1/audio/transcriptions

Transcribe audio (unit-billed, audio-seconds)

Specialty route (route_type: transcriptions), batch and streaming variants. Batch variant (default): the CLIENT face is multipart/form-data, but the GATEWAY translates — the file part's bytes cross to the model as the RAW request body under the file part's Content-Type, and a non-empty language field forwards as the ?lang=<code> query (the model owns the dedicated-code whitelist); JSON response passthrough. language is required in practice: omitted or non-dedicated reaches the model's default path and the client receives a 502 relayed VERBATIM — terminal, non-retryable, the one non-gateway-envelope error on this surface (do not retry the same language). Body-shape law (observed live): the model's in-cluster JSON error body never crosses the provider's edge (the edge replaces origin 5xx bodies with its own "error code: 502" text page), so clients see the edge's page and the gateway keys the terminal on the 502 status alone. Accepted form fields — file (required), model (required), language, prompt, response_format, temperature, stream; unknown fields are 400 unknown_param; prompt / response_format / temperature are accepted then DROPPED on the batch leg (the model never consumed them). Supported containers = the model's decode set (WAV / FLAC / Ogg-Opus) within the 25 MiB upload cap (413); an undecodable upload is 502 upstream_rejected (the model's reason lands in the ops log, not the client body); effective request ceiling ≈ 240 s — client-side chunking for longer audio. Streaming variant (stream=true): response is text/event-stream — data lines carrying {"type":"transcription.partial"|"transcription.final"|"transcription.refine","text":...} events (refine additionally carries the auto-detected "lang" — additive metadata, never meters), ": ping" keep-alive before the first event, terminal data: [DONE]; the stream ends at [DONE] after the model's own close OR a short post-event idle (the model ends a session by going silent — silence-after-events is a clean end, not an error), while a mid-stream model-side DEATH ends with the §6 terminal error event. SESSION TIME LIMIT: the host edge closes any WebSocket connection inside a measured 208-248 s band ("roughly 240 s" vendor-confirmed 2026-10-27; live-confirmed again 2026-10-28 at ~216 s connection age), so the GATEWAY ends the stream itself at a 200-second session cap — under the band's floor — with the named terminal error stream_time_limit (retryable:false — a retry of the same long stream hits the same wall; split longer audio into chunks, or use the batch variant within its own ~240 s effective ceiling). Events already delivered stand and captured finals are billed. Streaming accepts raw PCM/WAV only (audio/L16;rate=16000 family — anything else is 400 unsupported_audio_format); language is AUTO-DETECTED on the stream (no selection in the WS protocol — the refine event carries the detected code). Metering: unit_type='audio_seconds' = ceil of the model-reported duration (streaming: the sum of final-event durations), else — batch only — the wall-clock; the streaming fallback is the uploaded PCM's own duration, ceil(len/32000) at 16 kHz s16le mono (duration_source:"pcm_bytes" — wall-clock billed dial + upload + the idle-detect tail ~2x over). Idempotency-Key: accepted, no replay semantics (§8 route-scope).

Request

The body is multipart/form-data — one part per field below; the sample sends it with curl -F legs (curl owns the boundary — no Content-Type header).

Request body fields for createTranscription
Field Type Required Description
file string (binary) yes The audio file (≤ 25 MiB).
model string yes An IronStratum alias whose route_type is transcriptions.
language string no Required in practice on hayamimi-stt — forwarded as the ?lang= query; omitted/non-dedicated codes get the 502 non_dedicated_language body verbatim. Optional on whisper (auto-detected when omitted; forwarded as a form field on the provider's native API).
prompt string no —
response_format string no —
temperature string no —
stream string no "true" selects the SSE streaming variant.

Responses

400 400

400 response fields for createTranscription
Field Type Required Description
error object yes —

401 401

401 response fields for createTranscription
Field Type Required Description
error object yes —

402 402

402 response fields for createTranscription
Field Type Required Description
error object yes —

403 403

403 response fields for createTranscription
Field Type Required Description
error object yes —

404 404

404 response fields for createTranscription
Field Type Required Description
error object yes —

413 413

413 response fields for createTranscription
Field Type Required Description
error object yes —

500 500

500 response fields for createTranscription
Field Type Required Description
error object yes —

502 502

502 response fields for createTranscription
Field Type Required Description
error object yes —

503 503

503 response fields for createTranscription
Field Type Required Description
error object yes —

Status codes

  • 200 — Batch: the model's JSON response verbatim. stream=true: text/event-stream of transcription events ending [DONE].

Example

curl -X POST https://api.ironstratum.com/v1/audio/transcriptions \
  -H "Authorization: Bearer $IRONSTRATUM_API_KEY" \
  -F file=@<file>
  -F model=<model>

All operations · interactive reference · openapi.yaml