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

# Approval Team

> Three patterns for team approvals: tool on the team, on the member, or on both.

An `@approval` tool can live on the team, on a member agent, or on both. Each placement produces a different pause flow.

| Case         | Placement       | Pause behavior                                                     |
| ------------ | --------------- | ------------------------------------------------------------------ |
| Team-level   | Team            | One pause when the team calls the tool.                            |
| Member-level | Member agent    | One pause when the member calls the tool. The team pauses with it. |
| Both         | Team and member | Two pauses, two separate admin approvals.                          |

<Tabs>
  <Tab title="Team-level (Case 1)">
    ```python team_level_approval.py theme={null}
    """
    Team-Level Approval (Case 1)
    =============================

    Approval tool lives on the team itself (not on a member agent).

    Flow:
      1. User says "deploy payment to prod v2.5"
      2. Team calls approve_deployment -> run pauses
      3. Admin approves in Approvals page
      4. User clicks Continue Run -> tool executes -> team responds
    """

    from agno.approval import approval
    from agno.db.sqlite import SqliteDb
    from agno.models.openai import OpenAIResponses
    from agno.os import AgentOS
    from agno.team import Team
    from agno.tools import tool

    DB_FILE = "tmp/team_level_approval.db"

    session_db = SqliteDb(
        db_file=DB_FILE, session_table="agent_sessions", approvals_table="approvals"
    )


    @approval(type="required")
    @tool(
        name="approve_deployment",
        description="Request human approval to deploy a service.",
        requires_confirmation=True,
    )
    def approve_deployment(service: str, environment: str, version: str) -> str:
        return (
            f"Deployment approved for service={service}, "
            f"environment={environment}, version={version}"
        )


    approval_team = Team(
        id="team-level-approval",
        name="Deployment Approval Team",
        model=OpenAIResponses(id="gpt-5-mini"),
        members=[],
        tools=[approve_deployment],
        instructions=[
            "When the user asks to deploy, call approve_deployment with the service, environment, and version they provide.",
            "Do not ask for extra confirmation in chat. Just call the tool.",
        ],
        add_history_to_context=True,
        store_member_responses=True,
        db=session_db,
        telemetry=False,
    )

    agent_os = AgentOS(
        id="team-level-approval-demo",
        description="Team-level approval: the team has a tool that requires admin approval before executing",
        teams=[approval_team],
        db=session_db,
    )

    app = agent_os.get_app()

    if __name__ == "__main__":
        agent_os.serve(app="team_level_approval:app", port=7777, reload=True)
    ```

    ### Run the Example

    ```bash theme={null}
    # Clone and setup repo
    git clone https://github.com/agno-agi/agno.git
    cd agno/cookbook/02_agents/11_approvals

    # Create and activate virtual environment
    ./scripts/demo_setup.sh
    source .venvs/demo/bin/activate

    python team_level_approval.py
    ```
  </Tab>

  <Tab title="Member-level (Case 2)">
    ```python member_agent_level_approval.py theme={null}
    """
    Member-Level Approval (Case 2)
    ===============================

    Approval tool lives on the member agent. The team has no approval tools.

    Flow:
      1. User says "deploy services"
      2. Team delegates to Deployment Spec Collector member
      3. Member calls collect_deployment_specs -> member pauses -> team pauses
      4. User fills in the form fields (service, environment, version)
      5. Admin approves in Approvals page
      6. User clicks Continue Run -> member tool executes -> member returns result -> team responds
    """

    from typing import Optional

    from agno.agent import Agent
    from agno.approval import approval
    from agno.db.sqlite import SqliteDb
    from agno.models.openai import OpenAIResponses
    from agno.os import AgentOS
    from agno.team import Team
    from agno.tools import tool

    DB_FILE = "tmp/member_level_approval.db"

    session_db = SqliteDb(
        db_file=DB_FILE, session_table="agent_sessions", approvals_table="approvals"
    )


    @approval(type="required")
    @tool(
        name="collect_deployment_specs",
        description="Collect deployment fields from the user via a form.",
        requires_user_input=True,
        user_input_fields=["service", "environment", "version"],
    )
    def collect_deployment_specs(
        service: Optional[str] = None,
        environment: Optional[str] = None,
        version: Optional[str] = None,
    ) -> str:
        return (
            f"Deployment specs collected: "
            f"service={service}, environment={environment}, version={version}"
        )


    spec_collector = Agent(
        name="Deployment Spec Collector",
        model=OpenAIResponses(id="gpt-5-mini"),
        tools=[collect_deployment_specs],
        instructions=[
            "Call collect_deployment_specs to gather deployment details from the user.",
            "Always call it even if the user provided some values. Pass known values and None for missing ones.",
            "After the tool returns, output only the final values in one short line.",
        ],
        telemetry=False,
    )

    approval_team = Team(
        id="member-level-approval",
        name="Deployment Team",
        model=OpenAIResponses(id="gpt-5-mini"),
        members=[spec_collector],
        tools=[],
        instructions=[
            "Delegate to Deployment Spec Collector to gather deployment specs from the user.",
            "After the member returns, summarize the collected values.",
        ],
        add_history_to_context=True,
        store_member_responses=True,
        db=session_db,
        telemetry=False,
    )

    agent_os = AgentOS(
        id="member-level-approval-demo",
        description="Member-level approval: a member agent has a tool that requires admin approval",
        agents=[spec_collector],
        teams=[approval_team],
        db=session_db,
    )

    app = agent_os.get_app()

    if __name__ == "__main__":
        agent_os.serve(app="member_agent_level_approval:app", port=7777, reload=True)
    ```

    ### Run the Example

    ```bash theme={null}
    # Clone and setup repo
    git clone https://github.com/agno-agi/agno.git
    cd agno/cookbook/02_agents/11_approvals

    # Create and activate virtual environment
    ./scripts/demo_setup.sh
    source .venvs/demo/bin/activate

    python member_agent_level_approval.py
    ```
  </Tab>

  <Tab title="Team + Member (Case 3)">
    ```python team_and_member_agent_both_level_approval.py theme={null}
    """
    Both Member + Team Level Approval (Case 3)
    ============================================

    Approval tools on both the member agent AND the team.
    This creates a two-pause flow with two separate admin approvals.

    Flow:
      1. User says "deploy services"
      2. Team delegates to Deployment Spec Collector member
      3. Member calls collect_deployment_specs -> member pauses -> team pauses (PAUSE 1)
      4. User fills in the form, admin approves
      5. User clicks Continue Run -> member tool executes -> member returns values to team
      6. Team calls approve_deployment with the collected values -> team pauses (PAUSE 2)
      7. Admin approves in Approvals page
      8. User clicks Continue Run -> team tool executes -> team responds with final result
    """

    from typing import Optional

    from agno.agent import Agent
    from agno.approval import approval
    from agno.db.sqlite import SqliteDb
    from agno.models.openai import OpenAIResponses
    from agno.os import AgentOS
    from agno.team import Team
    from agno.tools import tool

    DB_FILE = "tmp/both_level_approval.db"

    session_db = SqliteDb(
        db_file=DB_FILE, session_table="agent_sessions", approvals_table="approvals"
    )


    # --- Member agent tool: collects deployment specs via user input form ---


    @approval(type="required")
    @tool(
        name="collect_deployment_specs",
        description="Collect deployment fields from the user via a form.",
        requires_user_input=True,
        user_input_fields=["service", "environment", "version"],
    )
    def collect_deployment_specs(
        service: Optional[str] = None,
        environment: Optional[str] = None,
        version: Optional[str] = None,
    ) -> str:
        return (
            f"Deployment specs collected: "
            f"service={service}, environment={environment}, version={version}"
        )


    # --- Team tool: requires confirmation before deploying ---


    @approval(type="required")
    @tool(
        name="approve_deployment",
        description="Request human approval to deploy a service. Call after collecting specs from the member.",
        requires_confirmation=True,
    )
    def approve_deployment(service: str, environment: str, version: str) -> str:
        return (
            f"Deployment approved for service={service}, "
            f"environment={environment}, version={version}"
        )


    spec_collector = Agent(
        name="Deployment Spec Collector",
        model=OpenAIResponses(id="gpt-5-mini"),
        tools=[collect_deployment_specs],
        instructions=[
            "Call collect_deployment_specs to gather deployment details from the user.",
            "Always call it even if the user provided some values. Pass known values and None for missing ones.",
            "After the tool returns, output only the final values in one short line.",
        ],
        telemetry=False,
    )

    approval_team = Team(
        id="both-level-approval",
        name="Deployment Approval Team",
        model=OpenAIResponses(id="gpt-5-mini"),
        members=[spec_collector],
        tools=[approve_deployment],
        instructions=[
            "Delegate to Deployment Spec Collector first to gather specs via its form.",
            "Once the member returns service, environment, and version, call approve_deployment immediately.",
            "Do not ask for extra confirmation in chat. Use the tools.",
        ],
        add_history_to_context=True,
        store_member_responses=True,
        db=session_db,
        telemetry=False,
    )

    agent_os = AgentOS(
        id="both-level-approval-demo",
        description="Both-level approval: member collects specs (approval 1), team approves deployment (approval 2)",
        agents=[spec_collector],
        teams=[approval_team],
        db=session_db,
    )

    app = agent_os.get_app()

    if __name__ == "__main__":
        agent_os.serve(
            app="team_and_member_agent_both_level_approval:app", port=7777, reload=True
        )
    ```

    ### Run the Example

    ```bash theme={null}
    # Clone and setup repo
    git clone https://github.com/agno-agi/agno.git
    cd agno/cookbook/02_agents/11_approvals

    # Create and activate virtual environment
    ./scripts/demo_setup.sh
    source .venvs/demo/bin/activate

    python team_and_member_agent_both_level_approval.py
    ```
  </Tab>
</Tabs>
