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

# Approval

> Route tool approvals to Slack, Discord, Telegram, or any channel before agents execute dangerous operations

Route tool approvals to Slack, Discord, Telegram, a webhook, or a local dashboard. Agents pause before executing dangerous tools and wait for human approval via your chosen platform.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai.bots import SlackApproval

agent = Agent(
    name="assistant",
    instructions="Help users with system tasks",
    tools=["execute_command"],
    approval=SlackApproval(channel="#approvals"),
)
agent.start("Delete old log files")
```

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Agent calls dangerous tool"
        A[🔧 Tool Call] --> B{🔒 Approval<br/>Required?}
        B -->|No| E[✅ Execute]
        B -->|Yes| C{📱 Backend}
    end

    subgraph "Messaging Platforms"
        C --> S["💬 Slack<br/>Block Kit message"]
        C --> D["🎮 Discord<br/>Rich embed"]
        C --> T["✈️ Telegram<br/>Inline keyboard"]
        C --> W["🌐 Webhook / HTTP"]
    end

    S -->|"yes"| E
    D -->|"yes"| E
    T -->|"✅ Approve"| E
    W -->|approved| E

    classDef tool fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef check fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef result fill:#10B981,stroke:#7C90A0,color:#fff
    classDef platform fill:#189AB4,stroke:#7C90A0,color:#fff

    class A tool
    class B,C check
    class E result
    class S,D,T,W platform
```

## Quick Start

<Steps>
  <Step title="Pick a backend">
    Choose your approval channel. Each backend reads its token from an environment variable:

    | Backend      | Command               | Required Env Vars                         |
    | ------------ | --------------------- | ----------------------------------------- |
    | **Slack**    | `--approval slack`    | `SLACK_BOT_TOKEN`, `SLACK_CHANNEL`        |
    | **Discord**  | `--approval discord`  | `DISCORD_BOT_TOKEN`, `DISCORD_CHANNEL_ID` |
    | **Telegram** | `--approval telegram` | `TELEGRAM_BOT_TOKEN`, `TELEGRAM_CHAT_ID`  |
  </Step>

  <Step title="Set environment variables">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Slack
    export SLACK_BOT_TOKEN=xoxb-your-token
    export SLACK_CHANNEL=C0123456789  # or #channel-name

    # Discord
    export DISCORD_BOT_TOKEN=your-bot-token
    export DISCORD_CHANNEL_ID=123456789

    # Telegram
    export TELEGRAM_BOT_TOKEN=123456:ABC-DEF
    export TELEGRAM_CHAT_ID=your-chat-id
    ```
  </Step>

  <Step title="Run with --approval">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai "deploy to production" --approval slack

    praisonai "delete old logs" --approval discord

    praisonai "clean up temp files" --approval telegram
    ```
  </Step>
</Steps>

***

## CLI Commands

The `--approval` flag works with all CLI commands:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Direct prompt
praisonai "task" --approval slack

praisonai "task" --approval telegram

praisonai "task" --approval discord
```

### All CLI Approval Flags

| Flag                       | Description                                             | Example                 |
| -------------------------- | ------------------------------------------------------- | ----------------------- |
| `--approval <backend>`     | Route approvals to a platform                           | `--approval slack`      |
| `--trust`                  | Auto-approve all tools (skip prompts)                   | `--trust`               |
| `--approve-level <level>`  | Auto-approve up to a risk level                         | `--approve-level high`  |
| `--approve-all-tools`      | Require approval for all tools, not just dangerous ones | `--approve-all-tools`   |
| `--approval-timeout <sec>` | Override backend timeout                                | `--approval-timeout 60` |

### Available Backends

| Value      | What Happens                                | Env Vars                                  |
| ---------- | ------------------------------------------- | ----------------------------------------- |
| `console`  | Interactive terminal prompt (default)       | —                                         |
| `slack`    | Slack Block Kit message → reply "yes"/"no"  | `SLACK_BOT_TOKEN`, `SLACK_CHANNEL`        |
| `telegram` | Telegram inline keyboard buttons            | `TELEGRAM_BOT_TOKEN`, `TELEGRAM_CHAT_ID`  |
| `discord`  | Discord embed → text reply "yes"/"no"       | `DISCORD_BOT_TOKEN`, `DISCORD_CHANNEL_ID` |
| `webhook`  | POST to HTTP endpoint → poll for decision   | `APPROVAL_WEBHOOK_URL`                    |
| `http`     | Local web dashboard (browser)               | —                                         |
| `agent`    | Delegate to an AI reviewer agent            | —                                         |
| `auto`     | Auto-approve everything (same as `--trust`) | —                                         |
| `none`     | Disable approval entirely                   | —                                         |

***

## Programmatic Usage

<Tabs>
  <Tab title="Slack">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai.bots import SlackApproval

    agent = Agent(
        name="assistant",
        instructions="Help users with system tasks",
        tools=["execute_command"],
        approval=SlackApproval(channel="#approvals"),
    )
    agent.start("Delete old log files")
    ```

    The Slack bot token needs `chat:write` and `channels:history` (or `im:history` for DMs) scopes.

    | Parameter       | Default                              | Description                     |
    | --------------- | ------------------------------------ | ------------------------------- |
    | `token`         | `SLACK_BOT_TOKEN` env                | Slack bot token (`xoxb-...`)    |
    | `channel`       | `SLACK_CHANNEL` env, or bot's own DM | Channel ID, `#name`, or user ID |
    | `timeout`       | `300` (5 min)                        | Seconds to wait for response    |
    | `poll_interval` | `3.0`                                | Seconds between reply polls     |

    ```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    sequenceDiagram
        participant Agent
        participant SlackApproval
        participant Slack

        Agent->>SlackApproval: request_approval(tool, args)
        SlackApproval->>Slack: Post Block Kit message
        Note over Slack: 🔒 Tool Approval Required<br/>Tool: execute_command<br/>Reply yes/no
        Slack-->>SlackApproval: User replies "yes"
        SlackApproval->>Slack: Update message ✅ Approved
        SlackApproval-->>Agent: ApprovalDecision(approved=True)
    ```
  </Tab>

  <Tab title="Discord">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai.bots import DiscordApproval

    agent = Agent(
        name="assistant",
        instructions="Help users with system tasks",
        tools=["execute_command"],
        approval=DiscordApproval(channel_id="YOUR_CHANNEL_ID"),
    )
    agent.start("Delete old log files")
    ```

    | Parameter       | Default                 | Description                     |
    | --------------- | ----------------------- | ------------------------------- |
    | `token`         | `DISCORD_BOT_TOKEN` env | Discord bot token               |
    | `channel_id`    | *(required)*            | Channel ID to send approvals to |
    | `timeout`       | `300` (5 min)           | Seconds to wait for response    |
    | `poll_interval` | `3.0`                   | Seconds between polls           |
  </Tab>

  <Tab title="Telegram">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai.bots import TelegramApproval

    agent = Agent(
        name="assistant",
        instructions="Help users with system tasks",
        tools=["execute_command"],
        approval=TelegramApproval(chat_id="YOUR_CHAT_ID"),
    )
    agent.start("Delete old log files")
    ```

    | Parameter       | Default                  | Description                  |
    | --------------- | ------------------------ | ---------------------------- |
    | `token`         | `TELEGRAM_BOT_TOKEN` env | Telegram bot token           |
    | `chat_id`       | *(required)*             | Chat ID to send approvals to |
    | `timeout`       | `300` (5 min)            | Seconds to wait for response |
    | `poll_interval` | `2.0`                    | Seconds between polls        |

    ```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    sequenceDiagram
        participant Agent
        participant TelegramApproval
        participant Telegram

        Agent->>TelegramApproval: request_approval(tool, args)
        TelegramApproval->>Telegram: sendMessage + InlineKeyboard
        Note over Telegram: 🔒 Tool Approval Required<br/>✅ Approve  ❌ Deny
        Telegram-->>TelegramApproval: callback_query "approve"
        TelegramApproval->>Telegram: editMessageText ✅ Approved
        TelegramApproval-->>Agent: ApprovalDecision(approved=True)
    ```
  </Tab>

  <Tab title="Webhook">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai.bots import WebhookApproval

    agent = Agent(
        name="assistant",
        tools=["execute_command"],
        approval=WebhookApproval(
            webhook_url="https://your-app.com/api/approvals",
            headers={"Authorization": "Bearer sk-xxx"},
        ),
    )
    ```

    | Parameter       | Default                    | Description                    |
    | --------------- | -------------------------- | ------------------------------ |
    | `webhook_url`   | `APPROVAL_WEBHOOK_URL` env | URL to POST requests to        |
    | `status_url`    | `webhook_url/{request_id}` | URL template for polling       |
    | `headers`       | `{}`                       | Extra HTTP headers (e.g. auth) |
    | `timeout`       | `300` (5 min)              | Seconds to wait                |
    | `poll_interval` | `5.0`                      | Seconds between polls          |
  </Tab>

  <Tab title="HTTP Dashboard">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai.bots import HTTPApproval

    agent = Agent(
        name="assistant",
        tools=["execute_command"],
        approval=HTTPApproval(host="127.0.0.1", port=8899),
    )
    # Open http://127.0.0.1:8899/approve/<request_id> in your browser
    ```

    | Parameter | Default       | Description                  |
    | --------- | ------------- | ---------------------------- |
    | `host`    | `127.0.0.1`   | Bind address                 |
    | `port`    | `8899`        | Port to listen on            |
    | `timeout` | `300` (5 min) | Seconds to wait for response |
  </Tab>

  <Tab title="Agent">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonaiagents.approval import AgentApproval

    reviewer = Agent(
        name="security-reviewer",
        instructions="Only approve low-risk read operations. Deny anything destructive.",
    )

    worker = Agent(
        name="assistant",
        tools=["execute_command"],
        approval=AgentApproval(approver_agent=reviewer),
    )
    ```

    | Parameter        | Default       | Description                         |
    | ---------------- | ------------- | ----------------------------------- |
    | `approver_agent` | Auto-created  | Agent instance to evaluate requests |
    | `llm`            | `gpt-4o-mini` | LLM for default approver agent      |
  </Tab>
</Tabs>

***

## Approval Keywords

All messaging backends (Slack, Discord, Telegram) understand these keywords:

| Action      | Keywords                                                   |
| ----------- | ---------------------------------------------------------- |
| **Approve** | yes, y, approve, approved, ok, allow, go, proceed, confirm |
| **Deny**    | no, n, deny, denied, reject, block, stop, cancel, refuse   |

<Tip>
  Users can reply with richer text like *"yes, but change the path to \~/Downloads"*. The backend uses an LLM to classify intent and extract **modified arguments** — the tool runs with the updated values.
</Tip>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant Agent
    participant Backend
    participant Registry

    Agent->>Agent: Check self._approval_backend
    alt Agent has approval backend
        Agent->>Backend: request_approval(ApprovalRequest)
        Backend-->>Agent: ApprovalDecision
    else No agent backend (fallback)
        Agent->>Registry: approve_sync(agent_name, tool, args)
        Registry->>Registry: Check: required? env? yaml? already?
        alt Fast path
            Registry-->>Agent: ApprovalDecision(approved=True)
        else Needs backend
            Registry->>Backend: request_approval(ApprovalRequest)
            Backend-->>Registry: ApprovalDecision
            Registry-->>Agent: ApprovalDecision
        end
    end
```

| Step                 | What Happens                                                    |
| -------------------- | --------------------------------------------------------------- |
| **Agent backend**    | `approval=True` or custom backend on the Agent is checked first |
| **Required?**        | Only tools in the dangerous-tools set need approval             |
| **Env check**        | `PRAISONAI_AUTO_APPROVE=true` skips all prompts                 |
| **YAML check**       | Tools listed in YAML `approve` field are auto-approved          |
| **Already approved** | Once approved in a session, no re-prompt                        |
| **Backend**          | ConsoleBackend (default), AutoApproveBackend, or your custom    |

***

## Configuration Options

### Agent Parameter (Recommended)

| Value                            | Behavior                                        |
| -------------------------------- | ----------------------------------------------- |
| `approval=True`                  | Auto-approve all dangerous tools for this agent |
| `approval=False` / `None`        | Use registry fallback (default: console prompt) |
| `approval=SlackApproval(...)`    | Route approvals to Slack                        |
| `approval=TelegramApproval(...)` | Route approvals to Telegram                     |
| `approval=DiscordApproval(...)`  | Route approvals to Discord                      |

### Other Methods

| Method                                                         | Scope        | Use Case               |
| -------------------------------------------------------------- | ------------ | ---------------------- |
| `PRAISONAI_AUTO_APPROVE=true`                                  | All agents   | CI/CD, testing         |
| `get_approval_registry().set_backend(backend)`                 | All agents   | Global policy          |
| `get_approval_registry().set_backend(backend, agent_name="x")` | Single agent | Registry-level control |
| YAML `approve: [tool1, tool2]`                                 | Per-task     | Declarative configs    |

***

## Multi-Agent Example

Different agents can have different approval policies:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonaiagents.approval import AgentApproval
from praisonai.bots import SlackApproval, TelegramApproval

# Bot agent: auto-approve everything
bot = Agent(name="bot", approval=True)

# Interactive: console prompt (default)
interactive = Agent(name="interactive")

# Critical ops: approved via Slack
deployer = Agent(
    name="deployer",
    approval=SlackApproval(channel="#deploy-approvals"),
)

# Data ops: approved via Telegram
data_agent = Agent(
    name="data-processor",
    approval=TelegramApproval(chat_id="123456"),
)

# AI-reviewed: no human needed
reviewer = Agent(name="reviewer", instructions="Only approve safe read operations")
ai_agent = Agent(name="ai-reviewed", approval=AgentApproval(approver_agent=reviewer))
```

***

## Dangerous Tools (Default)

These tools require approval by default:

| Tool              | Risk Level |
| ----------------- | ---------- |
| `execute_command` | critical   |
| `kill_process`    | critical   |
| `execute_code`    | critical   |
| `write_file`      | high       |
| `delete_file`     | high       |
| `move_file`       | high       |
| `execute_query`   | high       |
| `crawl`           | medium     |
| `scrape_page`     | medium     |

Add or remove requirements:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.approval import get_approval_registry

registry = get_approval_registry()
registry.add_requirement("my_dangerous_tool", risk_level="high")
registry.remove_requirement("crawl")
```

***

## Best Practices

<AccordionGroup>
  <Accordion title="Use approval=True for bot agents">
    Set `approval=True` directly on agent constructors for unattended bots. This is the simplest, most agent-centric approach.
  </Accordion>

  <Accordion title="Use --approval slack for team oversight">
    Route dangerous tool approvals to a shared Slack channel so your team can review and approve in real time. Works across timezones — the agent waits up to 5 minutes by default.
  </Accordion>

  <Accordion title="Cross-platform: Telegram bot → Slack approval">
    Users can chat with your agent via Telegram while dangerous tool approvals are routed to a Slack admin channel. Just set `approval=SlackApproval(...)` on the agent powering the Telegram bot.
  </Accordion>

  <Accordion title="Use environment variable for CI/CD">
    Set `PRAISONAI_AUTO_APPROVE=true` in your CI environment to avoid blocking on prompts during automated testing.
  </Accordion>

  <Accordion title="Use per-agent backends for multi-agent systems">
    Different agents may need different approval policies. Pass different backends to each agent's `approval=` parameter.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Approval Protocol" icon="shield-check" href="/features/approval-protocol">
    Full protocol reference, custom backend interface, and registry API
  </Card>

  <Card title="CLI Tool Approval" icon="terminal" href="/cli/tool-approval">
    `--trust`, `--approve-level`, and `--approval` CLI flags
  </Card>

  <Card title="Messaging Bots" icon="robot" href="/features/messaging-bots">
    Telegram, Discord, Slack, WhatsApp bots
  </Card>

  <Card title="Tools" icon="wrench" href="/tools/tools">
    Built-in tools reference
  </Card>
</CardGroup>
