Live mode
Live mode provides real-time transcription for voice agents, live captions, and other interactive audio applications. Your app streams audio over a WebSocket connection and receives JSON transcription events as speech is detected and processed.
Capabilities
Live mode includes:
- Continuous audio streaming over a secure WebSocket connection
- A completed transcript segment after each detected speech turn
- JSON events for session, audio-buffer, and transcription activity
Connect to Live mode
To connect to Live mode, open a WebSocket connection to this endpoint.
wss://api.zoom.us/v2/aiservices/scribe/live
Then, include the live-asr WebSocket subprotocol and a Zoom AI Services JWT in the Authorization header.
import WebSocket from "ws";
const socket = new WebSocket(
"wss://api.zoom.us/v2/aiservices/scribe/live",
["live-asr"],
{
headers: {
Authorization: `Bearer ${process.env.ZOOM_ACCESS_TOKEN}`,
},
},
);
Note
Create the WebSocket connection from a trusted backend. Browser WebSocket clients cannot set the
Authorizationheader, and placing a JWT in client-side code exposes your credentials. For browser audio capture, send audio through a backend WebSocket proxy that adds the authorization header.
Configure the session
After the WebSocket opens, configure the session by sending a session.update event.
{
"type": "session.update",
"language": "en-US",
"audio": {
"format": "pcm16"
}
}
Session options
| Parameter | Type | Description |
|---|---|---|
type | string | Message type. Set to session.update. |
language | string | Transcription locale, such as en-US. See supported languages. |
audio.format | string | Audio encoding. Set to pcm16. |
Audio
Clients stream binary PCM16 frames after configuring the session.
Use little-endian, 16 kHz, mono audio and stream it in approximately 100 ms frames.
Keep control messages, such as session.update and session.close, as JSON text messages. Do not wrap binary audio in JSON or Base64-encode it.
For browser microphone capture, an AudioWorklet can convert the browser's Float32 samples to PCM16 frames before sending them to your backend proxy.
Handle server events
The server returns JSON events throughout the session, including:
| Event | Payload fields besides type |
|---|---|
session.created | session_id |
session.updated | None |
input_audio_buffer.speech_started | item_id, audio_start_ms |
input_audio_buffer.speech_stopped | item_id, audio_end_ms |
transcription.completed | item_id, transcript, audio_start_ms, audio_end_ms, transcription_latency_ms |
error | error: { code, message, fatal } |
session.closed | reason |
This example sends the session configuration and handles transcription events:
socket.on("open", () => {
socket.send(
JSON.stringify({
type: "session.update",
language: "en-US",
audio: {
format: "pcm16",
},
}),
);
});
socket.on("message", (data) => {
const event = JSON.parse(data.toString());
if (event.type === "transcription.completed") {
console.log("Final:", event.transcript);
}
if (event.type === "error") {
console.error(event.error);
}
});
Close the session
To finish transcription and close the session.
- Stop sending audio.
- Send a
session.closeevent:
{
"type": "session.close"
}
- Continue reading events until the server sends any remaining final transcription and the
session.closedevent. - Close the WebSocket.
Rate limits
Live mode rate limits apply per account.
Concurrent sessions
| Account type | Concurrent sessions |
|---|---|
| Default | 20 |
| Enterprise | 100 |
| Large Contact Center | 1,000 |
| Custom | 5,000+ |
Session limits
| Limit | Default |
|---|---|
| Maximum session duration | 60 minutes |
| Idle timeout | 30 seconds without audio |