# Approvals

> Implement human-in-the-loop workflows with configurable approval checkpoints, webhook notifications, and approve/reject decisions.

Source: https://0.0.0.0:8080/docs/approvals

The approval system enables human-in-the-loop workflows where agent executions pause at configurable checkpoints and wait for human approval before continuing. This is essential for high-stakes operations where automated decisions need human oversight.

## Human-in-the-Loop Overview

When an agent has approval enabled, the execution flow becomes:

```
Input -> Agent Execution -> Checkpoint -> PAUSE (awaiting_approval)
                                            |
                              Human reviews execution
                                            |
                              Approve -> Continue -> Output
                              Reject  -> Execution marked as rejected
```

This ensures that critical actions (financial transactions, customer communications, data modifications) are reviewed by a human before taking effect.

## Enabling Approvals on Agents

Enable approvals in the agent version configuration:

```python
client.agents.create_version(
    agent_id="your-agent-id",
    config={
        "approval_required": True,
        "checkpoint_name": "review_response",
        "temperature": 0.7
    },
    message="Added approval requirement for customer responses"
)
```

| Config Field        | Description                                                                            |
| ------------------- | -------------------------------------------------------------------------------------- |
| `approval_required` | Set to `true` to enable the approval checkpoint                                        |
| `checkpoint_name`   | A descriptive name for the checkpoint (e.g., "review_response", "approve_transaction") |

## Approval Request Flow

### 1. Execution Reaches Checkpoint

When an agent with approvals enabled completes its LLM processing, instead of returning the result, it:

1. Creates an `ApprovalRequest` record
2. Sets the execution status to `awaiting_approval`
3. Fires a webhook event (`execution.awaiting_approval`)

### 2. Human Reviews

The approval request is visible in:

- The PromptRails dashboard (Approvals page)
- Via the API (`approvals:read` scope)
- Via webhook notifications

The reviewer can see:

- The agent that generated the output
- The execution input and output
- The checkpoint name
- When the request was created
- Optional expiration time

### 3. Decision

The reviewer approves or rejects:

```python
# Approve
client.approvals.decide(
    approval_id="approval-request-id",
    decision="approved",
    reason="Response looks accurate and appropriate"
)

# Reject
client.approvals.decide(
    approval_id="approval-request-id",
    decision="rejected",
    reason="Response contains inaccurate pricing information"
)
```

### 4. Execution Continues or Stops

- **Approved**: Execution status changes to `completed` and the output is delivered
- **Rejected**: Execution status changes to `rejected` and the output is discarded

## Approval Statuses

| Status     | Description                                             |
| ---------- | ------------------------------------------------------- |
| `pending`  | Awaiting human review                                   |
| `approved` | Approved by a reviewer                                  |
| `rejected` | Rejected by a reviewer                                  |
| `expired`  | The approval request expired before a decision was made |

## Listing Approval Requests

```python
# List pending approvals
approvals = client.approvals.list(status="pending")

for approval in approvals["data"]:
    print(f"ID: {approval['id']}")
    print(f"Agent: {approval['agent_id']}")
    print(f"Checkpoint: {approval['checkpoint_name']}")
    print(f"Created: {approval['created_at']}")
    print(f"Payload: {approval['payload']}")
    print("---")
```

**JavaScript SDK**

```typescript
const approvals = await client.approvals.list({ status: 'pending' })

for (const approval of approvals.data) {
  console.log(`${approval.checkpoint_name} - ${approval.created_at}`)
}
```

## Webhook Notifications

When an approval request is created or decided, webhook events are fired:

| Event                         | Description                          |
| ----------------------------- | ------------------------------------ |
| `execution.awaiting_approval` | An execution is waiting for approval |
| `approval.decided`            | An approval was approved or rejected |

These events can be used to notify reviewers via Slack, email, or other channels.

## Approval Request Fields

| Field             | Type      | Description                                  |
| ----------------- | --------- | -------------------------------------------- |
| `id`              | KSUID     | Unique approval request ID                   |
| `execution_id`    | KSUID     | The paused execution                         |
| `agent_id`        | KSUID     | The agent that generated the output          |
| `workspace_id`    | KSUID     | Workspace scope                              |
| `checkpoint_name` | string    | Name of the approval checkpoint              |
| `payload`         | JSON      | The execution output pending approval        |
| `status`          | string    | `pending`, `approved`, `rejected`, `expired` |
| `decided_by`      | KSUID     | User who made the decision                   |
| `decided_at`      | timestamp | When the decision was made                   |
| `expires_at`      | timestamp | Optional expiration time                     |
| `reason`          | string    | Optional reason for the decision             |
| `created_at`      | timestamp | When the request was created                 |

## Best Practices

- **Name checkpoints clearly** -- Use descriptive names like "review_customer_email" or "approve_refund" so reviewers understand what they are reviewing
- **Set expiration times** -- For time-sensitive operations, set an expiration to prevent stale approvals from blocking the pipeline
- **Monitor pending approvals** -- Set up webhook notifications to alert reviewers of new approval requests
- **Include context in payload** -- Ensure the approval payload includes enough information for the reviewer to make an informed decision
- **Document rejection reasons** -- Always provide a reason when rejecting to help improve the agent

## Related Topics

- [Agents](/docs/agents) -- Configuring agents with approval checkpoints
- [Executions](/docs/executions) -- Execution status integration
- [Webhook Triggers](/docs/webhook-triggers) -- Webhook-triggered executions with approvals
