What a widget binds together
A widget record holds these fields:| Field | Type | Default | Description |
|---|---|---|---|
id | UUID | generated | Widget identifier. Used in the embed snippet and in public endpoints. |
organization_id | string | from token | The organization that owns the widget. Set from your auth token at creation. |
agent_id | UUID | required | The agent the widget serves. |
agent_version_id | UUID | required | The specific agent version end users talk to. Pin this to a published version. |
domains | text[] | [] | Allowed domains the widget may load on. |
published | boolean | false | Whether the widget is live. Must be true for the widget to serve. |
config | object | {} | Appearance, branding, quick actions, forms, and feedback, versioned under v1. |
created_at | timestamp | now | When the widget was created. |
updated_at | timestamp | now | When the widget was last changed. |
config object is namespaced under a v1 key so its shape can evolve without breaking existing embeds. Appearance, text and voice options, quick actions, forms, and feedback all live inside config.v1.
Requirements to go live
Two gates must both be satisfied before a widget serves traffic:The agent has a published version
The widget’s
agent_version_id should point at a published version of the agent. Publish the agent version you want end users to reach before pointing a widget at it.Pinning the widget to a specific
agent_version_id means published changes to other versions do not silently alter what end users experience. Update the widget’s version when you want to roll a new version out.How conversations work
End users talk to the agent over LiveKit WebRTC. The same widget handles both text chat and voice on thewebrtc channel, so switching between typing and speaking happens inside one session.
webrtc channel and joins a LiveKit room. The widget can resume an existing conversation by id, reconnecting the user to the agent in a fresh room.
Allowed domains and security
Thedomains list is the allowlist of sites the widget may run on. The public embed snippet reads a widget’s allowed domains and enforces them, so a widget cannot be loaded from a site you have not listed. Keep this list tight and add only the origins you control.
Next steps
Create a widget
Bind an agent and published version, set allowed domains, and publish.
Install the snippet
Drop the embed snippet onto your site and verify it loads.
Appearance and branding
Theme the bubble, set avatars, and apply your brand.
Text, voice, and quick actions
Tune chat and voice behavior and suggested questions.
Forms and feedback
Collect input mid-conversation and gather post-conversation feedback.
Allowed domains and security
Lock the widget to the domains you control.

