Overview
A widget is an embeddable voice call entry point. You create a widget, configure its appearance and linked assistant, then embed it in your product. When a user clicks the call button, your frontend callsPOST /v1/widgets/create-call to get a WebSocket URL and starts the audio session.
Required scopes: widgets:read (read), widgets:write (create/update/delete/call)
POST /v1/widgets
Creates a new widget for your organization. Pass assistantId to attach an existing agent at creation time — if a widget already exists for that agent, the existing widget is returned instead of creating a duplicate. Omit it to create an unattached widget you configure later via PATCH /v1/widgets/{id}.
Announcer agents (see Agents → Announcer agents) can’t be attached to a widget — they’re one-way broadcast agents with no conversational voice engine. Passing an announcer agent’s id as
assistantId here (or in PATCH /v1/widgets/{id}) returns a 400.201 Created
400 assistantId belongs to an announcer agent · 403 missing widgets:write scope
GET /v1/widgets
Lists all widgets for your organization.
200 OK
Common status codes
200success403missingwidgets:read500server error
GET /v1/widgets/{id}
Returns a single widget by ID.
200 OK
Common status codes
200success403missingwidgets:read404widget not found (including a widget that belongs to a different organization)500server error
PATCH /v1/widgets/{id}
Updates a widget’s appearance, assistant, and allowed origins. This is a full replace, not a partial patch — every field below is required on every call, even to change just one of them. Unrecognized fields in the payload are ignored rather than causing an error.
Setting water_mark_enabled to false requires an active paid subscription on the organization — this returns 403 for organizations on the Free plan or with no active subscription.
Most fields are plain CSS-style values (hex colors, pixel radii, button labels) and are self-explanatory from the example below. Two worth calling out:
allowed_origins— an array of origins (scheme + host, e.g.https://app.example.com) permitted to embed and call this widget from the browser. Requests from any other origin are rejected.terms_and_condition_content— free text shown whenterms_and_conditionistrue. It isn’t validated server-side, so an empty or missing value is accepted even whenterms_and_conditionistrue— it’s on you to supply real copy in that case.
400 validation error · 403 missing widgets:write scope, or organization is not on a paid plan (when disabling water_mark_enabled) · 404 widget not found
POST /v1/widgets/create-call
Creates a call session for a widget. Call this from your server when a user clicks the call button in your UI.
201 Created
gateway.url to your browser client to open the WebSocket connection. The call_id can be used later to retrieve the transcript via GET /v1/calls/{id}/transcripts.
Common errors: 400 invalid payload; widget has no assistant attached (attach one via PATCH /v1/widgets/{id} first); or the Origin header doesn’t match the widget’s allowed_origins · 403 missing widgets:write scope · 404 widget not found
DELETE /v1/widgets/{id}
Permanently deletes a widget.
403 missing widgets:write scope · 404 widget not found