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