
Hang up a SIP call
End an active SIP Speech to Speech call from your application when the agent finishes a path, when a menu should drop the PSTN leg, or when you must tear down after a failed transfer you do not want to keep talking on. Official Voice REST documents POST https://api.x.ai/v1/realtime/calls/{call_id}/hangup with Bearer API-key auth and an empty JSON success body, and the SIP Phone Calls guide places hangup next to refer under Call control so hangup ends the call while refer transfers it.
What you need
You need a live SIP session whose call_id came from the realtime.call.incoming webhook (the same id you pass on wss://api.x.ai/v1/realtime?call_id=…) plus an inference API key for that team. Neighboring jobs include Transfer a SIP call with refer when a human should take the caller instead of dropping them, Handle SIP phone calls with Speech to Speech for join and session.update, and Handle DTMF on SIP calls when keypress menus drive hangup; more voice jobs live on the Voice hub.
Call hangup
While the caller is still connected, POST hangup with the webhook call_id and no request body so SpaceXAI ends the PSTN leg through the documented call-control path.
export XAI_API_KEY="your_api_key"
CALL_ID="00000000-0000-0000-0000-000000000000"
curl -i -X POST "https://api.x.ai/v1/realtime/calls/${CALL_ID}/hangup" \
-H "Authorization: Bearer ${XAI_API_KEY}"
import os
import requests
call_id = "00000000-0000-0000-0000-000000000000"
response = requests.post(
f"https://api.x.ai/v1/realtime/calls/{call_id}/hangup",
headers={"Authorization": f"Bearer {os.environ['XAI_API_KEY']}"},
)
print(response.status_code, response.text)
A successful response returns empty JSON ({}). Hangup always uses call_id, not phone_number_id from inventory list or create, and closing only the realtime WebSocket without hangup can leave carrier behavior inconsistent, so prefer the documented hangup endpoint when your app owns the teardown decision.
When to prefer hangup over refer
Use hangup after a completed IVR path, after the agent says goodbye, or when you intentionally drop the PSTN leg, and use Transfer a SIP call with refer when the caller should reach another tel: or sip: destination. Docs treat a failed refer as a no-op that keeps the same session usable, which is the opposite of hangup: you are done with this call. Conversation resumption on a later SIP call is a separate opt-in via session.resumption, and hangup alone does not erase that cache if you previously enabled it.
Pitfalls
Posting hangup with phone_number_id fails because you must resolve the live call_id from the incoming webhook. Calling refer when you meant hangup bridges the caller elsewhere instead of ending the session. Assuming the WebSocket close alone is enough skips the documented call-control path carriers expect. Confusing hangup with Delete a registered SIP phone number removes inventory for future inbound calls while leaving the current PSTN leg untouched until hangup or remote disconnect.