FormTrigger NodeTypeCode: form-trigger
Present a structured Atlas Form to an assigned user and start the downstream workflow when they submit it. Two-phase: the workflow suspends after form dispatch and resumes with validated form data on submission.
When to Use
- Employee leave request: An employee fills in a leave request form (leave type, start/end dates, notes). On submission, the workflow routes to the manager for approval, checks leave balance in the HRMS, and creates the calendar block — all triggered by form submission with no manual handoff.
- Expense claim submission: Finance distributes an expense claim form to employees. The form captures expense type, amount, date, cost center, and receipt upload. Submission triggers the approval routing workflow based on amount thresholds and policy rules.
- IT access request: A new employee submits an IT access request form listing systems they need access to and the business justification. Submission creates the IT ticket, routes for manager approval, and triggers provisioning steps once approved.
- Customer feedback form: After service delivery, the workflow sends a customer a satisfaction survey form. Submission triggers sentiment analysis, routes negative responses to the support team, and logs results in the CRM.
- Vendor onboarding form: A new vendor is sent a structured onboarding form to capture business details, compliance declarations, and banking information. Submission triggers the vendor verification and ERP setup workflow.
Two-Phase Execution
CRITICAL — Two-phase suspension: The FormTrigger workflow suspends at the
pending port after dispatching the form. The workflow will remain suspended indefinitely until the assigned user submits the form. Always configure a deadline mechanism (using the Approval node's deadlineSeconds or a separate timeout branch) to prevent workflows from hanging permanently on unsubmitted forms.
Phase 1 — Form Dispatch
Suspend & Present
- Creates an EngageSession linked to this execution
- Creates an InboxItem for the assigned actor
- Sends notification to the assigned user (in-app + email)
- Workflow suspends; pending port fires
- Caller receives an immediate 200 response
Phase 2 — Form Submission
Resume & Continue
- User opens their inbox and fills in the Atlas Form
- Form validates all required fields before submission
- On submit, workflow engine resumes execution
- All form field values become output data
- success port fires with full form data
Configuration
| Setting | Required | Description |
|---|---|---|
form_schema |
Required | The Atlas Form ID (integer) referencing a form defined in the Atlas Form builder, OR an inline JSON schema object defining the form fields. Using an Atlas Form ID is strongly recommended for production — it allows the form to be updated without redeploying the workflow. Example: 10045 (Atlas Form ID) or inline JSON schema. |
assigned_to |
Required | Who should receive the form in their inbox. Format: user:<userId> for a specific user (e.g. user:jane.doe), or role:<roleName> for any member of a role (e.g. role:payroll-officer). Supports BizFirst expressions for dynamic assignment: user:{{ $output.prevNode.managerUserId }}. |
title |
Optional | The title displayed at the top of the form page and in the inbox notification. Supports BizFirst expressions. Default: the workflow name. |
description |
Optional | Supporting text shown below the title on the form page, providing context to the user about what to complete and why. Supports BizFirst expressions. |
Output Ports
| Port | When It Fires |
|---|---|
pending | Phase 1 completion. Fires immediately after the form is dispatched to the assigned user and the workflow suspends. Use this port to send a "form sent" notification to stakeholders or log the pending state. |
success | Phase 2 completion. Fires when the assigned user submits the form. All form field values, the submitter identity, and the submission timestamp are available on this port. |
error | Fires when the form cannot be dispatched (e.g., the assigned user does not exist, the Atlas Form ID is invalid, or the role resolves to zero members). Also fires if form submission fails server-side validation. |
Output Fields
These fields are available on the success port after the form is submitted:
| Field | Type | Description |
|---|---|---|
form_data | object | A key-value object containing all submitted form field values. Keys match the field IDs defined in the Atlas Form schema. Example: { "leaveType": "Annual", "startDate": "2026-06-10", "endDate": "2026-06-14" }. |
submitted_by | string | The user ID of the actor who submitted the form. May differ from assigned_to if the form was delegated. |
submitted_at | string | ISO 8601 timestamp of when the form was submitted. |
Sample Configuration
{
"nodeType": "form-trigger",
"settings": {
"form_schema": 10045,
"assigned_to": "user:{{ $output.hrLookup.employeeUserId }}",
"title": "Annual Leave Request — {{ $output.hrLookup.employeeFullName }}",
"description": "Please complete your leave request form. Your manager will be notified automatically on submission."
}
}
Sample Output
Success Port — Form Submitted
{
"formId": 13005,
"submissionId": "sub_xyz123",
"submittedBy": {
"userId": "usr_emp_007",
"name": "Michael Torres",
"email": "m.torres@company.com"
},
"submittedAt": "2025-03-15T10:45:00Z",
"data": {
"requestType": "Equipment Purchase",
"itemDescription": "Standing desk — ergonomic model",
"estimatedCost": 650.00,
"currency": "USD",
"businessJustification": "Improving ergonomics for remote work setup",
"urgency": "medium",
"managerApproved": true
},
"formVersion": "1.2",
"workflowTriggered": "expense-approval-workflow"
}
Expression Reference
| Expression | Value |
|---|---|
{{ $output.formTrigger.form_data.leaveType }} | The "leaveType" field submitted by the user in the form. |
{{ $output.formTrigger.form_data.startDate }} | The leave start date as submitted. |
{{ $output.formTrigger.submitted_by }} | The user ID of the person who submitted the form. |
{{ $output.formTrigger.submitted_at }} | ISO timestamp of the form submission. |
Node Policies & GuardRails
| Policy | Rationale |
|---|---|
form_schema must reference a valid Atlas Form ID | If the form ID does not exist or the schema is malformed, the node routes to the error port and the workflow cannot suspend correctly. Always test with the target form in the staging environment before publishing. |
assigned_to must resolve to an existing user or role at runtime | Dynamic assignment expressions are evaluated at execution time. If the referenced user does not exist (e.g., a deleted account), the node routes to error. Add a user-existence check before the FormTrigger in critical workflows. |
| Set a deadline to prevent indefinite suspension | A FormTrigger workflow with no deadline can remain suspended forever if the user never submits. Configure a parallel timeout branch using the Delay + StopWorkflow pattern, or enforce deadlines via the surrounding process design. |
| Use Atlas Form IDs rather than inline schemas in production | Inline schemas are embedded in the workflow node configuration and require a workflow redeployment to change. Atlas Form IDs let the form be updated independently without touching the workflow. |
Always handle the error port | Assignment failures (invalid user, bad form ID) would silently stall the workflow if the error port is unconnected. Route it to a notification node to alert the workflow owner. |
Pattern Examples
Pattern 1 — Employee Leave Request Workflow
A triggered workflow (from ManualTrigger or a scheduled email prompt) sends each employee a leave request form. On submission, the manager is notified and the approval chain begins.
// FormTrigger settings — dynamically assign to the requesting employee
{
"form_schema": 10045,
"assigned_to": "user:{{ $var.requestingEmployeeId }}",
"title": "Leave Request Form",
"description": "Please fill in your leave details. Your line manager will receive a notification on submission."
}
// Downstream on 'success' port — extract leave period
{
"Mappings": [
{ "SourceField": "form_data.leaveType", "TargetField": "leaveType" },
{ "SourceField": "form_data.startDate", "TargetField": "leaveStart" },
{ "SourceField": "form_data.endDate", "TargetField": "leaveEnd" },
{ "SourceField": "form_data.reason", "TargetField": "reason" }
]
}
// Downstream: Approval node assigned to manager
Pattern 2 — IT Access Request with Role Assignment
Any employee in the "staff" role can submit an IT access request form. Submission creates a Jira ticket and routes for manager approval.
// FormTrigger settings — assign to role, not specific user
{
"form_schema": 11200,
"assigned_to": "role:staff",
"title": "IT System Access Request",
"description": "List the systems you need access to and provide business justification. Your manager and IT team will be notified."
}
// Downstream on 'success' port — CodeExecute to build Jira payload
var form = formData;
result = {
summary: "Access Request: " + form.requestedSystems.join(", "),
description: form.justification,
requestedBy: submitted_by,
priority: form.urgency === "high" ? "P1" : "P3"
};