Interim words, then finals
Interim results replace each other while the person speaks. Finals carry case, punctuation and word timings, and never change.
Speech-to-text API
Stream audio over a WebSocket or send a file. Interim words while the person speaks; the final transcript 35 ms median (p95 46 ms) after Finalize, measured in US East. Add your network round trip.
120 free hours with no card and no deadline, up to 4 streams. Then $0.30 per audio hour. Always on.
# pip install websockets (Python 3.10+)
import asyncio, json, os, wave
from websockets.asyncio.client import connect
URL = ("wss://api.saidwire.com/v1/listen?encoding=linear16&sample_rate=16000"
"&interim_results=true&punctuate=true&endpointing=500")
async def main(path):
with wave.open(path) as w: # 16 kHz, mono, 16-bit
pcm = w.readframes(w.getnframes())
headers = {"Authorization": f"Token {os.environ['SAIDWIRE_API_KEY']}"}
async with connect(URL, additional_headers=headers) as ws:
async def reader():
async for raw in ws:
m = json.loads(raw)
if m["type"] == "Results" and m["is_final"]:
print(m["channel"]["alternatives"][0]["transcript"])
r = asyncio.create_task(reader())
for i in range(0, len(pcm), 640): # 20 ms frames, real time
await ws.send(pcm[i:i + 640])
await asyncio.sleep(0.02)
await ws.send(json.dumps({"type": "CloseStream"}))
await r
asyncio.run(main("call.wav"))# pip install openai
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.saidwire.com/v1", api_key=os.environ["SAIDWIRE_API_KEY"])
with open("meeting.mp3", "rb") as f:
r = client.audio.transcriptions.create(model="saidwire-en", file=f)
print(r.text)// npm install ws
const WebSocket = require("ws");
const ws = new WebSocket(
"wss://api.saidwire.com/v1/listen?encoding=linear16&sample_rate=16000&interim_results=true&punctuate=true",
{ headers: { Authorization: `Token ${process.env.SAIDWIRE_API_KEY}` } });
ws.on("message", (raw) => {
const m = JSON.parse(raw);
if (m.type === "Results")
console.log(m.is_final ? "final " : "interim", m.channel.alternatives[0].transcript);
});
ws.on("open", () => {
// send binary 16-bit PCM frames (20-100 ms each) as they are captured, then:
// ws.send(JSON.stringify({ type: "CloseStream" }));
});# Transcribe a recorded file (WAV, MP3, FLAC, Ogg, WebM or M4A, up to 60 min)
curl -s -X POST "https://api.saidwire.com/v1/listen?punctuate=true" \
-H "Authorization: Token $SAIDWIRE_API_KEY" \
-H "Content-Type: audio/wav" \
--data-binary @meeting.wav \
| jq -r '.results.channels[0].alternatives[0].transcript'# Already using a Deepgram-compatible client? Change two values.
- base URL wss://<your current endpoint>/v1/listen
+ base URL wss://api.saidwire.com/v1/listen
- API key <your current key>
+ API key sk_live_...
# Query parameters, Results messages, KeepAlive, Finalize and
# CloseStream keep the same names. Differences are listed in the docs.Tools and protocols Saidwire works with, each linked to its setup guide. Not customers, partners or endorsements. All integrations
Final transcript 35 ms median (p95 46 ms) after Finalize, measured in US East; add your network round trip. Word error rate 3.9%. From a 24-hour run of Coval's open-source benchmark method against our public API: 912 clips, 0 failures. Our own run, not an independent ranking. How we measured
What you get
Interim results replace each other while the person speaks. Finals carry case, punctuation and word timings, and never change.
Send Finalize when your own detector says the user stopped and get the final right away, or let speech_final mark the pause.
Linear PCM from 8 to 48 kHz, μ-law and A-law telephone audio, or a WAV stream. One channel per stream.
POST /v1/listen with WAV, MP3, FLAC, Ogg, WebM or M4A up to 60 minutes.
POST /v1/audio/transcriptions works with the official OpenAI SDKs and the tools built on them.
Same query parameters, message types and control messages. Change the base URL and the key.
Measured
From our 24-hour run of Coval's open-source benchmark method against the public API: 912 clips, 0 failures. Our own run, not an independent ranking.
| Audio | Clips | Final, mean ms | WER |
|---|---|---|---|
| Mixed benchmark set | 480 | 34 | 3.1% |
| Clean speech | 192 | 35 | 3.9% |
| Accented speech | 48 | 30 | 3.5% |
| Phone audio | 48 | 37 | 4.7% |
| Far-field microphone | 48 | 37 | 4.8% |
| Noise and gaps | 48 | 39 | 5.2% |
| Clipped audio | 48 | 37 | 9.4% |
| All | 912 | 34 | 3.9% |
Trust and security
Speech goes in, text comes out, and the audio is gone. Security or compliance questions go to support@saidwire.com.
Audio is processed in memory and never stored. Transcripts are not stored or logged.
The API is served only over HTTPS and secure WebSockets (WSS).
Saidwire keeps only a hash of each key, so a lost key is replaced, never recovered.
Every stream and request returns a request ID, so support can find it without your audio.
Read the API privacy notice and API terms.
Talk to us
To get a key now, sign up in the dashboard: 120 free hours, no card. For volume pricing or help moving an existing integration, tell us what you're building. One reply from a person, no sequence.
FAQ
120 free audio hours with no card and no deadline, and up to 4 streams at once. Sign up in the dashboard and get a key in a minute.
Yes. The API is always on; there is no warm-up window.
Saidwire is compatible with Deepgram's API. Change the base URL to wss://api.saidwire.com (or https:// for files) and use your Saidwire key. The compatibility notes list the few differences.
Yes, for whole files. Set the base URL to https://api.saidwire.com/v1 and call audio.transcriptions.create. See OpenAI-compatible transcription.
English only. Streaming takes linear PCM from 8 to 48 kHz and μ-law or A-law phone audio. Files can be WAV, MP3, FLAC, Ogg, WebM or M4A, up to 60 minutes.
Final transcript 35 ms median (p95 46 ms) after Finalize, measured in US East; add your network round trip. Word error rate 3.9% on the same 912-clip run. See Benchmarks for the method, and measure it on your own audio with the free hours.
Seconds of audio you send, from the first byte to the end of the stream, silence included.
No. Audio is processed in memory and never stored.
Yes. Tell us which datasets you used and we will link your results.