Forms (new) Step

Collects user input via an ordered list of form components. Use this step to build interactive forms and capture structured data (text, numbers, selections), lay out pages/sections, and include static content such as headings and dividers.

Top-level properties

nametyperequiredconstraintsdescription
typestringnoenum: data-captureOptional discriminator used by some orchestrators.
presentationobjectnoContainer-level presentation metadata for the entire form.
componentsarrayyesitems: union of component variantsOrdered list of components defining the form’s content and layout.

Presentation

nametyperequiredconstraints
presentation.formobjectnoContainer-level form display settings
form.labelstringyesmaxLength: 60

Component: text

Use for single-line or multi-line text input. This is also used with the "format" option for fields such as email and phone.

nametyperequiredconstraints
idstringnoformat: uuid; special-case all-zero/ffff allowedStable identifier for the component (for mapping/data pipelines).
typestringyesenum: textDiscriminator for the component variant.
labelstringyesMachine-readable field key (often snake_case), used for data mapping.
validation.requiredbooleannoWhether input is mandatory.
validation.minnumbernominimum: 0Minimum character length.
validation.maxnumbernominimum: 1Maximum character length.
presentation.formobjectnoUI rendering hints for this field.
form.labelstringyes if presentation.form presentmaxLength: 60Human-readable label shown to end users.
form.typestringyes if presentation.form presentenum: input, richtext, select, textarea; default: inputInput control type.
form.placeholderstringnoExample text shown inside the input.
form.helpTextstringnoHelper text displayed near the input.

Component: number

Use for numeric input with optional formatting and range constraints.

nametyperequiredconstraints
idstringnoformat: uuidStable component id.
typestringyesenum: numberDiscriminator for numeric fields.
labelstringyesMachine-readable field key.
validation.requiredbooleanyes if validation presentdefault: falseWhether value is mandatory.
validation.minnumbernoMinimum allowed value.
validation.maxnumbernoMaximum allowed value.
presentation.formobjectnoUI control settings.
form.labelstringyes if presentation.form presentmaxLength: 60Human-readable label.
form.typestringyes if presentation.form presentenum: input; default: inputInput control type.
form.placeholderstringnoExample numeric value.
form.helpTextstringnoHelper copy for guidance.

Component: options

Use for single or multi-select choices populated from a static list or a dynamic endpoint. Dropdowns, Radio or Checkboxes

nametyperequiredconstraints
idstringnoformat: uuidStable component id.
typestringyesenum: optionsDiscriminator for option fields.
labelstringyesMachine-readable key.
validation.sourcestringyesenum: endpoint, static_listWhere options come from.
validation.requiredbooleanyesdefault: falseWhether a selection is mandatory.
validation.optionsarray[Option]nominItems: 1Static choices when source is static_list.
presentation.formobjectyesUI settings for select control.
form.labelstringyesmaxLength: 60Human-readable label.
form.typestringyesenum: checkbox, dropdown; default: dropdownSelect control type.
form.placeholderstringnoPlaceholder for dropdown.
form.helpTextstringnoHelper copy.

Option

nametyperequired
idstringno (nullable)Optional stable option id
labelstringyesDisplay text shown to users
valuestringyesValue stored on selection

Component: static_content

Use to display non-interactive content such as header field or description areas.

nametyperequiredconstraints
idstringnoformat: uuidStable id for reference
typestringyesenum: static_contentDiscriminator for display-only blocks
labelstringyesInternal key for this block
presentation.formobjectnoUI rendering hints
form.typestringyes if presentation.form presentenum: heading, htmlDisplay variant
form.labelstringyes if presentation.form presentmaxLength: 60Title for headings or accessibility label
form.contentstringyes if presentation.form presentBody content (HTML/Markdown/string)

Component: group

Use to create and update grouped options such as Pages and grouped fields like "Name"

nametyperequiredconstraints
idstringnoformat: uuidStable group id
typestringyesenum: groupDiscriminator for groups
labelstringyesInternal key for this group
presentation.formobjectnoGroup-level UI settings
form.labelstringyes if presentation.form presentmaxLength: 60Visible label/title for the group
form.typestringyes if presentation.form presentenum: full_name, grid, group, none, page, sectionLayout mode controlling rendering
form.gridOptions[]arraynoeach item requires gridColumnStart, gridColumnEnd, gridRowStart, gridRowEndGrid position hints for nested components
components[]arraynoitems: same component union as top-levelNested components within the grou

Assignment

The taskAssignment property configures how form completion notifications are sent to users.

nametyperequiredconstraintsdescription
typestringyesenum: email, phone, inheritFromPreviousStepAssignment method.
namestringyes if type is email or phoneTask assignment name.
configobjectyes if type is email or phoneConfiguration object specific to the assignment type.

Email Assignment Config (type: "email"):

nametyperequiredconstraintsdescription
recipientsarray(string)yesArray of email addresses to notify.
fromstringnoSender email address.
replyTostringnoReply-to email address.
subjectstringyesEmail subject line.
messagestringyesEmail body message.
buttonLabelstringyesLabel for the action button in the email.

Phone Assignment Config (type: "phone"):

nametyperequiredconstraintsdescription
recipientsarray(string)yesArray of phone numbers to notify.
messagestringyesSMS message text.

Example (JSON)

{
  "type": "data-capture",
  "presentation": {
    "form": {
      "label": "Customer Intake"
    }
  },
  "components": [
    {
      "id": "00000000-0000-0000-0000-000000000000",
      "type": "text",
      "label": "Email Address",
      "validation": {
        "required": true,
        "format": "email",
        "min": 5,
        "max": 255,
        "errorMessage": "Please enter a valid email address"
      },
      "presentation": {
        "form": {
          "label": "Email Address",
          "type": "input",
          "placeholder": "[email protected]",
          "helpText": "We will send your receipt here."
        }
      }
    },
    {
      "id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
      "type": "number",
      "label": "Quantity",
      "validation": {
        "format": "integer",
        "required": true,
        "min": 1,
        "max": 100
      },
      "presentation": {
        "form": {
          "label": "Quantity",
          "type": "input",
          "placeholder": "1",
          "helpText": "Enter a value between 1 and 100"
        }
      }
    },
    {
      "id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
      "type": "options",
      "label": "Plan",
      "validation": {
        "source": "static_list",
        "required": false,
        "options": [
          { "id": "basic", "label": "Basic", "value": "basic" },
          { "id": "pro", "label": "Pro", "value": "pro" }
        ],
        "endpoint": "https://api.example.com/plans",
        
      },
      "presentation": {
        "form": {
          "label": "Plan",
          "type": "dropdown",
          "placeholder": "Select a plan",
          "helpText": "Choose your subscription plan"
        }
      }
    },
    {
      "id": "cccccccc-cccc-4ccc-8ccc-cccccccccccc",
      "type": "static_content",
      "label": "Terms",
      "validation": {},
      "presentation": {
        "form": {
          "type": "md",
          "label": "Terms & Conditions",
          "content": "By continuing you agree to the terms."
        }
      }
    },
    {
      "id": "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
      "type": "group",
      "label": "Personal Information",
      "validation": {},
      "presentation": {
        "form": {
          "label": "Personal Information",
          "type": "grid",
          "gridOptions": [
            {
              "gridColumnStart": "1",
              "gridColumnEnd": "3",
              "gridRowStart": "1",
              "gridRowEnd": "1"
            }
          ]
        }
      },
      "components": [
        {
          "id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
          "type": "text",
          "label": "ZIP Code",
          "validation": {
            "required": true,
            "format": "zip",
            "min": 5,
            "max": 10,
            "errorMessage": "Enter a valid ZIP code"
          },
          "presentation": {
            "form": {
              "label": "ZIP Code",
              "type": "input",
              "placeholder": "90210",
              "helpText": "Five or nine digits"
            }
          }
        }
      ]
    }
  ]
}