Audio transcription API
Multipart transcription, verified quotes, durable operations and private results.
No current prepared translation is available. The English source is shown without machine translation.
Base URL in these examples: https://api.model-gate.com. Use the enabled API of your own service profile or custom domain. An ordinary active API key identifies the permitted owner, principal and key context. An operation belongs to that context and is not exposed to a different key automatically. Every endpoint requires authentication and the applicable domain/IP and model permissions. Playground uses a narrowly scoped temporary permission instead of exposing the key secret; ordinary browser credentials are not general-purpose background-job keys.
Methods
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/audio/catalog | Available transcription offers for model; no supplier request. |
| POST | /v1/audio/quote | Multipart file validation and price quote; no paid transcription. |
| POST | /v1/audio/transcriptions | One saved transcription intent. |
| GET | /v1/audio/operations | Recent operations for this key/actor, or a read-only intent lookup. |
| GET | /v1/audio/operations/{id} | Compact state and result availability; accounting via ?view=details. |
| GET | /v1/audio/operations/{id}/result | Original saved JSON/text/subtitle response; download=1 suggests download. |
Multipart input
file and model are required. Upload exactly one file; URL references, arrays of files, JSON/base64 bodies, empty uploads and repeated scalar fields are rejected. The server checks actual bytes and complete decoding. Supported local containers are WAV/MP3/FLAC/OGG/M4A/WebM; an individual offer can be narrower. Maximum recording size is 25 MiB, maximum duration 1800 seconds, one mono/stereo audio stream, sample rate 8000–192000 Hz; the selected offer may impose lower size/duration limits. Multipart overhead has its own bound and an upstream-facing HTTP upload limit may be lower.
Optional fields, only when supported: response_format from json, verbose_json, text, srt, vtt; language as two lowercase letters; prompt as vocabulary/context up to the offer’s character limit; temperature as decimal 0–1 with at most six fractional digits; repeated timestamp_granularities[] with word or segment. Do not duplicate a granularity. Timestamps require verbose JSON. Omitted response format uses the first supported format in the selected offer; other omitted controls are not invented or sent.
model_gate is a local JSON object with async boolean, route_id for a particular offered route, and optional 64-hex quote_sha256. Unknown properties, duplicate JSON keys, unsupported formats and controls are rejected. Streaming, translations, speaker diarization and audio generation are outside this endpoint. General Async/OpenAI Batch must not be used to bypass this Audio API.
# Explicit paid example: choose a reviewed model, your recording and retain this intent.
curl --fail-with-body 'https://api.model-gate.com/v1/audio/transcriptions' \
-H "Authorization: Bearer $MODEL_API_KEY" \
-H 'Idempotency-Key: my-recording-0001' \
--form-string 'model=YOUR_ALLOWED_TRANSCRIPTION_MODEL' \
--form-string 'response_format=json' \
--form-string 'model_gate={"async":true}' \
-F 'file=@recording.wav'
Do not paste a real key into shared examples or add automatic cURL retries. A different multipart boundary or changed file is a changed HTTP body; use the saved exact body for a browser-grant retry. Ordinary API idempotency is based on the validated intent, file digest and settings, not the random transport boundary.
Price check
Send the same multipart fields to POST /v1/audio/quote. It validates/decode-checks the file and returns a selected route_id, request.file facts, quote, quote_sha256 and explicit charged:false, file_content_verified:true, provider_health_verified:false. No business operation or wallet debit is created. This check does not prove the supplier is currently healthy or reserve funds.
A price can be per successful request, locally decoded duration, supplier-reported duration or token usage, according to your offer. Duration rates specify a rounding step; for decoded duration the exact decoded sample count, not MIME metadata or bytes, is used. Token-priced offers require actual non-overlapping audio/text input and text output usage. Required missing usage is unknown, not zero. All applicable valuations must have sufficient data even when the customer-facing amount is fixed.
Playground does not send max_cost_usd. Its optional legacy API form remains recognized for existing integrations, only for a provable fixed quote. Include the returned quote_sha256 in your launch to reject changes to the price context. It is not a promise of reserved capacity. A refreshed quote does not itself submit a new paid request.
Idempotency and execution
Creation requires Idempotency-Key, 1–128 ASCII non-space characters. The same key and unchanged intent returns the existing operation; different model, content, normalized settings, route or price conditions with that key are a conflict. async changes waiting behavior, not the intended work. Records survive output cleanup: changing or deleting your local pointer is not permission to resend paid work.
async=true returns HTTP202 and Location. Otherwise the connection waits up to55 seconds: completed work returns its saved response; unfinished accepted work returns202 and can continue after disconnect. Always inspect operation state; HTTP200 for a state GET is not proof of successful transcription.
States: queued → preparing → dispatching → received → completed. Safe preparation may wait for capacity; the queue has a five-minute lifetime. Once a paid dispatch has begun, timeout, redirect or ambiguous supplier failure never permits automatic POST replay or switching supplier. Unknown outcomes use outcome_unknown; an incompatible saved response or missing necessary pricing evidence uses review_required. A clear rejection can become failed. Read the safe error code and contact Support rather than creating a duplicate.
History and results
GET /v1/audio/operations?before=... returns the most recent50 scoped operations and a cursor. ?idempotency_key=... searches the same existing intent read-only; a momentary “not found” is not authorization for automatic replay. Default state responses are compact. The explicit details view adds quote, normalized usage and accounting_recorded.
/result returns the original stored response in the selected format, without another supplier call. Before completion it returns a conflict; unavailable/expired results are not regenerated. JSON includes the provider’s text and other accepted response fields; text, SRT and VTT are not wrapped in invented JSON. The service bounds supplier replies to4 MiB and transcript text to2 MiB. Results normally remain available for24 hours from creation; access must still be valid.
In the explicit details view, accounting_recorded means exactly one input has been submitted to the financial calculation, not confirmation that the balance or Usage Limit has already been updated. Recorded time and tariffs are not changed by later result reads. An unknown/review outcome cannot be assumed free merely because this flag is false.
Failure handling
Malformed requests use HTTP400; unsupported media/content type can use415, body limits413, unsupported parameters/quote changes422, conflicting intents409, permissions401/403, admission429 and unavailable catalog/decode service503. Operation failures are also reported in state, so do not rely only on transport status. Safe codes distinguish invalid files, expired queues, unknown dispatches, invalid result structures and required missing token/duration usage. Never send a second recording merely to bypass an unresolved first request.
File preparation and observable quote errors
An offer may declare an outbound WAV profile while accepting the input formats in its catalog. Clients still upload their original file. A successful quote adds transport_file: converted, format, mime, bytes and, when converted, sample_rate, channels, codec. It describes predicted output size based on the fully decoded sample count; it is not an uploaded-file hash or supplier health check. The original request.file remains separate. The catalog's max_request_bytes is the application body cap, not a guarantee that an earlier HTTP hop allows the same size.
audio_payload_too_large and audio_converted_file_too_large distinguish oversized original multipart from an oversized prepared WAV; both are rejected before a supplier POST. Local decoding also distinguishes audio_decode_timeout, audio_decode_failed, audio_format_unsupported and audio_codec_unsupported. Errors may come from an earlier HTTP hop as non-JSON text, so clients must preserve the observed status/content type rather than assuming all failures are JSON. Existing operation ids, frozen intent and no-automatic-paid-retry behavior are unchanged.
Settlement and saved supplier observations
Specific-operation GET and idempotency lookup with ?view=details include a read-only settlement object scoped to the same owner, principal, key and group. It has status, record_found, Unix settled_at, wallet_debited, usage_applied, and Unix observed_at. Unknown observations are JSON null. pending/failed have not established a completed debit; settled/recovered with a timestamp and positive recorded cost establish the recorded settlement event. not_required is distinct from a failed lookup. not_available means the matching accounting row is absent, possibly past retention; unavailable means observation failed. Neither means free work. Unobserved history rows can report not_checked; read the specific operation for a fresh observation. No observation creates a payment, refund or reservation.
supplier_http_status is the saved supplier status (0 before one is available), and response_saved indicates a recorded response timestamp. They are not the HTTP status of this API GET or of the original202 enqueue response. A saved5xx is not proof of no supplier cost. Do not automatically resubmit an unknown paid outcome.
Compact status and accounting details
Since version11.0.0, operation responses are compact by default: object, id, model, status, created, status_url, result_url. An actionable error_code or reported progress is included only when present. Completed results include availability, expiry and required file descriptors. Empty fields, quote, normalized usage, settlement and supplier diagnostics are omitted. Omission does not mean zero cost or a completed debit.
Use GET /v1/audio/operations/{id}?view=details for the previous full authorized accounting view. Lists and result manifests also support the explicit details view where applicable. Reading details never generates new media or expands access. The quote endpoint remains the separate place to inspect an uncharged price calculation.
Read a result: Raw and cURL
Use the same active API key and actor context that created the operation. Another key under the same account does not automatically inherit its results. Current access and domain/IP restrictions are checked again. Get OPERATION_ID from the accepted creation response or your authorized history, and set MODEL_API_KEY locally without publishing the secret. A temporary Playground permission is not a reusable CLI credential; copying a command does not export or enlarge that permission.
GET https://api.model-gate.com/v1/audio/operations/{id}/result
Authorization: Bearer <YOUR_API_KEY>
# status
curl --fail-with-body --request GET \
--url "https://api.model-gate.com/v1/audio/operations/${OPERATION_ID:?Set OPERATION_ID}" \
--header "Authorization: Bearer ${MODEL_API_KEY:?Set MODEL_API_KEY}" \
--output audio-status.json
# result
curl --fail-with-body --request GET \
--url "https://api.model-gate.com/v1/audio/operations/${OPERATION_ID:?Set OPERATION_ID}/result" \
--header "Authorization: Bearer ${MODEL_API_KEY:?Set MODEL_API_KEY}" \
--output transcript.json
/result is the saved transcription in the response format selected at creation. The example filename assumes JSON; use .txt, .srt or .vtt for those formats. Do not attempt to decode a text or subtitle result as JSON, and do not request a different format by changing the filename. The original recording is not a result download.
These are bodyless GET requests: no Content-Type, Idempotency-Key, quote, route_id or max_cost_usd is needed. Read status until it reports completion, then read the result/file. Pending, failed, expired and unauthorized responses are not output files; --fail-with-body returns a nonzero exit status for HTTP errors but may still write their body to the output filename. Check the status and content type before treating a downloaded body as media. Do not repeat a paid POST because a GET failed.
Playground's Get the result · Raw / cURL block generates these commands for the selected operation and its original key. They are examples of a new read, not a recording of an earlier HTTP exchange. Copying or switching command tabs makes no network request. Opening history or a saved result still performs its normal authorized read; it does not generate, reserve or charge again.