Skip to main content
Some agent actions need human approvals for dangerous actions: deploying code, sending money, modifying user accounts. With Restate, your agent can pause execution, wait for an external signal, and resume exactly where it left off, even if the process restarts in the meantime.

How it works

Restate provides durable promises (awakeables) that survive crashes and restarts:
  1. The agent creates a durable promise and gets a unique ID
  2. The agent sends this ID to whoever needs to approve (Slack, email, dashboard)
  3. The agent suspends, freeing compute resources (no idle billing on serverless)
  4. When the approver responds, they resolve the promise via HTTP
  5. The agent resumes from the exact point it paused

Example: approval tool for an agent

human-approval-agent.ts
Install Restate and launch it:
Get the example:
Export your OpenAI API key and run the agent:
Register the agents with Restate:
Use curl with the send verb to start the claim asynchronously, without waiting for the result:
You can restart the service to see how Restate continues waiting for the approval.If you wait for more than a minute, the invocation will get suspended.
Invocation overview
Simulate approving the claim by executing the curl request that was printed in the service logs, similar to:
See in the UI how the workflow resumes and finishes after the approval.
Invocation overview

Why this matters for agents

  • No idle resources: The agent suspends while waiting. On serverless infrastructure, you pay nothing during the wait.
  • Survives restarts: Even if the process or infrastructure changes, the agent resumes when the approval arrives.
  • Composable: Combine with tool calls, multi-step workflows, and other patterns. The approval is just another durable step.

Adding timeouts

Add a timeout to prevent approval steps from hanging indefinitely. Restate persists both the timer and the approval promise, so if the service crashes or is restarted, it will continue waiting with the correct remaining time.
human-approval-agent-with-timeout.ts
Start the timeout agent (stop any previously running agent first):
Register the agents with Restate:
Send a request to the service:
Restart the service and check in the UI how the process will block for the remaining time without starting over.You can also lower the timeout to a few seconds to see how the timeout path is taken.