Inspiration

AI agents are starting to pay for things, and most of what they buy is tiny: an API call, a data lookup, a tool invocation. While researching the hackathon we kept hitting the same two bad options for developers:

  1. Hand the agent your PayPal credentials. It can then spend without limit and without an audit trail. PayPal's own Agent Toolkit has open GitHub issues asking for a spend bound and a human gate on pay_order.
  2. Bill the agent per call. This loses money. PayPal's fixed fee of about $0.49 is roughly 25× the price of a 2-cent call.

Crypto rails like x402 solve metering, but most businesses can't hold stablecoins. We asked: what if agents could pay the way people do at a bar? Open a tab, order as you go, and settle once at the end, on rails businesses already use.

What it does

Agent Tab is a bar tab for AI agents, settled through PayPal.

  • Any API or MCP tool can charge agents in dollars. A seller adds one Express middleware, requirePayment({ price }). Unpaid requests get 402 Payment Required with a price quote.
  • The agent runs a metered tab against a PayPal payment method its owner vaulted once. The agent never holds a payment credential, only short-lived, single-use signed receipts.
  • Hard limits the agent can never change: a per-call cap, a session cap, a daily cap, a merchant allowlist, a rate limit, and a threshold above which a human must approve the charge in an inbox.
  • An AI treasurer decides when to settle. It closes the tab with a single PayPal capture so the fixed fee isn't paid on every call, and it explains each decision in one line.
  • A live ledger shows every tab line, blocked attempt, approval, treasurer rationale, and settlement with its PayPal capture id and fee.

In our demo, a Claude research agent makes eight paid calls. One call waits for human approval, a $9 export is blocked by the per-call cap, and the tab settles in one PayPal capture. Fees: $3.93 billed per call vs $0.52 on the tab.

How we built it

It's a TypeScript monorepo with four packages and four apps:

Part Role
@agent-tab/shared zod schemas, Ed25519 receipt signing, a fail-closed policy engine
@agent-tab/server Seller middleware: answers 402 with a quote, verifies receipts, rejects replays by nonce
@agent-tab/client A fetch wrapper that handles 402 → tab → retry and waits for human approval
@agent-tab/mcp MCP server exposing paid_fetch and tab_status to Claude Desktop or any agent runtime
tab-service Tabs, policies, approvals, treasurer, PayPal gateway, settlements, live events (SSE)
ledger Vite + React + AG Grid + AG Charts ledger with an approval inbox
paid-data-api / research-agent Demo seller and a Claude buyer (Vercel AI SDK)

The protocol: the agent requests data and gets a 402 with a quote. It posts the quote to the tab service, where the policy engine returns 403 with a reason, 202 (needs a human) or 201 with a signed receipt. The agent retries with Authorization: Tab <receipt>. The seller verifies the Ed25519 JWT (120-second lifetime) against the tab service's public key.

PayPal: we use Vault v3 (setup token → buyer approval → payment token → vault_id) and then Orders v2 with payment_source.paypal.vault_id and merchant-initiated stored_credential {MERCHANT, UNSCHEDULED, SUBSEQUENT} flags. Each settlement's PayPal-Request-Id is derived from tab_id:n, so retries are idempotent. The actual paypal_fee from every capture is recorded.

The treasurer uses PayPal's fee model:

$$ \text{fee}(a) = 0.49 + 0.0349\,a $$

Billing $n$ calls individually costs $\sum_{i=1}^{n} \text{fee}(p_i) = 0.49n + 0.0349\sum p_i$, while one settlement costs $0.49 + 0.0349\sum p_i$. Batching saves $0.49(n-1)$. A deterministic core settles when the outstanding balance crosses a threshold, when the session ends, or when the balance has been open longer than an exposure window. An optional Claude advisor may recommend settling earlier, never later. The deterministic rule always wins.

We wrote 32 tests, including end-to-end runs of the full protocol, the approval round trip, the blocked export, and a check that 40 calls settle in 3 or fewer captures with a balanced ledger.

Challenges we ran into

  • Sandbox account country. Our auto-generated India sandbox business account never received Vault v3 scopes. POST /v3/vault/setup-tokens kept returning 403 NOT_AUTHORIZED, and the token carried only the legacy v1/vault/credit-card scope. A new US sandbox business account with a fresh app fixed it immediately.
  • Buyer ≠ seller. Approving the vault setup while logged in as the business account fails ("You are logging into the account of the seller"). We needed a separate US sandbox personal account as the buyer.
  • Finding the right request shapes for setup tokens, payment tokens and merchant-initiated orders. We logged every raw request and response from a standalone spike script until two buyer-absent captures succeeded from one vault_id.
  • Keeping the AI out of the money path. Agents can be prompt-injected, so policy lives in the tab service, outside the model. The LLM treasurer got a strict boundary: it can only move a settlement earlier and can never touch policy.

Accomplishments that we're proud of

  • Real PayPal sandbox captures. Two merchant-initiated captures from one vaulted method with the buyer absent, plus a full end-to-end agent run against the live gateway: 8 calls, 1 approval, 1 block, 1 capture.
  • Our fee model matched PayPal to the cent. Observed fees of $0.52 on $1.00 and $0.58 on $2.50 are exactly $0.49 + 3.49%.
  • The agent never sees a credential. It holds only single-use receipts. The vault id and PayPal keys stay in the tab service.
  • Drop-in for both sides. One middleware line for sellers, one fetch wrapper or MCP config for agents.
  • Runs in 5 minutes without a PayPal account, using a mock gateway, so anyone can try the full loop.

What we learned

  • Micropayments on card-style rails are a fixed-fee problem, not a percentage problem. Batching settlements is what makes agent-scale pricing viable.
  • Vault v3 fits agents well: the human consents once, and merchant-initiated captures handle the rest.
  • Safety for agent payments comes from architecture, not prompts. Fail-closed policy, signed receipts, replay protection and human-approval thresholds have to sit outside the model.
  • Sandbox details (account country, buyer/seller separation, scopes) are worth spiking on day one. We did ours before building the settlement layer.

What's next for Agent Tab

  • Persistent storage. The tab service currently uses an in-memory store.
  • Production Vault approval and live money. Today everything runs in the sandbox.
  • Multi-tenant auth, so many owners, agents and sellers can share one tab service.
  • More seller adapters beyond Express, and publishing the client, server and MCP packages to npm.
  • Richer treasurer policies, such as budget windows and per-merchant settlement schedules.

Built With

Share this project:

Updates

Submission history