Live API outbound SIP calling: dialing real phone numbers with GPT-Live
The 2026-11-02 changelog opened outbound SIP calling to all organizations through the Live API: sip transport fields, trunk requirements, call-progress events, 3-minute ringing and 2-hour call limits, plus the SDK type-layer status.
How to
Configure your SIP trunk
Pick a SIP provider that supports TLS signaling and SDES-SRTP media, and enable SRTP in the provider's settings first; prepare the provider endpoint (sips: form, default port 5061), digest-authentication credentials, and your calling number (E.164).
Create the outbound session
Send the session configuration and transport block to POST /v1/live/sessions: type sip, destination as the called E.164 number, trunk with provider_url, digest auth, and caller_number; omit audio.format (SIP negotiates it). The 200 response with session.id means initialization succeeded, not that the call was answered.
Attach the sideband and monitor progress
Right after creation, connect to `wss://api.openai.com/v1/live/sessions/{session_id}/attach` and do not send session.start again; watch transport.ringing, transport.answered, and transport.failed — the sideband replays only the preceding 3 seconds, so deduplicate by event_id.
Drive the call and close out
Send transport.dtmf.send for keypad tones, POST to the refer endpoint to transfer, and POST to hangup to end the call as needed; keep the sideband open until session.closed delivers the final usage.
Until now the Live API's SIP story concentrated on inbound calls: your provider hands a call to OpenAI and you accept or reject it. The official changelog entry dated 2026-11-02 turned the direction around — outbound SIP calling became available to all organizations through the Live API. Your server names a phone number, your own SIP provider carries the phone-network connection, and GPT-Live handles the conversation. Fact sources for this article are the official changelog, the Telephony and SIP guide (fetched as .md full-text variants on 2026-11-09), and the tag sources of both official SDKs; the code samples are reproduced from the official guide (documentation-checked, not executed in a live environment on our side).
1. The announcement and its boundaries
The changelog entry for 2026-11-02 (Feature, labeled Model gpt-live-1 and API v1/live/sessions) reads:
Outbound SIP calling is now available to all organizations through the Live API. Connect GPT-Live to a phone number through your SIP provider.
Two boundaries are worth pinning down first. First, outbound calls are offered only through the Live API — the guide's Place an outbound call section states "Outbound SIP calling is available to all organizations through the Live API, not the Realtime API call-creation endpoint," so the Realtime API call-creation endpoint is not part of this outbound path. Second, pricing: the official pricing page (fetched 2026-11-09) lists gpt-live-1 voice sessions at $0.05 per minute, billed per second without rounding up to a whole minute, with backend model and tool usage charged separately.
Status anchor: as of the fetch on 2026-11-09, the newest entry in the official changelog was still the Nov 5 GPT-6 Cyber item — no newer API-layer entry existed in November.
2. The full life cycle of an outbound call
An outbound call has four segments: create the session, attach the sideband, watch the call-progress events, then drive the call (optional), keeping the sideband open until session.closed delivers final usage. Unlike inbound, an outbound call needs no incoming-call webhook and no accept request — creating the session is the dial action.
Session creation uses the guide's own curl and jq example (the example selects client delegation, so your backend must handle delegated work; replace the provider endpoint and phone numbers with your own):
jq -n \
--arg username "$SIP_USERNAME" \
--arg password "$SIP_PASSWORD" \
'{
"session": {
"model": "gpt-live-1",
"instructions": "Help the user schedule an appointment.",
"audio": { "output": { "voice": "marin" } },
"delegation": { "type": "client" }
},
"transport": {
"type": "sip",
"destination": "+14155550123",
"trunk": {
"provider_url": "sips:sip.example.com:5061",
"auth": {
"type": "digest",
"username": $username,
"password": $password
},
"caller_number": "+14155550100"
}
}
}' | curl https://api.openai.com/v1/live/sessions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @-
A successful request returns 200 with a minimal body:
{
"session": { "id": "live_123" },
"transport": { "type": "sip" }
}
The guide emphasizes three things about this response: it does not mean the call has been answered; it contains no SDP and no trunk credentials; and the session.id must be preserved unchanged, since the sideband connection and call controls both depend on it. Also omit audio.format when creating an outbound session — the audio format is negotiated by SIP.
3. Trunk configuration fields and provider requirements
The trunk configuration is supplied with each request; the fields below all come from the official guide:
| Field | Value |
|---|---|
transport.destination | The phone number to call, in E.164 format (for example +14155550123); SIP URI destinations are not supported |
transport.trunk.provider_url | A provider endpoint such as sips:sip.example.com:5061; the default port is 5061 and ;transport=tcp is optional |
transport.trunk.auth.type | digest (SIP Digest authentication) |
transport.trunk.auth.username | Your provider's SIP username |
transport.trunk.auth.password | Your provider's SIP password |
transport.trunk.caller_number | The caller number sent to your provider, in E.164 format |
Provider-side hard requirements: the trunk must support TLS signaling and SDES-SRTP media, with SRTP enabled in your provider's settings before placing a call. provider_url must use the sips: form (TLS signaling); the URL must not include credentials, paths, URI headers, or other URI parameters; local hostnames and literal private or local IP addresses are rejected. Keep your OpenAI API key and SIP credentials on your own server. There is also a network allowlist: SIP signaling uses the GeoIP-routed endpoints sip.api.openai.com and sip-eu.api.openai.com (allow outbound TCP/TLS on port 5061 to the addresses DNS returns), and SRTP media needs bidirectional UDP to the address and port the negotiated SDP specifies — the guide lists four /28 CIDRs for it.
4. Call-progress events, limits, and errors
Once the sideband is attached, call progress arrives as three events (the guide's event table):
| Event | Meaning |
|---|---|
transport.ringing | The provider reports ringing or early media |
transport.answered | The call has been answered and media is established |
transport.failed | Call setup failed after session initialization; inspect error.code and error.message |
Every event carries event_id and session_id. Attachment timing is a hard constraint: the sideband only replays events from the preceding 3 seconds, so a later attachment misses earlier call progress; replayed events keep their original event IDs, and deduplicating by event_id is enough.
Limits and errors are the guide's own numbers and codes: ringing is limited to 3 minutes, a connected call to 2 hours, and neither is configurable in the creation request; invalid session configuration is returned on the creation request; transport setup failures can return 502 and initialization timeouts 504; async setup failures after a successful creation surface through transport.failed.
5. In-call controls: DTMF, transfer, and hang up
The guide states these controls apply to both inbound and outbound calls. Keypad tones use three sideband events: when the other side presses a key you receive transport.dtmf.received; to send a tone to the trunk you send a transport.dtmf.send client event and receive transport.dtmf.sent once it is delivered; if you supply an event_id it comes back as client_event_id, and failures return an error event with error.client_event_id.
Transfer and hang-up are two ordinary HTTP endpoints. The transfer (refer) body has a single field:
{ "target_uri": "sip:agent@example.com" }
The 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. Hang-up sends POST /v1/live/sessions/{session_id}/hangup with no request body. Both endpoints return 200 with an empty body on success. Closing rule: keep the sideband open until session.closed arrives — final usage is supplied with it.
6. SDK type-layer status: nothing beyond webrtc yet
Our same-day check (2026-11-09) of both official SDK tag sources: SIP outbound calling has not reached the type layers.
- openai-python v3.47.0: in src/openai/types/live/live_create_params.py the Transport type field is Required[Literal["webrtc"]] with only sdp alongside — the sip type and the destination and trunk fields are absent; src/openai/resources/live/sessions.py lists accept, download_recording, fork, hangup, refer, and reject (sync and async each), with no create.
- openai-node v7.53.0: LiveCreateParams.Transport in src/resources/live/live.ts likewise only defines type 'webrtc' plus sdp.
The event side is one step ahead: the ServerEvent union in openai-node v7.53.0 already includes TransportRinging, TransportAnswered, TransportFailed, and the three DTMF events (transport.dtmf.received / send / sent), matching the guide's progress events one to one. In other words, the event types are in place while the create-session SIP transport is not — until the type layers catch up, place outbound calls over raw HTTP per the official guide and move back to typed calls once the SDKs update.
7. Common errors and troubleshooting
- The creation request fails outright: invalid session configuration is returned on the creation request — check the trunk fields one by one (sips: form, digest auth, E.164 numbers) and the omitted audio.format.
- You get a 502: transport setup failed; one of the status codes the guide names — before retrying, confirm SRTP is enabled on the provider side.
- You get a 504: initialization timed out.
- Creation succeeded but the phone never rang: the 200 response does not mean the dial succeeded; attach the sideband and watch transport.failed, then inspect error.code and error.message.
- You missed the ringing event: you attached later than the replay window (only the preceding 3 seconds); next time attach immediately after the creation response and deduplicate replayed versus live events by event_id.
- A DTMF send failed: look for error.client_event_id in the error event to identify which send failed.
8. Next steps
- The inbound accept / reject / hang up / refer controls and the Live API resource surface: The Live API lands in the OpenAI SDK: gpt-live-1, dual WebRTC/WebSocket channels, and SIP call control.
- Where SIP DTMF first landed in the SDK (the transport.dtmf.send client command): openai-python 3.42.0 and openai-node 7.46/7.47: agent compaction and review settings, external keys, SIP DTMF.
- The WebRTC and WebSocket big picture of realtime voice: Realtime Voice guide: gpt-realtime and Voice Mode.
- The continuously updated release timeline: OpenAI Models Release Notes (2026, Living Document).
Key points
- Official changelog entry 2026-11-02: outbound SIP calling is available to all organizations through the Live API; the entry is labeled Model gpt-live-1, API v1/live/sessions (fetched and verified 2026-11-09; the newest changelog entry that day was still the Nov 5 GPT-6 Cyber item)
- Outbound calls do not go through the Realtime API call-creation endpoint: the official guide states the capability is provided through the Live API; create the session with transport.type set to sip, a destination in E.164 format (for example +14155550123); SIP URI destinations are not supported
- Trunk requirements: TLS signaling (provider_url in sips: form, default port 5061) plus SDES-SRTP media, with SRTP enabled in your provider's settings first; auth.type is digest, plus a caller_number (E.164)
- Call-progress events transport.ringing / transport.answered / transport.failed arrive over the sideband WebSocket, each carrying event_id and session_id; the sideband replays only the 3 seconds before attachment, so attach immediately and deduplicate by event_id
- Limits: ringing up to 3 minutes, connected calls up to 2 hours, and the guide states neither can be configured in the creation request; transport setup failures can return 502 and initialization timeouts 504, while async failures after creation surface through transport.failed
- SDK types lag behind: as of openai-python v3.47.0 and openai-node v7.53.0 (tag-level check), LiveCreateParams.transport in both packages still only defines webrtc, and the python sessions sub-resource has no create method — outbound calls go over raw HTTP per the official guide
Frequently asked questions
Official references
- ChangelogOpenAI API Changelog (.md variant of the official changelog)
- DocsTelephony and SIP (official Live API SIP guide, .md variant)
- Docsopenai-python v3.47.0 live_create_params.py (SDK type source)
- Docsopenai-python v3.47.0 live/sessions.py (SDK resource source)
- Docsopenai-node v7.53.0 live.ts (SDK type source)
Related articles
The Live API lands in the OpenAI SDK: gpt-live-1, dual WebRTC/WebSocket channels, and SIP call control
openai-python v3.12.0 and openai-node v7.14.0 (09-10) add the Live API: WebRTC session setup, WebSocket connect, SIP call control, recording download, sideband — plus a gpt-live-1 literal. Only SDK-source-verifiable facts.
Read articleGPT-Realtime-2.1 End-to-End vs ASR+LLM+TTS Pipelines: Choosing a Voice Architecture
For voice products: Realtime end-to-end or a self-assembled ASR+LLM+TTS pipeline? A five-dimension comparison (latency, interruption, control, deployment, multilingual) plus scenario-based recommendations.
Read articleRealtime API multilingual production: zh / en / ja auto-detect + cross-language dialog + dialect robustness
GPT-Realtime-2.1 multilingual capability: auto-detect user language (zh / en / ja / ko / es etc.), cross-language dialog (user speaks A, AI answers B), dialect robustness (Cantonese / Sichuanese), translate mode auto-translation.
Read articleSubscribe to GPTMap Weekly
One email every Monday: curated OpenAI updates, deep dives, and best practices. No ads, unsubscribe anytime.
Submitting opens Buttondown in a new tab to confirm your subscription.