Rich widgets
Cards, buttons, forms and status widgets the agent can render.
Widgets are structured UI the agent can attach to a reply — in the embedded chat, the inbox and the API (widget on the chat response, widget SSE event). The model produces them via the show_widget tool or an action with responseMode: "widget".
Widget kinds #
card
json
{
"kind": "card",
"title": "Pro plan",
"description": "Unlimited agents, 10k messages/mo",
"imageUrl": "https://…/pro.png",
"buttons": [
{
"label": "Upgrade",
"url": "https://supportai.co.uk/pricing",
"style": "primary"
}
]
}buttons
Tapping a button sends its value (or label) as the visitor’s next message, or opens url.
json
{
"kind": "buttons",
"text": "What would you like to do?",
"buttons": [
{
"label": "Track an order",
"value": "Track my order"
},
{
"label": "Talk to a human",
"value": "I'd like to speak to a person"
}
]
}quickReplies
json
{
"kind": "quickReplies",
"options": [
"Yes",
"No",
"Not sure"
]
}link
json
{
"kind": "link",
"title": "Returns policy",
"url": "https://example.com/returns",
"description": "30-day no-questions returns"
}image
json
{
"kind": "image",
"url": "https://example.com/map.png",
"alt": "Store map",
"caption": "We're on the second floor"
}keyValue
A status card. progress (0–100) renders a bar; statusTone colours the pill.
json
{
"kind": "keyValue",
"title": "Order #48213",
"status": "Out for delivery",
"statusTone": "success",
"progress": 80,
"rows": [
{
"label": "Carrier",
"value": "DPD"
},
{
"label": "ETA",
"value": "Today, 2–4pm"
}
]
}form
Collects structured input. Submissions are stored as a lead on the conversation and emit lead.created.
json
{
"kind": "form",
"formId": "callback",
"title": "Request a callback",
"fields": [
{
"key": "name",
"label": "Name",
"type": "text",
"required": true
},
{
"key": "phone",
"label": "Phone",
"type": "phone",
"required": true
},
{
"key": "time",
"label": "Best time",
"type": "select",
"options": [
"Morning",
"Afternoon"
]
}
],
"submitLabel": "Request"
}Form field types #
| type | Renders as |
|---|---|
| text | Single-line input |
| Email input with validation | |
| phone | Telephone input |
| textarea | Multi-line input |
| select | Dropdown using options |
Rendering widgets yourself #
If you build a custom UI on the public API, treat unknown kind values as text-only and ignore them. All URLs are validated server-side to be http(s).