Control WebSocket
The control WebSocket is the primary integration surface. It is a multiplexed JSON request/response/event channel.
Connect
Connect to CONTROL_WS_PATH, default /control.
GET /control
Authorization: Bearer <token>
Upgrade: websocketAfter connection, the gateway sends:
{
"type": "event",
"event": "control.connected",
"eventId": "connection-id",
"occurredAt": "2026-06-30T00:00:00.000Z",
"data": { "connectionId": "connection-id" }
}Message Envelopes
Request:
{ "type": "request", "id": "req-1", "method": "session.list", "params": {} }Response:
{ "type": "response", "id": "req-1", "ok": true, "result": {} }Event:
{
"type": "event",
"event": "sip.terminated",
"eventId": "event-id",
"sessionId": "session-id",
"sequence": 3,
"occurredAt": "2026-06-30T00:00:00.000Z",
"data": {}
}Route Registration
{
"type": "request",
"id": "register-1",
"method": "route.register",
"params": {
"routes": [{ "match": "exact", "value": "support" }]
}
}Registered routes are owned by the connection. A competing connection cannot register the same route while it is active.
Inbound SIP Decisioning
When an inbound INVITE matches a WebSocket route, the gateway sends sip.invite before allocating rtpbridge resources. This lets the application reject, redirect at the SIP level, or create media only when it is ready to answer.
{
"type": "request",
"id": "invite-1",
"method": "sip.invite",
"params": {
"event": "invite",
"callId": "abc@example.com",
"sipCallId": "abc@example.com",
"destinationUri": "sip:support@example.net",
"destinationUser": "support",
"sourceUri": "sip:+15551234567@example.net",
"sdp": "v=0..."
}
}Reject:
{
"type": "response",
"id": "invite-1",
"ok": true,
"result": { "action": "reject", "status": 486, "reason": "Busy Here" }
}Answer:
{
"type": "response",
"id": "invite-1",
"ok": true,
"result": { "action": "answer", "sdp": "v=0..." }
}Command Parity
The WebSocket command surface is the canonical command surface. HTTP routes call into the same command dispatcher where a REST-like equivalent exists. Recording download and merge remain HTTP streaming routes because WebSocket is not a good fit for large binary PCAP streams.
Ownership Cleanup
Media sessions and SIP dialogs created or accepted by a control connection are tied to that connection. When the connection closes, owned media is torn down and owned SIP dialogs are terminated.