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
Use runs.wait() with callbacks to handle approval pauses inline — no manual polling loop needed:
Both callbacks receive the full PermissionRequest so you can inspect what's being asked:
AskUserQuestion
AskUserQuestion answers always go through runs.answer().
Behavior
When an agent calls AskUserQuestion, the run immediately pauses to awaiting_approval.
It stays paused indefinitely — the user can answer after seconds, minutes, or days.
- 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. Each has tool_name == "AskUserQuestion" and tool_input["questions"] with the full question list:
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.
Use req.is_plan_approval and req.plan_text to detect and display the plan:
After plan approval, execution continues with approval-style checks for non-safe tools.
Plan mode in your product
If you're embedding plan approval in a UI, fetch the plan text and show it to your user before calling runs.answer():
Switch permission mode mid-run
You can change the permission mode on a running or paused run without restarting it.
When switching to autonomous, all currently pending tool approval requests are auto-approved immediately.
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.
Commonly pre-approved tools (read-only, low-risk):
Set policies at user creation time:
Tip for internal teams: In approval mode, pre-approve read-only tools (search, fetch, list) and only require approval for write/send/delete actions. This keeps the agent productive while still letting you review high-impact operations.
Production pattern: webhooks
For production, prefer webhooks over polling:
- Subscribe to
run.awaiting_input - For AskUserQuestion pauses, questions are in the webhook payload — no extra call needed:
For tool approval pauses, questions is absent — fetch with runs.permissions().
3. Show them in your UI
4. Send decisions back with answer or approve
See Webhook Events for payloads and signature verification.
Important reply behavior
runs.reply() always runs as non-interactive. It does not enable AskUserQuestion, approval mode, or plan mode.
If you need HITL handling on a follow-up, use reply_and_wait() instead:
