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

Just tried connectivity test:
Perfect! All connectivity tests PASSED:

Test Results

✓ TCP 35.222.4.219:5060 - SUCCESS
✓ TCP kamailio.ginihelp.com:5060 - SUCCESS
✓ UDP 35.222.4.219:5060 - SUCCESS
✓ Loopback 127.0.0.1:5060 - SUCCESS

Latest attempt:

  1. Request reaches OpenAI successfully (changed from ECONNABORTED to 504)
  2. Cloudflare returns 504 meaning OpenAI’s backend timed out
  3. Your infrastructure is accessible:
    - Port 5060 open (verified with nc)
    - DNS resolves: kamailio.ginihelp.com → 35.222.4.219
    - Firewall allows all IPs
  4. REFER target_uri: sip:call_76030e93-073a-410e-a36200fc8de2f65b_1759846050985@kamailio.ginihelp.com

What validation does the REFER endpoint perform on the target_uri? Our endpoint is publicly accessible, but your backend returns 504 Gateway Time-out."

Call ID: rtc_cd747713b1744ea9bca12d304b322bde

Latest attempt:
Tried by completely removing my Kam and transferring to a direct number with tel: and REFER succeeds. 200 response. So, the problem is definitely on my end. I’ll report further findings in the coming hours.

1 Like

FWIW the issue on the rtc_cd74… call seems to be a TCP/TLS mismatch, our service was able to contact your gateway but failed to establish TLS: TLS handshake error: EOF

Thank you for this post. It helped resolve my issue.

2 Likes

I can receive a 200 from Refer. The solution is to utilize a service that allows REFER. In my case, I’m using Signalwire. They don’t let it because it’s facing the PSTN, and upstream carriers won’t accept them, which is why it hangs up. Unless you create a domain app to funnel it through, they allow that in this case. That’s the solution I went with. I hope this helps others!

@jason.sunbelt can you give us some help here, Im having the same issue, and you opened and closed a similar issue, how did you fixed?

I don’t really remember all the details, and I don’t have time right now to dig back through it—sorry. The main “aha” moment for me was realizing that OpenAI doesn’t actually control the phone call, so it can’t do a transfer on its own. I was using Twilio with TwiML, and I had a function that updated the TwiML. That function got called from the webhook endpoint that was getting updates from OpenAI.