# User approval

Pause the workflow until a human approves or rejects, then resume on the chosen branch.

## Overview

When execution hits this node, the run is suspended with status `awaiting_approval` and the current `last_output` is snapshotted. The user receives a notification (in-app, optionally email or Slack) with the approval message and a resume link. Clicking **Approve** or **Reject** signs the resume URL with a one-shot token and continues the workflow down the matching branch.

The node exposes two output handles:

- `approved` — followed if the reviewer approves.
- `rejected` — followed if the reviewer rejects.

Use it to gate any action whose mistake cost is high: production deploys, sending invoices, posting public messages, deleting records.

## Configuration

| Field | Description |
| --- | --- |
| `message` | Markdown text shown to the reviewer. Supports `{placeholders}` from workflow state (e.g. `Send invoice for {customer_email} totaling {total}?`). |
| `approvalScope` | Optional approval target. Leave unset or use `any` for existing single-reviewer behavior, `team_roles` for role-based approval, or `specific_users` for named approvers. |
| `approvalRoles` | Role names that may approve when `approvalScope` is `team_roles`. Use an array, comma-separated text, or one role per line. |
| `approverEmails` | Explicit approver email addresses when `approvalScope` is `specific_users`. Use an array, comma-separated text, or one email per line. |
| `minApprovals` | Minimum approvals required before resuming. Defaults to `1`; keep it greater than zero and no higher than the eligible approver count. |
| Notification channels | In-app is always on. Email and Slack require the workspace integration to be configured. |
| Output handles | `approved`, `rejected`. |

Approval Group fields are additive. Workflows that only define `message` keep their existing behavior.

The resume URL is single-use and scoped to the execution. The token is invalidated as soon as the run resumes.

## Example

Gate a production deploy:

```
Agent (build release notes) → User approval ("Deploy {version} to prod?")
                                ├─ approved → HTTP Request (POST /deploy)
                                └─ rejected → Set state (deploy_skipped=true)
```

The workflow returns `status: awaiting_approval` and stays paused. The reviewer gets a notification with the rendered message, an Approve and a Reject button. Whichever they pick, the workflow resumes from that branch.

## Gotchas

- Paused runs are persisted, but unbounded queues are not free — clean up stale approvals via the execution list if reviewers ghost a request.
- The reviewer sees the rendered `message` only, not the full workflow context. Surface every decision-critical field in the message.
- The branch handles are `approved` and `rejected` — leaving `rejected` unwired means a rejection silently halts the workflow.
- Approval tokens are single-use. Re-sending the link after consumption returns a 410.
- If the workflow times out before a decision, the run ends as `expired` and the resume link 404s.

---

*Source: https://agentbuilder.systalink.sn/docs/node-user-approval — human documentation.*
*Other language: [/docs-md/fr/node-user-approval.md](/docs-md/fr/node-user-approval.md).*
*Machine-readable index: [/llms.txt](/llms.txt).*
