> ## Documentation Index
> Fetch the complete documentation index at: https://agentheya.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# collect_form

> Render a structured form in the chat and collect multiple fields at once.

# collect\_form

Renders a structured form in the chat to collect multiple fields at once (lead capture, contact intake, structured questionnaire). Returns immediately with an `interaction_id`; submitted values arrive on the next turn keyed exactly by `key`.

Use instead of asking field-by-field. The form schema **is** the contract — the LLM cannot misread the values because they come back under the keys it specified.

## Parameters

| Name           | Type             | Required | Description                                |
| -------------- | ---------------- | -------- | ------------------------------------------ |
| `title`        | string (1-120)   | yes      | Form title.                                |
| `description`  | string (≤2000)   | no       | Optional intro shown above the fields.     |
| `submit_label` | string (1-40)    | no       | Submit button text. Default `"Submit"`.    |
| `fields`       | array (1-20)     | yes      | Field definitions. See below.              |
| `ttl_minutes`  | integer (1-2880) | no       | How long the form stays valid. Default 60. |

### Field definition

| Name          | Type                                     | Required               | Description                                                                                                                                               |
| ------------- | ---------------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `key`         | string `/^[a-z][a-z0-9_]{0,40}$/i`       | yes                    | Stable identifier; values come back under this key. Must be unique within the form.                                                                       |
| `label`       | string (1-120)                           | yes                    | Visible field label.                                                                                                                                      |
| `type`        | enum                                     | yes                    | `text` \| `textarea` \| `email` \| `phone` \| `number` \| `integer` \| `date` \| `time` \| `datetime` \| `select` \| `multiselect` \| `checkbox` \| `url` |
| `required`    | boolean                                  | no                     | Default `false`.                                                                                                                                          |
| `placeholder` | string (≤120)                            | no                     | Placeholder text.                                                                                                                                         |
| `help`        | string (≤300)                            | no                     | Helper text shown under the field.                                                                                                                        |
| `options`     | `[{ value, label }]` (≤50)               | for select/multiselect | Required for `select` / `multiselect`.                                                                                                                    |
| `min`         | number                                   | no                     | For numeric/date/datetime/time/text-length.                                                                                                               |
| `max`         | number                                   | no                     | Upper bound.                                                                                                                                              |
| `pattern`     | string (≤200)                            | no                     | Regex for text inputs (also re-checked server-side).                                                                                                      |
| `default`     | string \| number \| boolean \| string\[] | no                     | Default value.                                                                                                                                            |

## Returns

```json theme={null}
{
  "action": "request_form",
  "interaction_id": "...",
  "expires_at": "...",
  "status": "pending",
  "display": { "title": "...", "fields": [...], "submit_label": "..." }
}
```

On submit (next turn): `{ status: "submitted", result: { values: { <key>: <value>, ... } } }`.

***

## Examples

### Callback scheduler

```json theme={null}
{
  "title": "Schedule a callback",
  "submit_label": "Request callback",
  "fields": [
    { "key": "name",  "label": "Your name",  "type": "text",  "required": true },
    { "key": "email", "label": "Email",       "type": "email", "required": true },
    {
      "key": "when",
      "label": "Best time",
      "type": "select",
      "required": true,
      "options": [
        { "value": "morning",   "label": "Morning (9 am – 12 pm)" },
        { "value": "afternoon", "label": "Afternoon (12 pm – 5 pm)" },
        { "value": "evening",   "label": "Evening (5 pm – 8 pm)" }
      ]
    },
    {
      "key": "notes",
      "label": "Anything we should know?",
      "type": "textarea",
      "placeholder": "Optional context about your inquiry"
    }
  ]
}
```

Result values shape: `{ name, email, when, notes }`.

***

### Support ticket

```json theme={null}
{
  "title": "Open a support ticket",
  "description": "We'll respond within one business day.",
  "submit_label": "Submit ticket",
  "fields": [
    {
      "key": "subject",
      "label": "Subject",
      "type": "text",
      "required": true,
      "max": 120,
      "placeholder": "Brief description of the issue"
    },
    {
      "key": "priority",
      "label": "Priority",
      "type": "select",
      "required": true,
      "default": "normal",
      "options": [
        { "value": "low",      "label": "Low — general question" },
        { "value": "normal",   "label": "Normal — something isn't working" },
        { "value": "high",     "label": "High — blocking my work" },
        { "value": "critical", "label": "Critical — system down" }
      ]
    },
    {
      "key": "description",
      "label": "Describe the issue",
      "type": "textarea",
      "required": true,
      "min": 20,
      "max": 2000,
      "placeholder": "Steps to reproduce, what you expected, what happened instead"
    },
    {
      "key": "consent",
      "label": "I agree to share my account data with the support team for diagnostic purposes",
      "type": "checkbox",
      "required": true
    }
  ]
}
```

***

### Newsletter preferences

```json theme={null}
{
  "title": "Customize your newsletter",
  "description": "Choose the topics you'd like to hear about.",
  "submit_label": "Save preferences",
  "fields": [
    {
      "key": "topics",
      "label": "Topics",
      "type": "multiselect",
      "required": true,
      "options": [
        { "value": "product",   "label": "Product updates" },
        { "value": "tutorials", "label": "How-to guides" },
        { "value": "industry",  "label": "Industry news" },
        { "value": "events",    "label": "Events & webinars" },
        { "value": "offers",    "label": "Special offers" }
      ]
    },
    {
      "key": "frequency",
      "label": "How often?",
      "type": "select",
      "required": true,
      "default": "weekly",
      "options": [
        { "value": "daily",    "label": "Daily digest" },
        { "value": "weekly",   "label": "Weekly roundup" },
        { "value": "monthly",  "label": "Monthly highlights" }
      ]
    },
    {
      "key": "unsubscribe_all",
      "label": "Unsubscribe from all emails",
      "type": "checkbox",
      "default": false
    }
  ]
}
```

Result values shape: `{ topics: ["product", "tutorials"], frequency: "weekly", unsubscribe_all: false }`.

***

### Product configuration (numeric bounds + URL)

```json theme={null}
{
  "title": "Configure your widget",
  "submit_label": "Save configuration",
  "fields": [
    {
      "key": "widget_name",
      "label": "Widget name",
      "type": "text",
      "required": true,
      "max": 60
    },
    {
      "key": "max_users",
      "label": "Max concurrent users",
      "type": "integer",
      "required": true,
      "min": 1,
      "max": 10000,
      "default": 100,
      "help": "Requests above this limit will be queued."
    },
    {
      "key": "rate_limit",
      "label": "Rate limit (requests/minute)",
      "type": "number",
      "min": 0.5,
      "max": 1000,
      "default": 60
    },
    {
      "key": "webhook_url",
      "label": "Webhook URL",
      "type": "url",
      "placeholder": "https://your-server.com/webhook",
      "help": "We'll POST events here. Must be HTTPS."
    },
    {
      "key": "environment",
      "label": "Environment",
      "type": "select",
      "required": true,
      "default": "staging",
      "options": [
        { "value": "staging",    "label": "Staging" },
        { "value": "production", "label": "Production" }
      ]
    }
  ]
}
```

***

### Date-range report request

```json theme={null}
{
  "title": "Generate a report",
  "submit_label": "Run report",
  "fields": [
    {
      "key": "report_type",
      "label": "Report type",
      "type": "select",
      "required": true,
      "options": [
        { "value": "revenue",  "label": "Revenue" },
        { "value": "usage",    "label": "Usage" },
        { "value": "errors",   "label": "Error log" }
      ]
    },
    {
      "key": "date_from",
      "label": "From",
      "type": "date",
      "required": true
    },
    {
      "key": "date_to",
      "label": "To",
      "type": "date",
      "required": true
    },
    {
      "key": "email_results",
      "label": "Email me a copy when ready",
      "type": "checkbox",
      "default": true
    }
  ]
}
```

***

## Call from your own custom tool

```js theme={null}
export async function handle(input, ctx) {
  return await ctx.tools.collect_form({
    title: 'Schedule a callback',
    fields: [
      { key: 'name',  label: 'Your name',  type: 'text',  required: true },
      { key: 'email', label: 'Email',      type: 'email', required: true },
      { key: 'when',  label: 'Best time',  type: 'select', required: true,
        options: [
          { value: 'morning',   label: 'Mornings' },
          { value: 'afternoon', label: 'Afternoons' },
        ]
      },
    ],
  });
}
```

Values come back on the next turn:

```js theme={null}
// result.result.values ===
{ name: 'Jane Smith', email: 'jane@example.com', when: 'morning' }
```

***

## Does this use json-render?

**No.** `collect_form` has its own purpose-built renderer and a fixed field-type catalog. It's optimised for simple data collection — the LLM describes what it needs, the renderer builds the HTML natively.

If you need a fully custom layout — data tables, stat cards, buttons, nested sections — use [render\_ui](/builtin-tools/render_ui) instead. `render_ui` accepts a [json-render.dev](https://json-render.dev/) spec and can render arbitrary UI including `form` components with submit actions.

### Choosing the right tool

|                                | `collect_form`                          | `render_ui`                                      |
| ------------------------------ | --------------------------------------- | ------------------------------------------------ |
| **Purpose**                    | Collect structured input                | Display any UI (or interactive UI)               |
| **Spec format**                | field-list JSON                         | json-render.dev spec                             |
| **Forms**                      | Yes — native                            | Yes — via `form` + `input` components            |
| **Tables, stat cards, badges** | No                                      | Yes                                              |
| **LLM guidance**               | Field types are described to the model  | Full component catalog is available to the model |
| **Best for**                   | Data collection, intake, questionnaires | Dashboards, rich results, multi-action UIs       |

***

## Notes

* Always registered.
* Duplicate `key`s within a form are rejected by the input schema.
* For `select` / `multiselect`, `options` is required (also rejected if missing).
