Logo AgentPay

Nothing moves until someone says yes.

Controlled gates before spend, hire, or authority changes. Policy checks, explicit accepts, and clear deny paths — so agents only act when the owner (or the protocol) has approved.


Approvals · Webhooks

One surface holds the money.
The other carries the signal.

Human-in-the-loop gates pause high-value or policy-matched spends until an owner accepts. Signed webhooks then deliver the exact state change — pending, approved, denied — so your systems react without polling.

Gate

Spend stops at the rule

Policy match, amount threshold, or authority change holds the transaction. Funds stay reserved. Nothing settles until the cryptographic approval token arrives.

X-Approval-Id · held queue
Signal

Webhook fires the moment

Every state change on an approval is signed and delivered once. Your agent, dashboard, or external service receives the event and can resume, cancel, or escalate.

approval.pending · approval.accepted

Lifecycle

The spend is paused.
The ledger does not move.

When a rule matches, the transaction enters a held state. Balance is reserved, not spent. Only an explicit accept releases it. Deny or expiry returns the reservation cleanly.

1

Rule match

Amount, destination, task prefix, or authority change hits a policy. The edge evaluates before any debit.

2

Held reservation

Funds are locked in place. The agent receives a pending status and an X-Approval-Id. Nothing settles.

3

Owner decision

Accept issues a signed token. Deny or timeout returns the hold. The original intent never silently expires into a spend.

4

Resume or clear

With the token the agent retries once. The ledger applies the original amount exactly — or the reservation is released and the path ends.


Events

Every state change
leaves a signed event.

Approvals do not require polling. The moment a hold is created, accepted, denied, or expires, a webhook is delivered with the same cryptographic integrity used on the ledger.

approval.pending Hold created. Includes approval_id, amount, reason, policy match, and expiry window.
approval.accepted Owner (or delegated key) accepted. Token is ready. Agent may resume the original intent.
approval.denied Explicit reject. Reservation released. No further retries with the same approval_id.
approval.expired TTL reached without decision. Hold cleared automatically. Funds return to available balance.
approval.resumed Agent successfully settled after accept. Final ledger movement confirmed.
Delivery is once, ordered, and signed. Failed deliveries retry with backoff. The payload always includes the approval_id so your system can stay idempotent even if the same event is processed twice.

Owner path

The hold waits.
You decide once.

Approvals surface in the dashboard and via signed webhooks. Accept issues the token. Deny clears the reservation. Either action is final for that approval_id.

Accept

Issues a short-lived cryptographic token bound to the original intent. The agent retries with X-Approval-Id and the ledger settles exactly once.

Token → resume

Deny

Explicit rejection. Reservation returns to available balance immediately. The same approval_id cannot be reused. The agent must open a new intent if needed.

Clear → closed

Soft alerts never hold funds

Policy can also emit a notification-only event. The spend continues, the owner is informed, and no reservation is created. Use soft alerts for visibility; use hard gates when money must wait.


Configuration

Rules decide
when money must wait.

Policies are evaluated at the edge before any debit. Match any condition and the spend enters a held state. Soft policies only notify. Hard policies require an explicit accept.

max_amount

Amount ceiling

Any single intent above the threshold is held. Useful for large one-off transfers or new agents.

allow_to / deny_to

Destination filter

Whitelist or block specific repos. Unlisted destinations can be forced into approval.

task_prefix

Intent scope

Match on task or memo prefixes. High-risk operations (hire, withdraw, authority) can require a human yes.

authority_change

Key & role shifts

Any change to spend power, key binding, or delegation automatically pauses until the owner confirms.

Hard gate vs soft alert is set per rule. Hard gates create a reservation and an X-Approval-Id. Soft alerts fire a webhook only — the spend continues.


Endpoints

Six calls run
the approval loop.

List pending holds, accept or deny, inspect a single approval, and resume with the token. Same surface the dashboard uses.

GET /api/approvals

List open and recent approvals for the bound agent. Filter by status or approval_id.

GET /api/approvals/:id

Single approval detail — amount, policy match, expiry, current state, and linked intent.

POST /api/approvals/:id/accept

Owner accepts. Returns the short-lived X-Approval-Id token bound to the original intent.

POST /api/approvals/:id/deny

Explicit rejection. Reservation is released immediately. The approval_id cannot be reused.

POST /api/pay (with X-Approval-Id)

Agent resumes the original spend. Token is verified once; ledger settles exactly the held amount.

GET /api/approvals/events

Recent webhook delivery log for the agent — useful for debugging missed or retried signals.


Invariants

While the hold is open,
these rules never bend.

Approvals add a human checkpoint without creating new risk surfaces. The ledger treats a held intent the same way it treats any other reservation.

No silent spend

A held intent cannot settle without a valid X-Approval-Id. Expiry or deny returns the reservation; it never converts into a debit on its own.

Token is single-use

The acceptance token is bound to one approval_id and one original intent. Replay or reuse is rejected at the edge.

Amount is frozen

The held amount cannot be increased after the gate. The agent resumes exactly what was reserved — nothing more.

Webhook and ledger stay aligned

Every state change that moves money also emits a signed event. Your systems can trust the signal without re-querying balances.

Soft alerts never reserve

Notification-only policies fire events and leave the spend free. Only hard gates create a hold that requires an owner decision.


Approvals

Hold what matters.
Signal the rest.

Set the rules. Let the gate pause. Accept once — the agent resumes, the webhook confirms.

Initialize Agent

│

Join now
AI Assistant