BlogUpdated 26 October 2026 · 2 min read

Human-in-the-loop email agents

An approval queue checks the agent’s replies. A hand-off gives the conversation to a person. Here is how an email agent hands one over, how a person takes it, and how it comes back.

A queue for approval is not a hand-off

Most "human in the loop" setups for email agents are an approval queue: the agent writes a reply, and a person checks it before it goes. That is useful, and it is not the hard case. The hard case is the conversation the agent should stop answering altogether: the customer who wants a refund above what it may approve, the supplier who is angry, the reply that is really a legal question.

For that, the conversation has to change hands. A person has it now, the agent has stepped back, and everything watching knows.

The owner is a field on the thread

In Pidgeon every conversation has an owner: agent, human or automation. Handing one over is one call, because it is one intention:

curl https://pidgeon.ai/api/v1/threads/$THREAD_ID \
  -X PATCH \
  -H "Authorization: Bearer $PIDGEON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "owner_type": "human",
    "status": "human_review",
    "reason": "They want a refund above what I can approve."
  }'

The people who can answer as that address get a notification and an email with the reason. In the inbox the conversation sits under Waiting for a person with a Take it button. They reply as the same address, from the web inbox or from Apple Mail with an app password, and a reply takes the conversation over even if nobody pressed anything.

Your code hears all of it: thread.assigned and thread.updated fire on every change, and thread.updated carries the previous owner beside the new one. Hand it back with owner_type: "agent" and the agent finds it among its own conversations. Over MCP, the update_thread tool does the same.

The other side keeps writing to the same address, in the same thread. Whether to tell them a person has joined is your call.

An inbox per role, and a key for each

Builders who run several agents tend to land on the same shape:

  • One inbox per agent role. support@, billing@, scout@, each created in one call. Mail arriving at an agent address starts a conversation the agent owns, so each agent's queue is the list of its own threads.
  • A key per agent. Scope each agent's key to its own addresses, and it cannot read another agent's conversations or the inbox a person works from.
  • An inbound policy per inbox. Give an address its own allow list, so the billing agent only hears from customers on file. A sender on the list counts only when its DMARC passes, so a forged From is a stranger.

Start

The hand-off guide walks through all of it against your own address in about five minutes: mail arrives, the agent gets stuck, a person takes it and hands it back. To have a person check each reply instead, see approving drafts.

Everything an agent's inbox does is on email inboxes for AI agents.

01

Keep reading

All posts

Give your agents an inbox

Every inbox comes with its ID, and both are free to start.

Create your first inbox, it’s free