Forms library
A form is a reusable, structured questionnaire your assistant can present inside a conversation. Attach a form to an assistant and it becomes a tool the assistant calls whenever the conversation matches — it asks the questions, validates each answer, and emits a clean payload of captured fields to your downstream systems.
Use a form whenever the shape of the data you need to collect matters: lead intake, KYC, insurance details, GDPR consent, booking forms. The alternative — letting the assistant ask the questions free-form — works for chat but leaks fields and produces dirty data at scale.
What a form has
| Field | What it is |
|---|---|
| Name | Internal label. |
| Trigger instructions | A natural-language description of when the assistant should invoke the form. Read by the model as the tool description. |
| Form type | natural (assistant asks the questions in conversation) or simple (rendered as a form UI in the chat widget). |
| Fields | Ordered list of fields with type, validation, and help text. |
| Webhook | Optional URL to call when the form is captured. |
| Trigger tools | Optional tools to run after capture. |
| Contact mapping | Optional mapping of form fields to contact fields so captured values sync. |
Field types
| Type | UI label | Use it for |
|---|---|---|
text | Text | Short answers — name, company, order ID. |
textarea | Text Area | Longer answers — description, notes, reason. |
date | Date picker | Appointment date, date of birth. |
checkbox | Checkbox | Yes/no toggles — "subscribe to newsletter". |
select | Select Options | Pick-one questions — service type, urgency, plan. |
gdpr | GDPR consent | Consent to data processing — auto-required. |
tel | Telephone | Phone numbers with optional dial-code picker. |
Per field you set: name (machine key, alphanumeric + underscore), description (help text the assistant uses), required (true/false), plus type-specific options.
There's no built-in email or number type today. Validate email with regex on a text field; capture numbers as text and parse on your end.
Form types
- Natural — the assistant asks the questions conversationally, validates each answer, and re-asks on bad input. Best for voice and most chat use cases.
- Simple — rendered as a structured form UI. Used inside the
render_formwidget for embedded HTML forms.
Four business use cases
Dental clinic — new-patient intake form. Bright Smile Dental defines a natural form with fields: full name, date of birth, insurance provider, reason for visit, preferred date. The voice assistant invokes it whenever a caller is identified as a new patient. The captured payload syncs to the practice management system via the webhook. Outcome: every new-patient record arrives complete, no missing fields.
Fintech — KYC questionnaire. A neo-bank defines a form with 8 fields covering ID type, ID number, address, source of funds, and a GDPR consent. The chat assistant invokes it at the start of every onboarding conversation. The webhook fires the captured form into the bank's compliance review queue.
Real estate — buyer lead form. A brokerage defines a form with fields: name, phone, budget range (select), preferred zip codes (text), timeline (select). The assistant invokes it once a caller self-identifies as a buyer. The captured form is mapped via contact mapping to the HubSpot contact's custom fields.
E-commerce — feedback survey. A meal-kit company defines a 4-field form with rating (select 1–5), favourite recipe (text), suggestion (textarea), and GDPR consent. The chat widget invokes the form after delivery confirmation. The webhook lands the data in the company's analytics warehouse.
Creating a form
- Open Build → Library → Forms → New form.
- Set name, description, and form type.
- In Trigger instructions, write a one-paragraph description of when the assistant should invoke this form. This becomes the tool description the model reads.
- Add fields one by one. For each, set type, name (e.g.
phone), description (e.g. "Phone number for callback"), and required. - Optional: Set a webhook URL to receive the captured payload.
- Optional: Map form fields to contact fields under Contact mapping for automatic CRM sync.
- Save.
Example fields JSON
[
{ "type": "text", "name": "full_name", "description": "Caller's full name", "required": true },
{ "type": "tel", "name": "phone", "description": "Phone number for callback", "required": true, "show_country_code": true },
{
"type": "select",
"name": "service",
"description": "Which service the caller needs",
"required": true,
"options": ["cleaning", "filling", "consultation"]
},
{ "type": "date", "name": "preferred_date", "description": "Preferred appointment date", "required": false },
{ "type": "gdpr", "name": "gdpr_consent", "description": "Consent to data processing", "required": true }
]
Attaching a form to an assistant
Open the assistant under Build → Assistants → [your assistant] → Forms and toggle the form on. From the model's perspective, each linked form is a tool with the form's trigger instructions as its description.
What happens on capture
When the user finishes the form:
- A captured-form record is created and linked to the conversation.
- If a webhook is configured, a
captured_form.createdevent fires to your endpoint with the full payload. - If trigger tools are configured, they run in sequence.
- If contact mapping is configured, the captured values propagate to the matched contact.
Webhook payload shape
{
"event": "captured_form.created",
"data": {
"form_id": "0190d1f8-...",
"conversation_id": "0190d1f9-...",
"captured_at": "2026-05-14T09:32:11Z",
"fields": {
"full_name": "Jane Patel",
"phone": "+15125550123",
"service": "consultation",
"preferred_date": "2026-05-20",
"gdpr_consent": true
}
}
}
See Webhooks for delivery details (single-attempt, no signing — verify by IP allowlist or a hard-to-guess URL path).
Where to next
- Intents library — classify the overall conversation outcome alongside the form.
- Prompts library — reference forms by name in your prompt templates.
- Create an assistant — attach a form to a working assistant.