Human-in-the-Loop: Pause, Wait, Resume
Pause a running graph at any node and wait for external input - human approval, payment callbacks, document uploads, or any decision that can't be made by the bot.
How It Works
The HumanInLoop Action
| Parameter | Type | Required | Description |
|---|---|---|---|
reason | str | Yes | Internal reason for pausing (logged, passed to hooks). |
say | str | No | User-facing hold message spoken via TTS. |
timeout | float | No | Seconds before auto-resume with empty payload. |
Writing a HIL Node
async def payment_verification(state, ctx):
# PATH 2: Resumed - external system provided the result
if ctx.human_input:
if ctx.human_input.get("status") == "success":
return Route("confirm_order", update={"transaction_id": ctx.human_input["transaction_id"]})
await ctx.say("Payment failed. Please try again.")
return Route("retry_payment")
# PATH 1: First call - pause and wait
return HumanInLoop(
reason=f"Awaiting payment for order #{state.order_id}",
say="I've sent you a payment link. Please complete the payment.",
timeout=600,
)
Resuming
prompt = await graph.resume_with_human_input({
"status": "success",
"transaction_id": "txn_abc123",
})
What happens: is_paused -> False, timeout cancelled, on_resume hooks fire, ctx.human_input set to payload, same node re-runs, ctx.human_input cleared after.
While Paused
- All user input returns a hold message.
- Checkpoints are still saved.
graph.is_pausedreturnsTrue.
Timeout
return HumanInLoop(reason="Needs approval", say="Please hold.", timeout=120)
# After 120s: resume_with_human_input(None) called automatically
# ctx.human_input will be None - handle this case in your node
Common Use Cases
| Use Case | Pattern |
|---|---|
| Human approval | Pause at review node, resume via admin dashboard API |
| Payment | Pause after sending payment link, resume on Razorpay/Stripe webhook |
| Document upload | Pause while user uploads docs, resume when backend confirms |
| OTP verification | Pause after sending OTP, resume when confirmed via separate channel |
| Escalation | Pause and transfer to human agent, resume when agent resolves |
Got a Question? Ask us on discord

