n8n form approvals

n8n form approvals use FormNode to capture the human decision before an n8n workflow performs the work. The approver can decide from email or a portal surface, and FormNode sends the result back to n8n as structured JSON.

Direct answerUse FormNode approvals when an n8n workflow needs customer or manager signoff, email-based decisions, per-row decision tables, approval history, or a callback payload that n8n can branch on reliably.

Approval callback shape

When an approval is decided, FormNode posts an approval.responded event to the configured callback URL.

{
  "eventType": "approval.responded",
  "approvalId": "8f2a4e1c-6b7d-4f3a-9e8d-1c2b3a4d5e6f",
  "formId": "5a8b3c2d-1e4f-4a9b-8c7d-6e5f4a3b2c1d",
  "status": "responded",
  "decision": "approved",
  "comments": "Approved for Sunday maintenance.",
  "contextData": {
    "customer": "Acme",
    "ticketId": "CW-104923",
    "requestedBy": "sarah.chen@example.com"
  },
  "responseData": {
    "decision": "approved"
  },
  "respondedAt": "2026-05-14T18:42:11.337Z",
  "respondentInput": {
    "email": "client@example.com",
    "name": null
  }
}

In n8n, branch on $json.decision. Preserve $json.approvalId and related ticket or request IDs for auditability.

Two implementation paths

PathUse whenn8n responsibility
Form submission creates an approvalA user submits a request and approval is the next stepWait for the approval callback before fulfillment
n8n creates an approval through the APIn8n detects work first, such as firmware updates or access reviewsCreate the approval, then branch when FormNode calls back

Decision tables

Decision tables are for approvals where each row can have a different outcome. Firmware upgrades, device maintenance, license changes, and batch access reviews often need this shape.

{
  "responseData": {
    "firewall_decisions": [
      { "deviceId": "fw_001", "decision": "approved", "scheduledFor": "2026-05-18T07:00:00Z" },
      { "deviceId": "fw_002", "decision": "rejected", "reason": "Replace next quarter" }
    ]
  }
}

In n8n, iterate the row array. Fulfill approved rows, skip rejected rows, and write both outcomes back to the ticket or system of record.

n8n approval implementation rules

  • Do not perform the protected side effect before approval arrives.
  • Handle rejection as a first-class workflow path, not an error.
  • Handle expiration and missing callbacks separately from rejection.
  • Use the approval ID and any request ID you stored in contextData for idempotency.
  • Keep enough context in contextData for the approver to decide without opening n8n.

Common n8n approval workflows

  • Microsoft 365 user onboarding that needs manager approval.
  • License changes that need budget owner approval.
  • Firmware or patch maintenance that needs customer approval.
  • Access requests that need owner approval before provisioning.
  • Ticket work that needs customer confirmation before scheduling.

Troubleshooting

n8n continues before the approval

Move the side effect behind the approval callback. Creating the approval should not also provision the user, schedule the upgrade, or update the target system.

Approval email was sent but n8n did not resume

The callback fires only after the approver decides. Check FormNode approval delivery logs and the n8n webhook execution for non-2xx responses.

Rejected rows were still processed

Iterate the decision-table results and branch per row. Do not treat the overall approval as a single approved boolean when the form uses per-row decisions.