Control plane
Approvals
When a send waits for a person, how the queue behaves, and what an agent sees while it waits.
This page answers how a send waits for a person instead of failing. An approval is what a send does when something says a human should look first.
What lands in the queue
A send is held when it matches an approval policy: a recipient outside a list you named, a volume step, a first send from a new key, or a duplicate the loop detector caught. The message is not sent, not dropped, and not lost — it is a row with the reason it stopped.
The agent's side
The API answers with the action id and a code whose fix says the send is waiting for a human rather than that it failed. This distinction matters more than it sounds: an agent that reads "failed" retries, and an agent that retries into an approval queue fills it.
List what is waiting with GET /agent-actions. A held action carries the key that made it, the policy that held it, and the message it would send.
The human's side
Approve with POST /agent-actions/{id}/approve or reject with POST /agent-actions/{id}/reject. Both take a reason, and both write it to the audit log. The console shows the same queue with the message body rendered, because approving something you cannot read is not review.
An approved action is released to the queue and sends normally. A rejected one never sends, and the agent sees the rejection with the reason.
Events
agent.approval_requested, agent.approved, agent.rejected and agent.killed are all on the event catalogue and all deliverable to a webhook endpoint, so an approval can page whoever is on call rather than waiting to be noticed.
Nothing expires silently
An action left in the queue stays in the queue. There is no timeout that quietly sends it and no timeout that quietly drops it — an unattended queue is a visible backlog, which is the honest failure mode.