[{"data":1,"prerenderedAt":4},["ShallowReactive",2],{"article-doc:docs\u002Fapi-reference\u002Fbatch-jobs":3},"---\ntitle: Batch Transcription Jobs\ndescription: Asynchronous batch transcription from audio_url (CF Workflow).\n---\n\n## POST \u002Fv1\u002Faudio\u002Ftranscriptions\u002Fjobs\n\n### What it does\n\nSubmit 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.\n\nFor synchronous client-VAD clips use [Segment Transcription](\u002Fdocs\u002Fapi-reference\u002Fsegment-transcription) (`POST \u002Fv1\u002Faudio\u002Ftranscriptions` with multipart).\n\n### Endpoint\n\n```\nPOST \u002Fv1\u002Faudio\u002Ftranscriptions\u002Fjobs\n```\n\n`POST \u002F` and `POST \u002Fv1\u002Faudio\u002Ftranscriptions` with JSON still work but are **deprecated** (return `Deprecation: true`).\n\n### Authentication\n\n```\nAuthorization: Bearer sk-...\n```\n\n### Request body\n\n```json\n{\n  \"audio_url\": \"https:\u002F\u002Fcdn.example.com\u002Faudio\u002Fmeeting.wav\",\n  \"language\": \"zh\",\n  \"prompt\": \"Medical cardiology conference\",\n  \"review\": true,\n  \"metadata\": { \"medical_specialty\": \"cardiology\" },\n  \"webhook_url\": \"https:\u002F\u002Fyour-server.com\u002Fwebhook\"\n}\n```\n\n| Field | Type | Required | Default | Description |\n|---|---|---|---|---|\n| `audio_url` | string | **yes** | — | Public URL of the audio file. Must be `http(s):\u002F\u002F`. |\n| `request_id` | string | no | random UUID | Idempotency key. Re-submitting with the same ID resumes from R2 checkpoints. |\n| `language` | string | no | — | Audio language hint (e.g. `zh`, `en`). |\n| `model` | string | no | env default | STT model override. |\n| `prompt` | string | no | — | Transcription context hint. |\n| `segment_seconds` | number | no | 300 | Target slice length in seconds. Must be > 0. |\n| `response_format` | string | no | `verbose_json` | Response format (workflow hardcodes verbose_json per chunk today). |\n| `concurrency` | number | no | 6 | Concurrent transcription of chunks. Must be > 0. |\n| `webhook_url` | string | no | — | POSTed the full result (raw + reviewed) when the job completes. |\n| `review` | boolean | no | `false` | Enable two-stage LLM review pipeline. |\n| `metadata` | object | no | — | Contextual metadata forwarded to review stages. |\n\n### Response — 202 Accepted\n\n```json\n{\n  \"request_id\": \"...\",\n  \"workflow_id\": \"cf_55190d1a608984daf77cbfca6b7b5438891436f8522f2be7be12fc93fa239ad4\",\n  \"status\": \"queued\",\n  \"endpoint\": \"GET \u002Fcf_...\",\n  \"poll_endpoint\": \"GET \u002Fv1\u002Faudio\u002Ftranscriptions\u002Fjobs\u002Fcf_...\"\n}\n```\n\n`workflow_id` is a Cloudflare Workflow instance id (`cf_` + 64 hex), **not** a UUID.\n\n### Errors\n\n| Status | Description |\n|---|---|\n| 400 | Non-JSON body or invalid\u002Fmissing `audio_url` |\n| 401 | Authentication failed |\n\n---\n\n## GET \u002Fv1\u002Faudio\u002Ftranscriptions\u002Fjobs\u002F{workflowId}\n\n### What it does\n\nPoll batch job status and result (**preferred** path).\n\n### Endpoint\n\n```\nGET \u002Fv1\u002Faudio\u002Ftranscriptions\u002Fjobs\u002F{workflowId}\n```\n\nAliases: `GET \u002Fv1\u002Faudio\u002Ftranscriptions\u002F{workflowId}`, `GET \u002F{workflowId}`\n\n### Response\n\n```json\n{\n  \"workflow_id\": \"cf_...\",\n  \"status\": \"complete\",\n  \"steps\": [ ... ],\n  \"output\": { ... },\n  \"error\": null\n}\n```\n\n### Status values\n\n| Status | Meaning |\n|---|---|\n| `queued` | Waiting to start |\n| `running` | Processing |\n| `complete` | Done (result in `output`) |\n| `errored` | Failed (error in `error`) |\n| `terminated` | Terminated |\n| `paused` | Paused |\n| `waiting` | Waiting |\n\n### Complete output structure\n\n```json\n{\n  \"result\": {\n    \"segments\": [\n      {\n        \"id\": 0,\n        \"start_time\": 0.0,\n        \"end_time\": 3.2,\n        \"duration\": 3.2,\n        \"text\": \"The weather is nice today\",\n        \"confidence\": 0.95\n      }\n    ],\n    \"summary\": {\n      \"total_duration\": 120.5,\n      \"total_speech_duration\": 95.3,\n      \"overall_speech_ratio\": 0.79,\n      \"num_segments\": 45\n    },\n    \"metadata\": {\n      \"language\": \"zh\",\n      \"model\": \"whisper-large-v3-turbo\",\n      \"chunk_count\": 3,\n      \"audio_duration_seconds\": 120.5\n    }\n  }\n}\n```\n\n## R2 artifacts\n\nResult artifacts are stored in R2 under `transcription\u002F{request_id}\u002F`:\n\n| Artifact | R2 key |\n|---|---|\n| Per-chunk transcription | `chunk_{i}.json` |\n| Raw aggregated transcript | `result.json` |\n| Per-chunk review annotations | `review_chunk_{i}.json` (when `review: true`) |\n| Final corrected transcript | `reviewed_result.json` (when `review: true`) |\n\n## Webhook\n\nSet `webhook_url` to receive the final result via HTTP POST when the job completes.\n\n## OpenAPI\n\nFull OpenAPI specification at `GET \u002Fopenapi.json`. Swagger UI at `GET \u002Fdocs`.\n\n## Related\n\n- [Transcribe Audio](\u002Fdocs\u002Frecorded\u002Ftranscribe-audio) — usage guide\n- [Segment Transcription](\u002Fdocs\u002Fapi-reference\u002Fsegment-transcription) — sync client-VAD clips\n- [Timestamps & Speakers](\u002Fdocs\u002Frecorded\u002Ftimestamps-speakers) — timestamp details\n- [Errors](\u002Fdocs\u002Fapi-reference\u002Ferrors) — error codes\n",1790059118945]