Approvals
Implement human-in-the-loop workflows with configurable approval checkpoints, webhook notifications, and approve/reject decisions.
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:
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:
- Creates an
ApprovalRequestrecord - Sets the execution status to
awaiting_approval - 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:readscope) - 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:
# 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
completedand the output is delivered - Rejected: Execution status changes to
rejectedand 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
# 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
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 -- Configuring agents with approval checkpoints
- Executions -- Execution status integration
- Webhook Triggers -- Webhook-triggered executions with approvals