On this page
Dynamic Forms#
Dynamic Forms let the chatbot collect structured input from visitors using a real form — not a sequence of prose questions. When the agent needs a date, a choice from your catalogue, a rating, or a piece of contact information, it presents a form directly in the chat. The visitor fills it in and submits; the agent then uses the answers to continue the conversation.
No Console configuration is required. The agent authors forms automatically when a task calls for structured input.
Question Kinds#
A form can contain up to six questions. Each question is one of four kinds:
| Kind | What the visitor sees |
|---|---|
choice | A list of options to pick from — single or multi-select. An optional "Other…" field lets the visitor type a value not in the list. |
input | A text field. Variants include plain text, email, phone, number, and multi-line textarea. Date and time variants render a calendar picker and time-slot chips (see Date & Time Inputs). |
slider | A range slider for numeric values — useful for budget, party size, or any bounded number. |
rating | A thumbs-up / thumbs-down or star rating — useful for satisfaction or preference signals. |
Multi-Step Forms#
A form with two or more questions renders as a stepped wizard. The visitor sees one question at a time with a progress indicator. After answering all questions, a review step summarises every answer before submission, with an edit link to go back to any step.
A single-question form renders as one screen. Nothing is submitted until the visitor taps the submit button on the final review step.
Knowledge-Grounded Choices#
Choice options can be grounded in your knowledge base. When the agent draws options from your product catalogue, FAQ, or location data, every option is validated against what the agent actually retrieved in that turn. The agent cannot invent choices that are not in your data.
This means a visitor choosing from a product list or a set of available time slots is always choosing from real data — not from something the model fabricated.
Date & Time Inputs#
A date question renders an inline calendar. A time question renders a grid of time-slot chips. When a booking integration or knowledge base field provides a specific set of available dates or times, only those slots are enabled — everything else is greyed out.
Dates and times are always shown in the visitor's local timezone. When the visitor submits a date or time answer, their browser timezone is recorded alongside the local value. The server derives the corresponding UTC instant, so your integration receives both the visitor-local text the visitor saw and a machine-readable UTC timestamp.
Reading date and time answers
Use the UTC value for storage and downstream processing. Use the local text and timezone when displaying the answer back to the visitor or to an operator. Do not read the date portion of the UTC value as a calendar date — for visitors east of UTC, a local date can map to the previous UTC day.
Answered Questions Are Not Re-Asked#
The chatbot keeps a per-session record of every question the visitor has answered. A question the visitor already answered will not appear again in the same session, even if the conversation takes a different turn or the chat history is compressed.
If a visitor sends a plain message while a form is waiting for a response, the form is marked as bypassed and the conversation continues. The bypassed questions are noted so the agent can raise them again in a new form if they are still needed.
Widget#
The embedded widget renders Dynamic Forms natively. When the agent presents a form, the widget displays it inline in the chat panel. The visitor fills it in and submits without leaving the chat. No extra integration work is needed.
Conversation API#
When you use the Conversation API, forms are delivered in the response body alongside the agent's reply. Your integration is responsible for rendering the form in your interface and collecting the visitor's answers.
A message response that contains a form includes a form field:
{
"data": {
"sessionId": "sess_abc123",
"reply": "I can help with that. Please fill in the details below.",
"form": {
"formId": "frm_xyz456",
"title": "Booking Details",
"questions": [
{
"key": "q1",
"kind": "input",
"inputType": "date",
"prompt": "Which date works for you?",
"required": true
},
{
"key": "q2",
"kind": "choice",
"prompt": "Which session would you prefer?",
"options": [
{ "value": "morning", "label": "Morning (9–12)" },
{ "value": "afternoon", "label": "Afternoon (1–5)" }
],
"required": true
}
]
}
}
}Once the visitor has filled in the form, submit their answers to the form-submissions endpoint. Use the formId from the form and a map of question keys to answer values.
curl -X POST https://api.infinichat.dev/widgets/{widgetId}/conversations/{sessionId}/form-submissions \
-H "X-API-Key: api_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"formId": "frm_xyz456",
"answers": {
"q1": "2026-09-15",
"q2": "morning"
}
}'A valid submission runs the agent's next turn and is billed the same as a message. The response follows the same shape as a normal message response — it may contain another form if the agent needs more information, or a plain reply if the form answers were sufficient.
An invalid submission — wrong answer format, a value not in the offered options, or a stale formId — returns a 400 without reaching the model. The error body names the field that failed.
If your integration sends a plain message while a form is pending, the pending form is automatically dismissed and the conversation continues. The session is never left in a wedged state by an unanswered form.