Transcription API
Recorded (offline) transcription endpoint.
POST /v1/audio/transcriptions
What it does
Submit an audio URL for asynchronous transcription. The service fetches the file, slices it, transcribes the segments concurrently, aggregates the results, and optionally posts them to a webhook.
Endpoint
POST /v1/audio/transcriptions
POST / is a backward-compatible alias.
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 | whisper-large-v3-turbo | 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. |
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 (e.g. medical_specialty, speaker_roles, known_medications). |
response_format defaults to verbose_json in the OpenAPI schema, but the offline workflow currently hardcodes verbose_json for every chunk transcription. Setting this field has no effect today.Response — 202 Accepted
{
"request_id": "...",
"workflow_id": "<uuid>",
"status": "queued",
"endpoint": "GET /<workflow_id>"
}
Errors
| Status | Description |
|---|---|
| 400 | Non-JSON body or invalid/missing audio_url |
| 401 | Authentication failed |
GET /{workflowId}
What it does
Poll the status and result of a transcription job.
Endpoint
GET /{workflowId}
Response
{
"workflow_id": "...",
"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
}
}
}
Segment fields
| Field | Type | Description |
|---|---|---|
id | number | Segment index (from 0) |
start_time | number | Start time in seconds |
end_time | number | End time in seconds |
duration | number | Duration in seconds |
text | string | Transcribed text |
confidence | number | Confidence score (0–1, 3 decimal places) |
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.
Related
- Transcribe Audio — usage guide
- Timestamps & Speakers — timestamp details
- Errors — error codes
