Embed a voice, video, or capture widget on your site
Orbit ships a family of embeddable web widgets — drop-in surfaces a visitor on your site can use without leaving the page. One install pattern covers four widgets, because they all share the same public, Origin-gated mount model:- Native-chat web widget — the omnichannel chat surface (with an optional conversation flow: pre-chat form, FAQ deflection, routing, AI handoff).
- AI voice-agent widget — a “Talk to AI” button that opens a browser WebRTC voice call straight to your AI agent.
- Prebuilt video room — the
OrbitVideoRoom/<orbit-video-room>drop-in video-call UI (a live room on your own page). - Sign-up forms — an embeddable list-growth form (inline, popup, flyout, exit-intent) you publish from a no-code builder.
The shared mount model — public key + origin allowlist
Every widget below mounts with two public values, and both are safe to put in a plain HTML page:public_key— your widget’s public key (today the tenant id you see in Settings → Native Chat). This is a public identifier, not a secret.- Your site’s origin — added to the widget’s origin allowlist under Settings → Native Chat → Privacy, or switch on Allow embedding from any domain.
POST /widget/session,
POST /widget/voice-agent-session, POST /widget/video-session) are
anonymous and Origin-gated: they read the browser’s Origin header and
only mint a session when that origin is in your allowlist. Your API
key never touches the browser — only the short-lived session token the
widget needs.
All the widgets read the same origin allowlist and the same widget
config row, so you configure privacy once and it applies to voice, video,
chat, and signup formats alike.
2. Choose the widget and its config surface
Native-chat widget + conversation flow
The chat widget is driven by an optional conversation flow you author in the no-code builder (Settings → Native Chat → Flow). The flow is the chain of decisions the widget runs on first contact:
The flow is published to the widget as part of the session bootstrap; a
missing or partially-written flow degrades to the plain
config-bootstrapped behaviour, so a bad publish never breaks the public
widget.
AI voice-agent widget (OrbitVoiceAgent)
The voice widget is the browser’s front door to your AI voice agent —
a “Talk to AI” button the visitor presses to hold a live WebRTC voice
conversation with the agent you bind. You configure it in Settings →
Channels → Voice Agent; the install snippet generator reads the same
config.
The voice widget never selects a phone carrier and never routes an
outbound PSTN leg — it’s an inbound, visitor-initiated WebRTC call
bridged to your AI agent on Orbit’s own media stack.
Prebuilt video room (OrbitVideoRoom / <orbit-video-room>)
The video drop-in paints a complete conferencing surface — participant
tiles, control bar, screen share, device picker — from a single element.
The fastest path is the Video Rooms → Embed dialog in the dashboard:
open a live room, choose the options (camera on join, screen share,
device picker), and copy the snippet. The dialog gives you three shapes:
- Element — the declarative
<orbit-video-room>tag: - JavaScript — the imperative
OrbitVideoRoom.init(): - Server — the token-mint call your backend makes (never in the browser).
POST /widget/video-session mount
route — same public-key + origin-allowlist model as the chat and voice
widgets, so a paste-in-page snippet needs no API key. See the full
video-token flow in Using a video room access
token.
3. The minimal HTML embed
Whichever widget you mount, the pattern is the same: a container element, the Web SDK module, andinit() with the public values. Here’s the
voice agent end to end:
publicKey (chat) or a minted token + serverUrl (video) +
init(container, …). Mount the widget on a click (not on page load)
so an idle page costs nothing.
4. Web-call context — the screen-pop half
When a visitor starts a browser voice or chat call, the widget collects where the call came from and posts it along: the page URL, page title, referrer, and an optional bag of host-supplied attributes (plan tier, cart value, account id, …). That context rides with the session as the participant’s metadata, so the agent runtime that answers — and, on a handoff, the human agent’s screen-pop — knows which page the visitor was on and who they are, instead of a cold “anonymous web visitor.” Because the context arrives from an anonymous, public browser surface, it’s strictly bounded before it touches a room token:- URLs must be
http(s)— any other scheme is dropped. - Page title, URLs, and attribute values are length-capped.
- The attribute map is count- and size-capped, and the serialized blob is hard-capped so it always fits the media token’s metadata budget.
- A malformed or oversized field is dropped, never fatal — a bad context attribute can’t block the visitor from starting their call.
metadata and control
auto-collection with collectPageContext (set false on a
privacy-sensitive embed that should send only an explicit bag, or
nothing).
5. Sign-up forms — list growth on your own page
The sign-up form is a capture surface (not a chat routing aid): a tenant-authored form with display rules, A/B variants, field→contact mappings, and a consent block, that grows your own contacts and lists. You build it in the no-code builder and it publishes to the same widget surface as the chat. Each form is made of:
Every form has a
version the runtime can refuse if it doesn’t
recognise it, and the public surface only ever serves enabled
forms — a disabled draft is withheld from the visitor’s browser.
6. Transcripts + agent trust policy
Chat transcript
A visitor can email themselves a copy of a chat conversation (POST /widget/conversations/:id/transcript). The email is optional —
when omitted, the transcript goes to the address the visitor already
supplied; it’s only required if they’re still anonymous. This is the
same “email me a copy” touch every chat widget ships, rendered by a
pure, side-effect-free renderer.
Agent trust policy
This is the tenant-facing control for which foreign AI agents you trust when a browser-resident agent (via Web Bot Auth / an AP2 directory) drives your widget. You list the foreign agent directories you choose to trust by exact HTTPS directory URL, and what to grant a verified request:allow— grant access at the surface’s normal posture.deny— revoke a previously-trusted directory without deleting the row.rate— allow, but apply that directory’s hourly rate limit.
PUT /api/v1/settings/native-chat/agent-trust-policy.
7. Guardrails for MCP / WebMCP agents
Opening the widget as an in-page tool surface a browser-resident AI agent can drive (WebMCP / agent action calling) is hardened by a set of independent write guardrails that run before any action executes:- Rate lane — a per-visitor-session, per-hour sliding-window cap on agent-invoked actions (on top of the normal IP-keyed widget rate limit).
- Per-session caps — cumulative ceilings on actions and preview-cost “spend” for a single session.
- Audit — a structured line for every agent-invoked tool call, allowed or denied.
- Agent-identity attestation — verify + classify the calling agent (Web Bot Auth signature and/or a scoped agent token) so you can allow, deny, or rate by identity.
- Reputation (KYA) — a per-tenant behavioural score that can tighten — never loosen — the trust decision, downgrading an allowlisted agent that starts misbehaving.
- Compliance — an agent-scheduled callback is a future outbound voice leg, so it runs through your tenant-configured quiet-hours / dialing window. Per the compliance posture this is default-open and tenant-owned: with no channel opted into quiet hours the gate allows; when you’ve configured a window and the visitor is outside it, the request is rejected with a reason.
Where to go next
- Video meetings and video room access tokens — the token flow the video embed’s Server tab runs.
- Add a “video call us” button — a full walkthrough of one video-consultation embed with waiting room + retention.
- Web SDK — the
OrbitVideoRoom,OrbitVoiceAgent, andOrbitChatsurfaces with the full event map.