Streaming transcription
WSwss://api.lucidweights.ai/v1/stt/stream
Real-time streaming transcription. The server detects end-of-speech and emits a final transcript per utterance. You do not need to signal turn boundaries.
Connect
wss://api.lucidweights.ai/v1/stt/stream?api_key=KEY&sample_rate=16000&languages=en
Query parameters
| Field | Type | Default | Description |
|---|---|---|---|
| api_key | string | required | Required in the query string, not a header |
| sample_rate | int | 16000 | Sample rate of the PCM you send |
| backend | string | ultra | ultra, fast, or normal |
| model_name | string | large | For fast/normal backends |
| languages | string | "" | Comma-separated ISO codes |
| enable_interim_transcript | bool | false | Emit non-final partial results |
| silence_threshold | int (ms) | 800 | Trailing silence that ends a turn |
| vad_threshold | float | 0.6 | Speech-detection sensitivity (higher = stricter) |
| enable_turn_taker | bool | false | Semantic end-of-turn model. Ends turns sooner than silence alone |
| turn_taker_threshold | float | 0.55 | Confidence to end a turn early |
| wait_end_digit | int (ms) | 500 | Extra hold when transcript ends in a number |
| audio_gain | float | 1 | Linear gain before processing, clipped at ±1.0 |
| auto_detect_sample_rate | bool | false | Infer rate from packet timing |
Sending audio
JSON text frames only. Binary frames are not read.
| Field | Type | Default | Description |
|---|---|---|---|
| audio_data | string | required | Base64 of 16-bit signed LE PCM, mono, at sample_rate |
| client_send_timestamp | int | - | Client epoch ms. Required for meaningful ctos_latency on finals |
{
"audio_data": "<base64 int16 PCM>",
"client_send_timestamp": 1721470000000
}There is no end-of-stream message. Close the socket. Pending audio is flushed after silence_threshold ms of inactivity.
Receiving transcripts
Interim (when enable_interim_transcript=true):
{ "transcription": "hello wor", "final": false }Final:
{
"transcription": "hello world",
"final": true,
"send_timestamp_ms": 1721470001234,
"ctos_latency": 42,
"vad_run_count": 0,
"total_vad_proccesing_time": 0
}NOTE
ctos_latency appears only on turn-end finals, not inactivity flushes. Empty transcripts are never sent.
WARNING
No µ-law mode on the stream. G.711 callers must expand to PCM16 client-side. Mono 16-bit signed integer only. Three consecutive failed utterances end the stream with close code 1011.
Example
import asyncio, base64, json, time, websockets
URL = (f"wss://api.lucidweights.ai/v1/stt/stream"
f"?api_key=YOUR_KEY&sample_rate=16000&languages=en")
async def main():
async with websockets.connect(URL) as ws:
async def send():
for chunk in pcm16_chunks(): # bytes, 16-bit LE mono
await ws.send(json.dumps({
"audio_data": base64.b64encode(chunk).decode(),
"client_send_timestamp": int(time.time() * 1000),
}))
async def recv():
async for msg in ws:
d = json.loads(msg)
if d.get("final"):
print("FINAL:", d["transcription"])
await asyncio.gather(send(), recv())
asyncio.run(main())