Speko Docs
Concepts

Provider params

Canonical STT/TTS fields, provider-scoped providerOptions, workload defaults, and how params behave across failover.

Routing picks the provider; provider params tune what that provider does. There are two layers:

  • Canonical fields (L1) - one cross-provider name, translated to each vendor's wire param by Speko.
  • providerOptions (L2) - provider-scoped passthrough, validated against Speko's param registry. A provider's options apply only when that provider serves the request.

Where params are accepted

SurfaceFieldsValidated as
POST /v1/transcribe - X-Speko-Stt-Options header (JSON, max 4 KB)workload, diarization, speakersExpected, smartFormat, fillerWords, profanityFilter, providerOptions (plus keywords, language)batch
WS /v1/transcribe/stream - config framesame STT request fields; diarization has no streaming mapping yetstreaming
POST /v1/synthesize - bodyworkload, providerOptionsstreaming
/v1/sessions, /v1/sessions/phone, /v1/agents - sttOptions / ttsOptionssame STT request fields; diarization is batch-only; TTS: workload, providerOptions (providerOptions capped at 2 KB serialized)streaming

Each providerOptions param in the registry declares the surfaces it supports. Sending one on the wrong surface is rejected with unsupported_surface - for example Deepgram's streaming-only endpointing on /v1/transcribe. Canonical fields use the failover rules below; diarization currently has batch mappings only.

Canonical fields (L1)

FieldTypeMeaningWhen a candidate cannot serve it
diarizationbooleanSeparate speakers in a batch transcriptdemote (candidate excluded)
speakersExpectedintegerHint of how many speakers to expectdrop
smartFormatbooleanProvider-side formatting (punctuation, casing, numbers)drop
fillerWordsbooleanKeep filler words ("um", "uh") instead of removing themdrop
profanityFilterbooleanMask profanity in the transcriptdrop
wordTimestampsbooleanPer-word start/end timings in the done frame's wordsdemote (candidate excluded)

Per-provider wire mapping:

FieldProviderWire paramSurfaces
diarizationDeepgramdiarizebatch
diarizationAssemblyAIspeaker_labelsbatch
diarizationElevenLabsdiarizebatch
diarizationSonioxenable_speaker_diarizationbatch
diarizationGooglediarizationConfigbatch
speakersExpectedAssemblyAIspeakers_expectedbatch
speakersExpectedElevenLabsnum_speakersbatch
speakersExpectedGooglediarizationConfig.maxSpeakerCountbatch
smartFormatDeepgramsmart_formatstreaming, batch
smartFormatAssemblyAIformat_text + punctuate (streaming: format_turns)batch
smartFormatGooglefeatures.enableAutomaticPunctuationstreaming, batch
smartFormatxAIformatbatch
fillerWordsDeepgramfiller_wordsstreaming, batch
fillerWordsAssemblyAIdisfluenciesbatch
profanityFilterDeepgramprofanity_filterstreaming, batch
profanityFilterAssemblyAIfilter_profanitybatch
wordTimestampsGeminimode.timestamp_granularities: ["word"]batch
wordTimestampsDeepgramper-word words (not Flux)batch

diarization and wordTimestamps are batch-only. Either one makes the done frame carry words: an array of { text, start, end, confidence?, speaker? } with start/end in seconds from the start of the audio (multiply by 1000 for subtitle cue times). wordTimestamps is served by gemini-3.5-transcribe and by Deepgram's batch models (not Flux). Gemini cannot combine it (or diarization) with keywords, so the term list is dropped for that request, and Google caps timestamped audio at 30 minutes. Pin Gemini to be sure of it. A demote-class field excludes candidates that cannot serve it rather than selecting one that can, and automatic routing does not rank the pre-recorded Gemini row, so an unpinned request answers 422 no_capable_provider unless a Deepgram model is on the language's ladder. When Gemini fails, a pinned request falls back to Deepgram if Deepgram ranks for the language:

-H 'X-Speko-Stt-Options: {"wordTimestamps":true}' \
-H 'X-Speko-Constraints: {"allowedProviders":{"stt":["gemini:gemini-3.5-transcribe"]}}'

The Router needs no pin — its automatic routing filters candidates on the capability itself. Streaming speaker forwarding is not exposed yet. Speaker labels from diarization-capable providers are normalized to S0, S1, ... on word-level output, regardless of the vendor's native labeling.

Deepgram Flux models deliberately accept none of the canonical or provider-specific params in these tables.

providerOptions (L2)

{
  "providerOptions": {
    "deepgram": { "dictation": true },
    "elevenlabs": { "timestamps_granularity": "word" }
  }
}
  • Keys are provider ids; each inner object is validated against the registry tables below.
  • Unknown providers, unknown params, wrong types, invalid enum values, and numbers outside a strict 0-1 range return 400 invalid_provider_options with per-param details.
  • Numbers outside a documented non-unit range pass through with an out_of_range warning - the provider decides.
  • A provider's options apply only when that provider serves the request. On failover they never cross to the winning provider; the losing provider's dict is discarded.
  • Options for a provider outside your allowedProviders pins produce a provider_not_pinned warning; they still apply if routing picks that provider.
  • Spelling a canonical field inside providerOptions while also setting it at the top level (for example providerOptions.deepgram.diarize next to diarization, or voice_settings.speed next to speed) is rejected as canonical_collision - set one spelling.

STT params

ProviderParamTypeValuesSurfacesEffect
Deepgrampunctuatebooleanstreaming, batchAdds punctuation and capitalization to transcripts.
Deepgramnumeralsbooleanstreaming, batchFormats spoken numbers as numerals in supported languages.
Deepgramendpointinginteger10-2000streamingSilence duration in milliseconds before speech finalization.
Deepgramutterance_end_msinteger1000-5000streamingWord-gap duration in milliseconds before an UtteranceEnd event.
Deepgramvad_eventsbooleanstreamingEmits speech-start voice activity events.
Deepgramdetect_languagebooleanbatchDetects the dominant language of each channel.
Deepgramdictationbooleanstreaming, batchConverts spoken dictation commands into punctuation and layout.
Deepgrammeasurementsbooleanstreaming, batchFormats spoken measurement units as abbreviations.
AssemblyAIend_of_turn_confidence_thresholdnumber0-1streamingSets the confidence threshold for semantic end-of-turn detection.
AssemblyAImin_end_of_turn_silence_when_confidentinteger0-5000streamingSets the minimum confident end-of-turn silence in milliseconds.
AssemblyAImax_turn_silenceinteger100-10000streamingSets the maximum silence in milliseconds before forcing a turn end.
AssemblyAIformat_turnsbooleanstreamingFormats final streaming turns with punctuation and casing.
AssemblyAImultichannelbooleanbatchTranscribes each channel of a recording separately.
AssemblyAIlanguage_detectionbooleanbatchDetects the language of a prerecorded transcript.
ElevenLabsvad_silence_threshold_secsnumber0.3-3streamingSets the VAD silence duration in seconds before committing a turn.
ElevenLabstag_audio_eventsbooleanbatchIncludes non-speech audio event tags in the transcript.
ElevenLabstimestamps_granularityenumword, characterbatchSelects word- or character-level transcript timestamps.
Sonioxenable_language_identificationbooleanstreaming, batchIncludes detected language information on transcript tokens.

Google and xAI expose only the canonical fields above. OpenAI and Cartesia expose no tunable STT params yet.

TTS params

ProviderParamTypeValuesEffect
ElevenLabsvoice_settingsobjectsee belowOverrides the selected voice's per-request generation settings.
ElevenLabsapply_text_normalizationenumauto, on, offControls provider-side text normalization.
MiniMaxvolumenumber0.5-2Controls output volume multiplier.
MiniMaxpitchinteger-12 to 12Shifts pitch by semitones.
Cartesiaspeednumber0.6-1.5Controls speaking-rate multiplier. Collides with top-level speed.
Cartesiavolumenumber0.5-2Controls output volume multiplier.
Fish Audiolatencyenumnormal, lowSelects normal quality or low-latency generation.
Blandexpressivenessnumber0-1Controls expressive variation in generated speech.
Blandstabilitynumber0-1Controls consistency in generated speech.

voice_settings (ElevenLabs) properties:

PropertyTypeValuesEffect
stabilitynumber0-1Controls consistency versus expressive variation.
similarity_boostnumber0-1Controls similarity to the source voice.
stylenumber0-1Controls style exaggeration.
use_speaker_boostbooleanEnables additional speaker-similarity processing.
speednumber0.7-1.2Speaking-rate multiplier. Collides with top-level speed - set one.

Failover behavior

  • Drop-class params are omitted for a candidate that cannot serve them. The request still runs; the omission is reported as a param_dropped warning and the param is absent from applied.
  • Demote-class params (diarization) remove incapable candidates from the failover ladder before the first attempt, each reported as a candidate_excluded warning. If no candidate remains, the request fails with 422 { "error": "no_capable_provider", "code": "NO_CAPABLE_PROVIDER", "param": "diarization" } instead of silently running without the capability.

When a request carries any of the new fields, the response reports what actually applied:

  • /v1/transcribe: the final done SSE event gains effectiveParams: { provider, model, applied, defaultsVersion }, plus warnings when non-empty.
  • /v1/transcribe/stream: a metadata frame after ready carries the same object.
  • /v1/synthesize: response headers X-Speko-Applied-Params (JSON array of param names) and X-Speko-Warnings (JSON array, capped at 2 KB).

Requests without any of the new fields get byte-identical responses to before these fields existed.

Workload defaults

workload: 'conversation' | 'transcription' | 'narration' applies per-provider defaults from the registry. Defaults are presence-keyed: no workload, no defaults. Explicit fields always override defaults. Responses echo defaultsVersion (currently 2026-08-06) so a registry change is visible.

ModalityProviderWorkloadDefaults applied
STTDeepgramconversationsmartFormat: false, punctuate: true, fillerWords: true, vad_events: true
STTDeepgramtranscriptionsmartFormat: true
STTAssemblyAIconversationformat_turns: true
STTAssemblyAItranscriptionsmartFormat: true
STTElevenLabstranscriptiontimestamps_granularity: "word", tag_audio_events: false
TTSElevenLabsnarrationvoice_settings: { stability: 0.5, similarity_boost: 0.75, use_speaker_boost: true }

A default only applies when the candidate's surface and model support the param. On /v1/synthesize, workload: "narration" additionally prefers a 24 kHz output ladder when the request sets no sampleRate and at least one candidate serves that rate.

Use-case vocabulary

Three vocabularies coexist on different surfaces:

Router key useCasePlatform workloadVertical useCaseId (/v1/recommend-stack)
phone_agentconversationany of the 10 vertical profiles
realtime_agent (UI: "In-app voice assistant")conversationany of the 10 vertical profiles
transcriptiontranscription-
voice_content (UI: "Narration")narration-
translation, other (legacy, API-only)--

Vertical profiles: customer-support, sales-outbound, healthcare, telephony-receptionist, voice-assistant, education-tutoring, restaurant-ordering, mental-health-coaching, legal-intake, financial-banking-ivr.

Guides: Batch transcription, Narration.

On this page