Skip to main content
Use POST /v1/asr/batches when a recording needs background processing or you want to submit several recordings together. A batch can contain a single file. Each input becomes an independent transcription with its own ID, status, result, and billing.
Beta. File acceptance constraints can change. Handle submission errors and per-file failures instead of assuming every recording can be accepted. CSV uploads and intermediate-result streaming are not supported.
For a complete transcript in the same HTTP request, use File transcription. For live audio, use the WebSocket.

Batch limits

These are the current default limits for the beta async API. Deployment configuration can change the duration, byte-size, and processing-time limits. The synchronous file API has separate, smaller limits. Duration is checked per recording, not across the batch. The request-size allowance includes form fields and framing; it does not increase the per-file limit. Acceptance does not guarantee that processing will complete within the job deadline.

Upload a recording

Send multipart/form-data with a JSON string in manifest and one files attachment. Use file_index: 0 to reference that attachment exactly once. The field retains the name files, but accepts at most one file per request. Give each input a custom_id that is unique within the batch so you can match results to your own records.
Let your HTTP client set the multipart boundary. Send encoded media files, such as WAV, MP3, FLAC, or an MP4 containing an audio track. You do not need to pace uploads in real time or convert them into WebSocket audio frames. The API receives the uploaded file and stores the original before accepting the batch. The async worker then retrieves it and processes it in the background. A 202 response confirms acceptance, not successful transcription. Once accepted, a job continues if you close the tab or disconnect. Save the batch ID and poll from a later request.

Submit media URLs

For multiple recordings, send JSON with an audio_url for each input, up to 100 inputs:
Use direct public HTTP or HTTPS media URLs. Signed URLs are supported. Keep each URL valid while the job waits and downloads, including retries. The async worker downloads the media after acceptance. A URL submission does not download the media before returning 202. Private-network URLs and URLs requiring custom authentication headers cannot be fetched. Each input must have exactly one of audio_url or file_index. You can mix up to 99 URL inputs with one upload in a multipart manifest. The files field is optional when every input uses audio_url. JSON-only submissions use URLs.

Choose settings per file

See Languages, modes, and styles. Settings belong to each input, so files in the same batch can use different settings.

Retry a submission safely

Supply an Idempotency-Key and save it with your request. If the submission times out before you receive its ID, retry with the same key, manifest, and file bytes. A matching retry returns the existing batch and the same input-to-transcription ID mapping. Reusing that key for different inputs or settings returns 409. A new key creates a new batch and can lead to another charge. Idempotency recovers submission results; it does not restart a failed file. To retry a terminal failed file, submit it as a new batch.

Poll the batch and its files

An accepted batch looks like this:
Work can start immediately, so the initial status may already be processing.
1

Save the batch ID

Poll GET /v1/asr/batches/{batch_id} for aggregate status and counts. Missing status keys in counts mean zero files have that status.
2

Find each transcription ID

Save the items mapping returned by submission. Each entry contains your custom_id and its transcription id, in submission order. You can also fetch items_url on the same API host with your API key, following next_cursor until null. History is ordered newest first, so correlate by custom_id, not position.
3

Read each result

Poll GET /v1/asr/transcriptions/{transcription_id} until completed, failed, or cancelled. Poll every few seconds with backoff on transient errors. A successful polling HTTP response does not itself mean the transcription succeeded.
A completed transcription includes these fields (other metadata omitted):
Word times are estimates in seconds from the beginning of the recording. words is empty when timestamps were not requested; it can be null when timing data is unavailable. Confidence scores and speaker labels are not returned.

Status and progress

Batches use queued, processing, and cancelling while active. Their terminal statuses are: progress.stage describes the current activity, such as downloading, decoding, sending_audio, or transcribing. progress.stage_percent describes that stage only and can be null. For example, sending 100% of the audio does not mean transcription has finished. It is not a processed-duration counter or a completion ETA. Polling may return a partial result.text with is_final: false, or result: null before text is available. Treat each partial result as a snapshot, not a delta to append. Partial snapshots are not guaranteed and can change. Use the final result after completed for downstream work.

Cancel unfinished work

Cancel one transcription or the unfinished files in a batch:
Cancellation returns 202 with current resource details. An already terminal batch or transcription stays unchanged, without an extra refund or terminal event. Continue polling until terminal. A running file can complete before cancellation takes effect. Finished files remain unchanged. These routes do not cancel synchronous file requests or live WebSocket sessions. Async transcription shares workspace ASR concurrency with live and synchronous file requests. Queued files wait for capacity. A slot is held while a file is being prepared and transcribed. Completed files are billed by audio duration. A file cancelled or failed after charging receives a full refund; a file stopped before charging has no charge. Saved partial text is not currently billed separately. Check billing.status for the settled outcome. billing.credits is the current net debit, so a full refund leaves zero credits. Cancellation does not refund files that already completed.

Handle submission and processing errors

Submission rejection versus per-file failure

For example, nine successful recordings and one over-duration recording produce a partially_completed batch. Duration validation happens before charging that recording. The failed transcription currently reports error.code: "invalid_input". After acceptance, download, decoding, credit, and transcription failures are reported on the individual transcription. Inspect its status, error, and billing; do not infer success from 202. Application error responses follow Errors & troubleshooting. You can replace frequent polling with completion webhooks, and use unified history to find jobs later.

Processing error codes

Error messages are safe descriptions, not stable identifiers. Handle unknown future codes as failures and retain the transcription ID for support. See Transcription history for the complete resource field semantics.