Skip to main content
The voice widget is a floating control on your site. Visitors start a spoken call in the browser: Lovi’s iframe asks for the microphone and the AI Agent replies with audio. Do not confuse it with: Production embed is https://widget.lovi.ai/iawidget.js with mode="voice". The GitHub repo voice-widget-lovi is an older prototype (no Lovi iframe, keys in the page). Do not copy that.

How to embed it

Paste this before </body>. mode="voice" is what loads voice instead of text chat:
Loader order: mode="voice" first, then WhatsApp full, then chat. If both mode="voice" and WhatsApp full are set, voice loads. There is no dom embed for voice: the iframe is position:fixed; bottom:0; left or right. Chat dom / config WhatsApp-on-mobile do not apply to this iframe. No public npm package and no window.startVoice. The visitor taps the control.

What the visitor sees

  1. The voice control appears (fixed to the corner).
  2. On a real click, the browser asks for the microphone (getUserMedia inside Lovi’s iframe, including voiceIsolation where supported).
  3. They hear the agent and can hang up.
  4. After hang-up they can leave 👍/👎 feedback.
Test on HTTPS or localhost. The mic does not work on plain HTTP. If your page wraps the widget in a cross-origin iframe, that host iframe needs allow="microphone" and, where you use Permissions-Policy, allow microphone toward https://widget.lovi.ai. Lovi’s own iframe already sets allow="microphone; autoplay".

Appearance

Colours, position, and animation come from GET /functions/v1/voice-widget (Voice-config). They are not set in your HTML except language-lovi.

Audio and handoff (what the iframe does)

You do not call these from the host page. The iframe does:
  1. GET …/functions/v1/voice-widget — appearance (Voice-config) only. Not the live audio session.
  2. GET …/functions/v1/voice-widget/signed-url — ElevenLabs ConvAI session (signed URL + SDK; WebSocket and/or WebRTC).
  3. Also used internally: POST …/voice-widget/search, feedback, POST …/voice-widget/handoff, POST …/voice-widget/handoff/end, GET …/voice-widget/chat-by-conversation.
There is a transfer-to-human path in the voice iframe (states such as transferring / waiting_agent / with_human, LiveKit). That is not a public API for your site’s JavaScript.

Technical requirements (host page)

The host must reach at least:
  • https://widget.lovi.ai
  • https://cloud.lovi.ai
  • https://api.elevenlabs.io and wss://api.elevenlabs.io
  • wss://livekit.rtc.elevenlabs.io
  • https://cloud-api.livekit.io
  • https://cdn.jsdelivr.net (AudioWorklet)
Neither iawidget.js nor widget.lovi.ai send a Content-Security-Policy header. This list is for your CSP / firewall / tag manager.

Troubleshooting