Problems with session and call_id when working with SIP trunking calls and the realtime API

Hi there,

I am running an example of using python and websocket to respond to a SIP call.

My code has a tool that is called when hang-up is necessary.

The logs below show the last part of the session:

Received from WebSocket: {"type":"response.output_audio_transcript.done","event_id":"event_CCyukZjWkFhgtfhMqDMfV","response_id":"resp_CCyui3BxEwFFIwQYUMno6","item_id":"item_CCyuifr6R6su8USlxRKBd","output_index":0,"content_index":0,"transcript":"I'm sorry, but I can only assist with messages for someone else. Thank you for calling, and goodbye."}
Received from WebSocket: {"type":"response.content_part.done","event_id":"event_CCyukmV9W8v52R9vwhn3d","response_id":"resp_CCyui3BxEwFFIwQYUMno6","item_id":"item_CCyuifr6R6su8USlxRKBd","output_index":0,"content_index":0,"part":{"type":"audio","transcript":"I'm sorry, but I can only assist with messages for someone else. Thank you for calling, and goodbye."}}
Received from WebSocket: {"type":"conversation.item.done","event_id":"event_CCyukX9z4zi5y8WlQ71BZ","previous_item_id":"item_CCyugsVf1updte06613l5","item":{"id":"item_CCyuifr6R6su8USlxRKBd","type":"message","status":"completed","role":"assistant","content":[{"type":"output_audio","transcript":"I'm sorry, but I can only assist with messages for someone else. Thank you for calling, and goodbye."}]}}
Received from WebSocket: {"type":"response.output_item.done","event_id":"event_CCyukmTw4r59W3odkwvNF","response_id":"resp_CCyui3BxEwFFIwQYUMno6","output_index":0,"item":{"id":"item_CCyuifr6R6su8USlxRKBd","type":"message","status":"completed","role":"assistant","content":[{"type":"output_audio","transcript":"I'm sorry, but I can only assist with messages for someone else. Thank you for calling, and goodbye."}]}}
Received from WebSocket: {"type":"rate_limits.updated","event_id":"event_CCyukDsBS6kUsFQlQzd6W","rate_limits":[{"name":"tokens","limit":40000,"remaining":39263,"reset_seconds":1.105}]}
Received from WebSocket: {"type":"response.output_item.added","event_id":"event_CCyukZrZJO4DAPkkh15zv","response_id":"resp_CCyui3BxEwFFIwQYUMno6","output_index":1,"item":{"id":"item_CCyukmjd4xx0GTLIK4mvU","type":"function_call","status":"in_progress","name":"terminate","call_id":"call_BbiuiILJygpHblXR","arguments":""}}
Received from WebSocket: {"type":"conversation.item.added","event_id":"event_CCyukRVWoWV3nGFrCr58U","previous_item_id":"item_CCyuifr6R6su8USlxRKBd","item":{"id":"item_CCyukmjd4xx0GTLIK4mvU","type":"function_call","status":"in_progress","name":"terminate","call_id":"call_BbiuiILJygpHblXR","arguments":""}}
Received from WebSocket: {"type":"response.function_call_arguments.delta","event_id":"event_CCyukNyL11KdJctQ2kUqA","response_id":"resp_CCyui3BxEwFFIwQYUMno6","item_id":"item_CCyukmjd4xx0GTLIK4mvU","output_index":1,"call_id":"call_BbiuiILJygpHblXR","delta":"{}","obfuscation":"vQwBum8CxI6riu"}
Received from WebSocket: {"type":"response.function_call_arguments.done","event_id":"event_CCyukanC9c1oexEMxudIv","response_id":"resp_CCyui3BxEwFFIwQYUMno6","item_id":"item_CCyukmjd4xx0GTLIK4mvU","output_index":1,"call_id":"call_BbiuiILJygpHblXR","name":"terminate","arguments":"{}"}
TERMINATE CALL:call_BbiuiILJygpHblXR
OPENAI HANGUP RESPONSE:<Response [404]>
OPENAI HANGUP RESPONSE:{
    "error": {
        "message": "No session found for the provided call_id",
        "type": "invalid_request_error",
        "code": "call_id_not_found",
        "param": ""
    }
}

So the session is not found for the call_id, but that call_id comes in the last websocket communication, which actually calls the tool.

To test, I added code to count the number of events and call the same function to hangup with the on-going call_id when events > 20; then it abruptly ends the call.
It seems there is a problem with the session and the call_id; or I am not understanding something.

Here is my POST to end the call:

print(f"TERMINATE CALL:{call_id}")
call_close = {
    "type": "realtime",
    "call_id": call_id,
    "instructions": "terminate the call and hang-up.",
    "model": "gpt-realtime",
}

resp = requests.post(
    "https://api.openai.com/v1/realtime/calls/"
    + call_id
    + "/hangup",
    json=call_close,
    headers={**AUTH_HEADER, "Content-Type": "application/json"},
)

Am I doing something wrong?

Thanks,

Juan

I actually made this exact same mistake. If you’re using the call_id from the last WebSocket event that you receive, then it’s likely you’re actually using the ID of the tool call, not the ID of the phone call.

Instead, you’ll want to store the call_id given to the initial webhook, and then use that once it’s time to hang up. This ID should be the one you’re passing to /accept.

Thank you so much Ryan! that was my mistake. The Twilio call ID that is received with the first post is not recognized by Twilio – for some reason. Anyway, you solved my problem.