Build a speech-to-speech voice agent with the Realtime API. The model works directly with audio, maintains conversation state, and can call tools. This guide starts with the Agents SDK for a browser application; use the lower-level connection guides when you need direct control.
For full-duplex conversations with a separate delegated backend, see GPT-Live. To compare voice architectures and chained pipelines, see Voice agents.
Build a speech-to-speech voice agent
Use the Realtime API when the interaction should feel conversational and immediate. This is the best starting point for voice agents that need barge-in, low first-audio latency, natural turn taking, and realtime tool use.
The usual browser flow is:
- Your application server creates an ephemeral client secret for the Realtime session.
- Your frontend creates a
RealtimeSession. - The session connects over WebRTC in the browser or WebSocket on the server.
- The agent handles audio turns, tools, interruptions, and handoffs inside that session.
import { RealtimeAgent, RealtimeSession } from "@openai/agents/realtime";
const agent = new RealtimeAgent({
name: "Assistant",
instructions: "You are a helpful voice assistant.",
});
const session = new RealtimeSession(agent, {
model: "gpt-realtime-2.1",
});
await session.connect({
apiKey: "ek_...(ephemeral key from your server)",
});From there, attach tools, handoffs, and guardrails to the RealtimeAgent the same way you would attach them to a text agent. Keep audio transport concerns in the session layer, and keep business logic in the agent definition.
Start with the transport docs when you need lower-level control:
Safety identifiers
If your application identifies individual end users, include a safety identifier with Realtime API requests. OpenAI recommends safety identifiers but doesn’t require them. They help OpenAI detect harmful behavior and target enforcement to an individual user rather than your entire organization. Use a stable, privacy-preserving value, such as a hashed internal user ID.
For Realtime API requests, send the identifier in the OpenAI-Safety-Identifier header. When using ephemeral tokens, set the header on the server-side request that creates the client secret to associate the identifier with the session. When connecting from a trusted server with WebSocket or the unified WebRTC interface, set the header on the connection request.
Safety identifiers don’t carry over from Responses API requests or other sessions. If you use the Responses API safety_identifier parameter elsewhere in your application, pass the same stable value when you create or connect each Realtime session.
Beta to GA migration
If you still have a beta Realtime integration, migrate it to the GA interface before moving forward with new work. The most important changes are:
- Remove the
OpenAI-Beta: realtime=v1header when calling the GA interface. - Use
POST /v1/realtime/client_secretsto create ephemeral credentials for browser or mobile clients. - Use
/v1/realtime/callswhen establishing WebRTC sessions. - Update session and event shapes for the GA interface. In particular, set
session.type, move output audio configuration undersession.audio.output, and use the newer response event names likeresponse.output_text.delta,response.output_audio.delta, andresponse.output_audio_transcript.delta. - If you are moving a speech-to-speech app forward, start from the browser example. If you are moving a transcription workflow forward, use Realtime transcription.
See the Realtime client events reference, Realtime sessions reference, and browser example for the current GA flow.
Next steps
- Managing conversations: Configure sessions and handle audio, text, and events.
- Voice activity detection: Configure automatic turn detection.
- Tools and MCP: Add functions, MCP servers, and connectors.
- Prompting voice models: Use the guide for your Realtime model.
- Cost optimization: Understand Realtime accounting and caching.
- Server-side controls: Keep tool execution and session control on your server.
Other audio workflows
The workflow chooser and shared audio vocabulary now live in Audio and voice. For continuous translation, use Live translation. For live captions, use Live transcription; for recorded audio, use File transcription.