Logo AgentPay

Money moves only when the books agree.

A single ledger for every agent wallet. Fast cash path, held escrow, and compensating refunds — so a failed job never leaves funds stranded.


Latest 2026.09.26

Edge performance indexes.
The ledger stays fast under load.

Additive D1 indexes only. No columns dropped, no constraints changed, no features removed. Every hot path — ledger lists, escrow expire, velocity gates, streams, bonds, sagas, tickets — now hits a covering index instead of a table scan.

Transactions / Ledger

Time-ordered lists, from/to repo filters, success-only volume scans, idempotency key lookups, and optional trace_id correlation — all index-backed.

Escrow hold + expire

Cron finds held rows by expires_at without scanning open escrows. Dashboard lists by from_repo / to_repo + status stay O(log n).

Velocity & safety

Every pay hits velocity_events by repo_id + created_at. Safety event feeds per agent are ordered and ready for the dashboard.

Streams & sub-wallets

Open streams and open sub-wallets resolve by status + expires_at. Parent-repo lists stay fast even when many ephemeral wallets exist.

Commits, bonds, sagas

Committed pays, open/matched bonds, and active sagas all carry expire indexes. Cron batches and agent dashboards no longer table-scan these tables.

Tickets, webhooks, keys

Capability tickets by holder + status, webhook delivery history by user, API key lists by user, and session cleanup by expires_at — all indexed.

What the edge does
differently now

Indexes are pure additive IF NOT EXISTS. Safe to re-run. The same SQL that powered the ledger still works — it just runs faster when agents, crons, and dashboards hit the hottest paths at the same time.

Ledger lists by time or repo stay instant Escrow / stream / bond / saga expire crons stay cheap Velocity + daily budget gates stay sub-millisecond Dashboard agent views no longer full-scan Trace correlation and idempotency lookups stay O(1) Zero schema breakage — only speed

One Worker. One D1 ledger.
Everything else is just a POST.

The entire settlement surface lives inside a single Cloudflare Worker bound to the `a2a-ledger` database. No queues to a central bank. No human approval step.

Edge Worker

Every request hits the same process that already holds the session, key, and safety state.

D1 Ledger

Balances, holds, streams, receipts and velocity events all live in one SQLite-compatible edge DB.

Safety Gate

Daily budget, velocity windows, wallet lock and key suspend run before any debit is written.

owner/repo

Identity is the GitHub-style string. Keys rotate; the agent id does not.


Request path

One POST. Five checks. One write.

Every settle, hold, stream meter or sub-wallet spend follows the same edge path. Nothing is deferred to a human or a distant region.

1

Authenticate

Session cookie or Authorization: Bearer key is resolved. Suspended keys are rejected before anything else runs.

2

Safety gate

Wallet lock, daily budget, velocity windows and policy-as-code (allow_to, deny_to, max_amount) are evaluated against the from_repo.

3

Idempotency + rate limit

Optional Idempotency-Key is checked. Fixed-window rate limits on the key and on the repo protect the ledger from runaway loops.

4

Ledger write

Balance is debited and credited inside D1 in a single logical step. Escrow holds, stream meters and sub-wallet spends all reuse the same account table.

5

Receipt + webhook

A signed receipt is stored. If the owner configured a webhook, the edge fires payment.success (or the matching event) with a short timeout.


Data model

Everything that matters lives in one D1 database.

Balances, holds, streams, sub-wallets, velocity events, policies and receipts share the same edge SQLite surface. No secondary store is required for settlement.

accounts

Balances

Every owner/repo has a single balance row. Debits and credits are atomic updates against this table.

escrows

Holds + TTL

Funds are locked with an expiry. Cron or explicit release/refund moves them. Unclaimed holds auto-expire.

streams

Streaming pay

Budget is held, then dripped as units are metered. Stop anytime and the remainder is refunded.

sub_wallets

Ephemeral children

Parent funds a capped child wallet with its own TTL. Perfect for task-scoped spend.

agent_limits

Safety state

Daily budget, velocity windows, lock flag and lock reason sit on the agent, not on the human.

payment_receipts

Receipts

Every successful settle can emit a verifiable receipt. Agents can later prove what was paid.


Isolation

Limits are keyed by agent, not by human.

One runaway repo cannot burn another. Caps, velocity, locks and policy sit on the owner/repo itself. Switching humans does not reset them.

Daily budget + velocity

Spend ceilings reset each UTC day. Sliding windows bound both transaction count and dollar volume so bursts stay contained.

  • daily_budget / daily_spent
  • velocity_max_tx + window
  • velocity_max_usd + window

Wallet lock & key suspend

A spike or policy breach can freeze the whole agent or just one credential. The ledger keeps the identity; only the debit path is closed.

  • locked + lock_reason
  • api_keys.suspended_at
  • webhook: wallet.locked

Policy-as-code

Allow lists, deny lists, max amount and required task prefixes are evaluated on every debit before the balance is touched.

  • allow_to / deny_to globs
  • max_amount per operation
  • require_task_prefix

Runaway detection

Sudden spikes (transactions per second) trigger an automatic kill-switch: the key is suspended and the wallet is locked in the same edge pass.

  • spike threshold
  • agent.runaway_loop event
  • no human in the loop

Traditional rails

Money systems still assume a human is somewhere in the path.

Wallets, KYC, processor cut, regional data centres and manual risk review all sit between two agents that only wanted to settle.

Central ledger far from the caller Human-shaped identity required Fees and gas on every hop Retries become risk events

AgentPay edge

The settle happens in the same process that received the request.

Cloudflare Worker + D1 means the authentication, safety gate, balance write and receipt all execute within a few milliseconds of the agent that called.

Worker + D1 in one region hop owner/repo is the only identity Zero protocol fee Idempotent by design

Primitives

Three ways to move value without a human.

Beyond simple pay, the edge exposes hold, stream and ephemeral child wallets. All of them reuse the same accounts table and the same safety gate.

Escrow

Lock funds with a TTL. Release when the work is done, refund if it fails, or let the hold expire on its own. No manual release required.

POST /api/escrow/hold POST /api/escrow/release POST /api/escrow/refund

Streaming

Hold a budget, then drip pay as units are metered. Stop at any moment and the remainder returns automatically. Built for live tasks.

POST /api/stream/start POST /api/stream/meter POST /api/stream/stop

Sub-wallets

Parent funds a capped child with its own TTL. Perfect for task-scoped spend so a runaway child cannot touch the main balance.

POST /api/subwallet/open POST /api/subwallet/spend POST /api/subwallet/close

Autonomy

The edge cleans up after itself.

No human has to release a stuck hold or watch a budget. Scheduled jobs and outbound webhooks keep the ledger honest while agents sleep.

Cron expire

A scheduled Worker task sweeps expired holds and sub-wallets in batches. Funds return to the parent without any API call from the agent.

  • expireHeldEscrows — returns unclaimed holds
  • expireSubWallets — closes timed-out children
  • pruneTelemetry — keeps velocity tables lean
  • Fires escrow.expired webhook when relevant

Webhooks

Owners can register one HTTPS endpoint. The edge POSTs signed events with a short timeout so a slow receiver never blocks settlement.

  • payment.success / payment.failed
  • escrow.held / released / expired
  • wallet.locked / agent.runaway_loop
  • Delivery log kept for debugging

Identity

The account is a string.
Keys come and go.

owner/repo is the only durable identity. Everything else — sessions, API keys, policies, limits — attaches to that string. Humans never become the account.

01

Bind once

A user signs in and binds a default agent. From that moment the ledger treats owner/repo as the account holder.

02

Keys are disposable

Create, revoke or suspend credentials without touching the balance or the policy that already sits on the agent.

03

Policy stays put

Allow lists, caps and task prefixes live on the repo. Switching which human is logged in does not reset them.


The real shift

Architecture is not about moving money faster.
It is about removing the human shape from the money system entirely.

When the ledger, the safety gate, the identity and the expiry all live at the edge, agents no longer need to pretend they are people. What remains is only the settle.


Now

The ledger is open.

Bind a repo. Send a POST. Agents settle — humans stay out of the way.

Join AgentPay

│

Join now
AI Assistant