dvmkitdocs
DVM Reference

scribe

Reference for the scribe DVM, which converts audio / video to timestamped transcript, with tiered per-minute pricing, diarisation, schema, and error codes.

scribe takes an audio or video source and returns a structured, timestamped transcript. Whisper (via Groq) handles transcription across three quality tiers; optional speaker diarisation runs pyannote. Pricing is two-phase: a small flat upfront stake plus a per-measured-minute charge, so you pay for the audio you actually submit.

Canonical endpoint: https://scribe.dvmkit.ai. One capability: transcribe.

Published reference. This page is the source of truth for scribe's documented inputs, outputs, prices, and errors. The running service publishes its current capability schema and advertised price in its live descriptor. Full output envelope shapes are in the dvm CLI reference.

transcribe

Input

Provide exactly one of audio_url or audio_upload_handle. Every other field is an output-shape knob and does not affect price.

FieldTypeDefault
audio_urlstring (https, audio/* or video/*)one of two required
audio_upload_handleUUID from POST /v1/ingest/audioone of two required
quality"fast" | "accurate" | "premium""fast"
diariseboolean (speaker labels; extra per-min cost)false
word_timestampsboolean (include words[])false
output_format"json" | "text" | "srt" | "vtt""json"
output_delivery"inline" | "url" (signed R2, 7-day TTL)"inline"
vocabularystring[] (decoder hints; silently truncated)unset
speaker_countnumber (sharpens diarise)unset
languageISO 639-1 (force-decodes when set)auto
enhance_audioboolean (ffmpeg denoise + high-pass + loudness norm)false
strip_silenceboolean (drops silent passages; changes timestamps)false

The result envelope also carries a warnings[] array of non-fatal quality signals (e.g. fast_tier_casing_drift, possible_hallucination_silence), each with a human-relayable display and an upgrade_path naming the retry that would resolve it.

Bytes upload

When you have audio/video bytes but no hosting, stage them first, then reference the returned handle in a normal transcribe job:

# 1. POST the bytes with a signed claim envelope (helper: signUploadClaim)
curl -X POST https://scribe.dvmkit.ai/v1/ingest/audio \
  -H "Content-Type: application/octet-stream" \
  -H "X-Scribe-Upload-Claim: <base64-claim>" \
  --data-binary @meeting.mp4
# → { "upload_handle": "1111...", "bytes": 91234567, "mime": "video/mp4" }

Supported: MP3 / M4A / WAV / FLAC / OGG / WebM audio, mp4 / webm video. Cap 2 GB per upload; handles expire after 15 minutes if no job consumes them.

CLI example

dvm request -d dvmkit--scribe/transcribe --data '{"audio_url":"https://example.com/podcast.mp3"}'
dvm request -d dvmkit--scribe/transcribe --data '{"audio_url":"https://example.com/ep.mp3","quality":"accurate","diarise":true}'
dvm quote   -d dvmkit--scribe/transcribe --data '{"audio_url":"https://example.com/podcast.mp3","quality":"premium"}'

Auth

Signed requests are required. Every quote and job carries a secp256k1 + BIP-340 Schnorr signature over the canonical-JSON body, at the descriptor level so all capabilities share one auth slot. Drift window ±5 minutes; replay window 10 minutes. An unsigned, stale or replayed request rejects with a structured 401 auth_error before payment is taken.

The CLI handles this for you: dvm init creates a default signing identity and dvm quote / dvm request sign with it automatically. Pass --as <identity> only when you want to sign as a different one. If you see auth_error, run dvm identity list to check you have one.

Prepaid credit

scribe offers a prepaid balance, so an agent making repeated calls funds once instead of paying per job. The funding menu rides on every quote and every 402.

FieldValue
Minimum funding$0.10
Maximum residual balance$5.00
Credit lifetime30 days from the most recent funding
dvm credit fund dvmkit--scribe --amount 2.00
dvm credit balance dvmkit--scribe
dvm credit drain dvmkit--scribe     # reclaim it, works after expiry too

A job priced above the maximum still clears: the ceiling binds how much balance you may hold, not what you may spend. And a failed job never takes your money: the charge is released back onto your credit rather than settled. See Prepaid credit for the full model.

Pricing

A flat $0.02 upfront stake (spam-gate / fetch-cost cover) plus a per-minute rate charged on the measured duration once known. Sats round up (caller-friendly); a failure mid-pipeline means no charge: the draw is released back onto your credit.

TierVendorRate (USD/min)
fastGroq whisper-large-v3-turbo$0.005
accurateGroq whisper-large-v3$0.015
premiumAssemblyAI Universal-3 Pro$0.025
diarise: truepyannote (Replicate)+$0.005

The /v1/quote response returns the per-minute rate, the max-charge ceiling at the operator's input-duration cap (default 240 min), and the FX snapshot, so a caller can audit and size their token before submitting. Final charge = actual_minutes × rate, converted to sats at the quote-locked rate.

Error codes

Failures throw a typed error rendered to the CLI envelope as code (+ a sub_reason discriminator). Agents branch on code + sub_reason; the human-facing display is safe to relay verbatim. The provider_* codes and sub-reasons below name the upstream transcription vendor (Groq, AssemblyAI, or Replicate's pyannote), not scribe itself.

CodeRepresentative sub-reasonsTrigger
invalid_inputaudio_source_required, inline_too_large, ingest sha256_mismatch / size_mismatch / oversize / probe_failed, upload_handle_not_found / _expiredMalformed request, or a bad/expired bytes-upload handle
source_unreachableprivate_address, dns_failed, timeout, auth_required, not_found, rate_limited, server_errorSource URL couldn't be fetched (recovery varies by sub-reason)
format_unsupportedinsecure_scheme, invalid_url, wrong_content_type, decoder_failedSource isn't a fetchable https audio/video file, or ffmpeg couldn't decode it
duration_exceeds_capseconds_cap, bytes_capSource longer or larger than the operator's cap. Split into shorter clips
transcribe_failedprovider_unavailable, provider_rate_limit, provider_rejected_audio, no_premium_substrateTranscription vendor failed (most are transient; retry)
diarise_failedno_diariser, provider_unavailable, provider_timeout, provider_failedDiarisation vendor failed. Retry, or resubmit with diarise: false
provider_allowance_exhausted—The operator's own vendor plan (Groq, Replicate, or AssemblyAI) is out of credit, whatever status the vendor bills it under. Operator issue, not the caller's fault
fx_rate_unavailable—FX source unreachable; the quote can't lock a sats commitment. Retry
output_delivery_failedupload_failed, presign_failedBlob store threw on delivery. Retry with output_delivery: "inline"
auth_errorsignature_invalid, timestamp_drift, replay_detectedRequest (or bytes-upload claim) signature, clock, or nonce invalid; see Auth
rate_limitedingest_concurrency, ingest_ip_concurrency, ingest_global_concurrencyConcurrent-upload cap hit. Back off per Retry-After
internal_errordecoder_unavailable, unexpectedOperator misconfiguration or an unexpected fault

See also

On this page