Integration · LiveKit Agents
Saidwire speech-to-text for LiveKit Agents
livekit-plugins-saidwire adds Wire-1, Saidwire's real-time English speech-to-text, to LiveKit Agents. The plugin streams the user's audio over a WebSocket and emits interim and final transcripts. When the agent session's VAD or turn detector ends the user's turn, it flushes the stream; the plugin sends Finalize and the final transcript comes straight back, so the session never waits on a timeout.
Wire-1: 50 ms p95 to final transcript, 1st of 29 on mean time to final segment in Coval's STT benchmark (30-day window to Nov 9, 2026). Source: Coval model page, 30-day window to Nov 9, 2026, 2,857 samples, US-hosted endpoint. Add your own network round trip. Method and how to reproduce.
| you need | |
|---|---|
| LiveKit Agents | Python, LiveKit Agents 1.8 or later |
| Saidwire API key | sk_live_... from saidwire.com/dev (120 free hours, no card) |
1. Install
pip install livekit-plugins-saidwire
export SAIDWIRE_API_KEY=sk_live_...
2. Use it in an AgentSession
from livekit.agents import AgentSession
from livekit.plugins import saidwire, silero
session = AgentSession(
stt=saidwire.STT(), # reads SAIDWIRE_API_KEY
vad=silero.VAD.load(),
llm=...,
tts=...,
)
3. Options
stt = saidwire.STT(
api_key="...", # default: $SAIDWIRE_API_KEY
model="saidwire-en-2026-10-30",
language="en", # en, en-US, en-GB, ... (English only)
sample_rate=16000, # 8000 for telephony audio
interim_results=True,
punctuate=True,
endpointing_ms=None, # server default; 0 = leave turn-taking to the session
utterance_end_ms=None, # e.g. 1000: END_OF_SPEECH after 1 s of silence
vad_events=False, # True: START_OF_SPEECH from the server
early_words=False, # True: "early_word" events
warmup_timeout=300.0,
)
| option | meaning |
|---|---|
endpointing_ms | pause, in ms, that ends an utterance on the server. None uses the server default; 0 leaves turn-taking to the session |
utterance_end_ms | the server sends UtteranceEnd (mapped to END_OF_SPEECH) after this much silence |
vad_events | the server sends SpeechStarted (mapped to START_OF_SPEECH) |
early_words | an early_word event for each word as soon as it is committed, useful for "stop" or "cancel" triggers |
stt.update_options(...) changes options at runtime. recognize() sends pre-recorded audio to POST /v1/listen.
Behavior
- The session's flush at end of turn sends
Finalize; the answer is a final transcript (empty if everything was already final). - Words an earlier final already delivered are not repeated in later finals or interims; the plugin checks word timings.
- While audio is not flowing, a free
KeepAliveholds the stream open. - A bad or revoked key, or used-up credit, fails at once with a non-retryable error.
stream.request_ididentifies the connection for support.
Source and listing
- Package: pypi.org/project/livekit-plugins-saidwire
- The plugin is built and maintained by Saidwire. A pull request to add it to the LiveKit Agents repository is in review.
Questions
Does it work with turn detection?
Yes. When the session's VAD or turn detector ends the turn it flushes the stream; the plugin sends Finalize and the final transcript returns right away.
Can I use it for phone calls?
Yes. Set sample_rate=8000 for telephony audio.
What does it cost?
120 free hours with no card and no deadline, up to 4 streams at once, then $0.25 per audio hour, billed per second.
Which languages?
English only.
Questions or stuck? Email support@saidwire.com with the request ID from the failed call.
Pipecat, LiveKit, Vapi, OpenAI and the other names on this page belong to their respective owners. They are named only to describe compatibility; no partnership or endorsement is implied. Coval benchmark figures are from Coval's public model page; Coval does not endorse Saidwire.