OpenAI Realtime API SIP REFER Endpoint Returns 500 Internal Server Error

OpenAI Realtime API SIP REFER Endpoint Returns 500 Internal Server Error

Issue Summary

I’m implementing call screening using OpenAI’s Realtime API with SIP integration. The call acceptance, WebSocket monitoring, AI conversation, and tool calling all work perfectly. However, when attempting to transfer an approved call using the /v1/realtime/calls/{call_id}/refer endpoint, I consistently receive a 500 Internal Server Error.

Architecture Overview

  • SIP Provider: SignalWire (example-domain.signalwire.com)
  • Proxy: Kamailio (creates SIP B-leg to OpenAI)
  • Monitoring: Voice API server monitors via WebSocket
  • Flow: Caller → Kamailio → OpenAI SIP → AI Screening → REFER transfer to user’s phone

Working Components :white_check_mark:

  1. Call acceptance via POST /v1/realtime/calls/{call_id}/accept - Works
  2. WebSocket connection to wss://api.openai.com/v1/realtime?model=gpt-realtime&call_id={call_id} - Works
  3. AI conversation with caller - Works
  4. Tool calling with make_screening_decision function - Works perfectly (AI decides ALLOW/REJECT)

The Problem :cross_mark:

When the AI decides to ALLOW the call, we attempt to transfer it using REFER, but OpenAI returns 500 Internal Server Error.

Accept Endpoint Configuration

const response = await axios.post(
  `https://api.openai.com/v1/realtime/calls/${callId}/accept`,
  {
    type: 'realtime',
    model: 'gpt-realtime',
    instructions: 'You are a friendly call screening assistant...',
    tools: [
      {
        type: 'function',
        name: 'make_screening_decision',
        description: 'Make final screening decision after gathering information from caller',
        parameters: {
          type: 'object',
          properties: {
            decision: { type: 'string', enum: ['ALLOW', 'REJECT', 'VOICEMAIL'] },
            reason: { type: 'string' }
          },
          required: ['decision', 'reason']
        }
      }
    ],
    tool_choice: 'auto'
  }
);

REFER Request (Currently Failing)

const referPayload = {
  target_uri: "sip:+14155551234@example-domain.signalwire.com"
};

const referResponse = await axios.post(
  `https://api.openai.com/v1/realtime/calls/${callId}/refer`,
  referPayload,
  {
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
      'OpenAI-Project': 'proj_XXXXXXXXXXXXX'
    },
    timeout: 10000
  }
);

Error Response

Status: 500 Internal Server Error
Response: "Internal Server Error"
x-envoy-upstream-service-time: 367ms

The request reaches OpenAI’s servers (processes for ~367-390ms) but fails with a generic 500 error.

What We’ve Tried

1. Different URI Formats

  • :cross_mark: tel:+14155551234 → 500 error
  • :cross_mark: sip:+14155551234@example-domain.signalwire.com → 500 error

2. WebSocket Timing

  • :cross_mark: Closing WebSocket before REFER → 500 error
  • :cross_mark: Keeping WebSocket open during REFER → 500 error

3. Request Validation

  • :white_check_mark: Request structure matches documentation
  • :white_check_mark: Headers are correct (Authorization, Content-Type, OpenAI-Project)
  • :white_check_mark: Call ID is valid (same ID used successfully for accept/WebSocket)
  • :white_check_mark: Payload is valid JSON

Request Details from Logs

POST /v1/realtime/calls/rtc_XXXXXXXXXXXXXXXXXXXX/refer HTTP/1.1
Accept: application/json, text/plain, */*
Content-Type: application/json
Authorization: Bearer sk-proj-[REDACTED]
OpenAI-Project: proj_XXXXXXXXXXXXX
Content-Length: 59
Host: api.openai.com

{"target_uri":"sip:+14155551234@example-domain.signalwire.com"}

Questions

  1. Is REFER supported for SIP calls accepted through the REST API? The documentation mentions REFER for transferring calls, but all examples show browser-based WebRTC.

  2. What URI format should target_uri use for PSTN numbers? Should it be:

    • tel:+14155551234
    • sip:+14155551234@domain.com
    • sip:14155551234@domain.com (without +)
    • Something else?
  3. Are there any state requirements? Does the call need to be in a specific state before REFER? Should we:

    • Close the WebSocket first?
    • Wait for a specific event?
    • Send a session.update before REFER?
  4. Is there any logging available? The 500 error is generic - is there a way to get more detailed error information about why the REFER is being rejected?

Additional Context

  • Call ID format: rtc_XXXXXXXXXXXXXXXXXXXX
  • WebSocket events show successful tool calling:
    response.function_call_arguments.done
    Screening decision: ALLOW - [example reason]
    
  • After REFER fails, we successfully call /hangup endpoint (works fine)

Expected Behavior

REFER request should succeed and transfer the call to the specified target_uri, keeping the PSTN call leg alive.

Actual Behavior

REFER request consistently returns 500 Internal Server Error with no additional error details.


Any insights on what might be causing this or what we should try next would be greatly appreciated! Is REFER even supported for SIP calls in the current implementation?

@juberti Hi Justin. Wondering if you can take a look at this for me.

@josh31 Was there any progress on this? I believe I have exactly the same issue.

I took a quick look at your POST body and it looks reasonable. if you can post an actual call ID we can look at what happened on our side.

Still getting the 500 error.

I unfortunately decided to go down another path. But I can say that this is happening for others. Are you all seeing any 500 errors on your end? I no longer have the call id. Is it possible you can look it up based on my project account in conjunction with the refer api call?

If not, maybe @Kyle_Rogers can provide his?

Thank you.

I looked over the past day and only found a single instance of a 500 error across the entire service.

Hi!
Here is the call: https://api.openai.com/v1/realtime/calls/rtc_403010eabd15464892c4581f2175681b/refer
this was my target uri: sip:call_7ae6621b-439e-45ac-a518-5c4fd708b16d_1759791330392@freeswitch.ginihelp.com

it looks like we tried to send the REFER to your UA but we weren’t able to make a connection to 35.22.4.x:5060. Do you have SIP logs on your end that you can cross-ref?

this seems to be the only destination that we’ve failed to reach. I also tried to connect to it directly just now and was not able to make a connection.

Cleaning up my post:

Initial Attempt

curl -X POST "https://api.openai.com/v1/realtime/calls/rtc_12dddb03e9304953b96cedb5f04b1c2c/refer" \
  -H "Authorization: Bearer <OPENAI_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"target_uri": "sip:call_fa19aac3-2b15-4fc9-bde2-a903363102fe_1759795900083@kamailio.ginihelp.com"}'

Error received

AxiosError: timeout of 10000ms exceeded
Error code: ECONNABORTED

Troubleshooting completed

  • Removed all firewall rules
  • Issue persists even with firewall disabled

Key findings

  1. Early hangup scenario: When the call is disconnected too soon, I receive:

    {
      "error": {
        "message": "No session found for the provided call_id",
        "type": "invalid_request_error",
        "code": "call_id_not_found"
      }
    }
    
  2. With active call: When keeping the call alive and attempting REFER, I now get a 504 Gateway Timeout error instead.

Recent test call IDs

  • rtc_491247ab8f6a4a868c202db0605f457d
  • rtc_dc49f8becc0047c8b97a00ee204c7512 (504 error)

Tried with different target_uri type

  • tel:+131228839XX

I still see the same TCP timeout, dial TCP error: dial tcp ->35.222.4.x:5060: connect: connection timed out

The issue isn’t with your target_uri, it’s either your Contact header or a on-route proxy that’s inserting itself into a Record-Routeheader. You can verify by doing telnet IP port and see if that times out as well.

If you can post your SIP INVITE headers we can try to see if the Contactis OK.

SIP INVITE Headers - OpenAI REFER Investigation

Captured: 2025-10-07 05:50:26 UTC

Call Direction: SignalWire → Kamailio → OpenAI

Issue: REFER endpoint returns connection timeout to 35.222.4.219:5060


Initial INVITE (Kamailio → OpenAI)

Request Line


INVITE sip:proj_YA5ozas5Bj80YPpQCimjIUxW@sip.api.openai.com SIP/2.0

Contact Header


Contact: <sip:mod_sofia@138.197.198.13:35181;transport=tls;swrad=138.197.198.13~36607~3>

Record-Route Headers


Record-Route: <sip:35.222.4.219:5060;transport=tcp;r2=on;lr=on;ftag=0eKrUHDBKvXFB;did=e61.bc32>

Record-Route: <sip:35.222.4.219;r2=on;lr=on;ftag=0eKrUHDBKvXFB;did=e61.bc32>

Record-Route: <sip:152.42.144.114:5060;r2=on;lr;ftag=0eKrUHDBKvXFB;nat=yes>

Record-Route: <sip:152.42.144.114:5061;transport=tls;r2=on;lr;ftag=0eKrUHDBKvXFB;nat=yes>

Via Headers


Via: SIP/2.0/TCP 35.222.4.219:5060;branch=z9hG4bK8c51.14a3f766560b05f82e8410daa22ef588.0

Via: SIP/2.0/UDP 152.42.144.114:5060;branch=z9hG4bK8c51.5a3160c67f160008b7c6e49421e7930c.0;i=9eed1

Via: SIP/2.0/TLS 138.197.198.13:35181;received=138.197.198.13;rport=36607;branch=z9hG4bKX0c5vFHtS656r

Call Identification


From: <sip:+13477497248@sip.signalwire.com>;tag=0eKrUHDBKvXFB

To: <sip:inbound@kamailio.ginihelp.com:5060;transport=UDP>

Call-ID: 14f108a5-c92b-4602-b14f-0012b70eddcd

CSeq: 105354320 INVITE

Complete INVITE Headers


INVITE sip:proj_YA5ozas5Bj80YPpQCimjIUxW@sip.api.openai.com SIP/2.0

Record-Route: <sip:35.222.4.219:5060;transport=tcp;r2=on;lr=on;ftag=0eKrUHDBKvXFB;did=e61.bc32>

Record-Route: <sip:35.222.4.219;r2=on;lr=on;ftag=0eKrUHDBKvXFB;did=e61.bc32>

Record-Route: <sip:152.42.144.114:5060;r2=on;lr;ftag=0eKrUHDBKvXFB;nat=yes>

Record-Route: <sip:152.42.144.114:5061;transport=tls;r2=on;lr;ftag=0eKrUHDBKvXFB;nat=yes>

Via: SIP/2.0/TCP 35.222.4.219:5060;branch=z9hG4bK8c51.14a3f766560b05f82e8410daa22ef588.0

Via: SIP/2.0/UDP 152.42.144.114:5060;branch=z9hG4bK8c51.5a3160c67f160008b7c6e49421e7930c.0;i=9eed1

Via: SIP/2.0/TLS 138.197.198.13:35181;received=138.197.198.13;rport=36607;branch=z9hG4bKX0c5vFHtS656r

Max-Forwards: 61

From: <sip:+13477497248@sip.signalwire.com>;tag=0eKrUHDBKvXFB

To: <sip:inbound@kamailio.ginihelp.com:5060;transport=UDP>

Call-ID: 14f108a5-c92b-4602-b14f-0012b70eddcd

CSeq: 105354320 INVITE

Contact: <sip:mod_sofia@138.197.198.13:35181;transport=tls;swrad=138.197.198.13~36607~3>

User-Agent: SignalWire

Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY

Supported: timer, path, replaces

Allow-Events: talk, hold, conference, refer

Session-Expires: 600;refresher=uac

Min-SE: 90

Content-Type: application/sdp

Content-Length: 502


OpenAI 200 OK Response

Contact Header


Contact: <sip:OAI@sip.api.openai.com:5061>

Record-Route Headers (Preserved)


Record-Route: <sip:35.222.4.219:5060;r2=on;lr=on;ftag=0eKrUHDBKvXFB;did=e61.bc32;transport=tcp>

Record-Route: <sip:35.222.4.219;ftag=0eKrUHDBKvXFB;did=e61.bc32;r2=on;lr=on>

Record-Route: <sip:152.42.144.114:5060;nat=yes;r2=on;lr;ftag=0eKrUHDBKvXFB>

Record-Route: <sip:152.42.144.114:5061;ftag=0eKrUHDBKvXFB;nat=yes;transport=tls;r2=on;lr>

SDP Body


v=0

o=- 1759803327 1759803329 IN IP4 52.247.59.112

s=OAI

c=IN IP4 52.247.59.112

t=0 0

m=audio 47816 RTP/AVP 0 101

a=rtpmap:101 telephone-event/8000

a=fmtp:101 0-16

a=ptime:20

a=rtpmap:0 PCMU/8000


Analysis

Network Topology


Caller (SignalWire)

138.197.198.13:35181 (TLS)

|

v

152.42.144.114:5060/5061 (SignalWire Proxy)

|

v

Kamailio (SBC)

35.222.4.219:5060 (TCP/UDP)

|

v (stunnel TLS proxy on 127.0.0.1:5061)

OpenAI

sip.api.openai.com:5061 → 52.247.59.112:47816

REFER Routing Problem

Expected REFER path (based on Record-Route):


OpenAI → 35.222.4.219:5060 (Kamailio) → ...

Error reported:


dial tcp 35.222.4.219:5060: connect: connection timed out

Root cause:

  • Record-Route header instructs OpenAI to send REFER to 35.222.4.219:5060

  • Firewall rule deny-sip-other was blocking incoming connections

  • Rule has been deleted - port 5060 now accepts traffic from all sources

Current Firewall Status

Before:


Priority 910: deny-sip-other - DENIED port 5060 to 'kamailio' tag

After:


Priority 905: kamailio-sip - ALLOWS 0.0.0.0/0 on ports 5060/5061

(deny rule removed)

Connectivity Verification

DNS:


kamailio.ginihelp.com → 35.222.4.219

Listening ports:


UDP *:5060 (all interfaces)

TCP 0.0.0.0:5060 (all interfaces)

Suggested test from OpenAI network:


telnet 35.222.4.219 5060

Contact Header Analysis

Current Contact (from caller):


Contact: <sip:mod_sofia@138.197.198.13:35181;transport=tls;...>

This points to the SignalWire endpoint (originating caller). When OpenAI sends REFER, it will use the Record-Route path, not the Contact header, so this should be correct.

Record-Route Chain

The Record-Route creates this path for subsequent requests:

  1. 35.222.4.219:5060 (Kamailio - TCP)

  2. 35.222.4.219 (Kamailio - UDP)

  3. 152.42.144.114:5060 (SignalWire - UDP)

  4. 152.42.144.114:5061 (SignalWire - TLS)

OpenAI will follow this chain in reverse when sending REFER, starting with the first Record-Route (35.222.4.219:5060).


Questions for OpenAI Support

  1. Can you verify connectivity to 35.222.4.219:5060 from your REFER infrastructure?

  2. Are the Record-Route headers correctly formed, or is there a routing loop?

  3. Should we remove one of the Kamailio Record-Route entries (TCP vs UDP)?


Resolution Status

  • Firewall blocking resolved

  • Port 5060 now accessible from all sources

  • Kamailio properly listening on TCP/UDP

  • DNS resolution confirmed

  • Ready for REFER retry testing