transcribe
POST /v1/transcribe — speech-to-text with automatic provider routing.
Transcribe an audio payload. The router picks the best STT provider for your (language, optimize_for) and fails over automatically.
result = speko.transcribe(
audio_bytes,
language="es-MX",
)
print(result.text, result.provider, result.confidence)Signature
Speko.transcribe(
audio: bytes,
*,
language: str,
optimize_for: OptimizeFor | None = None,
content_type: str = "audio/wav",
constraints: PipelineConstraints | dict | None = None,
) -> TranscribeResultawait AsyncSpeko.transcribe(
audio: bytes,
*,
language: str,
optimize_for: OptimizeFor | None = None,
content_type: str = "audio/wav",
constraints: PipelineConstraints | dict | None = None,
) -> TranscribeResultParameters
audiobytesrequiredRaw audio bytes. Providers handle resampling and format conversion — any sample rate works. Wrap bytearray / memoryview with bytes(...) at the call site.
languagestringrequiredBCP-47 language tag, e.g. "en", "es-MX", "ja-JP".
optimize_for'balanced' | 'accuracy' | 'latency' | 'cost'Preset that biases the weighted score. Server default is balanced.
content_typestringdefault: audio/wavMIME type for the request body.
constraintsPipelineConstraints | dictAllow-list constraints. The router still ranks by score but only considers listed providers.
Returns — TranscribeResult
textstringTranscribed text.
providerstringUpstream provider that ran the request.
modelstringProvider-specific model identifier.
confidencefloat | NoneModel-reported confidence when available.
failover_countintNumber of providers tried before this one succeeded.
scores_run_idstring | NoneID of the scoring run that selected this provider — useful for joining to benchmark data.
Example — non-default MIME + allow-list
from pathlib import Path
from spekoai import AllowedProviders, PipelineConstraints, Speko
speko = Speko(api_key="sk_live_...")
audio = Path("call.ogg").read_bytes()
result = speko.transcribe(
audio,
language="en",
optimize_for="accuracy",
content_type="audio/ogg",
constraints=PipelineConstraints(
allowed_providers=AllowedProviders(stt=["deepgram", "assemblyai"]),
),
)Wire format
The audio ships as the raw HTTP body. The routing intent and constraints travel in two headers so no server-side re-parsing of the body is needed:
Content-Type: value ofcontent_type(defaultaudio/wav).X-Speko-Intent: compact JSON{"language", "optimizeFor"?}.X-Speko-Constraints: compact JSON whenconstraintsis set.
The response is a JSON TranscribeResult.
Provider params (API-level)
POST /v1/transcribe also accepts workload, diarization, speakersExpected, smartFormat, fillerWords, profanityFilter, and providerOptions in the X-Speko-Stt-Options header. The typed client does not expose these yet - call the endpoint directly to use them:
import httpx, json
res = httpx.post(
"https://api.speko.dev/v1/transcribe",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "audio/wav",
"X-Speko-Intent": json.dumps({"language": "en-US"}),
"X-Speko-Stt-Options": json.dumps(
{"workload": "transcription", "diarization": True}
),
},
content=audio,
)
# Response is the SSE stream (meta / transcript / done events); the done
# event carries effectiveParams + warnings when these fields are used.Field semantics, per-provider params, and failover behavior: Provider params and the batch transcription guide.