OpenAI Realtime
Process realtime text, audio, and function calls over a Realtime WebSocket connection.
OpenAI Realtime uses a persistent connection and bidirectional events to process realtime text, audio, and function calls. The client sends session, audio-buffer, conversation-item, and response-control events, while the server continuously returns session status, transcripts, text, audio, function arguments, and error events.
This page primarily covers WebSocket connections. When connecting, replace MODEL_ID with a model ID that is visible to the current account and supports Realtime.
Typical use cases include realtime voice conversations, live meeting transcription and voice assistants, realtime translation, speech transcription, interactive coding, and server-side realtime integrations. A single connection can carry both text and audio while events coordinate VAD, function calls, and state updates.
wss://api.agtcloud.cn/v1/realtime?model=MODEL_IDAuthentication and connection
WebSocket authentication
Server applications establish a WSS connection with a Bearer API key and include the Realtime Beta header in the handshake request.
| Item | Value |
|---|---|
| Connection URL | wss://api.agtcloud.cn/v1/realtime?model=MODEL_ID |
| Authorization | Bearer your-api-key |
| OpenAI-Beta | realtime=v1 |
Long-lived API keys should only be used on trusted servers. Do not include them in browsers, mobile application bundles, or public repositories. Always use HTTPS/WSS for connections.
Ephemeral tokens
Before a client connects, a trusted server can create an ephemeral token that is valid for one minute and limited to a single connection.
POST https://api.agtcloud.cn/v1/realtime/sessions
Content-Type: application/json
Authorization: Bearer your-api-key
{
"model": "MODEL_ID",
"voice": "verse"
}Connection flow
In the primary WebSocket flow, the server connects directly with an API key. After the handshake succeeds, it sends client events and receives server events over the same connection.
In the WebRTC flow, the client first requests an ephemeral token from its application server, which calls the session endpoint to create the token. The client then creates an SDP offer, submits it to the Realtime endpoint, receives the SDP answer, and exchanges JSON events through the oai-events data channel.
WebSocket connection examples
The examples below show Node.js, Python, event sending, and event receiving. After establishing a connection, the client sends JSON events and the server continuously returns JSON events.
import WebSocket from 'ws';
const ws = new WebSocket('wss://api.agtcloud.cn/v1/realtime?model=MODEL_ID', {
headers: {
Authorization: 'Bearer your-api-key',
'OpenAI-Beta': 'realtime=v1',
},
});
ws.on('open', () => {
console.log('Connected to server.');
});
ws.on('message', (message) => {
console.log(JSON.parse(message.toString()));
});WebRTC integration
WebSocket is currently recommended. Before using WebRTC, confirm that the target model supports it. The following examples illustrate the basic connection structure for ephemeral tokens, SDP, audio tracks, and data channels.
The WebRTC connection URL is https://api.agtcloud.cn/v1/realtime?model=MODEL_ID. The client submits application/sdp with an ephemeral token. The data channel is named oai-events, and events use JSON. Input audio is sent through addTrack(), while output audio is received through ontrack.
Browser client and SDP exchange
async function init() {
const tokenResponse = await fetch('/session');
const data = await tokenResponse.json();
const ephemeralKey = data.client_secret.value;
const pc = new RTCPeerConnection();
const audioElement = document.createElement('audio');
audioElement.autoplay = true;
pc.ontrack = (event) => {
audioElement.srcObject = event.streams[0];
};
const mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
pc.addTrack(mediaStream.getTracks()[0]);
const dataChannel = pc.createDataChannel('oai-events');
dataChannel.addEventListener('message', (event) => {
console.log(JSON.parse(event.data));
});
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const response = await fetch(
'https://api.agtcloud.cn/v1/realtime?model=MODEL_ID',
{
method: 'POST',
body: offer.sdp,
headers: {
Authorization: `Bearer ${ephemeralKey}`,
'Content-Type': 'application/sdp',
},
},
);
await pc.setRemoteDescription({
type: 'answer',
sdp: await response.text(),
});
}
init();Create an ephemeral token on the server
import express from 'express';
const app = express();
app.get('/session', async (_request, response) => {
const result = await fetch('https://api.agtcloud.cn/v1/realtime/sessions', {
method: 'POST',
headers: {
Authorization: 'Bearer your-api-key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'MODEL_ID',
voice: 'verse',
}),
});
response.send(await result.json());
});
app.listen(3000);Send and receive data-channel events
const dataChannel = pc.createDataChannel('oai-events');
dataChannel.addEventListener('message', (event) => {
const realtimeEvent = JSON.parse(event.data);
console.log(realtimeEvent);
});
dataChannel.send(JSON.stringify({
type: 'response.create',
response: {
modalities: ['text'],
instructions: 'Write a haiku about code',
},
}));Standard WebSocket example for browser-like runtimes
Browser-like runtimes such as Deno and Cloudflare Workers can pass authentication through subprotocols. Confirm that the current runtime and node support this approach before use. Do not place a long-lived API key in an ordinary browser page.
const ws = new WebSocket(
'wss://api.agtcloud.cn/v1/realtime?model=MODEL_ID',
[
'realtime',
'openai-insecure-api-key.your-api-key',
'openai-organization.ORGANIZATION_ID',
'openai-project.PROJECT_ID',
'openai-beta.realtime-v1',
],
);
ws.addEventListener('open', () => {
console.log('Connected to server.');
});
ws.addEventListener('message', (event) => {
console.log(JSON.parse(event.data));
});Sessions, audio, and conversations
Realtime supports text-only, voice-only, and mixed text-and-audio conversations. Session configuration can include input and output audio formats, voice, temperature, maximum output length, tools, and VAD settings.
- Input and output audio formats:
pcm16,g711_ulaw, andg711_alaw. - Example voice options:
alloy,echo, andshimmer. - VAD configuration includes the activation threshold, prefix padding, and silence duration.
- Sessions, conversation items, content parts, and response events jointly advance the conversation.
See the event browser below for individual event fields. Shared parameters and value ranges are collected under Common types.
Event reference
Select an event to view its field definitions and JSON example. You can switch event direction, filter by category, or search by event name.
session.update
Updates the default session configuration.
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
event_id | string | No | Client-generated event identifier. | event_123 |
type | string | No | Event type. | session.update |
modalities | string[] | No | Modalities the model can use in its response. | ["text", "audio"] |
instructions | string | No | System instructions applied before the model is invoked. | "Respond clearly and concisely." |
voice | string | No | Voice used by the model. | alloy, echo, shimmer |
input_audio_format | string | No | Input audio format. | pcm16, g711_ulaw, g711_alaw |
output_audio_format | string | No | Output audio format. | pcm16, g711_ulaw, g711_alaw |
input_audio_transcription.model | string | No | Model used for transcription. | whisper-1 |
turn_detection.type | string | No | Voice activity detection type. | server_vad |
turn_detection.threshold | number | No | VAD activation threshold from 0.0 to 1.0. | 0.8 |
turn_detection.prefix_padding_ms | integer | No | Amount of audio to include before speech starts. | 500 |
turn_detection.silence_duration_ms | integer | No | Silence duration used to detect the end of speech. | 1000 |
tools | array | No | Tools available to the model. | [] |
tool_choice | string | No | How the model selects a tool. | auto/none/required |
temperature | number | No | Model sampling temperature. | 0.8 |
max_output_tokens | string or integer | No | Maximum number of tokens in one response. | "inf"/4096 |
{
"event_id": "event_123",
"type": "session.update",
"modalities": [
"text",
"audio"
],
"instructions": "Respond clearly and concisely.",
"voice": "alloy, echo, shimmer",
"input_audio_format": "pcm16, g711_ulaw, g711_alaw",
"output_audio_format": "pcm16, g711_ulaw, g711_alaw",
"input_audio_transcription": {
"model": "whisper-1"
},
"turn_detection": {
"type": "server_vad",
"threshold": 0.8,
"prefix_padding_ms": 500,
"silence_duration_ms": 1000
},
"tools": [],
"tool_choice": "auto",
"temperature": 0.8,
"max_output_tokens": "inf"
}Common types
The sections below summarize shared parameter tables for rate limits, function calls, audio, VAD, tools, models, events, sessions, conversation items, content, responses, transcription, audio streams, and WebRTC.
Rate-limit event parameters4 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
name | string | Yes | Rate-limit name. | Example: requests_per_min |
limit | integer | Yes | Rate limit. | Example: 60 |
remaining | integer | Yes | Remaining capacity. | Example: 45 |
reset_seconds | integer | Yes | Seconds until reset. | Example: 35 |
Function-call parameters4 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
type | string | Yes | Function type. | Example: function |
name | string | Yes | Function name. | Example: get_weather |
description | string | No | Function description. | Example: Get the current weather |
parameters | object | Yes | Function parameter schema. | Example: {"type": "object", "properties": {...}} |
Audio-format parameters4 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
sample_rate | integer | — | Sample rate. | Options: 8000, 16000, 24000, 44100, 48000 |
channels | integer | — | Channel count. | Options: 1 (mono), 2 (stereo) |
bits_per_sample | integer | — | Bits per sample. | Options: 16 (pcm16), 8 (g711) |
encoding | string | — | Encoding. | Options: pcm16, g711_ulaw, g711_alaw |
Voice activity detection parameters3 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
threshold | number | — | VAD activation threshold. | Default: 0.5; range: 0.0-1.0 |
prefix_padding_ms | integer | — | Speech prefix padding in milliseconds. | Default: 500; range: 0-5000 |
silence_duration_ms | integer | — | Silence-detection duration in milliseconds. | Default: 1000; range: 100-10000 |
Tool-selection parameters2 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
tool_choice | string | — | Tool-selection mode. | Options: auto, none, required |
tools | array | — | Available tools. | Options: [{type, name, description, parameters}] |
Model-configuration parameters4 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
temperature | number | — | Sampling temperature. | Range/options: 0.0-2.0;Default: 1.0 |
max_output_tokens | integer or string | — | Maximum output length. | Range/options: 1-4096/"inf";Default: "inf" |
modalities | string[] | — | Response modalities. | Range/options: ["text", "audio"];Default: ["text"] |
voice | string | — | Voice. | Range/options: alloy, echo, shimmer;Default: alloy |
Common event parameters3 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
event_id | string | Yes | Unique event identifier. | Example: event_123 |
type | string | Yes | Event type. | Example: session.update |
timestamp | integer | No | Event timestamp in milliseconds. | Example: 1677649363000 |
Session-status parameters3 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
status | string | — | Session status. | Options: active, ended, error |
error | object | — | Error details. | Options: {"type": "error_type", "message": "error message"} |
metadata | object | — | Session metadata. | Options: {"client_id": "web", "session_type": "chat"} |
Conversation-item status parameters3 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
status | string | — | Conversation item status. | Options: completed, in_progress, incomplete |
role | string | — | Sender role. | Options: user, assistant, system |
type | string | — | Conversation item type. | Options: message, function_call, function_call_output |
Content-type parameters3 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
type | string | — | Content type. | Options: text, audio, transcript |
format | string | — | Content format. | Options: plain, markdown, html |
encoding | string | — | Encoding. | Options: utf-8, base64 |
Response-status parameters3 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
status | string | — | Response status. | Options: completed, cancelled, failed, incomplete |
status_details | object | — | Status details. | Options: {"reason": "user_cancelled"} |
usage | object | — | Usage statistics. | Options: {"total_tokens": 50, "input_tokens": 20, "output_tokens": 30} |
Audio-transcription parameters4 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
enabled | boolean | — | Whether transcription is enabled. | Example: true |
model | string | — | Transcription model. | Example: whisper-1 |
language | string | — | Transcription language. | Example: en, zh, auto |
prompt | string | — | Transcription prompt. | Example: "Transcript of a conversation" |
Audio-stream parameters3 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
chunk_size | integer | — | Audio chunk size in bytes. | Options: 1024, 2048, 4096 |
latency | string | — | Latency mode. | Options: low, balanced, high |
compression | string | — | Compression. | Options: none, opus, mp3 |
WebRTC configuration parameters3 fields
| Field | Type | Required | Description | Options or example |
|---|---|---|---|---|
ice_servers | array | — | ICE server list. | Default: [{"urls": "stun:stun.l.google.com:19302"}] |
audio_constraints | object | — | Audio constraints. | Default: {"echoCancellation": true} |
connection_timeout | integer | — | Connection timeout in milliseconds. | Default: 30000 |
Error handling and recovery
Realtime errors generally fall into four categories: connection, authentication, audio, or session errors.
| Type | Common cause | Recommended action |
|---|---|---|
| Connection error | Network interruption, handshake failure, or invalid connection configuration | Check the WSS URL, network, and handshake request, then reconnect a limited number of times |
| Authentication error | Invalid API key, expired ephemeral token, or credentials that do not match the API address | Refresh the credential and make sure the API key matches the API address used by the request |
| Audio error | Device permissions, an unsupported format, or mismatched encoding | Check device permissions, sample rate, and encoding, then reestablish the audio path |
| Session error | Session timeout, concurrency limits, or inconsistent event state | Save the error event, create a new session, and fall back to a non-realtime API when necessary |
Recovery strategies can include automatic reconnection, session recovery, limited retries, and feature fallback. When an error occurs, first inspect the error event and save its event_id, error.type, error.code, error.message, and related-event information before deciding whether to resend anything.