Media planes
A video room and a PSTN call look like the same thing from the API — “real-time media” — but they ride two different planes, and the plane is decided by the endpoint you call and the leg type, not by a request flag.- Orbit Media (SFU) carries WebRTC media: video rooms and the browser softphone.
- Jambonz SBC + RTPengine carries PSTN/SIP carrier media: inbound DIDs and outbound calls.
The two planes
Orbit Media (SFU)
Orbit Media is Orbit’s Selective Forwarding Unit. It handles everything that needs server-side fan-out or mixing of WebRTC media: simulcast, per-subscriber bitrate adaptation, codec negotiation, DTLS/SRTP, and server-side recording via egress. Use this plane when every participant is a WebRTC client — browsers, the dashboard softphone, or a native SDK. There is no non-SFU mode for video.Jambonz SBC + RTPengine
PSTN and SIP carrier media never touches the SFU. It terminates on the Jambonz session border controller, with RTPengine bridging RTP/SRTP between the carrier and Orbit:- Inbound — Telnyx and DIDWW DIDs route through Jambonz, which applies your number-handler routing.
- Outbound (MT) —
POST /api/v1/voice/callsinitiates the call through Jambonz, which terminates it on the Devotel wholesale softswitch. Outbound voice exits only via Devotel.
POST /api/v1/voice/calls/:id/recording/start), not SFU egress.
Which plane picks you
The deeper architecture narrative for both planes lives in
Transport architecture.
Tokens and credentials per plane
Clients never talk to a plane with a long-lived key. Each plane has its own short-lived credential path:- Video rooms (SFU) —
POST /api/v1/video/rooms(or/api/v1/video/rooms-scheduled) creates the room and mints a participant token against Orbit Media. See Video API. - Browser softphone (SFU) —
POST /api/v1/voice/softphone/tokenmints an Orbit Media token for the deterministic per-user roomsoftphone:<tenant>:<user>, so reconnects rejoin the same room and are idempotent. The token is short-lived (default 60 seconds). See Softphone token.
Browser softphone: SFU or SIP/WSS gateway
The browser softphone has two client transports, chosen by the SDK in use — not by a request flag:- Orbit Media (WebRTC) — the dashboard softphone calls
POST /api/v1/voice/softphone/tokenand joins an Orbit Media room. - SIP over WSS — the
@devotel-orbit/webSoftphonecallsPOST /api/v1/voice/softphone/registerto obtain a short-lived SIP credential andREGISTERs against Orbit’s WebRTC-to-SIP gateway over a secure WebSocket. The SIP password is HMAC-derived and never stored; issuance and revocation metadata (issue/expiry times, the owning org, a revoked flag) is persisted server-side so you can revoke a credential before it expires. CallDELETE /api/v1/voice/softphone/credentials/:usernameto revoke — the gateway rejects the HMAC on its next validation, even within its original lifetime.
End-to-end: browser softphone to PSTN
When a single call spans both planes, the path looks like this:- Your browser client mints a softphone token via
POST /api/v1/voice/softphone/token(SFU plane) or a SIP credential viaPOST /api/v1/voice/softphone/register(gateway plane). - The client dials out — either
POST /api/v1/voice/softphone/dialfrom an SFU session, or a SIPINVITEover the WSS gateway. - Jambonz bridges the browser leg onto the carrier plane and terminates the outbound leg on the Devotel wholesale softswitch.
- RTPengine bridges RTP/SRTP between the browser-side leg and the carrier for the duration of the call.
- Recording, if started, runs on the carrier plane as SIPREC; an SFU-only session would use Orbit Media egress instead.
What the API does not expose
To keep this page honest against the code:- There is no
transportfield onPOST /api/v1/voice/callsand noINVALID_TRANSPORTerror code. The plane is implied by the endpoint and leg type. - There is no client-facing “decision tree” endpoint that ranks SFU vs. WebSocket bridge per call, and no per-call latency-budget selection.