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"
}
FieldTypeRequiredDefaultDescription
audio_urlstringyesPublic URL of the audio file. Must be http(s)://.
request_idstringnorandom UUIDIdempotency key. Re-submitting with the same ID resumes from R2 checkpoints.
languagestringnoAudio language hint (e.g. zh, en).
modelstringnowhisper-large-v3-turboSTT model override.
promptstringnoTranscription context hint.
segment_secondsnumberno300Target slice length in seconds. Must be > 0.
response_formatstringnoverbose_jsonResponse format.
concurrencynumberno6Concurrent transcription of chunks. Must be > 0.
webhook_urlstringnoPOSTed the full result (raw + reviewed) when the job completes.
reviewbooleannofalseEnable two-stage LLM review pipeline.
metadataobjectnoContextual 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

StatusDescription
400Non-JSON body or invalid/missing audio_url
401Authentication 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

StatusMeaning
queuedWaiting to start
runningProcessing
completeDone (result in output)
erroredFailed (error in error)
terminatedTerminated
pausedPaused
waitingWaiting

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

FieldTypeDescription
idnumberSegment index (from 0)
start_timenumberStart time in seconds
end_timenumberEnd time in seconds
durationnumberDuration in seconds
textstringTranscribed text
confidencenumberConfidence score (0–1, 3 decimal places)

R2 artifacts

Result artifacts are stored in R2 under transcription/{request_id}/:

ArtifactR2 key
Per-chunk transcriptionchunk_{i}.json
Raw aggregated transcriptresult.json
Per-chunk review annotationsreview_chunk_{i}.json (when review: true)
Final corrected transcriptreviewed_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.