> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/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.

<Info>
  **This page covers tool approval** — asking a human before running dangerous tools such as `execute_command` or `delete_file`. **Plan approval** (used by `planning=True`) is a separate system; see [Planning › Non-interactive environments](/docs/concepts/planning#non-interactive-environments).
</Info>

```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="/docs/features/approval-protocol">
    Full protocol reference, custom backend interface, and registry API
  </Card>

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

  <Card title="Planning" icon="list-check" href="/docs/concepts/planning">
    Plan approval and non-interactive auto-approve
  </Card>

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

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


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.