Approvals
When a Model B execution request triggers step-up approval (based on the policy's stepUpApproval setting or a policy rule action), the request is paused and an approval request is created. A human reviewer can then approve or deny the request.
How Approvals Work
- An agent sends a Model B execution request (e.g.,
POSTto send an email) - The policy engine determines approval is required (based on
stepUpApprovalmode or a custom rule withrequire_approvalaction) - The execution gateway returns
202with anapprovalRequestId - The approval appears in the dashboard for workspace members to review
- A reviewer approves or denies the request
- If approved, the original HTTP request is executed and the result is returned
Approval requests expire after 5 minutes. Expired requests cannot be approved.
Step-Up Approval Modes
The stepUpApproval field on a policy controls when approval is triggered:
| Mode | Behavior |
|---|---|
always | Every request requires approval |
risk_based | Write methods (POST, PUT, PATCH, DELETE) require approval; reads pass through |
never | No approval required |
Custom policy rules can override these modes. A rule action of require_approval forces approval regardless of the mode, and a rule action of allow skips approval even for write methods.
Endpoint Summary
| Method | Endpoint | Description |
|---|---|---|
GET | /v1/approvals | List approval requests |
GET | /v1/approvals/:id | Get approval details |
POST | /v1/approvals/:id/approve | Approve and execute |
POST | /v1/approvals/:id/deny | Deny the request |
List Approval Requests
GET /v1/approvals
Returns all approval requests for the current workspace, including pending, approved, denied, and expired. Stale pending requests are auto-expired on each query.
Response:
{
"approvals": [
{
"id": "uuid",
"policyId": "uuid",
"agentId": "uuid",
"connectionId": "uuid",
"actor": "user-id",
"status": "pending",
"requestDetails": {
"method": "POST",
"url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/send",
"body": { "raw": "..." },
"emailMetadata": { "to": "user@example.com", "subject": "Hello" }
},
"expiresAt": "2025-06-01T00:05:00Z",
"createdAt": "2025-06-01T00:00:00Z",
"agentName": "Email Agent",
"connectionLabel": "Gmail - Work",
"connectionProvider": "google"
}
]
}
Approval statuses: pending, approved, denied, expired
The requestDetails object contains the original Model B request parameters (method, URL, headers, body) plus provider-specific metadata when available:
- Gmail:
emailMetadatawithto,cc,bcc,subjectfields - Telegram:
telegramMetadatawithchatId,textfields - Teams:
teamsMetadatawithchatId,channelId,teamId,contentType,contentfields
Get Approval Details
GET /v1/approvals/:id
Returns full details for a single approval request.
Approve Request
POST /v1/approvals/:id/approve
Approves a pending approval request. The original Model B request is executed immediately and the provider response is returned.
Response (200) -- same shape as a Model B execution response:
{
"model": "B",
"status": 200,
"headers": { "content-type": "application/json" },
"body": { ... },
"auditId": "uuid"
}
| Status | Description |
|---|---|
200 | Approved and executed successfully |
404 | Approval request not found |
409 | Already approved, denied, or connection revoked |
410 | Approval request has expired |
Deny Request
POST /v1/approvals/:id/deny
Denies a pending approval request. The original action is not executed.
Response:
{
"denied": true,
"approvalRequestId": "uuid",
"auditId": "uuid"
}
| Status | Description |
|---|---|
200 | Successfully denied |
404 | Approval request not found |
409 | Already approved or denied |
410 | Approval request has expired |