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
| Surface | Fields | Validated 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 frame | same STT request fields; diarization has no streaming mapping yet | streaming |
POST /v1/synthesize - body | workload, providerOptions | streaming |
/v1/sessions, /v1/sessions/phone, /v1/agents - sttOptions / ttsOptions | same 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)
| Field | Type | Meaning | When a candidate cannot serve it |
|---|---|---|---|
diarization | boolean | Separate speakers in a batch transcript | demote (candidate excluded) |
speakersExpected | integer | Hint of how many speakers to expect | drop |
smartFormat | boolean | Provider-side formatting (punctuation, casing, numbers) | drop |
fillerWords | boolean | Keep filler words ("um", "uh") instead of removing them | drop |
profanityFilter | boolean | Mask profanity in the transcript | drop |
wordTimestamps | boolean | Per-word start/end timings in the done frame's words | demote (candidate excluded) |
Per-provider wire mapping:
| Field | Provider | Wire param | Surfaces |
|---|---|---|---|
diarization | Deepgram | diarize | batch |
diarization | AssemblyAI | speaker_labels | batch |
diarization | ElevenLabs | diarize | batch |
diarization | Soniox | enable_speaker_diarization | batch |
diarization | diarizationConfig | batch | |
speakersExpected | AssemblyAI | speakers_expected | batch |
speakersExpected | ElevenLabs | num_speakers | batch |
speakersExpected | diarizationConfig.maxSpeakerCount | batch | |
smartFormat | Deepgram | smart_format | streaming, batch |
smartFormat | AssemblyAI | format_text + punctuate (streaming: format_turns) | batch |
smartFormat | features.enableAutomaticPunctuation | streaming, batch | |
smartFormat | xAI | format | batch |
fillerWords | Deepgram | filler_words | streaming, batch |
fillerWords | AssemblyAI | disfluencies | batch |
profanityFilter | Deepgram | profanity_filter | streaming, batch |
profanityFilter | AssemblyAI | filter_profanity | batch |
wordTimestamps | Gemini | mode.timestamp_granularities: ["word"] | batch |
wordTimestamps | Deepgram | per-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
400invalid_provider_optionswith per-param details. - Numbers outside a documented non-unit range pass through with an
out_of_rangewarning - 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
allowedProviderspins produce aprovider_not_pinnedwarning; they still apply if routing picks that provider. - Spelling a canonical field inside
providerOptionswhile also setting it at the top level (for exampleproviderOptions.deepgram.diarizenext todiarization, orvoice_settings.speednext tospeed) is rejected ascanonical_collision- set one spelling.
STT params
| Provider | Param | Type | Values | Surfaces | Effect |
|---|---|---|---|---|---|
| Deepgram | punctuate | boolean | streaming, batch | Adds punctuation and capitalization to transcripts. | |
| Deepgram | numerals | boolean | streaming, batch | Formats spoken numbers as numerals in supported languages. | |
| Deepgram | endpointing | integer | 10-2000 | streaming | Silence duration in milliseconds before speech finalization. |
| Deepgram | utterance_end_ms | integer | 1000-5000 | streaming | Word-gap duration in milliseconds before an UtteranceEnd event. |
| Deepgram | vad_events | boolean | streaming | Emits speech-start voice activity events. | |
| Deepgram | detect_language | boolean | batch | Detects the dominant language of each channel. | |
| Deepgram | dictation | boolean | streaming, batch | Converts spoken dictation commands into punctuation and layout. | |
| Deepgram | measurements | boolean | streaming, batch | Formats spoken measurement units as abbreviations. | |
| AssemblyAI | end_of_turn_confidence_threshold | number | 0-1 | streaming | Sets the confidence threshold for semantic end-of-turn detection. |
| AssemblyAI | min_end_of_turn_silence_when_confident | integer | 0-5000 | streaming | Sets the minimum confident end-of-turn silence in milliseconds. |
| AssemblyAI | max_turn_silence | integer | 100-10000 | streaming | Sets the maximum silence in milliseconds before forcing a turn end. |
| AssemblyAI | format_turns | boolean | streaming | Formats final streaming turns with punctuation and casing. | |
| AssemblyAI | multichannel | boolean | batch | Transcribes each channel of a recording separately. | |
| AssemblyAI | language_detection | boolean | batch | Detects the language of a prerecorded transcript. | |
| ElevenLabs | vad_silence_threshold_secs | number | 0.3-3 | streaming | Sets the VAD silence duration in seconds before committing a turn. |
| ElevenLabs | tag_audio_events | boolean | batch | Includes non-speech audio event tags in the transcript. | |
| ElevenLabs | timestamps_granularity | enum | word, character | batch | Selects word- or character-level transcript timestamps. |
| Soniox | enable_language_identification | boolean | streaming, batch | Includes 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
| Provider | Param | Type | Values | Effect |
|---|---|---|---|---|
| ElevenLabs | voice_settings | object | see below | Overrides the selected voice's per-request generation settings. |
| ElevenLabs | apply_text_normalization | enum | auto, on, off | Controls provider-side text normalization. |
| MiniMax | volume | number | 0.5-2 | Controls output volume multiplier. |
| MiniMax | pitch | integer | -12 to 12 | Shifts pitch by semitones. |
| Cartesia | speed | number | 0.6-1.5 | Controls speaking-rate multiplier. Collides with top-level speed. |
| Cartesia | volume | number | 0.5-2 | Controls output volume multiplier. |
| Fish Audio | latency | enum | normal, low | Selects normal quality or low-latency generation. |
| Bland | expressiveness | number | 0-1 | Controls expressive variation in generated speech. |
| Bland | stability | number | 0-1 | Controls consistency in generated speech. |
voice_settings (ElevenLabs) properties:
| Property | Type | Values | Effect |
|---|---|---|---|
stability | number | 0-1 | Controls consistency versus expressive variation. |
similarity_boost | number | 0-1 | Controls similarity to the source voice. |
style | number | 0-1 | Controls style exaggeration. |
use_speaker_boost | boolean | Enables additional speaker-similarity processing. | |
speed | number | 0.7-1.2 | Speaking-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_droppedwarning and the param is absent fromapplied. - Demote-class params (
diarization) remove incapable candidates from the failover ladder before the first attempt, each reported as acandidate_excludedwarning. If no candidate remains, the request fails with422{ "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 finaldoneSSE event gainseffectiveParams: { provider, model, applied, defaultsVersion }, pluswarningswhen non-empty./v1/transcribe/stream: ametadataframe afterreadycarries the same object./v1/synthesize: response headersX-Speko-Applied-Params(JSON array of param names) andX-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.
| Modality | Provider | Workload | Defaults applied |
|---|---|---|---|
| STT | Deepgram | conversation | smartFormat: false, punctuate: true, fillerWords: true, vad_events: true |
| STT | Deepgram | transcription | smartFormat: true |
| STT | AssemblyAI | conversation | format_turns: true |
| STT | AssemblyAI | transcription | smartFormat: true |
| STT | ElevenLabs | transcription | timestamps_granularity: "word", tag_audio_events: false |
| TTS | ElevenLabs | narration | voice_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 useCase | Platform workload | Vertical useCaseId (/v1/recommend-stack) |
|---|---|---|
phone_agent | conversation | any of the 10 vertical profiles |
realtime_agent (UI: "In-app voice assistant") | conversation | any of the 10 vertical profiles |
transcription | transcription | - |
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.