Human-in-the-Loop
By default, runs are autonomous. Turn on human in the loop when you want checkpoints before the agent continues.
This guide covers AskUserQuestion, tool approval, and plan mode in one place.
Quick start
AskUserQuestion
AskUserQuestion answers always go through runs.answer().
Behavior
- If the run is
running, your answer is stored and picked up by the active run. - If the run is
awaiting_approval, your answer resumes the run. - If the run is terminal (
completed,failed,cancelled),runs.answer()returns409.
Submit an answer
Find pending AskUserQuestion requests
runs.permissions() can include AskUserQuestion entries. Look for:
req.tool_name == "AskUserQuestion"- question payload in
req.tool_input["questions"]
Permission modes
Use human_in_the_loop=True with approval or plan. Without it, those modes return a validation error.
Approve or deny tool calls
Use runs.permissions() to fetch pending requests, then runs.approve().
remember=true applies to subsequent matching requests in the current run. For persistent cross-run policies, use client.permissions.create().
Plan mode
Plan mode uses AskUserQuestion with a Plan Approval question before execution.
After plan approval, execution continues with approval-style checks for non-safe tools.
Pre-approve trusted tools
Create per-user permission policies so trusted tools skip approval pauses.
Now runs for cust_123 in approval mode skip pauses for those tools.
Important reply behavior
runs.reply() always runs as non-interactive. It does not enable AskUserQuestion, approval mode, or plan mode.
Build this with webhooks
For production, prefer webhooks over polling:
- Subscribe to
run.awaiting_input - Load pending questions and permissions
- Show them in your UI
- Send decisions back with
answerorapprove
See Webhook Events for payloads and signature verification.
