[{"data":1,"prerenderedAt":4},["ShallowReactive",2],{"article-doc:docs\u002Frecorded\u002Ftranscribe-audio":3},"---\ntitle: Transcribe Audio\ndescription: Submit an audio URL for batch transcription.\n---\nSubmit a **batch transcription job** from a public audio URL.\n\nFor client-VAD speech clips use [Segment Transcription](\u002Fdocs\u002Fapi-reference\u002Fsegment-transcription) instead.\n\n## Submit a job\n\n### Request\n\n```bash\ncurl -X POST https:\u002F\u002Faudio.lansonai.com\u002Fv1\u002Faudio\u002Ftranscriptions\u002Fjobs \\\n  -H \"Authorization: Bearer sk-...\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"audio_url\": \"https:\u002F\u002Fcdn.example.com\u002Fmeeting.wav\",\n    \"language\": \"zh\",\n    \"prompt\": \"Medical cardiology conference\",\n    \"webhook_url\": \"https:\u002F\u002Fyour-server.com\u002Fwebhook\"\n  }'\n```\n\n### Request body\n\n| Field | Type | Required | Default | Description |\n|---|---|---|---|---|\n| `audio_url` | string | **yes** | — | Public audio URL, must be `http(s):\u002F\u002F` |\n| `request_id` | string | no | random UUID | Idempotency key; same ID resumes from R2 checkpoint |\n| `language` | string | no | — | 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 | Slice length in seconds, must be > 0 |\n| `response_format` | string | no | `verbose_json` | Response format |\n| `concurrency` | number | no | 6 | Concurrent chunk transcription, must be > 0 |\n| `webhook_url` | string | no | — | POST final result to this URL on completion |\n| `review` | boolean | no | `false` | Enable two-stage LLM review |\n| `metadata` | object | no | — | Context forwarded to review stages |\n\n::callout{icon=\"i-lucide-info\"}\n`response_format` defaults to `verbose_json` in the OpenAPI schema, but the workflow currently hardcodes `verbose_json` for every chunk transcription. Setting this field has no effect today.\n::\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 id (`cf_` + 64 hex), not a UUID.\n\n## Poll for results\n\n```bash\ncurl https:\u002F\u002Faudio.lansonai.com\u002Fv1\u002Faudio\u002Ftranscriptions\u002Fjobs\u002F\u003Cworkflow_id> \\\n  -H \"Authorization: Bearer sk-...\"\n```\n\nLegacy aliases: `GET \u002F\u003Cworkflow_id>`, `GET \u002Fv1\u002Faudio\u002Ftranscriptions\u002F\u003Cworkflow_id>`\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\n### Complete output\n\n```json\n{\n  \"status\": \"complete\",\n  \"output\": {\n    \"result\": {\n      \"segments\": [\n        { \"id\": 0, \"start_time\": 0.0, \"end_time\": 3.2, \"duration\": 3.2, \"text\": \"The weather is nice today\", \"confidence\": 0.95 }\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        \"chunk_count\": 3,\n        \"audio_duration_seconds\": 120.5\n      }\n    }\n  }\n}\n```\n\n## Webhook\n\nSet `webhook_url` to receive the final result via HTTP POST when the job completes.\n\n## LLM review\n\nSet `review: true` to enable two-stage LLM correction.\n\n## R2 artifacts\n\nResults are stored in R2 under `transcription\u002F{request_id}\u002F`:\n\n| Artifact | 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## Idempotency\n\nProvide `request_id` for idempotency — already-transcribed chunks are skipped on retry.\n\n## Related\n\n- [Batch Jobs API](\u002Fdocs\u002Fapi-reference\u002Fbatch-jobs)\n- [Segment Transcription](\u002Fdocs\u002Fapi-reference\u002Fsegment-transcription)\n- [Timestamps & Speakers](\u002Fdocs\u002Frecorded\u002Ftimestamps-speakers)\n- [Translation](\u002Fdocs\u002Frecorded\u002Ftranslation)\n",1790059118961]