You can do all of this without cURL: the Web Widgets dashboard
page (
/dashboard/web-widgets) creates the widget, sets its mode
and agent, manages allowed domains, and hands you the embed snippet.Prerequisites
1
Create an agent
The agent whose prompt and voice will run the widget session. Set
widget_enabled: true (the default).2
Decide the routing mode
mode="agent"— one static agent per key. Simplest.mode="webhook"— your server picks the agent per visitor via aweb.incomingwebhook. Use this for logged-in users, A/B tests, or per-page routing.
3
List the allowed domains
Publishable keys are origin-locked. You must name every hostname
that will embed the widget.
localhost / 127.0.0.1 are always
allowed during local dev.Create a publishable key
key starting with pk_live_.... Publishable
keys are public by design — safe to ship in your front-end bundle.
See Publishable keys reference for
all fields.
Drop the widget on your site
Three integration options are covered in the widget SDK docs:React component
<ThunderPhoneWidget publishableKey="pk_live_..." />.Headless hook
useThunderPhone() for custom UIs.CDN script tag
ThunderPhone.mount({...}) for non-bundler sites.publishableKey and render the mic button
plus the in-call audio element.
Widget context is truncated at 12,000 characters (roughly 3,400
tokens of typical English text) and counts toward the
prompt-size surcharge.
Widget-mode webhooks
Whenmode="webhook", ThunderPhone calls your webhook_url on every
session start with a web.incoming payload. Return the agent
configuration you want to run for that visitor — it follows the same
response schema as phone
calls:
Observe the sessions
Widget sessions show up inGET /v1/calls with
direction="widget" — same transcript, recording, grading, and
billing as phone calls. Filter by direction to build a widget-only
dashboard.
Next steps
Widget SDK reference
React / hook / CDN integration details.
Dynamic per-call config
Implement the
mode="webhook" flow end-to-end.Publishable keys reference
Every field on the key resource.
Mic sessions API
Skip the widget; drive LiveKit directly for custom UIs.