SIP over WebSocket · RFC 7118

Browser-native softphones. No installs, no per-seat charges, full duplex.

Open a URL, sign in, and your laptop is a SIP phone. It dials another extension, an AI agent, or a PSTN number through your trunk — and it rings when calls come the other way. Encrypted media, no plug-in, no extension chain.

01 · What it is

The shortest path from web page to phone call

SIP over WebSocket has been a published IETF standard (RFC 7118) since January 2014. It lets a SIP softphone live entirely inside a browser tab: signalling rides a WebSocket (ws:// or wss://) to the gateway, media flows over WebRTC with DTLS-SRTP encryption. The user installs nothing. The administrator adds an extension to a tenant and shares a URL.

CodeB ships the listener, the per-tenant TLS auto-discovery, the WebRTC to SIP media bridge, and the routing logic that gets in-dialog requests (BYE, REFER, INVITE) back to a browser whose registered Contact URI is not reachable from the public internet. That last part is technically demanding and is the reason several widely deployed soft-PBX platforms still don't offer SIP-WS as a first-class feature.

02 · How a call flows

Browser to bridge to anywhere

Browser softphone SIP.js / JsSIP wss:// + WebRTC CodeB gateway RFC 7118 listener WebRTC <-> SIP media DTLS-SRTP / Opus tenant-aware ACL dial ring SIP trunk PSTN / BYOC carrier AI virtual numbers voice receptionists Office / hardphone registered extensions Other browser tabs SIP-WS B2BUA ▸ outbound (dial) ◀ inbound (ring)

Same browser tab, both directions. No second app for incoming calls.

03 · Capabilities

What you can actually do

Full-duplex calling

Dial anything routable from your tenant; ring on inbound. No second-class endpoint. Same auth, same CDRs, same lawful-interception path as a hardphone.

In + Out

AI receptionist transfer

An AI agent on a virtual number can transfer the caller to a named registered colleague (browser or hardphone) mid-conversation via SIP REFER, then exit cleanly.

RFC 3515

BYOC SIP trunks

The same WebSocket softphone places calls through whichever trunk provider you already pay (consumer routers, on-prem PBX, Tier-1 wholesalers). No third-party intermediary.

No lock-in

Encrypted media

Audio negotiates DTLS-SRTP automatically (WebRTC default), Opus at 48 kHz. Per-direction RTP timestamping prevents jitter-buffer resets at the WebRTC to SIP boundary.

DTLS-SRTP

NAT traversal handled

The gateway injects server-reflexive ICE candidates into its SDP so the browser can reach it from any public network behind any NAT. Same ICE-Lite responder the sovereign SBC uses for hardphones.

ICE-Lite

Multi-tenant TLS

Per-tenant certificate auto-discovery on the WebSocket listener. One bridge process serves many tenants; each tenant's SAN cert is picked at connect time by SNI.

SNI · per-tenant

ACL gates apply

The same per-tenant allow / deny rules that govern UDP and TCP SIP traffic apply to WebSocket REGISTERs and INVITEs. Manage via the admin console.

Unified policy

Installable as PWA

The demo softphones are Progressive Web Apps: “Add to Home Screen” on iOS / Android puts a launcher icon on the home screen. Credentials persist in browser localStorage.

PWA

RFC 7118 native

Any RFC 7118 compliant client works — SIP.js, JsSIP, sipML5, Linphone-WS, your own. Not a vendor-locked browser app pretending to be a SIP softphone.

Open standard

Six-direction bridging

Every routing direction works: browser to AI agent, browser to office tab, browser to PSTN trunk, trunk to browser, office to browser, and browser to browser. Each direction is a first-class bridge, not a degraded fallback.

Full matrix

G.711 transcoding

European trunks negotiate A-law (PCMA), browsers default to mu-law (PCMU). The bridge transcodes between the two in either direction at the codec layer. Pass-through when both sides match; no overhead when codecs align.

PCMA ↔ PCMU

Ringback before answer

180 Ringing fires the moment the bridge receives the INVITE; the final 200 OK is deferred until the callee actually picks up. The caller's softphone plays its local ringback during setup — no silent “connected but dead” window.

Defer 200 OK

Sibling-fork collapse

When the upstream PBX forks the same call across two trunks, only the first delivery rings the softphone; the second is held silently at 180. The upstream's own fork arbitration resolves cleanly without sabotaging other endpoints.

Multi-trunk safe

Hot-reload config

Per-trunk capacity (inbound / outbound / total lines), credentials, registrar host and routing rules apply within the watchdog interval (under 10 seconds). No service restart, no dropped calls.

Under 10 s

Caller-hangup propagation

When the caller hangs up during ringback the bridge immediately CANCELs the callee leg with a matching Via branch (RFC 3261 sec 9.1). The callee phone stops ringing in milliseconds, not after a 30-second timeout.

RFC 3261

Wire-form correctness

Outbound SIP responses re-sync Content-Length to actual body byte count before serialisation. Defends against subtle truncation that some carrier stacks would otherwise reject as malformed SDP.

Bytes match
04 · Use cases

Where browser softphones replace something you currently maintain

Bring-your-own-device remote work

Field staff, contractors, hospitality casuals, part-time receptionists. Anyone who needs to make and take calls from a company number on their personal laptop without you shipping them software, paying per-seat licenses, or managing MDM enrollment. Send them a URL; sign-in is the same OIDC sign-in they use for the rest of the suite.

One-click “Talk to sales / support” from any page

A single bookmarked URL on a contact page, in an email signature, or as a QR code on print marketing dials your team instantly when the visitor opens it. No app install, no third-party redirect, no callback queue. Visitors stay on your domain.

AI-first call centres

Inbound calls hit an AI receptionist that triages, books, or hands off. The receptionist's REFER can land on a browser softphone in a corner of the agent's monitor — no separate softphone install per agent seat.

Embedded operations consoles

Drop a sip-js or JsSIP softphone into your internal admin tool / CRM / dispatch board. The phone becomes another widget on the page the operator is already looking at; calls log against the same record they're editing.

Compliance-bound industries

Browser softphones inherit the same per-tenant ACL, signed CDRs, recording hooks, and policy enforcement as the hardphone fleet. No new audit surface; the comms still run on your own self-hosted stack.

Disaster-recovery seat

When the main PBX dies or the hardphones won't register, anyone with the URL and credentials has a working softphone in 30 seconds on whatever browser is nearest.

05 · Try it now

Two installable demo softphones

Both run against the public CodeB tenant. Sign-in is automatic with the test credentials in the page; you can also add to your home screen and it behaves like a native phone app.

SIP.js demo

SimpleUser API. Smaller surface, easier to drop into existing JS code. Open the SIP.js softphone →

JsSIP demo

Event-driven API. Closer to the underlying SIP protocol; useful when you need full control over individual session events. Open the JsSIP softphone →

If you want to wire your own browser softphone (custom UI, embedded in an existing app), point the library's wsUri at wss://phone.aloaha.com:5443 and the tenant credentials work the same way.

06 · What this is not

Honest scoping

07 · FAQ

Operator questions, answered

Which call directions are supported?

All six: browser to AI agent, browser to office tab, browser to PSTN trunk, trunk to browser, office to browser, browser to browser. Each direction is a dedicated bridge with its own SDP shaping, ICE candidate injection and media path setup.

What about codec mismatch between browser (PCMU) and EU PSTN (PCMA)?

The bridge transcodes G.711 A-law and mu-law in either direction at the codec layer (PCM16 intermediate). Pass-through when both ends negotiate the same variant; no overhead when codecs align.

Does the caller hear ringback before the callee answers?

Yes. The bridge sends 180 Ringing the moment the INVITE arrives and defers the final 200 OK until the callee actually picks up. The caller's softphone plays its local ringback during the wait — no silent “connected but dead” gap.

What happens when an upstream PBX parallel-forks across two trunks?

Sibling-fork collapse: only the first delivery rings the softphone; siblings within a 2-second window are held silently at 180 so the upstream's own fork arbitration resolves naturally without a 4xx that would cancel every ringing endpoint on the account.

Can I disable a trunk for inbound without cancelling carrier parallel forks?

Set MaxConcurrentInbound to 0 in the per-tenant configuration. The bridge holds 180 silently instead of returning 403 Forbidden, so the upstream PBX continues fork arbitration to other trunks.

Are configuration changes hot-reloaded or do they need a restart?

Hot-reloaded. Per-trunk capacity, credentials, host, routing rules apply within the watchdog interval (under 10 seconds). Both global trunks in the bridge's appsettings.json and per-tenant trunks in the admin console reload without restarting the service or interrupting in-flight calls.

What standards does the SIP-WS stack conform to?

RFC 7118 for SIP over WebSocket transport, RFC 3261 for SIP signalling, RFC 3264 for offer/answer, RFC 3515 for in-call REFER, RFC 5245 / 8445 for ICE, RFC 8829 for DTLS-SRTP, RFC 4566 for SDP and RFC 3550 for RTP.

Get a tenant with browser softphones already on

SIP-over-WebSocket is included with every CodeB tenant by default. No extra license, no extra module, no per-seat charge for browser users.

Get your own tenant → All features
Related: All features · Sovereign SBC · AI receptionist · Telecoms · Compare · REST API