Portal Community

When to Use

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

SettingRequiredDescription
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

PortWhen It Fires
pendingPhase 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.
successPhase 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.
errorFires 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:

FieldTypeDescription
form_dataobjectA 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_bystringThe user ID of the actor who submitted the form. May differ from assigned_to if the form was delegated.
submitted_atstringISO 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

ExpressionValue
{{ $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

PolicyRationale
form_schema must reference a valid Atlas Form IDIf 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 runtimeDynamic 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 suspensionA 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 productionInline 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 portAssignment 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"
};