Product

Introducing VoiceRun STT Router and STT Model

Every realtime STT model.One key. One WebSocket.

VoiceRun STT Router gives voice agents one low-latency interface for changing how STT behaves while a call is live. Use external models or VoiceRun STT Model, then update context, turn-taking, language, and guardrails as the conversation moves.

Speech-to-text has become a fast-moving model market, but every provider still arrives with its own SDK, events, authentication, and endpointing behavior. Choosing one usually means wiring it deep into the audio path—and paying that integration cost again when a better model appears or a provider has an outage.

Today we're opening one realtime STT layer with two complementary parts. VoiceRun STT Router turns provider choice and live behavior into configuration: one VoiceRun API key, one WebSocket, one event shape, and one model string across providers. VoiceRun manages the integrations and charges usage to one credit balance.

VoiceRun STT Model is our own option inside that same Router. VoiceRun STT Model is the first-party model already taking production calls for VoiceRun agents. It is designed to use the Router's dynamic controls deeply, through the same protocol as every external model.

Live caller audio
PCM frames · continuously
One WebSocket
VoiceRun STT Router
API keyverified
Active routerealtime
voicerun-asr-realtime-v1
Billing
one balance
Failover
standby
Voice agent
Normalized realtime events
Route or fail over by model
VoiceRun
Deepgram
OpenAI
ElevenLabs
Google
Qwen

Access layer

VoiceRun STT Router

One realtime protocol and one VoiceRun key across STT providers. Change a model string and keep the same audio and transcript events downstream.

Explore STT Router →

First-party model

VoiceRun STT Model

Our context-aware model is available through that same protocol. Select voicerun-asr-realtime-v1 and authenticate with your VoiceRun API key.

Explore STT Model →

Integrate speech-to-text once

Connect to wss://api.voicerun.com/v1/stt, stream the same audio frames, and receive the same partial and final transcript events regardless of which provider is listening. Move between models by changing the session configuration—not your application's audio pipeline.

That makes model bake-offs practical on your own phone audio and gives production teams an escape hatch when a vendor degrades, changes pricing, or retires a model. Every enabled model uses the same VoiceRun API key and credit balance.

VoiceRunDeepgramOpenAIElevenLabsCartesiaSonioxGoogleQwenxAIInworldGradiumTencent
wss://api.voicerun.com/v1/stt · one protocol, any provider
# Same VoiceRun key, socket, and events. Change only the model.
{"type":"session.update","model":"nova-3"}
{"type":"session.update","model":"gpt-4o-transcribe"}
{"type":"session.update","model":"voicerun-asr-realtime-v1"}

  {"type":"input_audio_buffer.append","audio":"<base64 PCM16>"}
  {"type":"transcription.delta","text":"I'd like a table for four"}
  {"type":"turn.ended","text":"I'd like a table for four.","reason":"provider"}

The Router and model are one conversation loop

The Router is how your agent changes STT as the call develops; VoiceRun STT Model is built to respond to those changes. Generic speech-to-text gives you words. A voice agent also needs to know that “four” meant the party size it just offered, that the caller switched languages, and when they have actually finished talking. Get those wrong and the transcript can be technically accurate while the conversation falls apart.

VoiceRun STT Model builds on the open Qwen3-ASR foundation and is hardened on real phone lines, accents, code-switching, background noise, and half-finished sentences. Context and language can change between turns, while server-side turn-taking and guardrails keep the transcript usable in production. Together, the Router and model make configuration part of the realtime conversation rather than setup performed before it begins.

Every turn
update model configuration without reconnecting
5.01% WER
independently measured for VoiceRun STT Model across seven English suites
$0
during the free preview — access it through the VoiceRun STT Router

Configure the conversation, not just the connection

Most STT is configured once when the socket opens: one model, one language, one hint string, one turn threshold. Then the call changes and that configuration quietly becomes stale. The vocabulary that matters changes after every agent response. The caller may switch languages. A quick confirmation and a detailed explanation should not share the same turn-taking behavior. VoiceRun STT Router keeps those controls live on one socket, and VoiceRun STT Model is built to use them turn by turn.

Configure STT once per call and you're underperforming. Configure it once per turn and you're cooking.

Dynamic Context Update

Feed the model what matters now: the menu items just offered, the account name just retrieved, or the confirmation code the caller is about to say. Update context between turns without reconnecting, so recognition follows the conversation instead of a connect-time hint.

Dynamic Turn-taking Configuration

Change end-of-turn sensitivity as the interaction changes. A rapid menu selection should close quickly; an address, explanation, or emotional response needs more room. Tune semantic turn-taking per turn instead of forcing the entire call through one silence threshold.

Dynamic Language Configuration

Let the model detect within an allow-list, pin the language when the caller switches, or target a different language for translation. Apply the right policy to each turn on the same live socket, rather than guessing one language at the start and hoping it holds.

Dynamic Hallucination Guarding

Context makes recognition stronger, but aggressive hints can also surface as false speech during silence, noise, or a cough. Adjust protection with the context and phase of the conversation; VoiceRun STT Model strips prompt echoes while preserving genuine speech.

Accuracy you can verify

We ran the industry-standard Open ASR Leaderboard evaluation — its datasets, its normalizer, its scoring — against this API's live public endpoint, on the full test sets. Averaged across the board's seven English suites, VoiceRun STT Model lands at 5.01% word error rate, in the same tier as the best-known commercial speech APIs:

Average WER, Open ASR Leaderboard English suites

lower is better
View the 14 entries ahead of VoiceRun (implied No. 15)

VoiceRun is not listed on the leaderboard. Comparing its independently measured 5.01% with the leaderboard's current cleaned seven-suite public results places it after these 14 entries—an implied No. 15, not an official rank.

modulate/vfast4.43%
HojoAI/Hojo-ASR-V14.46%
microsoft/azure-speech-06-20264.51%
reson8/resonant-14.62%
bosonai/higgs-audio-v3-stt4.62%
AutoArk-AI/ARK-ASR-3B4.64%
elevenlabs/scribe_v24.65%
zoom/scribe_v14.65%
reson8/resonant-1-flash4.66%
OpenMOSS-Team/MOSS-Transcribe-preview-2B4.66%
bosonai/higgs-audio-v3-8b-stt-v24.73%
ibm-granite/granite-speech-4.1-2b4.90%
ibm-granite/granite-speech-4.1-2b-nar4.95%
Qwen/Qwen3-ASR-1.7B-hf4.98%
VoiceRun STT Model (voicerun-asr-realtime-v1)5.01%
AssemblyAI universal-3-5-pro5.03%
Gladia solaria-35.34%
Speechmatics enhanced5.90%
OpenAI whisper-large-v36.55%
View per-dataset results
LibriSpeech test-clean1.25%
SPGISpeech2.58%
LibriSpeech test-other2.90%
VoxPopuli AA-cleaned2.93%
GigaSpeech cleaned7.21%
AMI cleaned (meetings)8.37%
Earnings229.86%

Measured 2026-08-19 with the leaderboard's open-source harness against api.voicerun.com/v1/stt, full test sets, default decoding, no context biasing. Comparison figures recomputed from the leaderboard's published per-dataset results over the same seven public suites. VoiceRun STT Model is not listed on the leaderboard. The collapsed list above uses its current cleaned seven-suite public results as of August 20, 2026; No. 15 is a comparison with those published entries, not an official leaderboard rank.

It holds across languages — on the leaderboard's complete multilingual coverage (five languages, each across FLEURS, Common Voice, and Multilingual LibriSpeech) it averages 5.02%: Spanish 3.8, German 3.9, Italian 5.4, French 5.7, Portuguese 6.3. And every number on this page is the floor, not the ceiling: these runs used none of the dynamic context biasing this API exists to provide. The benchmark can't pass your menu, your SKUs, or your caller's name to the model mid-conversation. Your agent can.

One WebSocket away

If you already use VoiceRun, you already have access — your existing API key works as-is. Open the realtime WebSocket, stream audio, and the server does the rest. Here's a real session shape: the server closes turns semantically, your agent re-biases the context with the exact options it just offered, and when the caller switches to Spanish mid-call, you lock the language in — all on one socket, no reconnects:

wss://api.voicerun.com/v1/sttlive replay
connecting…
View the raw wire messages
wss://api.voicerun.com/v1/stt · Authorization: Bearer $VOICERUN_API_KEY
  {"type": "session.created"}

# start: language "" = auto-detect, constrained to your allow-list
  {"type": "session.update", "turn_detection": "server",
    "language": "",
    "allowed_languages": "en,es",
    "context": "reservation, booking, party size, high chair"}
  {"type": "session.updated", "turn_detection": "server"}

# turn 1 — just stream audio; the server segments the turns
  {"type": "input_audio_buffer.append", "audio": "<base64 pcm16 @ 16kHz>"}   × N
  {"type": "speech_started"}
  {"type": "transcription.delta", "text": "I'd like to book a table", "language": "en"}
  {"type": "turn.ended", "text": "I'd like to book a table for four tonight.",
    "language": "en", "reason": "acoustic", "eou_prob": 0.94}

# your agent offers 6:30 / 6:45 / 7:00 — bias the next turn with exactly that
  {"type": "session.update", "context": "offered times: 6:30 PM, 6:45 PM, 7:00 PM"}

# turn 2 — "six forty-five" resolves against the offer, not against guesswork
  {"type": "turn.ended", "text": "Six forty-five works.",
    "language": "en", "reason": "acoustic", "eou_prob": 0.91}

# next it needs a name — re-bias again, this time for spelled-out letters
  {"type": "session.update", "context": "caller name, spelling, letter by letter"}

# turn 3 — the letters survive because the context expects them
  {"type": "turn.ended", "text": "It's Maria — M-A-R-I-A.",
    "language": "en", "reason": "acoustic", "eou_prob": 0.90}

# turn 4 — the caller switches to Spanish; auto-detect follows...
  {"type": "turn.ended", "text": "Perdón, ¿puede agregar una silla alta?",
    "language": "es", "reason": "acoustic", "eou_prob": 0.89}

# ...and your agent locks it in for the rest of the call
  {"type": "session.update", "language": "es"}

# turn 5 — a trailing-off turn rides to the hard cap instead of hanging
  {"type": "turn.ended", "text": "Eh... un momento...",
    "language": "es", "reason": "timeout", "eou_prob": 0.12}

# turn 6 — your agent reads the booking back — the caller barges in;
# speech_started is your cue to cut the TTS
  {"type": "speech_started"}
  {"type": "turn.ended", "text": "¡Espera! Mejor a las siete.",
    "language": "es", "reason": "acoustic", "eou_prob": 0.92}

# re-bias one last time with the corrected booking for the confirm
  {"type": "session.update",
    "context": "confirmar: viernes 7:00 PM, mesa para cuatro, María, silla alta"}

# turn 7 — locked to Spanish, biased on the exact summary, the booking closes
  {"type": "turn.ended", "text": "Sí, confirmado — a las siete, a nombre de María.",
    "language": "es", "reason": "acoustic", "eou_prob": 0.95}

Have recordings instead of a live line? Stream them through the same socket — one endpoint, one protocol, whether the audio is a phone call in progress or a file on disk.

Start in about thirty lines

A complete working client — connect, turn on server-side turn-taking, stream audio, print finished turns:

quickstart.py
import asyncio, base64, json, wave, websockets  # pip install "websockets>=14"

URL = "wss://api.voicerun.com/v1/stt"
API_KEY = "YOUR_VOICERUN_API_KEY"

async def transcribe(wav_path):
    pcm = wave.open(wav_path, "rb").readframes(1 << 30)   # PCM16 mono 16 kHz
    pcm += b"\x00" * 32000       # 1 s of silence — the server closes a turn when it HEARS the
                                 # pause, and a file (unlike a mic) stops sending at the last word
    async with websockets.connect(
        URL, additional_headers={"Authorization": f"Bearer {API_KEY}"}
    ) as ws:
        await ws.recv()  # session.created

        # server-side turn-taking, auto-detect within your languages, + domain context
        await ws.send(json.dumps({
            "type": "session.update",
            "turn_detection": "server",
            "language": "auto",             # detect per turn (pin a code later to lock it in)
            "allowed_languages": "en,es",   # auto-detect never leaves this list
            # turn-taking, tunable per language — raise a threshold to cut callers off less
            "eou_threshold": {"default": 0.5, "es": 0.6},
            "vad_stop_ms": 200,             # silence before the first end-of-turn consult
            "eot_timeout_ms": 600,          # hard cap: close by here even if the model never agrees
            "context": "reservation, booking, party size, high chair",
        }))

        async def send_audio():
            for i in range(0, len(pcm), 3200):            # ~100 ms chunks
                await ws.send(json.dumps({"type": "input_audio_buffer.append",
                                          "audio": base64.b64encode(pcm[i:i+3200]).decode()}))
                await asyncio.sleep(0.1)
        asyncio.create_task(send_audio())

        async for raw in ws:
            m = json.loads(raw)
            if m["type"] == "turn.ended" and m["text"]:
                print(f"[{m['reason']}/{m['language']}] {m['text']}")

asyncio.run(transcribe("call.wav"))

Start transcribing today

Use one VoiceRun API key to access VoiceRun STT Model and external models through the same STT Router connection.

Free during preview