Human-in-the-Loop (HITL)
Some intents are low risk → agent executes immediately. Some are high risk → agent must obtain fresh user approval.
Flow
- Agent requests high-risk intent (e.g. payments.refund) with AAP assertion.
- Server verifies signature + delegation, sees intent requires approval.
- Server returns HTTP 403 with
decision: "CHALLENGE"andapprovalId. - User is notified and approves/denies (channel chosen by app: push, email, TOTP).
- User approval creates a short-lived approval token bound to the exact action.
- Agent retries within TTL with
X-AAP-Approvalheader. - Server verifies token and allows the action.
The approval page and channel are designed by the app, not the agent. The app owns the user's MFA/approval preference (push, email, TOTP, SMS, etc.) — similar to how 2FA methods are configured. The agent only triggers the flow; the app decides how to surface it.
CHALLENGE Response
{
"decision": "CHALLENGE",
"reason": "HITL_REQUIRED",
"approvalId": "apr_92fd...",
"expiresInSec": 600,
"methods": ["push", "email", "totp"],
"message": "Approve refund of $120 to Vendor X?"
}Approval Endpoints
GET /aap/v1/approvals/:id— Poll status (PENDING / APPROVED / DENIED)POST /aap/v1/approvals/:id/approve— User approves → returns approvalToken
Agent retries with header: X-AAP-Approval: apv1=<token>
Policy Config
{
"intents": {
"workorders.create": { "hitl": "never" },
"payments.refund": { "hitl": "always", "ttlSec": 600 }
}
}Create agent → Register → Click "Refund (HITL)" → Open Approve page → Click Approve → Retry with approval.