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

# Approval & Notifications

> Set up Slack, Teams, or Discord for step approval and completion notifications.

## Overview

Refrain provides two messaging features:

* **Approval** — Before executing a step marked with `requiresConfirmation: true`, a message with Approve / Skip / Abort buttons is sent to your team channel. Execution pauses until someone responds.
* **Notification** — After execution completes, a summary card is sent with success/failure counts, execution time, and failed step details.

<Note>
  HITL approval via Slack/Teams/Discord requires [Business or higher](/concepts/plan-tiers). Notifications require [Team or higher](/concepts/plan-tiers).
</Note>

## Approval workflow

When a step has `requiresConfirmation: true`, the executor:

1. Sends a card message to the configured channel with step details and risk level
2. Pauses execution and waits for a response
3. Resumes based on the response:
   * **Approve** — Executes the step
   * **Skip** — Skips the step and continues
   * **Abort** — Stops the entire execution

The default timeout is 5 minutes. If no response is received, execution is aborted.

## Notification

After execution completes (success or failure), a summary card is posted with:

* Total steps, success count, failure count, skipped count
* Execution duration
* Failed step details (if any)

Notification failures are logged as warnings but don't affect the exit code.

## Platform setup

<Tabs>
  <Tab title="Slack">
    ### 1. Create a Slack App

    1. Go to [api.slack.com/apps](https://api.slack.com/apps) and click **Create New App** → **From scratch**
    2. Name it (e.g., `refrain`) and select your workspace

    ### 2. Add Bot Token Scopes

    Go to **OAuth & Permissions** → **Bot Token Scopes** and add:

    | Scope         | Purpose                                          |
    | ------------- | ------------------------------------------------ |
    | `chat:write`  | Send messages (approval requests, notifications) |
    | `files:write` | Upload report files                              |

    ### 3. Install to workspace

    Click **Install to Workspace** and copy the **Bot User OAuth Token** (`xoxb-...`).

    ### 4. Invite the bot to a channel

    In Slack, run `/invite @refrain` in the target channel.

    Find the channel ID: right-click the channel name → **View channel details** → the ID is at the bottom (format: `C0123456789`).

    ### 5. Enable Interactivity (approval only)

    If using `--approval-mode slack`:

    1. Go to **Interactivity & Shortcuts** → Turn **On**
    2. Set **Request URL** to `https://<your-domain>/webhooks/slack`

    Not needed for `--notify slack` only.

    ### 6. Set environment variables

    ```bash theme={null}
    export SLACK_BOT_TOKEN="xoxb-..."
    export SLACK_CHANNEL_ID="C0123456789"
    ```

    ### CLI example

    ```bash theme={null}
    npx @refrainai/cli execute -- \
      --runbook ./payment-flow.yaml \
      --approval-mode slack \
      --notify slack
    ```
  </Tab>

  <Tab title="Teams">
    ### Environment variables

    ```bash theme={null}
    export TEAMS_APP_ID="..."
    export TEAMS_APP_PASSWORD="..."
    export TEAMS_CHANNEL_ID="..."
    ```

    ### CLI example

    ```bash theme={null}
    npx @refrainai/cli execute -- \
      --runbook ./payment-flow.yaml \
      --approval-mode teams \
      --notify teams
    ```
  </Tab>

  <Tab title="Discord">
    ### Environment variables

    ```bash theme={null}
    export DISCORD_BOT_TOKEN="..."
    export DISCORD_PUBLIC_KEY="..."
    export DISCORD_APPLICATION_ID="..."
    export DISCORD_CHANNEL_ID="..."
    ```

    ### CLI example

    ```bash theme={null}
    npx @refrainai/cli execute -- \
      --runbook ./payment-flow.yaml \
      --approval-mode discord \
      --notify discord
    ```
  </Tab>
</Tabs>

## CLI examples

**Approval only:**

```bash theme={null}
npx @refrainai/cli execute -- \
  --runbook ./flow.yaml \
  --approval-mode slack
```

**Notification only:**

```bash theme={null}
npx @refrainai/cli execute -- \
  --runbook ./flow.yaml \
  --notify slack
```

**Both:**

```bash theme={null}
npx @refrainai/cli execute -- \
  --runbook ./flow.yaml \
  --approval-mode slack \
  --notify slack
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Slack shows 'This didn't work' after clicking a button">
    The Interactivity Request URL is invalid or unreachable. Verify the URL in your Slack App's Interactivity settings points to the correct callback endpoint.
  </Accordion>

  <Accordion title="Approval times out and execution aborts">
    The callback is not reaching the executor. Verify that the callback endpoint is accessible from the internet and the Request URL is correctly configured.
  </Accordion>

  <Accordion title="'not_in_channel' error">
    The bot hasn't been invited to the channel. Run `/invite @your-bot-name` in the target channel.
  </Accordion>
</AccordionGroup>

## What's next

<CardGroup cols={2}>
  <Card title="Execute a runbook" icon="play" href="/guides/execute-runbook">
    Run your runbook with approval and notifications.
  </Card>

  <Card title="Plans & Pricing" icon="credit-card" href="/concepts/plan-tiers">
    Check plan requirements for messaging features.
  </Card>
</CardGroup>
