Skip to main content

How to add it

Add your voice agent to any website using the Configure Widget dialog in your agent’s settings. Step 1: Open the agent settings by clicking the gear icon in the top-right of the agent editor. Open agent settings Step 2: Scroll to the Add to Website section and click Configure Widget. Go to Add to Website Step 3: Enable embedding, add your website’s domain to Allowed Domains, choose Floating Widget, Inline Component, or Headless (Bring Your Own UI), customize the button (position, color, text) if applicable, and click Save Configurations. Save configurations Step 4: Copy the generated embed code and paste it into your web page to test your agent. Copy deployment code

Embed modes

Prerequisites

These apply to all three modes:
  • Serve your page over HTTPS or from http://localhost. Browsers refuse microphone access on plain HTTP origins or file://.
  • If you set Allowed Domains in the dashboard, include your test origin (e.g. localhost) — otherwise the widget’s config and signaling requests are rejected. Leave the list empty to allow all domains.
  • The embed snippet you copy from the dashboard is a single <script> tag that loads ambivert-widget.js asynchronously. The widget auto-initializes once it loads and exposes window.Ambivert AIWidget. Code that registers callbacks must wait for the widget to be available.

Floating Widget

Floating widget shown in the corner of a host page Renders a pill-shaped button (microphone icon + text) anchored to a corner of the page. Clicking it starts a call; clicking again ends it. The button auto-updates its label and color across the call lifecycle: configured text → “Connecting…” → “End Call” → “Retry” on failure. Configure Button Text, Button Color, and Position (top/bottom + left/right) from the dashboard. The host page writes no JavaScript — pasting the embed snippet is the entire integration. If you want to subscribe to call lifecycle events (e.g. analytics), see Lifecycle callbacks below

Inline Component

Inline widget rendered inside a page section Renders a panel (status icon + status text + CTA button) inside a <div> you place in your page. Status changes update the panel in place. Configure Button Text, Button Color, and Call to Action Text from the dashboard.

Plain HTML

Place a container <div> where you want the widget to render. The widget auto-attaches to it.

React

Because React mounts after the widget script may have already loaded, integrate via initInline on first mount and refresh on remount. Poll for window.Ambivert AIWidget to handle the async script load.

Headless Mode

Headless widget driven by host-page UI In Headless mode the widget injects no UI of its own. You render whatever buttons, banners, or in-call indicators you want, and call the JavaScript API to start and end calls.

JavaScript API

All on* setters are single-listener — calling the same one again replaces the previous handler.
About timing. The widget script loads asynchronously, so window.Ambivert AIWidget may not exist at the moment your inline <script> first runs. The examples below assume window.Ambivert AIWidget is already available when registration runs. To guarantee that:
  • Vanilla JS: wrap your registration code in window.addEventListener('load', () => { /* register here */ }).
  • React: inside useEffect, register immediately if document.readyState === 'complete', otherwise add a one-time window.load listener that registers on fire.
  • Click handlers that call start() / end() don’t need a guard — by the time a user clicks, the widget has long since loaded.

Vanilla JS

React + TypeScript

start() must run inside a real user-gesture handler (click, touchend, etc.). Browsers refuse to grant microphone access to scripts that request it outside of one — calling start() from a setTimeout or on page load will fail with a permission error.

Lifecycle callbacks (all modes)

The on* callbacks in the Headless JavaScript API work in all three embed modes, not just Headless. Use them for analytics or to trigger UI in the host page even when the widget is rendering its own UI (Floating or Inline).
onCallConnected and onCallDisconnected only fire when the call actually establishes a media connection — failed-to-connect attempts (e.g. denied mic, network failure) don’t trigger them, so analytics stay clean.