{"slug": "outbound-sip-calling-is-now-available-to-all-organizations", "title": "Outbound SIP calling is now available to all organizations", "summary": "OpenAI has made outbound SIP calling available to all organizations on GPT-Live, letting a backend create a session to dial a phone number through a SIP trunking provider such as Twilio without an incoming-call webhook or accept request. Inbound calls arrive as a `live.transport.incoming` webhook carrying `data.type: \"sip\"` and a `data.session_id`, which the backend accepts or rejects via `POST /v1/live/sessions/{session_id}/accept`; SIP signaling uses TLS and GPT-Live requires SRTP for call audio. OpenAI said existing integrations may still receive the deprecated `live.call.incoming` event, which has no `data.type`, and advised handling both names and keeping the old subscription until legacy deliveries and retries drain.", "body_md": "Choose your API to see its connection steps and session events.\n\nConnect incoming and outgoing phone calls to GPT-Live through a SIP trunk. Your provider exchanges call audio with OpenAI, while your backend handles session configuration, call controls, and business logic. SIP signaling uses TLS, and GPT-Live requires SRTP for call audio.\n\n- [Handle an inbound call](#handle-an-inbound-call) : receive an incoming-call webhook, then accept or reject the call.\n- [Place an outbound call](#place-an-outbound-call) : create a session to dial a phone number through your provider. No incoming-call webhook or accept request is needed.\n\nUse a [sideband connection](https://developers.openai.com/api/docs/guides/voice-server-controls?api=live) when your backend needs to receive session events or send commands. It attaches to the existing conversation while SIP carries the audio. Assign one handler to each action so that duplicate webhook deliveries or events observed on multiple connections don’t execute tools twice.\n\n## Handle an inbound call\n\nRoute incoming phone calls from your SIP provider to your OpenAI project. Your backend receives a webhook and decides whether to accept each call.\n\n### Configure your phone number and trunk\n\nUse a SIP trunking provider, such as Twilio, to connect a phone number to GPT-Live. After purchasing a number from your provider:\n\n1. Open your project in [OpenAI settings](https://platform.openai.com/settings) . Under**Webhooks** , create a[webhook endpoint](https://developers.openai.com/api/docs/guides/webhooks) subscribed to`live.transport.incoming` .\n2. Find your project ID under **General** . It starts with`proj_` ; use the same project that owns the webhook.\n3. Point your provider’s SIP trunk at `sip:$PROJECT_ID@sip.api.openai.com;transport=tls` . For European data residency, use`sip:$PROJECT_ID@sip-eu.api.openai.com;transport=tls` instead.\n\nConfirm that GPT-Live SIP support is enabled for your project and that your provider’s SIP trunk is routed to that project before using this flow.\n\n### Receive the incoming call\n\nWhen OpenAI receives a call for your project, it sends a `live.transport.incoming` event to your webhook endpoint. Verify the webhook signature and deduplicate deliveries, then accept or reject the call.\n\nThe webhook identifies a SIP call with `data.type: \"sip\"` and provides `data.session_id`. Use that session ID unchanged for every Live call action. Treat `data.sip_headers` as untrusted caller metadata, not authorization.\n\nFor example, the webhook body contains:\n\n```\n{\n  \"object\": \"event\",\n  \"id\": \"evt_abc123\",\n  \"type\": \"live.transport.incoming\",\n  \"created_at\": 1750287018,\n  \"data\": {\n    \"type\": \"sip\",\n    \"session_id\": \"live_123\",\n    \"sip_headers\": [\n      { \"name\": \"From\", \"value\": \"sip:+14155550123@sip.example.com\" },\n      { \"name\": \"To\", \"value\": \"sip:+18005550100@sip.example.com\" },\n      { \"name\": \"Call-ID\", \"value\": \"call-123@example.com\" }\n    ]\n  }\n}\n```\n\nThe `created_at` field is a Unix timestamp in seconds. Delivery headers include `webhook-id` for deduplication, `webhook-timestamp` for the delivery attempt, and `webhook-signature` for signature verification. See [webhook verification examples](https://developers.openai.com/api/docs/guides/webhooks#verifying-webhook-signatures) for server-side handlers.\n\nExisting integrations may still receive the deprecated `live.call.incoming` event, which has no `data.type`. During migration, handle both names and retain the old subscription until legacy deliveries and retries have drained. The same pending call can also emit a Realtime webhook; assign one handler to the accept/reject decision rather than accepting through both APIs.\n\n### Accept or reject the call\n\nApply your application’s authorization and routing rules. To [accept the call](https://developers.openai.com/api/reference/resources/live/subresources/sessions/methods/accept), send an authenticated `POST /v1/live/sessions/{session_id}/accept` request with a top-level `session` object:\n\n```\n{\n  \"session\": {\n    \"type\": \"live\",\n    \"model\": \"gpt-live-1\",\n    \"instructions\": \"You are answering an inbound support call.\",\n    \"audio\": { \"output\": { \"voice\": \"marin\" } },\n    \"delegation\": { \"type\": \"client\" }\n  }\n}\n```\n\nUse `Authorization: Bearer $OPENAI_API_KEY` from your trusted backend for call-control requests. Choose the voice and delegation mode at acceptance. SIP negotiates the audio format, so omit `audio.format`. The example selects client delegation; your backend must handle delegated work. See [Delegation and tools](https://developers.openai.com/api/docs/guides/live-delegation) for client and Responses configurations.\n\nA successful acceptance returns `200 OK` with an empty body after session initialization. Handle HTTP errors before treating the call as accepted.\n\nTo [reject the call](https://developers.openai.com/api/reference/resources/live/subresources/sessions/methods/reject), send `POST /v1/live/sessions/{session_id}/reject` with a SIP status, such as `{ \"status_code\": 486 }` for busy. The status must be an integer from 300 through 699. The first accept or reject decision wins; a later competing decision returns `decision_already_made`.\n\n### Attach your backend\n\nAfter acceptance, connect a [sideband WebSocket](https://developers.openai.com/api/docs/guides/voice-server-controls?api=live) at `wss://api.openai.com/v1/live/sessions/{session_id}/attach`. Use the accepted session ID and the same project authentication and connection headers. Do not send `session.start` again.\n\nSIP carries the call audio. Use the sideband for transcripts, delegation, tools, commands, and reflected audio. Choose one owner for each side effect, even if multiple connections observe an event.\n\nOnce connected, use the [active call controls](#manage-an-active-call) to send keypad tones, transfer the call, or hang up.\n\n## Place an outbound call\n\nCall a phone number through your SIP provider with [Create session](https://developers.openai.com/api/reference/resources/live/methods/create). Your provider handles the phone network connection while GPT-Live carries the conversation.\n\nOutbound SIP calling is available to all organizations through the Live API, not the Realtime API call-creation endpoint.\n\n### Configure your trunk\n\nUse a trunk that supports TLS signaling and SDES-SRTP media. Enable SRTP in your provider’s settings before placing a call.\n\nSupply the trunk configuration with each request:\n\n| Field | Value | \n|---|---|\n| `transport.destination` | The phone number to call, in E.164 format, such as `+14155550123` . SIP URI destinations aren’t supported. | \n| `transport.trunk.provider_url` | A provider endpoint such as `sips:sip.example.com:5061` . The default port is`5061` ;`;transport=tcp` is optional. | \n| `transport.trunk.auth.type` | `digest` for SIP Digest authentication. | \n| `transport.trunk.auth.username` | Your provider’s SIP username. | \n| `transport.trunk.auth.password` | Your provider’s SIP password. | \n| `transport.trunk.caller_number` | The caller phone number to send to your provider, in E.164 format. | \n\nThe provider endpoint must use `sips:` for TLS signaling. Don’t include credentials, paths, URI headers, or other URI parameters in the URL. Local hostnames and literal private or local IP addresses are rejected. Keep your OpenAI API key and SIP credentials on your server.\n\n### Create the session\n\nSend `POST /v1/live/sessions` with your session configuration and `transport.type: \"sip\"`. Choose the voice and delegation mode when creating the session. Omit `audio.format` because SIP negotiates the audio format.\n\nThis example uses `curl` and `jq`. Set `OPENAI_API_KEY`, `SIP_USERNAME`, and `SIP_PASSWORD` in your server environment, and replace the example provider endpoint and phone numbers with your own values. The example selects client delegation; your backend must handle [delegated work](https://developers.openai.com/api/docs/guides/live-delegation).\n\n```\njq -n \\\n  --arg username \"$SIP_USERNAME\" \\\n  --arg password \"$SIP_PASSWORD\" \\\n  '{\n    \"session\": {\n      \"model\": \"gpt-live-1\",\n      \"instructions\": \"Help the user schedule an appointment.\",\n      \"audio\": { \"output\": { \"voice\": \"marin\" } },\n      \"delegation\": { \"type\": \"client\" }\n    },\n    \"transport\": {\n      \"type\": \"sip\",\n      \"destination\": \"+14155550123\",\n      \"trunk\": {\n        \"provider_url\": \"sips:sip.example.com:5061\",\n        \"auth\": {\n          \"type\": \"digest\",\n          \"username\": $username,\n          \"password\": $password\n        },\n        \"caller_number\": \"+14155550100\"\n      }\n    }\n  }' | curl https://api.openai.com/v1/live/sessions \\\n    -H \"Authorization: Bearer $OPENAI_API_KEY\" \\\n    -H \"Content-Type: application/json\" \\\n    --data-binary @-\n```\n\nThe request returns `200 OK` after the session initializes:\n\n```\n{\n  \"session\": { \"id\": \"live_123\" },\n  \"transport\": { \"type\": \"sip\" }\n}\n```\n\nThis response doesn’t mean the call has been answered. It contains no SDP or trunk credentials. Preserve `session.id` unchanged for the sideband connection and call controls. You don’t need an incoming-call webhook or an accept request for an outbound call.\n\n### Monitor and end the call\n\nAttach your backend to `wss://api.openai.com/v1/live/sessions/{session_id}/attach` using your OpenAI API key. Don’t send `session.start` again. The [sideband connection](https://developers.openai.com/api/docs/guides/voice-server-controls?api=live) carries conversation events, delegated work, and call progress while SIP carries the audio.\n\n| Event | Meaning | \n|---|---|\n| `transport.ringing` | The provider reports ringing or early media. | \n| `transport.answered` | The call has been answered and media is established. | \n| `transport.failed` | Call setup failed after session initialization. Inspect `error.code` and`error.message` . | \n\nEach call-progress event includes `event_id` and `session_id`. Attach immediately after creation: the sideband only replays events from the preceding 3 seconds, so a later attachment can miss earlier call progress. Replayed events retain their original event IDs. Deduplicate events by `event_id`.\n\nOnce connected, use the [active call controls](#manage-an-active-call) to send keypad tones, transfer the call, or hang up. Keep the sideband open for `session.closed` and final usage as described in [Usage and graceful close](https://developers.openai.com/api/docs/guides/live-conversations#usage-and-graceful-close).\n\n### Handle limits and errors\n\nRinging is limited to 3 minutes, and a connected call is limited to 2 hours. These limits aren’t configurable in the creation request.\n\nInvalid session configuration is returned on the creation request. Transport setup failures can return `502`, and initialization timeouts return `504`. After creation succeeds, monitor `transport.failed` for asynchronous setup failures.\n\n## Manage an active call\n\nThese controls apply to both inbound and outbound SIP calls.\n\n### Send and receive keypad events\n\nThe sideband receives [`transport.dtmf.received`](https://developers.openai.com/api/reference/resources/live/sideband-websocket#transport.dtmf.received) when the caller presses a key. To send a DTMF tone to the SIP trunk, send a [`transport.dtmf.send` client event](https://developers.openai.com/api/reference/resources/live/sideband-websocket#transport.dtmf.send) over the sideband WebSocket. After the tone is successfully sent, the sideband receives [`transport.dtmf.sent`](https://developers.openai.com/api/reference/resources/live/sideband-websocket#transport.dtmf.sent).\n\nIf you supply an `event_id`, the notification includes it as `client_event_id`; failures return an `error` event with `error.client_event_id`.\n\n### Transfer or end the call\n\nTo [transfer the call](https://developers.openai.com/api/reference/resources/live/subresources/sessions/methods/refer), send `POST /v1/live/sessions/{session_id}/refer` with `{ \"target_uri\": \"sip:agent@example.com\" }` for your destination. To [hang up](https://developers.openai.com/api/reference/resources/live/subresources/sessions/methods/hangup), send `POST /v1/live/sessions/{session_id}/hangup` with no request body. Both return `200 OK` with an empty body on success.\n\nThe transfer target becomes the SIP `Refer-To` header and can be a telephone URI such as `tel:+14155550123` or a SIP URI such as `sip:agent@example.com`. Your provider handles the remaining transfer flow.\n\nKeep the sideband open until `session.closed` supplies final usage. See [Usage and graceful close](https://developers.openai.com/api/docs/guides/live-conversations#usage-and-graceful-close) for usage reporting and close reasons.\n\n## SIP network requirements\n\nGPT-Live SIP calls use separate network paths for signaling and media. Configure your network to allow both:\n\n- **SIP signaling:**`sip.api.openai.com` and`sip-eu.api.openai.com` are GeoIP-routed endpoints. Allow outbound TCP/TLS traffic to the addresses returned by DNS on port`5061` .\n- **SRTP media:** The API specifies a separate media IP address and UDP port in the negotiated SDP. Allow bidirectional SRTP traffic over UDP to and from the following CIDRs:\n  - `13.79.45.80/28`\n  - `23.98.140.64/28`\n  - `40.67.149.176/28`\n  - `40.83.204.240/28`\n\n## Next steps with GPT-Live\n\n- [Prompting guide](https://developers.openai.com/api/docs/guides/voice-prompting?api=live) : write instructions for your voice agent.\n- [Webhooks and server-side controls](https://developers.openai.com/api/docs/guides/voice-server-controls?api=live) : manage a session from your backend.\n- [Delegation and tools](https://developers.openai.com/api/docs/guides/live-delegation) : connect speech to your reasoning and tool backend.\n- [Managing sessions](https://developers.openai.com/api/docs/guides/live-conversations) : handle transcripts, session state, and close.\n- [Latency and cost](https://developers.openai.com/api/docs/guides/voice-latency-cost?api=live) : understand latency and usage.\n- [GPT-Live partner integrations](https://developers.openai.com/api/docs/guides/live-partner-integrations) : find provider-specific setup guides and examples.\n\n[SIP](https://en.wikipedia.org/wiki/Session_Initiation_Protocol) is a\nprotocol used to make phone calls over the internet. With SIP and the\nRealtime API you can direct incoming phone calls to the API.\n\n## Overview\n\nIf you want to connect a phone number to the Realtime API, use a SIP trunking provider (e.g., Twilio). This is a service that converts your phone call to IP traffic. After you purchase a phone number from your SIP trunking provider, follow the instructions below.\n\nStart by creating a [webhook](https://developers.openai.com/api/docs/guides/webhooks) for incoming calls, through your **platform.openai.com** [settings](https://platform.openai.com/settings) > Project > **Webhooks**.\nThen, point your SIP trunk at the OpenAI SIP endpoint, using the project ID\nfor which you configured the webhook, e.g., `sip:$PROJECT_ID@sip.api.openai.com;transport=tls`.\nFor European data residency, use `sip:$PROJECT_ID@sip-eu.api.openai.com;transport=tls` instead.\nTo find your `$PROJECT_ID`, visit [settings](https://platform.openai.com/settings) > Project > **General**. That page will display the project ID, which\nwill have a `proj_` prefix.\n\nWhen OpenAI receives SIP traffic associated with your project,\nyour webhook will be fired. The event fired will be a\n[`realtime.call.incoming`](https://developers.openai.com/api/docs/api-reference/webhook-events/realtime/call/incoming) event,\nlike the example below:\n\n```\nPOST https://my_website.com/webhook_endpoint\nuser-agent: OpenAI/1.0 (+https://platform.openai.com/docs/webhooks)\ncontent-type: application/json\nwebhook-id: wh_685342e6c53c8190a1be43f081506c52 # unique id for idempotency\nwebhook-timestamp: 1750287078 # timestamp of delivery attempt\nwebhook-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4= # signature to verify authenticity from OpenAI\n\n{\n  \"object\": \"event\",\n  \"id\": \"evt_685343a1381c819085d44c354e1b330e\",\n  \"type\": \"realtime.call.incoming\",\n  \"created_at\": 1750287018, // Unix timestamp\n  \"data\": {\n    \"call_id\": \"some_unique_id\",\n    \"sip_headers\": [\n      { \"name\": \"From\", \"value\": \"sip:+142555512112@sip.example.com\" },\n      { \"name\": \"To\", \"value\": \"sip:+18005551212@sip.example.com\" },\n      { \"name\": \"Call-ID\", \"value\": \"03782086-4ce9-44bf-8b0d-4e303d2cc590\"}\n    ]\n  }\n}\n```\n\nFrom this webhook, you can accept or reject the call, using the `call_id` value from the webhook.\nWhen accepting the call, you’ll provide the needed configuration\n(instructions, voice, etc) for the Realtime API session.\nOnce established, you can set up a WebSocket and monitor the session as usual. The APIs to\naccept, reject, monitor, refer, and hangup the call are documented below.\n\n## Accept the call\n\nUse the [Accept call endpoint](https://developers.openai.com/api/docs/api-reference/realtime-calls/accept-call) to\napprove the inbound call and configure the realtime session that will answer it.\nSend the same parameters you would send in a\n[`create client secret`](https://developers.openai.com/api/docs/api-reference/realtime-sessions/create-realtime-client-secret)\nrequest, i.e., ensure the realtime model, voice, tools, or instructions are set before bridging the\ncall to the model.\n\n```\n1\n2\n3\n4\n5\n6\n7\n8curl -X POST \"https://api.openai.com/v1/realtime/calls/$CALL_ID/accept\" \\\n  -H \"Authorization: Bearer $OPENAI_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n        \"type\": \"realtime\",\n        \"model\": \"gpt-realtime-2.1\",\n        \"instructions\": \"You are Alex, a friendly concierge for Example Corp.\"\n      }'\n```\n\nThe request path must include the `call_id` from the\n[`realtime.call.incoming`](https://developers.openai.com/api/docs/api-reference/webhook-events/realtime/call/incoming)\nwebhook, and every request requires the `Authorization` header shown above. The\nendpoint returns `200 OK` once the SIP leg is ringing and the realtime session\nis being established.\n\n## Reject the call\n\nUse the [Reject call endpoint](https://developers.openai.com/api/docs/api-reference/realtime-calls/reject-call) to\ndecline an invite when you do not want to handle the incoming call, (e.g., from\nan unsupported country code.) Supply the `call_id` path parameter\nand an optional SIP `status_code` (e.g., `486` to indicate “busy”) in the JSON\nbody to control the response sent back to the carrier.\n\n```\n1\n2\n3\n4curl -X POST \"https://api.openai.com/v1/realtime/calls/$CALL_ID/reject\" \\\n  -H \"Authorization: Bearer $OPENAI_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"status_code\": 486}'\n```\n\nIf no status code is supplied the API uses `603 Decline` by default. A\nsuccessful request responds with `200 OK` after OpenAI delivers the SIP\nresponse.\n\n## Monitor call events\n\nAfter you accept a call, open a WebSocket connection to the same session to\nstream events and issue realtime commands. Note that when connecting to an existing\ncall using the `call_id` parameter, the `model` argument is not used (as it has already been configured\nvia the `accept` endpoint).\n\n### WebSocket request\n\n`GET wss://api.openai.com/v1/realtime?call_id={call_id}`\n\n### Query parameters\n\n| Parameter | Type | Description | \n|---|---|---|\n| `call_id` | string | Identifier from the `realtime.call.incoming` webhook. | \n\n### Headers\n\n- `Authorization: Bearer YOUR_API_KEY`\n\nThe WebSocket behaves exactly like any other Realtime API connection. Send\n[`response.create`](https://developers.openai.com/api/reference/resources/realtime/client-events#response.create),\nand other client events to control the call, and listen for server events to\ntrack progress. See [Webhooks and server-side controls](https://developers.openai.com/api/docs/guides/voice-server-controls?api=realtime)\nfor more information.\n\n``` js\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16import WebSocket from \"ws\";\n\nconst callId = \"rtc_u1_9c6574da8b8a41a18da9308f4ad974ce\";\nconst ws = new WebSocket(`wss://api.openai.com/v1/realtime?call_id=${callId}`, {\n  headers: {\n    Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,\n  },\n});\n\nws.on(\"open\", () => {\n  ws.send(\n    JSON.stringify({\n      type: \"response.create\",\n    })\n  );\n});\n```\n\n## Redirect the call\n\nTransfer an active call using the\n[Refer call endpoint](https://developers.openai.com/api/docs/api-reference/realtime-calls/refer-call). Provide the\n`call_id` as well as the `target_uri` that should be placed in the SIP `Refer-To`\nheader (for example `tel:+14155550123` or `sip:agent@example.com`).\n\n```\n1\n2\n3\n4curl -X POST \"https://api.openai.com/v1/realtime/calls/$CALL_ID/refer\" \\\n  -H \"Authorization: Bearer $OPENAI_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"target_uri\": \"tel:+14155550123\"}'\n```\n\nOpenAI returns `200 OK` once the REFER is relayed to your SIP provider. The\ndownstream system handles the rest of the call flow for the caller.\n\n## Hang up the call\n\nEnd the session with the [Hang up endpoint](https://developers.openai.com/api/docs/api-reference/realtime-calls/hangup-call)\nwhen your application should disconnect the caller. This endpoint can be used to\nterminate both SIP and WebRTC realtime sessions.\n\n```\ncurl -X POST \"https://api.openai.com/v1/realtime/calls/$CALL_ID/hangup\" \\\n  -H \"Authorization: Bearer $OPENAI_API_KEY\"\n```\n\nThe API responds with `200 OK` when it starts tearing down the call.\n\n## SIP signaling and media IP ranges\n\nRealtime SIP calls use separate network paths for signaling and media. To ensure proper operation, configure your network to allow signaling and media traffic as described below.\n\n### SIP signaling\n\n`sip.api.openai.com` and `sip-eu.api.openai.com` are GeoIP-routed endpoints. Your network must allow\noutbound TCP/TLS traffic to the addresses returned by DNS on port `5061`.\n\n### SRTP media\n\nThe API specifies a separate media IP address and UDP port in the negotiated SDP. Your network must allow bidirectional SRTP traffic over UDP to and from the following CIDRs:\n\n- `13.79.45.80/28`\n- `23.98.140.64/28`\n- `40.67.149.176/28`\n- `40.83.204.240/28`\n\n## Server examples\n\nThe following is an example of a `realtime.call.incoming` handler. It accepts the call and then logs all the events from\nthe Realtime API.\n\nFor the Ruby example, set the `OPENAI_API_KEY` and `OPENAI_WEBHOOK_SECRET`\nenvironment variables, then install the required dependencies with\n`gem install openai webrick async-websocket`.\n\n```\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59\n60\n61\n62\n63\n64\n65\n66\n67\n68\n69from flask import Flask, request, Response, jsonify, make_response\nfrom openai import OpenAI, InvalidWebhookSignatureError\nimport asyncio\nimport json\nimport os\nimport requests\nimport time\nimport threading\nimport websockets\n\napp = Flask(__name__)\nclient = OpenAI(webhook_secret=os.environ[\"OPENAI_WEBHOOK_SECRET\"])\n\nAUTH_HEADER = {\"Authorization\": \"Bearer \" + os.environ[\"OPENAI_API_KEY\"]}\n\ncall_accept = {\n    \"type\": \"realtime\",\n    \"instructions\": \"You are a support agent.\",\n    \"model\": \"gpt-realtime-2.1\",\n}\n\nresponse_create = {\n    \"type\": \"response.create\",\n    \"response\": {\n        \"instructions\": (\"Say to the user 'Thank you for calling, how can I help you'\")\n    },\n}\n\nasync def websocket_task(call_id):\n    try:\n        async with websockets.connect(\n            \"wss://api.openai.com/v1/realtime?call_id=\" + call_id,\n            additional_headers=AUTH_HEADER,\n        ) as websocket:\n            await websocket.send(json.dumps(response_create))\n\n            while True:\n                response = await websocket.recv()\n                print(f\"Received from WebSocket: {response}\")\n    except Exception as e:\n        print(f\"WebSocket error: {e}\")\n\n@app.route(\"/\", methods=[\"POST\"])\ndef webhook():\n    try:\n        event = client.webhooks.unwrap(request.data, request.headers)\n    except (InvalidWebhookSignatureError, ValueError) as e:\n        print(\"Invalid signature\", e)\n        return Response(\"Invalid signature\", status=400)\n\n    if event.type == \"realtime.call.incoming\":\n        requests.post(\n            \"https://api.openai.com/v1/realtime/calls/\"\n            + event.data.call_id\n            + \"/accept\",\n            headers={**AUTH_HEADER, \"Content-Type\": \"application/json\"},\n            json=call_accept,\n        ).raise_for_status()\n        threading.Thread(\n            target=lambda: asyncio.run(websocket_task(event.data.call_id)),\n            daemon=True,\n        ).start()\n    return Response(status=200)\n\nif __name__ == \"__main__\":\n    app.run(port=8000)\n```\n\n## Next steps\n\nNow that you’ve connected over SIP, use the left navigation or click into these pages to start building your realtime application.", "url": "https://wpnews.pro/news/outbound-sip-calling-is-now-available-to-all-organizations", "canonical_source": "https://developers.openai.com/api/docs/guides/voice-sip", "published_at": "2026-11-06 23:03:55+00:00", "updated_at": "2026-11-06 23:19:59.651806+00:00", "lang": "en", "topics": ["ai-products", "developer-tools", "artificial-intelligence", "ai-agents"], "entities": ["OpenAI", "GPT-Live", "Twilio", "SIP", "SRTP", "TLS"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/outbound-sip-calling-is-now-available-to-all-organizations", "markdown": "https://wpnews.pro/news/outbound-sip-calling-is-now-available-to-all-organizations.md", "text": "https://wpnews.pro/news/outbound-sip-calling-is-now-available-to-all-organizations.txt", "jsonld": "https://wpnews.pro/news/outbound-sip-calling-is-now-available-to-all-organizations.jsonld"}}