The Complete Production SOP: How to Deploy and Run OpenAI Realtime API WebRTC & Audio Sessions in Autonomous AI Agents
Production SOP to install and run OpenAI Realtime WebRTC audio sessions in Codex, Claude Code, and Cursor. Master ephemeral sessions, VAD, and SDP negotiation.
Technical Overview & Architectural Context
Autonomous coding agents frequently stumble when implementing the OpenAI Realtime API due to the dual-channel nature of WebRTC and raw WebSocket streaming. Agents routinely attempt to expose long-lived `OPENAI_API_KEY` credentials directly in browser client code, fail to exchange ephemeral session tokens via the `/v1/realtime/sessions` endpoint, or produce flawed Session Description Protocol (SDP) answer/offer state machines. Furthermore, LLMs without deterministic rules often neglect audio buffer clearing when handling Voice Activity Detection (VAD) `input_audio_buffer.speech_started` events, resulting in unacceptable audio overlap, broken barge-in functionality, and corrupted PCM16 audio buffers. The `openai-realtime-voice-webrtc` skill enforces strict procedural boundaries across Codex, Claude Code, Cursor, and Windsurf. By structuring SDP exchanges into strict sequential stages, enforcing 24kHz single-channel PCM16 encoding, isolating key generation to backend micro-handlers, and managing cancellation frames across WebRTC data channels, this skill transforms non-deterministic coding suggestions into a production-grade, zero-leak bidirectional audio pipeline.
Prerequisites & Environment Requirements
Verified Search Intents & Long-Tail Queries Solved
This operational tutorial is engineered to provide deterministic solutions for these developer search queries:
Step-by-Step Execution Playbook
Local Environment Setup & SKILL.md Mounting
Create the local skill manifest directory and inject verified procedural rules into the agent runtime path.
Autonomous coding assistants evaluate local skill trees before invoking tasks. By placing `SKILL.md` under `~/.agents/skills/openai-realtime-voice-webrtc` or `.cursor/rules/`, you equip the agent with the precise procedural constraints needed to generate compliant WebRTC negotiation sequences without hallucinations.
mkdir -p ~/.agents/skills/openai-realtime-voice-webrtc && curl -fsSL https://askills.dev/api/skills/openai-realtime-voice-webrtc/raw -o ~/.agents/skills/openai-realtime-voice-webrtc/SKILL.md---
name: "openai-realtime-voice-webrtc"
description: "Build ultra-low-latency bidirectional voice agents with OpenAI Realtime API."
metadata:
author: "OpenAI"
version: "1.0.0"
runtime_compatibility:
- "codex"
- "claude-code"
- "cursor"
- "windsurf"
triggers:
- "connect to openai realtime api"
- "stream audio to realtime api"
- "handle realtime vad events"
permissions:
fs_read: true
fs_write: "workspace"
shell_exec: false
net_access: false
---
# OpenAI Realtime API WebRTC & Audio Sessions
Implements OpenAI Realtime API (WebSocket / WebRTC): session.update, conversation.item.create, response.create, audio input/output streaming, and voice activity detection (VAD).
## When to Invoke
Invoke this skill whenever you need to:
- connect to openai realtime api
- stream audio to realtime api
- handle realtime vad events
## Execution SOP & Rules
1. Establish ephemeral session tokens via backend server to protect primary OpenAI API keys.
2. Configure audio format as PCM16 (24kHz) for optimal clarity and low transport latency.
3. Listen for input_audio_buffer.speech_started events to instantly cut off model audio playback.
4. Submit function call results promptly to avoid pausing the conversational audio flow.
## Verification Checklist
- Run local linting, syntax validation, and type-checks before reporting completion.
- Ensure all created or modified files adhere to workspace boundaries and avoid uncommitted secrets.
- Verify tests or build commands exit cleanly with return code 0.In Cursor, symlink this directory into `.cursor/rules/realtime.mdc` to enforce continuous session boundaries without re-parsing prompt tokens on each prompt turn.
Do not grant `net_access: true` in the frontmatter metadata. Agents must write the code to proxy WebRTC calls rather than executing arbitrary network requests during prompt generation.
Ephemeral Token Server & WebRTC Session Handshake Setup
Configure a local backend route to generate ephemeral client tokens and handle WebRTC SDP exchange securely.
Direct browser-to-OpenAI WebRTC requires an ephemeral session token fetched via an authorized server. Agents must establish a lightweight backend route (Node.js/Next.js/Express) that calls `POST https://api.openai.com/v1/realtime/sessions` using the master key and returns the short-lived `client_secret` to the frontend peer connection.
cat << 'EOF' > server-realtime-token.ts
import express from 'express';
const app = express();
app.use(express.json());
app.post('/api/realtime-session', async (_req, res) => {
try {
const response = await fetch('https://api.openai.com/v1/realtime/sessions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gpt-4o-realtime-preview-2024-12-17',
voice: 'alloy',
input_audio_format: 'pcm16',
output_audio_format: 'pcm16',
turn_detection: {
type: 'server_vad',
threshold: 0.5,
prefix_padding_ms: 300,
silence_duration_ms: 500
}
}),
});
const data = await response.json();
res.status(response.status).json(data);
} catch (error) {
res.status(500).json({ error: 'Failed to negotiate ephemeral session' });
}
});
app.listen(3001, () => console.log('Token proxy listening on :3001'));
EOFNever allow the agent to instantiate `RTCPeerConnection` with hardcoded OpenAI authorization headers; enforce the ephemeral `client_secret.value` exchange pattern exclusively.
Ephemeral tokens expire within 60 seconds if the initial WebRTC SDP handshake is not finalized. Ensure the peer connection initializes immediately upon token receipt.
WebRTC PeerConnection & VAD Barge-In Implementation
Implement the client-side WebRTC audio track transceiver, data channel event bus, and interruption handling.
The client must open an `RTCPeerConnection`, attach a 24kHz mono microphone track, instantiate a `oai-events` data channel, and handle SDP offers through `https://api.openai.com/v1/realtime?model=...`. Critically, when `input_audio_buffer.speech_started` fires across the data channel, the client must mute or clear active playback elements instantly to support barge-in.
export async function initRealtimeWebRTC(ephemeralKey: string) {
const pc = new RTCPeerConnection();
const audioEl = document.createElement('audio');
audioEl.autoplay = true;
pc.ontrack = (e) => {
audioEl.srcObject = e.streams[0];
};
const ms = await navigator.mediaDevices.getUserMedia({ audio: { sampleRate: 24000, channelCount: 1 } });
pc.addTrack(ms.getTracks()[0]);
const dc = pc.createDataChannel('oai-events');
dc.addEventListener('message', (event) => {
const realtimeEvent = JSON.parse(event.data);
if (realtimeEvent.type === 'input_audio_buffer.speech_started') {
// Barge-in: Mute audio immediately while model cancels output
audioEl.pause();
audioEl.currentTime = 0;
}
});
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const baseUrl = 'https://api.openai.com/v1/realtime';
const model = 'gpt-4o-realtime-preview-2024-12-17';
const sdpResponse = await fetch(`${baseUrl}?model=${model}`, {
method: 'POST',
body: offer.sdp,
headers: {
Authorization: `Bearer ${ephemeralKey}`,
'Content-Type': 'application/sdp'
}
});
const answer = { type: 'answer' as RTCSdpType, sdp: await sdpResponse.text() };
await pc.setRemoteDescription(answer);
return { pc, dc };
}Explicitly passing `sampleRate: 24000` and `channelCount: 1` into `getUserMedia` prevents downstream audio resamplers from increasing end-to-end latency.
Failing to check `dc.readyState === 'open'` prior to sending client events like `conversation.item.create` will throw unhandled DOMExceptions.
Verification, Linting & Output Quality Gate
Execute automated self-healing checks to validate WebRTC lifecycle handlers and ensure zero secret leakage.
Instruct the autonomous agent to verify that SDP state machines handle disconnections cleanly and that tests confirm that `OPENAI_API_KEY` is not bundled into frontend client packages.
npx tsc --noEmit && npm test && git diff --checkInstruct Claude Code or Codex to run `grep -rn "sk-" src/` as an automated sanity check in the completion pipeline to safeguard against token leakage.
Do not bypass `git diff --check`. Trailing whitespace or unstaged binary audio assets can stall CI build hooks.
Real-World Scenario: Customer Support Voice Agent with Function Calling and Interruption Handling
“Connect to OpenAI Realtime API using WebRTC. Create a customer support agent that listens to audio via the microphone, supports real-time barge-in using input_audio_buffer.speech_started events, and provides an order status lookup tool via data channel function calling.”
Runtime Troubleshooting & Failure Modes
Root Cause: The agent attempted to query `https://api.openai.com/v1/realtime` passing a persistent `sk-proj-...` master key directly in the WebRTC SDP POST request, which is strictly disallowed by OpenAI's WebRTC implementation.
// Generate an ephemeral token via /v1/realtime/sessions first:
const sessionRes = await fetch('https://api.openai.com/v1/realtime/sessions', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ model: 'gpt-4o-realtime-preview-2024-12-17' })
});
const { client_secret } = await sessionRes.json();
// Use client_secret.value in the WebRTC SDP POST Authorization headerRoot Cause: The agent initiated `session.update` or `response.create` payloads immediately after instantiating `pc.createDataChannel('oai-events')` before the data channel reached the 'open' state.
await new Promise<void>((resolve) => {
if (dc.readyState === 'open') return resolve();
dc.onopen = () => resolve();
});
dc.send(JSON.stringify({ type: 'session.update', session: { modalites: ['audio', 'text'] } }));Frequently Asked Questions (OpenAI Realtime API WebRTC & Audio Sessions SOP)
Q:Why does the OpenAI Realtime API require WebRTC instead of standard WebSocket connections for browser apps?
WebRTC provides native peer-to-peer media streaming over UDP, significantly reducing audio latency and eliminating the browser-side buffer bloat, packet jitter, and base64 audio encoding overhead inherent to WebSockets.
Q:How does openai-realtime-voice-webrtc handle user interruptions (barge-in)?
The skill instructs agents to configure OpenAI's Server Voice Activity Detection (server_vad). When user speech is detected, the server emits `input_audio_buffer.speech_started`, triggering the client to stop local playback and dispatch a `response.cancel` event across the data channel.
Q:Can I use OpenAI Realtime API WebRTC & Audio Sessions across Codex, Claude Code, and Cursor simultaneously?
Yes. The skill conforms to the universal SKILL.md specification and can be injected into Claude Code rules, Cursor `.cursor/rules/`, Codex system instructions, or Windsurf workspace definitions without modification.
Ready to equip your autonomous agent with OpenAI Realtime API WebRTC & Audio Sessions?
Copy the complete audited SKILL.md specification or download the 1-click zip bundle directly from our verified registry.