Skip to content

Realtime

Real-time speech-to-text transcription over WebSocket. See the Realtime guide for concepts.

wss://api.reson8.dev/v1/speech-to-text/realtime
Header Value
Authorization ApiKey <api_key> or Bearer <access_token>
Sec-WebSocket-Protocol bearer, <access_token>

See Authentication for which header to use in different situations.

Parameter Type Default Description
encoding string auto Audio encoding: auto for detected container formats, pcm_s16le for raw PCM, or mulaw / alaw for raw G.711 telephony audio. See Audio Formats
sample_rate number 16000 Sample rate in Hz (only used depending on encoding)
channels number 1 Number of audio channels, 1-10 (only used depending on encoding)
language string Language to transcribe. Recommended for best quality. A comma-separated list (e.g. nl,en) constrains per-utterance auto-detection to those candidates. When omitted, the server auto-detects each utterance independently. See Languages for supported codes
phrases string Comma-separated phrases to bias transcription toward, up to 250. See Custom Models
custom_model_id string ID of a custom model to bias transcription. Overrides the model configured on the API client
bias_strength number 0.45 Strength of contextual biasing. Must be a non-negative number
include_timestamps boolean false Include start_ms and duration_ms on transcripts and words
include_words boolean false Include word-level detail on transcripts
include_language boolean false Include the detected language on transcripts (empty on interim)
include_confidence boolean false Include confidence on words
include_interim boolean false Include interim (partial) results and the is_final flag
diarize boolean false Enable speaker diarization. Adds speaker_id to each transcript
max_speakers number Maximum number of distinct speakers (1-4). When omitted, the count is determined automatically. Only used when diarize=true
patterns string Comma-separated regex-style patterns for short alphanumeric tokens (order codes, licence plates) to recover. Only set when the token is likely present; cannot be combined with phrases or a custom model - see Patterns
filler_mode string natural Controls filler words in final transcripts: clean removes them, natural lets the model decide, and verbatim preserves them. Interim transcripts are unaffected
import asyncio
import json
import websockets
async def transcribe():
url = "wss://api.reson8.dev/v1/speech-to-text/realtime"
headers = {"Authorization": "ApiKey <your_api_key>"}
async with websockets.connect(url, additional_headers=headers) as ws:
async def send_audio():
try:
with open("recording.wav", "rb") as f:
while chunk := f.read(8192):
await ws.send(chunk)
await ws.send(json.dumps({"type": "flush_request"}))
except Exception:
await ws.close()
raise
sender = asyncio.create_task(send_audio())
async for message in ws:
event = json.loads(message)
print(event)
if event["type"] == "flush_confirmation":
break
await sender
asyncio.run(transcribe())

Binary WebSocket frame containing audio data.

Force the server to finalize any buffered audio and return a transcript.

{
"type": "flush_request",
"id": "abc123"
}
Field Type Required Description
id string No Optional identifier, returned in the corresponding flush confirmation

Returned when speech is recognized. By default, only final results are returned. When include_interim=true, interim (partial) results are also returned - these may change as more audio is processed.

{
"type": "transcript",
"text": "the patient presented with chest pain"
}
Field Type Included Description
text string Always The recognized text
language string When include_language=true The detected language code (empty on interim)
is_final boolean When include_interim=true true for final, false for interim
start_ms number When include_timestamps=true Start time in milliseconds
duration_ms number When include_timestamps=true Duration in milliseconds
speaker_id number When diarize=true Speaker label for this transcript (integer, 0-indexed). See Diarization
words array When include_words=true Word-level detail

Each word contains:

Field Type Included Description
text string Always The recognized word
start_ms number When include_timestamps=true Start time in milliseconds
duration_ms number When include_timestamps=true Duration in milliseconds
confidence number When include_confidence=true Probability in (0, 1]

Sent after a flush request has been processed. The id field is always present; it is null if no identifier was provided in the request.

{
"type": "flush_confirmation",
"id": "abc123"
}
Field Type Included Description
id string Always The identifier from the corresponding flush request, or null if none was provided

Rejected WebSocket upgrades return no body; where available, the reason is in the X-Error-Message response header.

Status Description
400 Bad Request Invalid query parameter, unknown custom_model_id, or patterns combined with a custom model
401 Unauthorized Missing or invalid credentials
402 Payment Required Credit limit exceeded - see Limits
429 Too Many Requests Concurrent connection limit exceeded - see Limits

Malformed or unrecognized client messages are ignored; the session continues.

After the connection is established, errors are signalled through the WebSocket close code and reason (in browsers: event.code and event.reason on the close event). The reason is a stable machine-readable token: branch on the close code for coarse handling and on the reason for specifics.

Close code Reason Description
1000 Normal closure
1011 internal_error Unexpected server failure. Reconnect and resend unconfirmed audio
1011 internal_timeout An internal service did not recover within its reconnect budget (up to ~5 seconds). Reconnect and resend unconfirmed audio; back off if it recurs
4000 message_backlog Client did not read messages for 10 seconds. Consume promptly, then reconnect

A connection that drops without a close frame (surfaced as code 1006 in browsers) indicates a network failure or server crash. Treat it like 1011: reconnect and resend unconfirmed audio.