Form2Workflow

Building forms

Form settings & layout

Every form is a set of settings plus a config JSON object. This page covers the settings and the top-level config keys that control layout.

Form settings#

Set these in the dashboard's Form Settings dialog, or with the create_form / update_form MCP tools.

SettingDescription
nameDisplay name, shown as the form title.
slugURL-safe identifier, unique within your organization. Generated from the name if you don't set one. Used in embed snippets, hosted URLs and navigation.
n8n_webhook_urlSubmit webhook. The submit button only appears when this is set.
webhook_headersHeaders sent with every submission, e.g. an auth header your n8n Webhook node checks. Stored server-side, never exposed to the browser.
onload_webhook_url, onload_webhook_method, onload_webhook_headersWebhook called when the form loads. See Data pages.
is_activeInactive forms don't load, don't show on hosted pages and reject submissions. Use this to take a form offline without deleting it.
auth_requiredProtected: visitors must sign in as form users. Verified forms use verified_required instead. See Who can use a form.
folder_idDashboard folder. Organizational only.

Top-level config#

KeyTypeDefaultEffect
showTitlebooleantruefalse hides the form name heading — useful when the page already has its own heading.
columns1–41Number of grid columns. Collapses to one column on screens narrower than 768px.
theme_idUUIDnoneTheme to apply. See Themes.
buttonColorhex#2551edLegacy primary color, used only when no theme is set.
fieldsarray[]The fields, in display order. See the Field reference.

Multi-column layouts#

With columns set, fields flow left-to-right into the grid. Use linebreak to end a row early, and subtitle / divider for sections — layout and structural fields (subtitle, divider, linebreak, table, object, array) always span the full width.

Each other field takes one column unless you give it a width: "colSpan": 2 (any number up to columns) or "colSpan": "full". In the dashboard, open a field and choose Width. Widths larger than the form's column count are treated as full width, and on screens narrower than 768px every field is full width. Fields inside object and array groups follow the same grid.

To control where a field goes, set "newRow": true to start it on a new row, or "colStart": 3 to put it in a specific column (in the dashboard, Starts). Columns before it on that row stay empty, so "colStart": 2 on a two-column form puts a field on the right with nothing beside it. If the row has already passed that column, the field moves to the next row. These replace most uses of linebreak.

config — a field alone on the right
{
  "columns": 2,
  "fields": [
    { "id": "first", "type": "text", "name": "first_name", "label": "First name" },
    { "id": "last",  "type": "text", "name": "last_name",  "label": "Last name" },
    { "id": "notes", "type": "textarea", "name": "notes", "label": "Notes", "colSpan": "full" },
    { "id": "code",  "type": "text", "name": "promo", "label": "Promo code", "colStart": 2 }
  ]
}
config — two-column registration form
{
  "showTitle": false,
  "columns": 2,
  "fields": [
    { "id": "s1", "type": "subtitle", "label": "Your details" },
    { "id": "first", "type": "text", "name": "first_name", "label": "First name", "required": true },
    { "id": "last",  "type": "text", "name": "last_name",  "label": "Last name",  "required": true },
    { "id": "email", "type": "email", "name": "email", "label": "Email", "required": true, "colSpan": "full" },
    { "id": "d1",    "type": "divider" },
    { "id": "s2",    "type": "subtitle", "label": "Event" },
    { "id": "track", "type": "select", "name": "track", "label": "Track", "options": ["Workshop", "Talks", "Both"] },
    { "id": "diet",  "type": "text", "name": "dietary", "label": "Dietary needs", "placeholder": "Optional" }
  ]
}

Editing a form's config#

The dashboard editor saves the whole config at once. Through the API or MCP, config is also replaced as a whole — read the form first, change what you need, and send back the complete object. Sending only {"fields": [...]} drops showTitle, columns and theme_id.

Changing a slug breaks every embed snippet, hosted link and targetForm that uses the old slug.