Skip to main content

Pending Actions API: Human Approval Workflows

Use GET /api/v1/agents/{id}/pending-actions/ to find decisions that are blocking or awaiting human input. The response is {"actions": [...], "count": n}. Listing requires agents:read; action visibility also depends on the acting user's permissions.

Every action has id, type, status, created_at, expires_at, data, and allowed_decisions. The ID is a typed string such as human_input:<uuid>, not a bare UUID. Use the exact returned ID in:

POST /api/v1/agents/{id}/pending-actions/{actionId}/resolve/

On agents with application history, both listing and resolution responses require the complete history to be retained and readable by the credential's submission principal under current ownership. Otherwise they return 403 application_request_scope_required before action data, counts, or mutations. This applies to every action type, including approval previews and Outbox content. Management scope and inspect=true do not implicitly inspect another credential's input. Use the application request routes for scoped observations and explicit administrative inspection. Console human decisions retain their existing permissions.

Decision contracts​

TypeDecisionsAdditional inputRequired scope
human_inputanswer, dismissFor answers use selected_option_key and/or free_text as allowed by the request. continue_without_answer controls dismissal behavior.agents:operate
outbox_reviewapprove, discardversion from data.version is required for both decisions.agents:operate
spawn_requestapprove, declineOn approval, supply name when data.agent_naming_mode is required; optional otherwise. Inspect requested charter and handoff first. Declining needs no name.agents:manage
requested_secretprovide, removeprovide requires value; this field is write-only.agents:manage
contact_requestapprove, declineOptional allow_inbound, allow_outbound, can_configure.agents:manage
openapi_approvalapprove, declineDecision only; inspect integration, operation, and argument preview.agents:manage

Use allowed_decisions rather than deriving decisions from a display label. Unknown or malformed action types require manage scope and cannot be assumed to support any existing decision shape.

Example human-input response:

{
"decision": "answer",
"selected_option_key": "stable"
}

Example outbox approval:

{"decision": "approve", "version": 3}

Example specialist approval:

{"decision": "approve", "name": "Finance Review"}

The current Organization naming policy is enforced when approving, even if the request predates the policy change. A missing required name returns 400 and leaves the request pending so it can be retried with a name.

Successful resolution returns {"action": {...}}. A terminal action has an empty allowed_decisions array. Action data varies by type: human input includes question and options; secrets include credential names and domain scope without values; contact requests include channel and permissions; outbox reviews include recipients, subject, bodies, attachment metadata, and version; OpenAPI approvals include method, path, tool, integration, and previewed arguments.

Conflicts and asynchronous effects​

400 indicates invalid decision fields, 404 indicates an inaccessible or missing action, and 409 indicates a state conflict. In particular, approving an outbox version that has changed returns 409; fetch and review the replacement content before deciding again.

Resolution can resume processing, create an agent, save a credential, grant communication access, or approve an external write. A successful resolution is not confirmation that all resulting asynchronous work finished. Follow the agent timeline and the relevant operation's result.

Without Idempotency-Key, list actions and reconcile state after a timeout before deciding whether to resubmit. Different action types have different repeat behavior. Protected member-key replay is available when extended retry admission is enabled, as described below.

Event-driven review queues​

Subscribe to agent.pending_action.created, .resolved, .expired, or agent.pending_action.* through the agent's outbound webhook collection. Validate signatures and deduplicate event IDs as described in Webhooks and events. Fetch current pending actions before presenting or resolving a decision; delivery can be delayed or repeated, and an event's snapshot can be stale.

Reconcile a decision after response loss​

Gated member-key Idempotency-Key support retains the accepted resolution, including its action ID, decision and supplied Outbox version. Retry exactly that request; changed decisions/versions conflict. Current operation scope and type-specific human authority are checked again, including current OpenAPI approver membership. Service credentials cannot resolve pending actions. A new key racing another decision receives the existing type-specific terminal/stale result rather than a fabricated unresolved action. Operation-Id supports content-free authorized outcome lookup until expiry; requested-secret plaintext is excluded from generic metadata and responses. Decision replay is historical resolution and does not prove downstream send/execution. See Idempotency and retries.