Skip to content

Live Call Transcription

Overview

The Live Call Transcription WebSocket streams the transcript of a call while it is in progress. An external system (a supervisor dashboard, a CRM, a quality tool) opens one connection per call and receives each phrase as it is recognised, for the agent and for the customer separately.

The transcript is produced by the agent's web client: when live transcription is on for the call, the web client sends the audio of each side to the speech-to-text provider, and every result is also delivered to the subscribers of that call. Nothing is stored; a subscriber only receives what is said after it connects.

Requirements

Requirement Details
Live transcription on the account Config → Accounts → (account) → Calls: transcription enabled. Use Automatic mode so every call is transcribed; in Manual mode only the calls where the agent turns transcription on are streamed. See AI Transcription.
The agent answers in the web client Calls answered on a desk phone, a SIP softphone or the mobile apps are not transcribed live and produce no messages.
Credentials An API key or a login token of a user of the account who is an administrator or a call center supervisor. Other users get 403.

Endpoint

wss://your-domain:9443/ws/v1/calls/{call_id}/transcription

Method: GET (WebSocket upgrade).

{call_id} identifies the call (see Which call ID to use). URL-encode it.

Authentication

Use one of:

Method How
API key (server to server) Header X-API-Key: <api_key>. If the key belongs to a parent (reseller) account and the call belongs to a sub-account, also send X-Account-ID: <sub-account id>.
Login token Header Authorization: Bearer <token>, or the query parameter ?token=<token> when the client cannot set headers (browsers).

Warning

Do not put an API key in a web page. Browsers cannot send the X-API-Key header on a WebSocket, and anything in the page is visible to its users. Connect from your server and relay the messages to the browser.

Responses before the upgrade

Status Meaning
101 Connected.
400 No account could be determined for the credentials.
401 Missing or invalid credentials.
403 The user is neither an administrator nor a call center supervisor.

Messages

Every message is a JSON text frame with a type.

subscribed

Sent once, right after connecting.

{"type": "subscribed", "call_id": "f933ebf4-4433-47d4-aa4b-e90790d3c7a1"}

transcript

One phrase of one side of the call.

{
  "type": "transcript",
  "call_id": "f933ebf4-4433-47d4-aa4b-e90790d3c7a1",
  "side": "agent",
  "transcript": "thanks for calling, how can I help you",
  "confidence": 0.98,
  "is_final": true,
  "start": 12.4,
  "duration": 2.1
}
Field Description
side agent (the user on the web client) or customer (the other party).
transcript The recognised text.
is_final false for an interim result that may still change; true once the phrase is settled. Interim results for a phrase are followed by its final result, which replaces them. Omitted when false.
confidence 0 to 1, as reported by the speech-to-text provider.
start, duration Seconds from the moment that side started being transcribed.

Fields with an empty or zero value are omitted.

ended

That side of the call stopped being transcribed (the call ended or the agent turned transcription off). One ended arrives per side.

{"type": "ended", "call_id": "f933ebf4-4433-47d4-aa4b-e90790d3c7a1", "side": "customer"}

The connection is not closed by the server after ended; close it when you are done with the call.

Keep-alive

The server sends a WebSocket ping every 54 seconds and closes connections that do not answer it within 60 seconds. Standard WebSocket clients answer pings automatically. Messages sent by the client are ignored.

Which call ID to use

The ID is the one the agent's web client knows the call by:

Call call_id
Queue call The call ID of the caller's leg — the same ID recordings and CDRs of that call are linked to.
Any other call The call ID of the agent's leg, i.e. of the web client's own call.

A subscription to an ID that never matches simply receives no transcript messages. A subscription can be opened before the call is transcribed; messages start as soon as they are produced.

Example (Python)

import asyncio, json, os
import websockets

async def follow(call_id: str) -> None:
    url = f"wss://{os.environ['DOMAIN']}:9443/ws/v1/calls/{call_id}/transcription"
    headers = {"X-API-Key": os.environ["API_KEY"]}
    async with websockets.connect(url, additional_headers=headers) as ws:
        async for raw in ws:
            msg = json.loads(raw)
            if msg["type"] == "transcript" and msg.get("is_final"):
                print(f"{msg['side']}: {msg['transcript']}")

asyncio.run(follow("f933ebf4-4433-47d4-aa4b-e90790d3c7a1"))

Limitations

  • Only calls transcribed live in the web client are streamed. There is no server-side transcription of calls answered on other devices.
  • Nothing is replayed: phrases spoken before the subscription opened are not sent. The full transcript of a recorded call is available afterwards with the recording (see AI Transcription).
  • A subscriber that falls more than 64 messages behind loses messages until it catches up.
  • Language and provider are the ones set for live transcription on the account.