SaidwireDevelopers

Docs

Quickstart

Everything you need for a first transcript. The API reference covers every parameter, message and error.

WhatEndpoint
Streamingwss://api.saidwire.com/v1/listen (WebSocket)
FilesPOST https://api.saidwire.com/v1/listen
OpenAI-compatiblePOST https://api.saidwire.com/v1/audio/transcriptions (base URL https://api.saidwire.com/v1)
StatusGET https://api.saidwire.com/health
AuthAuthorization: Token <API key> or Bearer <API key>

Get a key in the dashboard: 120 free hours, no card. The API is always on.

1. Stream live audio

Open a WebSocket with your key, send binary audio frames of 20 to 100 ms in real time, and read JSON messages back. Send CloseStream when you are done.

  • interim_results=true for live guesses while the person speaks.
  • Finalize asks for a final right now, when your own detector says the user stopped. Final transcript 35 ms median (p95 46 ms) after Finalize, measured in US East; add your network round trip.
  • endpointing sets the pause, in ms (minimum 500), that ends a turn on its own.
# 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"))

2. Transcribe a file

POST the file to /v1/listen, or use the OpenAI-compatible endpoint with the official SDKs. WAV, MP3, FLAC, Ogg, WebM and M4A are accepted, up to 60 minutes.

# 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'

3. Switch an existing integration

Saidwire is compatible with Deepgram's API and with OpenAI's transcription API. If your app or framework lets you set the base URL, change it and the key.

See the compatibility notes and the integration guides.

# 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.