Overview
Forms are defined in the character’s appearance configuration under theforms array. When a form is defined, the agent automatically gains a callable tool with the same name. During a call, the agent can:
- Open the form panel (optionally pre-filling fields with values it already knows)
- Track field changes in real time via the data channel
- Guide the user through multi-step flows verbally
- Submit the completed form to your endpoint (or to Oshara’s managed storage)
Minimal single-step form
Multi-step stepper example
FormDefinition schema
| Field | Type | Required | Description |
|---|---|---|---|
id | string | ✓ | Stable identifier. Used as the tool name and for LiveKit topic matching. |
title | string | ✓ | Heading shown at the top of the form panel. |
subtitle | string | Subheading / context text below the title. | |
fields | FormFieldDef[] | one of fields or steps | Fields for a single-page form. Ignored if steps is set. |
steps | Step[] | one of fields or steps | Multi-step stepper. Each step has its own fields array. |
submit_url | string | null | POST target. Absolute URL or path relative to apiUrl. null = store in Oshara managed storage. | |
submit_method | "POST" | "PUT" | "PATCH" | HTTP method for submission (default "POST"). | |
submit_label | string | Submit button text (default "Submit"). | |
success_message | string | Message shown in the panel after successful submission. | |
disabled | boolean | true = form is not exposed to the agent as a tool. Useful to temporarily hide a form. | |
topics | string[] | Extra LiveKit data-channel topics that trigger this form to open. | |
event_types | string[] | Legacy event_type aliases for backwards compatibility. | |
confirmation_topic | string | Topic on which the widget echoes a confirmation message after submission (default "voice.user_text"). | |
confirmation_type | string | type field on the confirmation payload (default "{id}_submitted"). | |
layout.field_layout | "stack" | "grid" | "grid" enables two-column layout (use width: "half" on fields). | |
layout.density | "comfortable" | "compact" | Spacing density. | |
layout.label_position | "top" | "inline" | Label placement. |
Step object
| Field | Type | Description |
|---|---|---|
id | string | Step identifier. |
title | string | Step heading (shown in the stepper header). |
subtitle | string | Step subheading. |
fields | FormFieldDef[] | Fields for this step. |
next_label | string | ”Next” button label override. |
back_label | string | ”Back” button label override. |
FormFieldDef schema
| Field | Type | Description |
|---|---|---|
name | string | Field key — used as the key in the submitted JSON object. Not required for type: "display". |
label | string | Label text shown above the field. |
type | see below | Input type. |
placeholder | string | Placeholder text. |
required | boolean | Marks the field as mandatory (client-side validation). |
options | string[] | {value, label?}[] | Choices for select and radio fields. |
rows | number | Number of visible rows for textarea. |
default_value | string | Pre-filled value. The agent can also override this when opening the form. |
help_text | string | Sub-label hint shown below the field. |
pattern | string | Regex pattern for client-side validation. |
min | number | Minimum value (for number) or minimum character length (for text fields). |
max | number | Maximum value / length. |
width | "full" | "half" | Column width when field_layout is "grid". |
Field types
| Type | Renders as |
|---|---|
text | Single-line text input |
email | Email input (validated format) |
tel | Phone number input |
textarea | Multi-line text area |
select | Dropdown <select> |
number | Numeric input |
date | Date picker |
time | Time picker |
checkbox | Single checkbox (value is "true" / "false") |
radio | Radio button group |
display | Read-only text block (no name needed) |
Submit behaviour
submit_url: null — managed storage
When submit_url is null, the widget POSTs the form values to:
submit_url: "https://..." — direct POST
The widget sends a JSON POST directly to your URL with the body:
2xx status to indicate success.
Confirmation echo
After a successful submission the widget publishes a confirmation message on the LiveKit data channel so the agent knows the form was completed:How the agent opens a form
The agent calls a tool named after your form’sid. For example, with id: "book-demo", the tool invocation looks like:
name is used as a pre-fill value. The widget opens the form panel and populates those fields immediately.