Transcribe Audio
Submit an audio file or URL for transcription.
Submit audio for asynchronous transcription.
Submit a job
Request
curl -X POST https://audio.lansonai.com/v1/audio/transcriptions \
-H "Authorization: Bearer sk-..." \
-H "Content-Type: application/json" \
-d '{
"audio_url": "https://cdn.example.com/meeting.wav",
"language": "zh",
"prompt": "Medical cardiology conference",
"webhook_url": "https://your-server.com/webhook"
}'
Request body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
audio_url | string | yes | — | Public audio URL, must be http(s):// |
request_id | string | no | random UUID | Idempotency key; same ID resumes from R2 checkpoint |
language | string | no | — | 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 | Slice length in seconds, must be > 0 |
response_format | string | no | verbose_json | Response format |
concurrency | number | no | 6 | Concurrent chunk transcription, must be > 0 |
webhook_url | string | no | — | POST final result to this URL on completion |
review | boolean | no | false | Enable two-stage LLM review |
metadata | object | no | — | Context 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>"
}
Poll for results
curl https://audio.lansonai.com/<workflow_id> \
-H "Authorization: Bearer sk-..."
Status values
| Status | Meaning |
|---|---|
queued | Waiting to start |
running | Processing |
complete | Done (result in output) |
errored | Failed (error in error) |
terminated | Terminated |
Complete output
{
"status": "complete",
"output": {
"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
}
}
}
}
Webhook
Set webhook_url to receive the final result via HTTP POST when the job completes. Eliminates the need for polling.
LLM review
Set review: true to enable two-stage LLM correction:
- Per-chunk review: each chunk is independently reviewed by an LLM
- Global review: after aggregation, a final correction pass
Suitable for high-accuracy scenarios (medical, legal). The metadata field passes context to the review stages.
R2 artifacts
Results are stored in R2 under transcription/{request_id}/:
| Artifact | 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) |
Idempotency
Provide request_id for idempotency:
- Same
request_idresumes from R2 checkpoint - Already-transcribed chunks are skipped
- Avoids duplicate processing on retry
Related
- Transcription API — API reference
- Timestamps & Speakers — timestamp details
- Translation — file-level translation
