Set up the browser (WebRTC) softphone
The browser softphone lets an agent place and answer PSTN calls without leaving the browser — no desk phone, no desktop SIP app. There are three ways to put it in front of an agent, and they share the same credential and infrastructure underneath:- The built-in dashboard softphone — Orbit ships a ready-made softphone inside the dashboard. This is the zero-code path and the right starting point for most teams.
- An embedded LiveKit-based softphone (
Softphonein@devotel/orbit-web-sdk) — you mount the softphone inside your own agent workspace (CRM, contact-centre wall, internal tool) with your own UI. - An embedded SIP-over-WSS softphone (the SIP-register path) — a classic SIP client (e.g. JsSIP) that registers straight against Orbit’s WebRTC-to-SIP gateway, for teams that want standard SIP semantics and their own call-control logic.
The browser softphone only needs a browser with a microphone. Inbound
push notifications (section 1) are a mobile companion for when agents
move to the Orbit mobile app — they are not required for the browser
itself.
1. Device registration & VoIP push tokens (mobile)
Skip this section if your agents work only in the browser. Register a VoIP device only when the agent also needs inbound calls to ring their phone as a native call — i.e. the Orbit mobile app, backgrounded or locked, still rings like a phone call instead of showing a passive banner. Registering a VoIP device is a single API call:platformisiosorandroid. On iOSvoip_tokenis the PushKit (CallKit) token; on Android it’s the FCM registration token used for the high-priority call channel.bundle_id(iOS only) is the app bundle id — the VoIP push topic is<bundle_id>.voip.- The response returns the registered device (
id,platform,last_seen_at).
GET /push/voip-devices (list) and
DELETE /push/voip-devices/:id (unregister a device). You normally
don’t call these by hand — the mobile SDK registers, refreshes, and
removes its own row. A permanently-dead token (the OS revoked it, or
the app was uninstalled) is marked revoked automatically and skipped on
the next inbound ring, so a stale device never blocks the queue’s ring
cycle.
2. Mint softphone credentials
An agent browser needs a short-lived credential before it can connect. Which endpoint you mint against depends on the client you’ve chosen — dashboard, embedded LiveKit, or embedded SIP.Built-in dashboard / embedded LiveKit softphone
The softphone’s first move is a token request.POST /voice/softphone/token returns a short-lived LiveKit access token plus
the media URL to connect to:
POST /voice/softphone/dial with { "to": "+15550123", "from": "+15559876" } — see the full snippet in section 4.
Embedded SIP/WSS softphone
A SIP client registers directly over a WebSocket.POST /voice/softphone/register swaps your authenticated API request for a
short-lived SIP credential:
- Credentials live for 60 minutes — re-register before
expiresAtor the session drops. callerIdNumbermust be a number your organization owns (it’s 403’d otherwise) — this is how outbound CLI spoofing is blocked.- The username binds to your organization, so a stolen username can’t be replayed against a different tenant.
- Token issuance is owner/admin/developer-scoped — it’s not a public, anonymous endpoint.
Revoke a credential immediately with
DELETE /voice/softphone/credentials/:username if an agent leaves or a token
leaks. Revocation is owner-only so a leaked credential stays a
small-blast-radius event.3. Choose how inbound calls reach the softphone
Inbound calls must be routed so they land on an agent’s browser. You have three tenant-owned options — use the one that matches how your phone numbers are set up.- DNIS → queue → softphone. The most common path: your phone number’s inbound routing sends the call to an ACD queue, and the queue offers it to an available agent’s browser softphone (and, if they’re on the mobile app, a VoIP push — section 1). You set this up per number in the dashboard’s number routing, or through the flows builder.
- DNIS → SIP routing. Route inbound calls to the SIP domain your softphone registrations live on. Use this when your inbound traffic already lands on SIP (for example a DID forwarded to your SIP URI) and you want the registered softphone to answer directly.
- The caller’s softphone dials out. For outbound-driven teams the inbound question never arises — the agent initiates calls and any inbound answer is on a number that routes to a queue (back to option one).
4. Full JS snippet — mic, VoIP push + browser fallback
Here is a complete, copy-pasteable browser softphone. It works with both embedded options (LiveKit and SIP-over-WSS) and handles the browser-fallback reality: some agents will be on browsers or networks where the primary media path is unavailable, so you always wire a fallback.5. Verification & troubleshooting
Verify the setup end to end:- Mint a credential (section 2), connect the client (section 4), and
look for a room
connect/ SIPregisteredevent. - Place an outbound call to your own mobile — you should hear ring, then two-way audio on answer.
- Have an inbound call routed to your number (section 3) and confirm the softphone rings and answers.
- If you registered a mobile VoIP device (section 1), background the mobile app and confirm a native incoming-call UI appears.
Also confirm you aren’t reusing the wrong endpoint: register (SIP/WSS)
↔ SIP clients, token ↔ LiveKit clients,
voip-devices ↔ mobile push
only.
Where to go next
- SIP trunk setup — if you want to bring your own carrier/trunk alongside the browser softphone.
- Voice queues — the ACD queue inbound calls route through before a softphone answers.
- Web SDK — full event map for
Softphoneand the other SDK surfaces.