# Human approval

Human approval, also called human in the loop (HITL), lets an agent pause one sensitive step and ask a person before it runs. Add it to payments, refunds, deployments, and other high-impact tasks so the agent can keep going on the rest of the work, while that one command waits in Slack for **Approve** or **Deny**. A person stays in control of the actions that matter, and the agent still finishes everything else.

---

## How it works

1. You run a command that matches an approval policy.
2. Swytchcode sends an approval request to the workspace's Slack or Telegram channel. The terminal reports that the request is pending, then exits.
3. A message appears with **Approve** and **Deny**. It says what the command does (the policy's message), who asked for it, the workspace, and, for a call made for one of your app's users, which user.
4. **Approve** runs the command once. **Deny** stops it.
5. If nobody responds within 48 hours, the request expires and the command does not run.
6. If the request cannot be created, the command does not run, the terminal says why, and nothing is left waiting. That happens when the workspace has no channel configured, or when the plan does not include approvals. These show as `failed` in [`swy audit policy`](/cli/telemetry/#local-execution-history). Fix the setup, then run the command again to send a new request.

Create the rule with `swy policy add`, and review configured rules with `swy policy list`. Held, denied, and blocked commands are in `swy audit policy`. Managing rules (`swy policy`) is separate from that history (`swy audit policy`).

`swy exec` exits with code `7` while a command waits for approval, so scripts and agents can tell "waiting" apart from "failed".

### How soon an approved command runs

Swytchcode checks for a decision in the background, so your terminal is free while you wait. It checks every 2 minutes for the first hour after the request, then every 30 minutes. An approved command runs at the next check: within about 2 minutes if it's approved in the first hour, and up to 30 minutes later after that. The computer that ran the command needs to be on for it to run.

Running the same command again while the request is waiting doesn't send a second message.

---

## 1. Connect Slack

Open [app.swytchcode.com](https://app.swytchcode.com) and choose where approval messages go.

1. Log in at [app.swytchcode.com](https://app.swytchcode.com).
2. Go to **Settings**, then the **Workspaces** tab.
3. Open the workspace you want to use.
4. In **HITL Notifications**, choose **Slack**. The same section also lists Telegram when you want approvals there.

Every workspace starts on Swytchcode's shared Slack bot. Connect your own bot when approvals should arrive in a channel you control. If you leave the shared bot in place, the policy and command steps below still send a real approval request.

### Create a Slack app

Do this before you fill in the workspace form.

1. Go to [api.slack.com/apps](https://api.slack.com/apps) and create a new app.
2. Turn on **Socket Mode**. Approval delivery requires Socket Mode.
3. Under **OAuth & Permissions**, copy the **Bot Token**. It starts with `xoxb-`.
4. Under **Basic Information**, open **App-Level Tokens** and generate a token. It starts with `xapp-`.
5. Invite the bot into the Slack channel where approval messages should appear, then copy that channel's ID.

### Save the bot on the workspace

Back on the workspace form in [app.swytchcode.com](https://app.swytchcode.com), fill in:

- **Bot Token**, the `xoxb-` value
- **App Token**, the `xapp-` value
- **Destination Channel**, the channel ID

Save. After that, the form shows a masked token.

A workspace without a channel configured cannot send approval requests. Connect Slack before you rely on an approval policy.

---

## 2. Add an approval policy

A HITL approval happens only when a guard policy requires one. In a project where the [Swytchcode CLI is set up](/cli/projects/), run this once:

```bash
swy policy add --name "Demo Approval" --target stripe.create_payment --field amount --operator ">" --value 100 --action REQUIRES_APPROVAL --message "Payments over 100 require approval"
```

Any call to `stripe.create_payment` with an `amount` greater than 100 now waits for a person to approve it before it runs.

`swy` and `swytchcode` are the same CLI. Confirm the rule with `swy policy list`. The file those commands write is covered in [policies.json](/configuration/policy-json/) and [Policy Rules](/policies/policy-rules/).

### Reuse an approval, or set a deadline

In a [version-2 `policies.json`](/configuration/policy-json/#file-versions), an approval policy can also set:

- **`reuse`** - one approval covers later matching calls for a while. With `"reuse": { "for": "24h", "same": ["customer"] }`, after one refund to a customer is approved and run, more refunds to that customer go through without asking again for 24 hours. Without `same`, any call to the tool is covered.
- **`approval_timeout`** - how long the request waits, e.g. `"30m"`. After that, a late approval never runs the command. Requests always expire after 48 hours.
- **`notify`** - an extra message when the request is created, for example to a team channel. See [Alerts](/configuration/policy-json/#alerts).

```json
{
"id": "big-refunds",
"target": ["stripe.refund.create"],
"when": { "field": "amount", "operator": ">", "value": 50000 },
"action": { "type": "REQUIRES_APPROVAL", "message": "Refunds over 500.00 need approval" },
"reuse": { "for": "24h", "same": ["customer"] },
"approval_timeout": "2h"
}
```

---

## 3. Trigger the approval

Run a command that matches the policy:

```bash
swy exec stripe.create_payment --body '{"amount": 500}' --demo
```

The amount `500` is above the `100` threshold, so the policy matches. The `--demo` flag runs this without a connected Stripe account, which is useful while you are checking the approval flow. Inputs and other `swy exec` flags are in [Execute Tools](/cli/exec/).

---

## 4. Approve or deny in Slack

The terminal shows that the request is pending approval, then exits.

Swytchcode has already sent the request to the Slack channel from step 1. If you skipped your own bot, the message goes to the shared bot's channel.

The message shows the policy's `message`, who asked (your account and workspace) and, for a call made for an end user of your app, which one (see [Multi-tenant apps](/guides/multi-tenant/#audit-and-approvals)). It has **Approve** and **Deny**. Clicking one resolves that live request:

- **Approve** runs the command once.
- **Deny** stops it.

Review the outcome later with [`swy audit policy`](/cli/telemetry/#local-execution-history).

---

## When to require approval

Use a human approval policy when the action should run only after a person confirms it, such as a refund above a threshold.

Use an allow or deny rule when the action should never run in this environment, such as deleting production resources from a sandbox. Those rules are in [Policy Rules](/policies/policy-rules/).

---

## Workspace, policies, and plans

Approvals are set up **per workspace**, so each workspace can send requests to its own Slack or Telegram channel. You can use Swytchcode's shared bot, or connect a bot that belongs to your workspace. Notification settings are changed in [app.swytchcode.com](https://app.swytchcode.com) by the workspace owner or an admin. Roles are described in [Workspaces and teams](/guides/workspaces/).

Allow and deny rules in [`policies.json`](/configuration/policy-json/) stop a request immediately. An approval policy holds the command until someone responds. See [Policy Rules](/policies/policy-rules/) for hard blocks.

Allow and deny rules work on every plan. Approval workflows are included on Business and Enterprise. Current plans are on [swytchcode.com/pricing](https://www.swytchcode.com/pricing).

---

## Related

- [Policies overview](https://docs.swytchcode.com/policies/overview/) - How policies decide what can execute before a request reaches the provider.
- [Policy Rules](https://docs.swytchcode.com/policies/policy-rules/) - Write conditions, operators, and allow or deny actions.
- [Workspaces and teams](https://docs.swytchcode.com/guides/workspaces/) - Per-workspace approval settings, roles, and seats.
- [Execute Tools](https://docs.swytchcode.com/cli/exec/) - Run a command with swy exec, including demo executions.
- [Production Guardrails](https://docs.swytchcode.com/policies/production-guardrails/) - Recommended safeguards for running agents against production systems.
