Live transcription
Live transcription converts a real-time audio stream into text via WebSocket. Instead of uploading a file, the client opens a persistent WebSocket connection and streams raw PCM audio frames; the service replies with incremental transcript.partial and transcript.final events.
The two-step flow:
- (1) call
POST /v1/live-transcription/sessionsto obtain a short-lived signed token and a WebSocket URL; - (2) connect to that URL and stream audio.
Each session creation deducts 1 creditfrom the workspace's live_transcription monthly allowance.
WebSocket protocol
After connecting, send the raw binary frames containing PCM 16-bit mono audio. The required sample rate is returned in the session response as sampleRate:
- 24 000 Hz
- 16 000 Hz
The service buffers audio internally and emits transcript events as text accumulates. The client receives JSON text frames:
{ "type": "transcript.partial", "text": "Hello" }{ "type": "transcript.final", "text": "Hello world." }{ "type": "error", "text": "engine failed to connect" }Close the WebSocket when the session ends. The service flushes any buffered audio before the connection is torn down.
End-to-End Example
import asyncio
import json
import os
import requests
import websockets
API_KEY = os.environ["API_KEY"]
BASE_URL = "https://api.example.com"
# 1. Create a live transcription session
response = requests.post(
f"{BASE_URL}/v1/live-transcription/sessions",
headers={"Authorization": f"Bearer {API_KEY}"},
)
response.raise_for_status()
session = response.json()["data"]
ws_url = session["wsUrl"]
sample_rate = session["sampleRate"] # 24000 or 16000
# 2. Connect and stream audio
async def transcribe():
async with websockets.connect(ws_url) as ws:
# Send PCM16 mono audio bytes (replace with real audio)
silence = b"\x00\x00" * sample_rate
await ws.send(silence)
# Receive transcript events
async for raw in ws:
event = json.loads(raw)
# event["type"]: "transcript.partial" | "transcript.final" | "error"
if event["type"] == "transcript.final":
print("Transcript:", event["text"])
break
asyncio.run(transcribe())Create a session
/v1/live-transcription/sessionsCreates a short-lived session token for a live transcription WebSocket connection. The response includes a ready-to-use wsUrl (token already embedded) and the sampleRate expected by the configured engine.
Calling this endpoint deducts 1 credit from the live_transcription monthly allowance. A 403 quotaExceeded error is returned when the workspace has no remaining credits.
Requires permission
live-transcription:create
Returns
token, wsUrl, expiresAt, and sampleRate.Connect & stream audio
/ws/transcribeOpens a persistent WebSocket connection on the transcription service (the URL is returned as wsUrl from the session endpoint).
Once connected the client drives the session with a binary-in / text-out protocol:
- Send raw PCM 16-bit mono audio as binary WebSocket frames. Use the
sampleRatefrom the session response (24 000 Hz, 16 000 Hz). - Receive JSON text frames for every transcript update. See the event schema below.
Close the WebSocket normally when the session ends. Any buffered audio is flushed before the connection tears down.
Parameters
- <binary frame>bytes
- Raw PCM 16-bit mono audio at
sampleRateHz. Send as binary WebSocket frames continuously while recording.
Query parameters
- tokenstring
- Required. The signed session token returned by
POST /v1/live-transcription/sessions. Already embedded inwsUrl.
Returns
The server emits JSON text frames. Each frame has two fields:
type—"transcript.partial"while words are still arriving,"transcript.final"when a sentence is committed, or"error"on engine failure.text— the transcript text (or error message whentypeis"error").