Speko Docs
Build

Batch transcription

POST /v1/transcribe with workload=transcription: diarization, formatting, and per-provider batch params.

Recorded audio in, formatted transcript out. Set workload: "transcription" in the X-Speko-Stt-Options header to apply transcript-reading defaults such as smart formatting instead of the conversational defaults live agents use.

curl -X POST https://api.speko.dev/v1/transcribe \
  -H "Authorization: Bearer $SPEKO_API_KEY" \
  -H "Content-Type: audio/wav" \
  -H "x-speko-intent: {\"language\":\"en-US\"}" \
  -H "x-speko-stt-options: {\"workload\":\"transcription\"}" \
  --data-binary @meeting.wav

The response is the usual SSE stream. When the request uses workload or any provider param, the final done event reports what actually applied:

{
  "text": "...",
  "provider": "deepgram",
  "model": "nova-3",
  "confidence": 0.96,
  "failoverCount": 0,
  "effectiveParams": {
    "provider": "deepgram",
    "model": "nova-3",
    "applied": ["smartFormat"],
    "defaultsVersion": "2026-08-06"
  }
}

warnings appears alongside effectiveParams when params were dropped or candidates excluded. The per-provider defaults each workload applies are listed in Provider params.

Diarization

curl -X POST https://api.speko.dev/v1/transcribe \
  -H "Authorization: Bearer $SPEKO_API_KEY" \
  -H "Content-Type: audio/wav" \
  -H "x-speko-intent: {\"language\":\"en-US\"}" \
  -H "x-speko-stt-options: {\"workload\":\"transcription\",\"diarization\":true,\"speakersExpected\":2}" \
  --data-binary @interview.wav
  • diarization is batch-only and demote-class: providers that cannot diarize are removed from the failover ladder before the first attempt, each reported as a candidate_excluded warning. If no capable provider remains, the request fails with 422 { "error": "no_capable_provider", "param": "diarization" } rather than silently transcribing without speakers.
  • speakersExpected is a hint, forwarded where supported (AssemblyAI speakers_expected, ElevenLabs num_speakers, Google diarizationConfig.maxSpeakerCount) and dropped elsewhere.
  • Speaker labels are normalized to S0, S1, ... across providers on word-level output. Today the /v1/transcribe response returns the merged transcript text; exposing the per-word speaker labels on this endpoint is a follow-up.

Batch formatting params

Provider-specific batch knobs go in providerOptions. They are validated up front and apply only when that provider serves the request:

curl -X POST https://api.speko.dev/v1/transcribe \
  -H "Authorization: Bearer $SPEKO_API_KEY" \
  -H "Content-Type: audio/wav" \
  -H "x-speko-intent: {\"language\":\"en-US\"}" \
  -H "x-speko-stt-options: {\"workload\":\"transcription\",\"providerOptions\":{\"deepgram\":{\"dictation\":true}}}" \
  --data-binary @meeting.wav

Common batch params:

ProviderParamTypeValuesEffect
Deepgramdetect_languagebooleanDetects the dominant language of each channel.
AssemblyAImultichannelbooleanTranscribes each channel of a recording separately.
AssemblyAIlanguage_detectionbooleanDetects the language of a prerecorded transcript.
ElevenLabstimestamps_granularityenumword, characterSelects word- or character-level transcript timestamps.
ElevenLabstag_audio_eventsbooleanIncludes non-speech audio event tags in the transcript.

Full registry, validation rules, and failover semantics: Provider params.

Picking providers

  • POST /v1/recommend-stack with { "useCase": "<vertical id>" } returns ranked stacks per vertical; POST /v1/recommend-stack/from-description classifies a freeform description first.
  • To pin the STT pool directly, use the x-speko-constraints header: {"allowedProviders":{"stt":["deepgram","assemblyai"]}}. Routing still ranks within the allow-list.

Limits

  • X-Speko-Stt-Options is capped at 4 KB.
  • /v1/transcribe validates params against the batch surface. Streaming-only params (Deepgram endpointing, AssemblyAI turn thresholds) belong to the streaming WebSocket, /v1/transcribe/stream.

On this page