Give an agent a wallet with rules, instead of giving it your wallet.
Quickstart · For agents · For sellers · Protocol · Deployment · @paidwithtab
What is tab · Why tab · Mandates · How a payment works · Quickstart · For API providers · For agent developers · Settlement · Security model · Testing · Architecture · Roadmap
tab is an open payment protocol for software agents.
It lets an agent discover a paid HTTP service, receive a price, authorize the purchase against rules set by its owner, pay, and receive the result. No human has to create an account, enter a card, or copy an API key.
Owners define those rules once, in a signed mandate:
| Constraint | Purpose |
|---|---|
| Total budget | Caps lifetime spend |
| Maximum price per request | Blocks a single expensive call |
| Allowed sellers | Restricts where money can go |
| Spending window | Resets the budget each UTC day, or keeps one lifetime total |
| Expiration | Ends the authority automatically |
The owner signs once. The agent then transacts on its own, and it cannot exceed what the owner authorized.
Owner
│
│ signs mandate
▼
Agent
│
│ HTTP request
▼
Gateway ────────► API
│
│ verifies mandate
│ enforces budget
│ settles payment
▼
USDG
Software agents can already call APIs and use tools. Paying for those services is the part that still requires a person.
Today a human creates an account, enters payment information, generates an API key, configures billing, and hands credentials to the agent. tab replaces all of that with an HTTP payment.
| Without tab | With tab |
|---|---|
Agent calls API
HTTP/1.1 402 Payment RequiredAccount signup, card on file, API key handoff, billing setup. |
Agent pays through tab
HTTP/1.1 200 OK
Tab-Receipt: evm:0x...No account. No card details. No shared owner key. No unrestricted wallet. |
A mandate is a signed spending authorization from an owner to an agent.
| Field | Example |
|---|---|
| Agent | 7f2c... |
| Budget | $25.00 |
| Maximum per call | $0.05 |
| Allowed sellers | api.example.com |
| Expires | 2026-10-01 |
The owner key never has to be online while the agent is working. Every payment is checked independently by the seller's gateway against the signed mandate, so changing the agent's prompt cannot increase its authority.
tab uses standard HTTP payment semantics. A priced endpoint answers with 402 Payment Required and a signed challenge describing the purchase. The agent checks the price against its mandate and signs a credential bound to that exact request.
The gateway then runs the full lifecycle:
| Step | Action |
|---|---|
| 1 | Verify the challenge |
| 2 | Verify the mandate |
| 3 | Verify the agent |
| 4 | Verify the exact request |
| 5 | Reserve the budget |
| 6 | Call the upstream service |
| 7 | Settle only after a successful response |
| 8 | Return a signed receipt |
If the upstream service fails, the payment is voided.
Requires Node.js 22.13 or newer.
Give an agent a tab in one command:
npx paidwithtab initThis creates an owner key and an agent key in ~/.tab, signs a mandate ($1.00 per day, $0.05 per call, 90 days), and claims $1.00 of starter credits on the public gateway at pay.paidwithtab.com. Nothing to fund, no chain, no API keys.
Those credits buy real things: 40 routes across 23 services, from web search, translation and speech to text to geocoding, air quality, arXiv, PubMed, Crossref, OpenAlex, Hacker News, Stack Overflow, GitHub, Open Library, Wikidata, OpenStreetMap, earthquakes and crypto prices, between $0.001 and $0.02 a call. The full list with prices is in the quickstart.
1. Pay for something from the shell.
npx paidwithtab fetch "https://pay.paidwithtab.com/wikipedia/api/rest_v1/page/summary/Lisbon"paid 0.001 (ledger:cpKKYHocOLKlDW8n)
{"type":"standard","title":"Lisbon", ...}
2. Let Claude Code spend.
claude mcp add --scope user tab -- npx -y paidwithtab mcpThen ask Claude for something it needs to pay for, for example "find the weather in Lisbon through tab". It searches the catalog at paidwithtab.com/catalog, pays per request, and can never exceed the mandate.
3. See a price tag.
curl -i https://pay.paidwithtab.com/fx/latest?base=USDHTTP/1.1 402 Payment Required
WWW-Authenticate: Tab challenge="eyJ2ZXIiOiJ0YWIvMCIs..."The starter credits are sandbox money on that one gateway. For real money, fund an agent with USDG on Robinhood Chain: docs/buyers.md.
Want the whole stack on your machine? git clone https://github.com/paidwithtab/tab && cd tab && npm install && npm run demo starts a paid API, a gateway, a catalog and a local wallet. Full walkthrough
Any HTTP API becomes payable with a small JSON specification. Leave out rail to run on sandbox balances while you develop.
{
"realm": "api.example.com",
"recipient": "<wallet>",
"rail": "evm",
"evm": {
"rpc": "https://rpc.testnet.chain.robinhood.com",
"chain_id": 46630,
"token": "0x5B6C7cAF7F99f99154fD8375ec935Fcf03F326f5",
"decimals": 6, // the token's decimals, 0 to 18; USDG and USDC have 6
"recipient": "<your 0x payout address>"
},
"upstream": "http://127.0.0.1:8080",
"routes": [
{ "method": "GET", "path": "/v1/things/:id", "price": "0.01" },
{ "method": "POST", "path": "/v1/generate", "price": "0.002" }
]
}Start the gateway:
tab serve \
--spec spec.json \
--announce https://paidwithtab.comThe gateway handles payment negotiation, authorization, settlement, receipts, and proxying. Your application keeps serving normal HTTP.
1. Create an agent key.
tab key new --out agent.json2. Issue it a mandate.
tab mandate issue \
--owner owner.json \
--agent agent.json \
--budget 5.00 \
--window day \
--max-per-call 0.05 \
--allow 'api.example.com' \
--out mandate.json3. Spend within those limits.
import { TabClient, receiptOf } from 'paidwithtab/client';
const client = new TabClient({
agent,
mandate,
maxPerCallUsd: '0.05',
});
const res = await client.fetch('https://api.example.com/v1/things/42');
console.log(receiptOf(res)?.ref);Or skip the key handling: npx paidwithtab init does all three steps and claims starter credits on the public gateway.
tab also exposes five MCP tools, so compatible agents can discover and purchase services without ever receiving the owner's private key:
| Tool | Purpose |
|---|---|
tab_search |
Find services in a catalog |
tab_discover |
Inspect a service and its pricing |
tab_fetch |
Make a paid request |
tab_balance |
Check remaining budget |
tab_limits |
Read the active mandate constraints |
Hooking tab into a particular agent, with the MCP JSON for Cursor, Codex, Windsurf and Claude Desktop, framework tools, Python by subprocess, and where keys live in production: docs/agents.md
tab settles in USDG on Robinhood Chain mainnet and test USDC on its testnet, or in any ERC-20 a gateway chooses to charge in (its prices, challenges and receipts then name that token in currency), following a delivery first model. The gateway does not settle a payment until the upstream service has responded successfully.
authorize
│
▼
reserve
│
▼
call API
│
├── failure ──► void
│
▼
success
│
▼
settle
│
▼
receipt
tab is built around bounded authority.
| Property | Guarantee |
|---|---|
| Owner keys stay offline | The owner signs the mandate. The agent never receives the owner's private key. |
| Agents have explicit limits | Compromising an agent exposes only the authority its mandate granted. |
| Requests are cryptographically bound | Credentials commit to the exact request, including query string and body digest. |
| Payments cannot be replayed | Challenges are single use, and chain settlement adds a nonce boundary. |
| Gateways hold no buyer keys | The gateway verifies and broadcasts what the agent authorized. It cannot create payments on its own. |
Security issues involving payment invariants should be reported privately through SECURITY.md.
tab currently runs 128 automated checks across protocol behavior, adversarial conditions, and EVM settlement.
| Suite | Checks | Coverage |
|---|---|---|
npm test |
63 | Gateway, catalog, MCP, receipts, payment lifecycle, starter credits, tab init |
npm run test:adversarial |
24 | Concurrency, replay, mutation, SSRF, persistence |
npm run test:evm |
41 | Cryptography, EVM transactions, Robinhood Chain |
The concurrency suite fires 150 simultaneous $0.01 requests at a $1.00 mandate. Exactly 100 settle.
┌─────────────┐
│ Owner │
└──────┬──────┘
│
signed mandate
│
▼
┌─────────────┐ ┌─────────────┐
│ Catalog │◄──────►│ Agent │
└─────────────┘ └──────┬──────┘
│
HTTP + payment
│
▼
┌─────────────┐
│ tab Gateway │
└──────┬──────┘
│
verify + authorize
│
┌─────────────┴─────────────┐
▼ ▼
┌──────────┐ ┌──────────┐
│ API │ │ USDG │
└──────────┘ └──────────┘
Repository layout
src/ protocol, gateway, catalog, client, CLI and MCP
src/evm/ EVM cryptography, transactions and JSON RPC
src/rails/ sandbox and EVM settlement rails
web/ site and catalog
examples/ demos and example specifications
test/ protocol, adversarial and EVM tests
SPEC.md protocol specification
DEPLOY.md deployment and operations
The specification lives in SPEC.md.
Current version: Draft 0.3 · Wire protocol: tab/0
Areas currently under exploration:
- x402 compatibility
- Agents acting as sellers
- Metered pricing and payment channels
- Windowed onchain budgets
- Header binding and subscriptions
- Fee splits and gas sponsorship
MIT. See LICENSE.
Protocol · Buyers · Agents · Sellers · Deploy · Security · @paidwithtab