POST /v1/audio/transcriptions/jobs
What it does
Submit an audio URL for asynchronous batch transcription. The service fetches the file, slices it by time, transcribes chunks concurrently, aggregates results, and optionally posts to a webhook.
For synchronous client-VAD clips use [Segment Transcription](/docs/api-reference/segment-transcription) (POST /v1/audio/transcriptions with multipart).
Endpoint
POST /v1/audio/transcriptions/jobs
POST / and POST /v1/audio/transcriptions with JSON still work but are deprecated (return Deprecation: true).
Authentication
Authorization: Bearer sk-...
Request body
{
"audio_url": "https://cdn.example.com/audio/meeting.wav",
"language": "zh",
"prompt": "Medical cardiology conference",
"review": true,
"metadata": { "medical_specialty": "cardiology" },
"webhook_url": "https://your-server.com/webhook"
}
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| audio_url | string | yes | — | Public URL of the audio file. Must be http(s)://. |
| request_id | string | no | random UUID | Idempotency key. Re-submitting with the same ID resumes from R2 checkpoints. |
| language | string | no | — | Audio language hint (e.g. zh, en). |
| model | string | no | env default | STT model override. |
| prompt | string | no | — | Transcription context hint. |
| segment_seconds | number | no | 300 | Target slice length in seconds. Must be > 0. |
| response_format | string | no | verbose_json | Response format (workflow hardcodes verbose_json per chunk today). |
| concurrency | number | no | 6 | Concurrent transcription of chunks. Must be > 0. |
| webhook_url | string | no | — | POSTed the full result (raw + reviewed) when the job completes. |
| review | boolean | no | false | Enable two-stage LLM review pipeline. |
| metadata | object | no | — | Contextual metadata forwarded to review stages. |
Response — 202 Accepted
{
"request_id": "...",
"workflow_id": "cf_55190d1a608984daf77cbfca6b7b5438891436f8522f2be7be12fc93fa239ad4",
"status": "queued",
"endpoint": "GET /cf_...",
"poll_endpoint": "GET /v1/audio/transcriptions/jobs/cf_..."
}
workflow_id is a Cloudflare Workflow instance id (cf_ + 64 hex), not a UUID.
Errors
| Status | Description |
|---|---|
| 400 | Non-JSON body or invalid/missing audio_url |
| 401 | Authentication failed |
GET /v1/audio/transcriptions/jobs/{workflowId}
What it does
Poll batch job status and result (preferred path).
Endpoint
GET /v1/audio/transcriptions/jobs/{workflowId}
Aliases: GET /v1/audio/transcriptions/{workflowId}, GET /{workflowId}
Response
{
"workflow_id": "cf_...",
"status": "complete",
"steps": [ ... ],
"output": { ... },
"error": null
}
Status values
| Status | Meaning |
|---|---|
| queued | Waiting to start |
| running | Processing |
| complete | Done (result in output) |
| errored | Failed (error in error) |
| terminated | Terminated |
| paused | Paused |
| waiting | Waiting |
Complete output structure
{
"result": {
"segments": [
{
"id": 0,
"start_time": 0.0,
"end_time": 3.2,
"duration": 3.2,
"text": "The weather is nice today",
"confidence": 0.95
}
],
"summary": {
"total_duration": 120.5,
"total_speech_duration": 95.3,
"overall_speech_ratio": 0.79,
"num_segments": 45
},
"metadata": {
"language": "zh",
"model": "whisper-large-v3-turbo",
"chunk_count": 3,
"audio_duration_seconds": 120.5
}
}
}
R2 artifacts
Result artifacts are stored in R2 under transcription/{request_id}/:
| Artifact | R2 key |
|---|---|
| Per-chunk transcription | chunk_{i}.json |
| Raw aggregated transcript | result.json |
| Per-chunk review annotations | review_chunk_{i}.json (when review: true) |
| Final corrected transcript | reviewed_result.json (when review: true) |
Webhook
Set webhook_url to receive the final result via HTTP POST when the job completes.
OpenAPI
Full OpenAPI specification at GET /openapi.json. Swagger UI at GET /docs.