Tasks

Task forms

Design a User Task form on a grid, reuse it from the Forms library, theme it, and use its values later in the workflow.

A task form is what the assignee fills in on a User Task: typed fields placed on a simple grid, with an optional theme. The same designer builds the start form of a workflow (its inputs) and declares the form fields a task trigger expects.

The form designer

Open a User Task and choose Form → Design form. The dialog has three parts:

  • Palette (left): text, long text, number, currency, email, phone, URL, date, date and time, checkbox, single select, multi-select, person, section heading and divider. Drag a type onto the grid, or select it and press Enter to add it in a new row.
  • Grid (centre): rows of 1 to 4 columns. Choose the column count per row, add, move and remove rows, drag fields between cells, and set how many columns a field spans. Dropping onto a full row puts the field in a new row below it.
  • Properties (right): the selected field's label, key, type, width, help text, placeholder, required, read-only, default value (expressions and the Insert data picker work), validation (min / max, length, pattern with a message, date range, selection count), options with values and labels (or loaded from a data table column when the task is created) and Visible when (show the field only when another field equals / doesn't equal / contains a value, or has a value). The Form theme tab styles the form.

Preview shows exactly what the assignee sees, in light or dark mode and at desktop or phone width, with Check validation to try the rules. On phones every row collapses to one column.

The designer has undo and redo (Ctrl+Z, Ctrl+Shift+Z or Ctrl+Y outside text boxes) and asks before closing with unsaved changes.

Keyboard

Tab to a field on the grid. Alt+←/→ moves it within its row, Alt+↑/↓ moves it to the row above or below, Delete removes it and Enter selects it for the properties panel. Every palette item is a button.

Keys and downstream data

Each field has a key, generated in snake_case from its label until you edit it. Keys are unique, lowercase and can't be reserved names (outcome, task_data, id…). After the task, every value is available to later steps as {{task_data.<key>}}, and the Insert data picker lists each field with its label and type. Values are typed: numbers and currency are numbers, checkboxes are true / false, dates are ISO strings and multi-selects are arrays.

Renaming a key that later steps use opens a list of those references (step, setting and count) and offers to update them to the new key or keep them as they are.

Reusable forms

Automations → Forms is the library: search and filter by tag, create, edit, duplicate and delete forms, and see which workflow steps use each one. In the designer, Save as reusable form saves the form to the library and links the step to it; Use a saved form links an existing one.

  • A linked step shows Linked to form "…" vN. Saving in the designer can create a new version of the form or Detach and save here (the step keeps a local copy). Detach on the step does the same without opening the designer.
  • Every change to a form's fields, layout or theme creates a new version; name, description and tag changes don't.
  • Drafts follow the latest version of a linked form. Publishing pins the version in use, so a published workflow keeps its form until you publish again.
  • A form that workflows use can't be deleted; the error lists where it is used.

Forms need the View forms, Edit forms and Delete forms permissions (Owner, Admin and Manager have all three; Member and Viewer can view). They travel with config-as-code, GitHub sync and packages (a workflow that links a form brings it, and its saved theme, along), and have REST (/api/v1/forms, /api/v1/form-themes), MCP (forms_*, form_themes_*) and CLI (usertasks forms …) commands.

Form themes

By default a form uses the workspace theme. The Form theme tab can instead set a small set of overrides, starting from any built-in theme preset:

  • accent colour (buttons, focus ring, selection), background and text colour, separately for light and dark mode
  • corner radius, font (from the workspace theme's fonts), density (comfortable or compact) and label position (above or left of the input)
  • an optional header with a title, subtitle, banner colour and the workspace logo

Contrast is checked against the workspace theme in both modes. Low-contrast pairs are listed with an Auto-fix, and the form always raises them when it is drawn, so text is never illegible. A theme whose own text and background are below 3:1 can't be saved. Without dark colours, dark mode keeps the workspace's dark palette with your accent.

Save a theme to reuse it (Save as a reusable form theme, or Automations → Forms → Form themes). Tasks keep the theme they were created with.

Start forms and task triggers

  • Start form: in the workflow settings (nothing selected on the canvas), Design start form edits the workflow inputs (text, number, checkbox, date, date and time, email, URL and single select) on a grid with a theme. The Run dialog and the form shown for API and CLI starts follow it. From a saved form copies a library form's fields as inputs.
  • Task triggers: a task trigger's Task form declares the fields the triggering task carries, so they appear in the data picker as {{task.data.<key>}}.

Validation is enforced on the server

Every way of saving or completing a task — the task screen, POST /api/v1/tasks/{id}/action, PATCH /api/v1/tasks/{id}, the MCP task tools and the CLI — checks the values against the form: types, required fields (hidden fields are skipped), ranges, lengths, patterns, options and people. Read-only fields keep their value whatever is sent. Invalid values are refused with one message per field and nothing is recorded.

User Task config with a grid
{
  "task_title": "Review expense claim",
  "outcomes": ["Approved", "Rejected"],
  "fields": [
    { "key": "employee_name", "label": "Employee name", "type": "text", "required": true },
    { "key": "amount", "label": "Amount", "type": "currency", "currency": "USD", "min": 0 },
    { "key": "category", "label": "Category", "type": "choice", "options": ["Travel", "Meals", "Equipment"] },
    { "key": "expense_date", "label": "Expense date", "type": "date" }
  ],
  "form_layout": { "rows": [
    { "columns": 2, "cells": [{ "field_key": "employee_name", "span": 1 }, { "field_key": "amount", "span": 1 }] },
    { "columns": 2, "cells": [{ "field_key": "category", "span": 1 }, { "field_key": "expense_date", "span": 1 }] }
  ] }
}

A form without form_layout renders as it always has. Opening it in the designer shows one field per row and doesn't change anything until you edit it.