diff --git a/docs/src/content/docs/guides/voice-agents/transport.mdx b/docs/src/content/docs/guides/voice-agents/transport.mdx
index 96c20960..646bfca9 100644
--- a/docs/src/content/docs/guides/voice-agents/transport.mdx
+++ b/docs/src/content/docs/guides/voice-agents/transport.mdx
@@ -22,6 +22,7 @@ import historyUpdatedExample from '../../../../../../examples/docs/voice-agents/
import updateHistoryExample from '../../../../../../examples/docs/voice-agents/updateHistory.ts?raw';
import customWebRTCTransportExample from '../../../../../../examples/docs/voice-agents/customWebRTCTransport.ts?raw';
import websocketSessionExample from '../../../../../../examples/docs/voice-agents/websocketSession.ts?raw';
+import sipTransportExample from '../../../../../../examples/docs/voice-agents/sipTransport.ts?raw';
import transportEventsExample from '../../../../../../examples/docs/voice-agents/transportEvents.ts?raw';
import thinClientExample from '../../../../../../examples/docs/voice-agents/thinClient.ts?raw';
import cloudflareTransportExample from '../../../../../../examples/docs/extensions/cloudflare-basic.ts?raw';
@@ -47,6 +48,16 @@ building a phone agent with Twilio.
Use any recording/playback library to handle the raw PCM16 audio bytes.
+### Connecting over SIP
+
+Bridge SIP calls from providers such as Twilio by using the `OpenAIRealtimeSIP` transport. The transport keeps the Realtime session synchronized with SIP events emitted by your telephony provider.
+
+1. Accept the incoming call by generating an initial session configuration with `OpenAIRealtimeSIP.buildInitialConfig()`. This ensures the SIP invitation and Realtime session share identical defaults.
+2. Attach a `RealtimeSession` that uses the `OpenAIRealtimeSIP` transport and connect with the `callId` issued by the provider webhook.
+3. Listen for session events to drive call analytics, transcripts, or escalation logic.
+
+
+
#### Cloudflare Workers (workerd) note
Cloudflare Workers and other workerd runtimes cannot open outbound WebSockets using the global `WebSocket` constructor. Use the Cloudflare transport from the extensions package, which performs the `fetch()`-based upgrade internally.
diff --git a/examples/docs/voice-agents/sipTransport.ts b/examples/docs/voice-agents/sipTransport.ts
new file mode 100644
index 00000000..29fb332c
--- /dev/null
+++ b/examples/docs/voice-agents/sipTransport.ts
@@ -0,0 +1,57 @@
+import OpenAI from 'openai';
+import {
+ OpenAIRealtimeSIP,
+ RealtimeAgent,
+ RealtimeSession,
+ type RealtimeSessionOptions,
+} from '@openai/agents/realtime';
+
+const openai = new OpenAI({
+ apiKey: process.env.OPENAI_API_KEY!,
+ webhookSecret: process.env.OPENAI_WEBHOOK_SECRET!,
+});
+
+const agent = new RealtimeAgent({
+ name: 'Receptionist',
+ instructions:
+ 'Welcome the caller, answer scheduling questions, and hand off if the caller requests a human.',
+});
+
+const sessionOptions: Partial = {
+ model: 'gpt-realtime',
+ config: {
+ audio: {
+ input: {
+ turnDetection: { type: 'semantic_vad', interruptResponse: true },
+ },
+ },
+ },
+};
+
+export async function acceptIncomingCall(callId: string): Promise {
+ const initialConfig = await OpenAIRealtimeSIP.buildInitialConfig(
+ agent,
+ sessionOptions,
+ );
+ await openai.realtime.calls.accept(callId, initialConfig);
+}
+
+export async function attachRealtimeSession(
+ callId: string,
+): Promise {
+ const session = new RealtimeSession(agent, {
+ transport: new OpenAIRealtimeSIP(),
+ ...sessionOptions,
+ });
+
+ session.on('history_added', (item) => {
+ console.log('Realtime update:', item.type);
+ });
+
+ await session.connect({
+ apiKey: process.env.OPENAI_API_KEY!,
+ callId,
+ });
+
+ return session;
+}