Forms
Create branded public forms that trigger workflows when submitted.
Public Forms collect data from external users through a hosted web form. Every submission triggers any workflows you've wired to that form, with the form data exposed as {{trigger.data.fields.<name>}}.
Forms are workspace content (like workflows and shared pages). Each form belongs to one workspace. You create and manage forms in the sidebar tree's Forms section — or straight from a workflow's Trigger inspector (New form), without leaving the editor. The number of forms depends on your plan.
Creating a Form
- In the sidebar tree, open the workspace's Forms section.
- Click + - gives you an empty form with no fields.
- Add fields - pick from text, email, number, textarea, select, file upload, or checkbox. Each field has:
- Label - what the user sees.
- Name - the JSON key in the workflow payload (
{{trigger.data.fields.<name>}}). Stable across edits. - Required / validation rules - min/max length, regex, file size, accepted file types.
- Placeholder + help text - both optional.
- Choose a layout -
Stack(vertical) orGrid(2-column). See below for tradeoffs. - Configure branding - logo, colors, backgrounds. See Branding.
- Click Save to keep editing as a draft, or Publish to make it live.
Drafts have status DRAFT and are not reachable at the public URL. Published forms have status PUBLISHED. For Member-role users, publishing requires the Publish forms & pages workspace permission - see Members & Roles.
Layouts
The layout controls how fields stack on the page. Pick Grid when you have many short, related fields (name + email, city + zip, etc.) and Stack when fields need their full breathing room (long textareas, file uploads).
| Layout | Behavior | When to use |
|---|---|---|
| Stack | Each field on its own row, full width | Short forms, long textareas, mobile-first |
| Grid | Two columns; each field is full (spans 2 cols) or half (1 col) | Dense forms, paired fields, desktop-first |
In Grid layout, set each field's width to full or half from its inspector. Half-width fields pair up automatically left-to-right; a full-width field always starts on its own row. On mobile, grid collapses to a single column regardless of field width.
The visual layout builder shows the field arrangement as you drag - you don't have to publish-and-check to see the result.
Branding
Branding is configured per form (no org-wide theme). Every option is optional - leave a field blank and the form falls back to a neutral default.
| Setting | Effect |
|---|---|
| Logo | Uploaded to organization S3 storage; displayed centered above the form |
| Primary color | Submit button, focus rings, accent strokes |
| Page background color | Background of the page outside the form card |
| Page background image | Image overlay for the page background; takes precedence over the page background color |
| Form background color | Background of the form card itself (the panel containing the fields) |
| Custom CSS class | Class applied to the form container - for advanced styling via your own stylesheet |
| Header text | Custom heading rendered above the fields |
| Success message | Shown after a successful submission |
| Redirect URL | If set, the form redirects here on success instead of showing the success message |
Logos and background images are stored in the organization's file bucket. They are served from a presigned URL - there is no separate CDN configuration to do.
Public URL
Published forms are reachable at:
/f/<publicToken>
publicToken is a 192-bit random base64url string. Anyone with the URL can submit; there is no authentication on the form side.
If closeAfterDate is set, the form returns a "closed" message after that date instead of the form. If maxSubmissions is set, the form returns a "submissions closed" message once the count is reached.
A built-in honeypot field guards against naive bots; it can be disabled per-form (enableHoneypot: false) if you ever need to reach the form from an automated tool you control.
Embed Mode
Add ?embed=1 to the form URL to render it for iframe embedding on an external site:
<iframe
src="https://your-domain.com/f/TOKEN?embed=1"
width="100%"
height="600"
frameborder="0">
</iframe>
Embed mode strips:
- The page background (image and color)
- The logo and the form card chrome
- The default page padding
…leaving just the fields and the submit button. Use the form's Form background color to control how it looks against your host page's background.
Wiring a Form into a Workflow
A form by itself just collects data. To turn it into a trigger, you connect it to one or more workflows. One form can drive several workflows at once - every active workflow in the form's workspace that uses it runs on each submission.
Step 1 - Use triggerType: "form" in the workflow
- In the workflow editor, click the Trigger node.
- Set Trigger type to Form.
- Pick the form from the dropdown - the forms of the current workspace appear. Need a new one? Click New form right there.
- Save the workflow and activate it (status
ACTIVE).
When a user submits the form, every active workflow with a matching formId is triggered. Triggering is fire-and-forget: the form's success message renders as soon as the submission is queued, not when the workflows finish.
Step 2 - Read submission data in the workflow
The trigger payload follows a standard shape:
{
"formId": "form-cuid",
"formName": "Lead intake",
"submittedAt": "2026-04-30T12:00:00.000Z",
"fields": {
"name": "Ada Lovelace",
"email": "ada@example.com",
"company": "Analytical Engines Ltd"
}
}
Reference these fields in downstream nodes via:
{{trigger.data.fields.<name>}}- values for non-file fields{{trigger.data.formId}}/{{trigger.data.formName}}/{{trigger.data.submittedAt}}- submission metadata
File fields
File uploads are stored in S3 and surfaced as objects:
{
"fields": {
"resume": {
"fieldName": "resume",
"s3Key": "forms/<form-id>/<submission-id>/resume.pdf",
"url": "<presigned-download-url>",
"name": "ada-lovelace-resume.pdf",
"size": 245678,
"contentType": "application/pdf"
}
}
}
Pass {{trigger.data.fields.resume.url}} to a downstream HTTP node to download, or reference s3Key to operate on the file via the Files (S3) MCP server.
Submissions
View the raw submission history in the workspace's Forms section → (form) → Submissions. Each entry shows the timestamp, the field values, and links to any uploaded files. Submissions are kept independently of execution history - even if a triggered workflow fails or is deleted, the submission record stays.
Plan limits
The number of forms you can have per organization is governed by your plan. See Plans & Limits for current numbers.
Related
- Triggers - full Trigger node reference, including
form - Shared Pages - the output counterpart: publish a workflow's result as a public page
- Variables & Templates - how
{{trigger.data}}references work in nodes