> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spojit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Human Approval

> Pause a workflow and wait for one or more people to approve before continuing.

The **Human** node pauses workflow execution and waits for one or more people to approve or reject before the workflow continues. Approvals can target specific users, anyone holding a role, or any member of a team.

## When to use

* Approve high-value orders before processing
* Review AI-generated content before publishing
* Manually verify data before sending it to a third-party service
* Gate critical actions behind a multi-stakeholder sign-off

## Configuration

| Field                  | Description                                                                                     |
| ---------------------- | ----------------------------------------------------------------------------------------------- |
| **Label**              | Name shown on the node                                                                          |
| **Message**            | The request shown to approvers explaining what they need to decide                              |
| **Timeout (minutes)**  | How long to wait before the approval auto-expires. Leave blank for no timeout                   |
| **Notification title** | A custom title for the approval. Supports `{{ variables }}`. Defaults to the workflow name      |
| **Notification body**  | A custom description shown on the approval. Supports `{{ variables }}`. Defaults to the Message |
| **Urgency**            | `Low`, `Normal`, or `High`. High-urgency approvals show a badge in the inbox                    |
| **Email approvers**    | Off by default. When on, approvers are emailed when the approval is requested                   |
| **Approval slots**     | One or more slots defining who can approve (see below)                                          |

Only **Approval slots** is required; every other field is optional.

### Notification

Use the **Notification title** and **body** to control what approvers see in the Approvals inbox, which is useful when one workflow has several approval steps that would otherwise look the same. Leave them blank to fall back to the workflow name and the Message. Both can include `{{ variables }}` from earlier steps.

Turn on **Email approvers** to also email the assigned approvers when the approval is requested.

<Note>
  Only the first 10 assigned approvers are emailed; this is a notification convenience, not a restriction. Every assigned approver always sees the request in their Approvals inbox and can act on it, whether or not they were emailed. Each email counts toward your plan's monthly email allowance.
</Note>

### Approval slots

The slot model decides *who* can approve and *how many people* need to. It's built from two primitives:

* A **slot** is a group of approver **atoms**. Any atom inside a slot can satisfy that slot.
* An **atom** targets a specific person, a role, or a team.
* An approval completes when **every slot** has been satisfied by at least one approver.

Example: **CFO sign-off AND any Admin**:

* Slot 1: `user: CFO` → only the CFO can satisfy this.
* Slot 2: `role: Admin` → any Admin (or Owner; see role hierarchy) can satisfy this.

Both slots must be filled for the workflow to continue.

Example: **CFO or their delegate**:

* Slot 1: `team: CFO-and-delegates`

A single slot with a team containing both the CFO and their delegates. Any member satisfies it. Editing the team (e.g. vacation coverage) doesn't require editing every workflow.

### Atom types

| Atom     | Satisfied by                                               |
| -------- | ---------------------------------------------------------- |
| **User** | The specific user selected                                 |
| **Role** | Any tenant member with that role (hierarchical; see below) |
| **Team** | Any current member of the selected team                    |

### Role hierarchy

Roles cascade: higher roles satisfy slots configured for lower roles.

* **Any Member** is satisfied by Members, Admins, *and* Owners.
* **Any Admin** is satisfied by Admins *and* Owners.
* **Any Owner** is satisfied only by Owners.

This matches the permission ladder: someone with more authority can always fulfil a less-privileged approval.

### Validation

A workflow cannot be saved (or compiled) if:

* It has zero slots, or
* Any slot has zero atoms, or
* A user/team atom references an entity that no longer exists in the tenant.

At execution time, the approval also fails fast if any slot resolves to zero eligible users (e.g. the Admin role has no members in this tenant).

## How it works

<Steps>
  <Step title="Workflow reaches the Human node">
    Execution pauses. The execution and step status change to **Waiting for Approval**. The node shows an amber hourglass on the canvas.
  </Step>

  <Step title="Approvers are notified">
    The slot atoms are resolved to the specific people who can approve (roles and teams are expanded to their current members, and that list is snapshotted so an in-flight approval isn't silently re-routed if roles or team membership change later). The request appears in each person's **Approvals** inbox. If **Email approvers** is on, the first 10 of them are also emailed.
  </Step>

  <Step title="Approvers review">
    Each notified user sees the request in the **Approvals** inbox (`/approvals`) and on the **Pending Approvals** dashboard widget. The Approvals menu item also shows a badge with the count.
  </Step>

  <Step title="Approvers decide">
    Each approver can **Approve** or **Reject**, optionally with a comment. The approval completes when every slot has been approved by someone eligible.
  </Step>

  <Step title="Workflow resumes or halts">
    * **Approved**: the workflow continues to the next node.
    * **Rejected**: the workflow fails with an `APPROVAL_NOT_APPROVED` error. Any approver in any unfilled slot can reject.
    * **Timed out**: if a timeout was set and no decision was made in time, the approval is treated as rejected with outcome `TIMEOUT`.
    * **Cancelled**: if the execution is cancelled (or the workflow deleted) while pending, the approval is marked `CANCELLED`.
  </Step>
</Steps>

## Output

When the approval is **granted**, the node's output bound to `result_<nodeId>` looks like:

| Field          | Description                                                    |
| -------------- | -------------------------------------------------------------- |
| **approved**   | Always `true` for a successful approval                        |
| **approvalId** | The approval record ID, useful for linking in downstream nodes |
| **outcome**    | Always `APPROVED`                                              |

Rejections, timeouts and cancellations throw a non-retryable error and halt the workflow, so no output is bound in those cases.

## Where approvers see requests

| Surface            | What's shown                                                                                                                                                     |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/approvals` inbox | A full list with **Pending** and **History** tabs, server-paginated                                                                                              |
| `/approvals/[id]`  | A single approval with its title and details, slots, decisions made so far, approve/reject controls, and links to the execution and the workflow in the designer |
| Dashboard widget   | A "Pending Approvals" card with the count and the three most recent requests                                                                                     |
| User menu          | A count badge on the **Approvals** link, polled every 60 seconds                                                                                                 |
| Email              | If **Email approvers** is on, an email to the first 10 assigned approvers when the approval is requested                                                         |

## Audit

Every action is recorded in the audit log (`/settings/audit`):

* `Approval → Create`: when the workflow reaches the node (actor: system)
* `Approval → Approve` / `Approval → Reject`: each decision (actor: the approver, with Miraxa or impersonation attribution preserved)
* `Approval → Expire`: when a timeout fires (actor: system)

## Tips

* Prefer **teams** over lists of specific users when the same people get requested repeatedly, because editing one team covers every workflow that uses it.
* Use multiple slots when you need "AND" semantics (e.g. CFO *and* any Legal member).
* Keep timeouts realistic: humans sometimes take days to respond, and shorter timeouts often cause more re-runs than they save.
* Combine with a [Condition](/workflow-editor/nodes/condition) node *upstream* to skip approval for low-risk cases.
* Downstream branching ("on reject, do X") is not yet supported; a rejected approval halts the workflow.
