Agent approval queue
What it is
Section titled “What it is”When a vf_ak_* agent key submits a high-risk write (such as creating a campaign or deleting a webhook), the action is held for operator review rather than executing immediately. The agent receives 202 Accepted with an approval ID and must poll or subscribe to a webhook to learn the outcome.
MCP write tools that route to this queue by default: create_voucher (count > 100), create_campaign, update_campaign, create_webhook, and delete_webhook. See the MCP server tool table for the full list with per-tool dispositions and required scopes.
Secret key (vf_sk_*) calls bypass the queue entirely — they are treated as human-initiated server traffic and execute immediately.
Example response when approval is required:
{ "approvalId": "d4e5f6a7-...", "status": "pending_approval", "expiresAt": "2026-05-02T14:30:00Z"}Default policy
Section titled “Default policy”| Action | Default mode |
|---|---|
create_voucher (single) | auto-execute |
create_voucher (count > 100) | pending-approval |
create_campaign | pending-approval |
update_campaign | pending-approval |
create_webhook | pending-approval |
delete_webhook | pending-approval |
redeem_voucher | auto-execute |
any write via vf_sk_* | auto-execute (always) |
Per-tenant policy override
Section titled “Per-tenant policy override”Operators can override the default policy via the dashboard (Settings → Security → Agent Approval Policy) or by directly updating tenants.agent_approval_policy in the database. See your operator-only Agent Approval Queue runbook (internal docs) for the full policy schema and override examples.
Lifecycle
Section titled “Lifecycle”Approval entries progress through the following states:
| Status | Meaning |
|---|---|
pending_approval | Awaiting operator decision |
approved | Operator approved; replay in progress |
executed | Action ran successfully. executionResult contains the created entity. |
rejected | Operator rejected. Action will not execute. Rejection is final. |
expired | TTL elapsed (default 15 minutes) before operator acted. Action will not execute. |
Default TTL is 15 minutes. Entries past their expiresAt are swept automatically every 5 minutes.
Audit trail
Section titled “Audit trail”Subscribe to these webhook events to receive push notifications instead of polling:
| Event | When |
|---|---|
agent.action.pending_approval | Entry created; awaiting operator review |
agent.action.approved | Operator approved the entry |
agent.action.executed | Replayed action completed successfully |
agent.action.rejected | Operator rejected the entry |
agent.action.expired | TTL elapsed without a decision |
The agent.action.pending_approval payload includes a request_body_summary structured digest — the full raw request body is never included in events or API responses (PII guard).
Polling pattern
Section titled “Polling pattern”Auth model
- The originating agent key (
vf_ak_*) can pollGET /v1/agent-approvals/{id}to check its own action’s status. - The list endpoint (
GET /v1/agent-approvals) and the approve/reject endpoints are operator-only — they require a secret key (vf_sk_*) or a dashboard session with OWNER, ADMIN, or DEVELOPER role (DEVELOPER is read-only; approve/reject require OWNER or ADMIN). Agent keys receive403 Forbiddenon the list endpoint and404on a mismatched entry (anti-enumeration). - For agent-side notification of state changes, prefer subscribing to the
agent.action.*webhook events instead of polling the list endpoint.
Poll the approval entry with your agent key until the status is terminal (executed, rejected, or expired):
curl https://api.vauchflow.com/v1/agent-approvals/d4e5f6a7-... \ -H "X-API-Key: vf_ak_your-agent-key"Response when the action has executed:
{ "approvalId": "d4e5f6a7-...", "status": "EXECUTED", "executionResult": { "id": "cmp_01HX...", "name": "Summer Sale", "status": "ACTIVE" }}See API reference — Agent approvals for the full endpoint table including approve and reject calls.
See also: AI agents overview · Webhooks