Realtime Quickstart
Minimal runnable WebSocket examples.
Minimal runnable examples for real-time streaming transcription.
Node.js / TypeScript
import WebSocket from "ws";
const BASE = "wss://audio.lansonai.com";
const SK = "sk-...";
const ws = new WebSocket(`${BASE}/v1/audio/transcriptions/stream`, {
headers: { Authorization: `Bearer ${SK}` },
});
ws.on("open", () => {
// Optional: configure session
ws.send(JSON.stringify({ type: "session.update", language: "zh" }));
// Send PCM16LE base64 audio frames (100ms recommended)
ws.send(JSON.stringify({
type: "input_audio_buffer.append",
audio: "<base64 PCM16LE>",
}));
// Flush when a speech segment ends
ws.send(JSON.stringify({ type: "input_audio_buffer.flush" }));
});
ws.on("message", (data) => {
const event = JSON.parse(data.toString());
switch (event.type) {
case "session.created":
console.log("Session:", event.session_id, "Plan:", event.plan);
break;
case "conversation.item.input_audio_transcription.completed":
console.log(`[${event.utterance_index}] ${event.text}`);
break;
case "error":
console.error("Error:", event.code, event.message);
break;
}
});
ws.on("close", (code) => console.log(`Closed: ${code}`));
Browser JavaScript
Browser connections require a session token obtained from your backend:
// 1. Get session token from your backend
const { token } = await fetch("/your-backend/session-token", {
method: "POST",
}).then(r => r.json());
// 2. Open WebSocket
const ws = new WebSocket(
`wss://audio.lansonai.com/v1/audio/transcriptions/stream?access_token=${token}`
);
ws.onopen = () => {
// 3. Capture microphone audio at 16kHz mono
const ctx = new AudioContext({ sampleRate: 16000 });
navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
const source = ctx.createMediaStreamSource(stream);
// Use AudioWorklet to convert to PCM16LE and send frames
});
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === "conversation.item.input_audio_transcription.completed") {
console.log(data.text);
}
};
Python
import json, websocket
ws = websocket.create_connection(
"wss://audio.lansonai.com/v1/audio/transcriptions/stream",
header=["Authorization: Bearer sk-..."]
)
print(json.loads(ws.recv())) # session.created
ws.send(json.dumps({
"type": "input_audio_buffer.append",
"audio": "<base64 PCM16LE>"
}))
ws.send(json.dumps({"type": "input_audio_buffer.flush"}))
while True:
event = json.loads(ws.recv())
if event["type"] == "conversation.item.input_audio_transcription.completed":
print(f"[{event['utterance_index']}] {event['text']}")
elif event["type"] == "error":
print(f"Error: {event['code']}: {event['message']}")
break
Reference script
The repository's scripts/realtime-inspect.ts is a complete end-to-end validation script:
bun run inspect:realtime -- --audio ./sample.wav
It handles session-token flow, PCM16LE encoding, 100ms frame simulation, and completed-event verification. Requires ffmpeg.
Next steps
- Connection Lifecycle — timeouts and close codes
- Audio Input — format and frame size
- Client Messages — all message types
