Add a “video call us” button to your website
The fastest path from visitor on your site to face-to-face video session is theOrbitVideoRoom prebuilt widget — the drop-in, embeddable video-call UI
in the Web SDK. You ship one script tag plus three lines of
JavaScript, and the widget paints a complete conferencing surface with nothing
else to build:
- a participant tile grid and local self-view
- a control bar with mute, camera, screen-share, a device picker (microphone / camera / speaker, switchable mid-call), background blur, and leave
- automatic attach of remote tracks as they are subscribed
The four moving parts
1 — Embed the button on your site
The widget is host-agnostic — it renders into whatever container element you pass. Mount it behind a click so the media session only starts when the visitor actually asks for it.startWithCamera, startWithMicrophone,
enableScreenShare, enableDeviceSelection, autoJoin: false, the
participantJoined / participantLeft / error event map, and the
join() / leave() lifecycle — is on the Web SDK page under
Prebuilt video room.
2 — Mint the join token on your backend (never in the browser)
Your API key must never reach the visitor’s browser. The token comes from the same route the video-meetings guide uses —POST /api/v1/video/rooms/:id/join — issued by your backend, which then hands
only the short-lived token and the media-server URL to the page.
token (the media-server access JWT) and livekit_url
(the orbit-media WebSocket URL — point the widget at this host, not at the
retired livekit.cloud). Because your backend mints it per click, each
visitor gets a fresh, scoped token and your long-lived API key stays
server-side.
For a consultation you usually want one persistent room per queue or
department (“the sales room”, “the support room”) rather than a new room per
visitor: create it once from the dashboard (Rooms → New room) or the
video rooms API, then have your backend mint join
tokens against that same room ID.
3 — Put a waiting room in front of your agents
A consultation button that rings agents blindly is a poor experience. Arm the room’s waiting room so a new join holds in a receive-only lobby until a host admit — the same hold-and-admit flow the video-meetings surface uses for drop-in guests. The join route documents this in its response contract: theparticipant_tier
and permissions fields are the effective grant after any waiting-room
clamp, and lobby_downgraded is true when an armed waiting room forced
this join to receive-only viewer. Your cue is simple:
permissions.can_publish === false && permissions.can_subscribe === false→ the visitor is in the lobby; render “waiting for the team to admit you”- on admit, the host promotes them from the roster and their publish grant activates
4 — Record the session and set its retention
Consultation sessions are usually recorded for quality or compliance. Enablerecording_enabled on the room (dashboard settings or the rooms API) and the
session records to your tenant’s configured storage, with signed download
URLs — the same per-tenant storage posture the rest of the recording stack
uses.
Retention is a tenant-config window, not a platform lock-up. The hourly
retention sweep reads organizations.settings.video_room_retention_days:
- Default — 90 days. Sessions whose
ended_atis older than the window are soft-deleted; after a further 14-day grace they are hard-deleted. - Tenant override — set
video_room_retention_daysto a positive integer (minimum 7 days) to lengthen or shorten the window for your own compliance posture, or to lengthen the window for sessions you must keep.
Why not livekit.cloud?
Everything on this page runs on Orbit’s self-hosted media stack
(orbit-media). The token’s livekit_url is an orbit-media host — that
field name is inherited from the upstream fork; the actual media path is
Orbit’s own, which is why livekit.cloud (retired 2026-05-19) never appears
here. Self-hosting the media path is also why the embed adds no outbound
voice/SMS provider — the consultation is inbound WebRTC video end to end.
Production checklist
- The join token is minted server-side; the API key is never in the page.
-
serverUrlpoints at thelivekit_urlfrom the join response (anorbit-mediahost). - The button only mounts the widget on click, so idle page loads cost nothing.
-
waiting_room: trueon the room, and your agents admit from the host moderation panel. -
recording_enabledis set for sessions you must keep. -
video_room_retention_daysmatches your compliance window (or you accept the 90-day default). - You re-mint the token before
expires_atif a session can run long.