Batch Transcription Jobs

Asynchronous batch transcription from audio_url (CF Workflow).

POST /v1/audio/transcriptions/jobs

What it does

Submit 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.

For synchronous client-VAD clips use Segment Transcription (POST /v1/audio/transcriptions with multipart).

Endpoint

POST /v1/audio/transcriptions/jobs

POST / and POST /v1/audio/transcriptions with JSON still work but are deprecated (return Deprecation: true).

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_urlstringyes—Public URL of the audio file. Must be http(s)://.
request_idstringnorandom UUIDIdempotency key. Re-submitting with the same ID resumes from R2 checkpoints.
languagestringno—Audio language hint (e.g. zh, en).
modelstringnoenv defaultSTT model override.
promptstringno—Transcription context hint.
segment_secondsnumberno300Target slice length in seconds. Must be > 0.
response_formatstringnoverbose_jsonResponse format (workflow hardcodes verbose_json per chunk today).
concurrencynumberno6Concurrent transcription of chunks. Must be > 0.
webhook_urlstringno—POSTed the full result (raw + reviewed) when the job completes.
reviewbooleannofalseEnable two-stage LLM review pipeline.
metadataobjectno—Contextual metadata forwarded to review stages.

Response — 202 Accepted

{
  "request_id": "...",
  "workflow_id": "cf_55190d1a608984daf77cbfca6b7b5438891436f8522f2be7be12fc93fa239ad4",
  "status": "queued",
  "endpoint": "GET /cf_...",
  "poll_endpoint": "GET /v1/audio/transcriptions/jobs/cf_..."
}

workflow_id is a Cloudflare Workflow instance id (cf_ + 64 hex), not a UUID.

Errors

StatusDescription
400Non-JSON body or invalid/missing audio_url
401Authentication failed

GET /v1/audio/transcriptions/jobs/{workflowId}

What it does

Poll batch job status and result (preferred path).

Endpoint

GET /v1/audio/transcriptions/jobs/{workflowId}

Aliases: GET /v1/audio/transcriptions/{workflowId}, GET /{workflowId}

Response

{
  "workflow_id": "cf_...",
  "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
    }
  }
}

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.