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/sessions to 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

POST/v1/live-transcription/sessions

Creates 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

Returns a session object with token, wsUrl, expiresAt, and sampleRate.

Connect & stream audio

WS/ws/transcribe

Opens 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 sampleRate from 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 sampleRate Hz. 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 in wsUrl.

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 when type is "error").