A2A 1.0 · Ed25519 receipts · SOC 2 in progress
Build October 26, 2026Status
For agents · Approvals

A human gate before the irreversible step.

An agent that can act but cannot ask is a liability. AgentDraft parks the action, shows a person the exact evidence, and returns a decision the agent can act on — or a receipt another service can verify offline.

Direct answer: AgentDraft's approval gate is POST /v1/approvals. An agent submits an action type, a summary, and up to 64 KiB of JSON evidence, then polls the request. A signed-in human approves or denies it in the dashboard. Expiry is not approval: a request nobody decides resolves expired, and the agent is told it was not approved.

Any action · 64 KiB evidence · fail-closed TTL · Ed25519 receipts on Team+

Updated


01

The gap a gate closes

A tool call is one line of code. The permission behind it is a person deciding whether the world should change. Most agent stacks collapse those two things: the agent has the key, so the agent has the authority.

The failure is not that the model is malicious. It is that nobody was asked. The agent read the record, wrote the summary, and shipped the change before a human saw the diff. A log written after the fact is evidence, not a decision.

The longer field note is How to build an AI agent human approval workflow — async gates, JSON evidence, and MCP.


02

What goes into a request

The schema is deliberately small. Anything the reviewer needs to make the decision belongs in evidence, not in a long prose description the agent can shape.

action_type
A namespaced verb: deploy.production, custom.refund_over_1k, mailbox.send_external. Required, 3–64 chars.
summary
One sentence a reviewer can decide on. Required, up to 500 characters, trimmed and non-blank.
evidence
The payload the decision depends on: a diff, an amount, a recipient, record ids. JSON, capped at 64 KiB.
ttl_seconds
How long the request stays decidable. Minimum 60 seconds; default one hour; capped at 24 hours.
audience
Optional expected verifier for the signed receipt. A downstream service rejects a receipt whose aud is not its own.
hash, not hope

AgentDraft hashes the exact serialized evidence into evidence_sha256 at request time. The signed receipt binds that hash, so an approval for “deploy build 123” cannot be replayed for “deploy build 456”.


03

The four moves

01

Ask

The agent posts the action and evidence. The call returns immediately with {approval_id, status, expires_at}. Nothing blocks.

02

Park

The request lands in the owner's queue. The agent can poll GET /v1/approvals/{id} or use the SDK's wait(), which returns on any terminal status.

03

Decide

A signed-in human approves or denies from the dashboard. The notification email links to the approval queue; there is no one-click approval URL in the inbox.

04

Prove

On Team and above, an approval mints an Ed25519 receipt bound to the reviewer, the agent, the action, the audience, and the evidence hash. It verifies offline against the public JWKS.

python · ask, wait, stand down on anything but approvedapprovals:request
from agentdraft import Client

client = Client(api_key="avs_live_...")  # approvals:request

approval = client.approvals.request(
    action_type="deploy.production",
    summary="Ship api-2026.10.26 to production",
    evidence={
        "build": "api-2026.10.26",
        "tests": "1,249 passed",
        "migrations": 2,
    },
    ttl_seconds=3600,
)

result = client.approvals.wait(approval["approval_id"])
if result["status"] != "approved":
    raise SystemExit(f"stood down: {result['status']}")

04

What teams gate

The action type is a namespace, not an enum. If a human should see it before it happens, it can be a gate.

  • mailbox.send_externalAn outbound email to a recipient outside the workspace.
  • deploy.productionA release, a migration, or a feature flag change.
  • custom.refund_over_1kA refund above the limit an agent may issue alone.
  • calendar.book_execA meeting with an executive or a customer's decision-maker.
  • crm.delete_recordAny destructive write that cannot be undone by a retry.
  • contract.send_for_signatureA document that commits the company.

05

Where the boundary is

it does

Own the decision and its evidence trail for any action, including one AgentDraft never executes. A deploy, a refund, or an external send can use the same gate.

it does not

Replace your authorization model, execute the action, or approve on the agent's behalf. The agent still needs its own scoped key and your service still performs the side effect.

A request that reaches its TTL is resolved as expired and audited. The SDK's wait() returns that status rather than raising, so a caller cannot mistake a timeout for a yes. Both SDKs fail closed on anything other than approved.


06

What is included

The gate is part of the operations API.

Every tier can request and resolve approvals. Team and above add signed Ed25519 receipts, scoped delegation tokens, and the audit retention that makes the decision trail useful months later.

  • Free Developer tier: 3 agents, 1 mailbox, 50 bookings a month
  • Team $25/mo: signed approval receipts and 1-year audit retention
  • Scale $99/mo: 25 mailboxes and 2-year audit retention
See plans Start free

No card required


07

Questions

What is an AI agent approval gate?

An approval gate is a human sign-off step an agent must pass before it takes a consequential action. The agent submits the action and the evidence a reviewer needs, then waits. AgentDraft returns approval_id, status, and expires_at immediately; the action proceeds only after a signed-in human approves it in the dashboard.

Does an expired approval count as approval?

No. A request that reaches its TTL is resolved as expired, and the agent is told it was not approved. Expiry fails closed by design: a reviewer who never saw the request must not produce the same result as a reviewer who approved it. The default TTL is one hour and the maximum is 24 hours.

What evidence can an approval request carry?

Evidence is an arbitrary JSON object up to 64 KiB. AgentDraft hashes the exact serialized payload into evidence_sha256 at request time, so a receipt cannot be replayed for a different payload. Put the decision inputs in it: the diff, the amount, the recipient, the record ids, and the policy that triggered the gate.

Can an agent approve its own request?

No. Agents submit and poll through an API key with the approvals:request scope. Only a signed-in human can approve or deny, from the dashboard queue. Notification email links to that queue rather than carrying a one-click approval URL, because a link in an inbox is not a strong enough factor for an irreversible action.

Which tier includes signed approval receipts?

Team and above mint an Ed25519 receipt when an approval resolves. The receipt binds the reviewer, the agent, the action type, the audience, and evidence_sha256, and it verifies offline against the public JWKS. Free and Individual get the JSON status and the audit record, but not the signed receipt.

Can AgentDraft gate an action it does not execute?

Yes. action_type is an opaque namespaced string such as deploy.production, custom.refund_over_1k, or mailbox.send_external. AgentDraft owns the decision and its evidence trail, not the action. Your service checks the approval result and performs the side effect only when the status is approved.