Agents are good at deciding what data they need. They’ve learned to do what humans do – sign up for accounts, store API keys, manage credit cards – but this is far from ideal. Imitating humans is error prone, introduces unnecessary security risks, and simply copies economic inefficiencies.

Why sign up for an API subscription if only a little data is needed now? Why pay for more than you can use because you might need it later, or because the vendor doesn’t give you any other options? Why can’t an agent decide where to buy data each time it needs some?

x402 is an open payment standard that fixes this. No signups, no API key, no credit cards. Each transaction is independent of all others. It’s a payment standard that is completely in line with our emerging agentic economy.

This post explains the standard in plain terms and then shows how Testril, our pay-per-call blockchain indexer for agents, uses it.

x402 in one minute

x402 takes its name from HTTP status code 402, "Payment Required", which was reserved decades ago and barely used. The standard turns it into a simple handshake:

There are no accounts and no API keys. The standard is network-agnostic and transport-agnostic: the same messages can travel over plain HTTP or inside an agent protocol such as MCP. It also supports more than one payment "scheme". exact pays one quote with one transfer. batch-settlement lets a buyer deposit once and then sign cheap vouchers for many small payments.

How Testril uses it

Testril is an MCP server, so agents talk to it through tool calls, not raw HTTP. It speaks x402's MCP form directly: a paid tool is paid on the call itself, and a standard x402 client can pay it.

  1. Ask for the work and get a quote. An agent calls materialize (index a block range) or read (fetch indexed data). If payment is due, the call comes back as a standard x402 "payment required" message: the accepted payment options (scheme, network, USDC contract, who gets paid, amount) plus Testril's itemised quote. Nothing has been computed or charged yet. The quote freezes the price and the work for 120 seconds.

  2. Repeat the call with the payment. The agent signs one of the offered options and sends the same call again, with the signed x402 payment attached. That's the same payload that would travel in the HTTP PAYMENT-SIGNATURE header. Testril verifies and settles it through an x402 facilitator and does the work in that same call, returning an x402 payment receipt with the result. There's no separate pay step and no payment ID to carry around. A retried call with the same payment is served again without a second charge.

A paid materialize starts a job and answers straight away with a job handle; the agent follows it with inspect until it's done. A paid read returns its rows directly. If you use Testril from Claude Code, Codex or Grok Build, the testril CLI (coming soon) holds your key and pays within budgets you set.

Here is an illustrative exchange for a 15-block materialize. Amounts are in USDC atoms (1 USDC = 1,000,000 atoms); IDs and addresses are placeholders.

// 1. request (illustrative)
{ "tool": "materialize",
  "arguments": { "bound_function_id": "sha256:<id>", "from_block": 1000, "to_block": 1015 } }

// 1. response: x402 payment required (isError: true; illustrative)
{ "x402Version": 2,
  "error": "payment_required",
  "resource": { "url": "mcp://tool/materialize" },
  "accepts": [ {
      "scheme": "batch-settlement",
      "network": "eip155:84532",
      "asset": "<USDC address>",
      "payTo": "<receiver>",
      "amount": "1800",
      "maxTimeoutSeconds": 3600,
      "extra": { "name": "USDC", "version": "2", "minDeposit": "10000",
                 "receiverAuthorizer": "<address>", "withdrawDelay": 3600 } } ] }
// ...plus Testril's quote alongside it:
{ "quote_id": "quote:<uuid>",
  "amount": { "atoms": "1800", "usd": "$0.0018" },
  "lines": [ { "label": "materialize_blocks", "units": 15,
               "unit_price": { "atoms": "120", "usd": "$0.00012" },
               "amount": { "atoms": "1800", "usd": "$0.0018" } } ] }

// 2. the same call again, with the signed payment attached
{ "tool": "materialize",
  "arguments": { "bound_function_id": "sha256:<id>", "from_block": 1000, "to_block": 1015 },
  "_meta": { "x402/payment": { "x402Version": 2, "accepted": { /* the accepts row, copied whole */ },
                               "payload": { /* signature */ } } } }

// 2. response: the work starts, with an x402 receipt
{ "outcome": "success", "result": "materializing",
  "job": { "job_id": "job:<id>", "quote_id": "quote:<uuid>", "blocks_total": 15, "state": "running" },
  "_meta": { "x402/payment-response": { "success": true, "network": "eip155:84532", "payer": "0x<wallet>" } } }

What things cost

Prices are in US dollars and settle in USDC. Today's rates are:

These are currently hard-coded amounts that mirror industry standards for index creation and data reads, but they will soon be much more dynamic and mirror actual costs. Pre-AI this wasn’t possible, but when agents manage costs and are able to price small amounts of work on a continuous basis, the impossible becomes possible. Early modeling indicates that our hard-coded fees are too high!

Even today, most of these amounts are far below a cent. Quotes of $0.01 or more can be paid with exact: one USDC transfer per quote. Every quote can be paid with batch-settlement, which is how nearly every read is paid: the agent deposits at least $0.01 of USDC into an escrow once, then signs a cheap voucher for each call, and Testril collects many vouchers in one onchain transaction. That way an agent isn't paying network fees on a payment worth a fraction of a cent.

The NFT: cache, earnings and claims

Your first indexing purchase on a payment network gives your wallet an NFT there: a transferable ERC-721 that records your purchases and what you've earned. It is minted just after your purchase is served, so your data never waits for it. If you sell the NFT, its history goes with it, and your next purchase creates a new one.

When you index a range, you're supplying data that other agents may want. When someone later pays to read blocks you cached, part of the per-block read fee is credited to you as earned, and another slice extends how long your cache is kept. Popular data stays cached and keeps earning. Data nobody reads expires.

The NFT shows lifetime totals: paid, refunded, cost, earned, claimed, unclaimed and profit and loss. You withdraw earnings with claim_rewards, naming the NFT. Payouts go in USDC to whoever owns the NFT, once its unclaimed balance reaches $0.01. Below that, the claim succeeds but pays nothing, so dust doesn't cost more in fees than it's worth.

Where we are today

Testril is live on testnet. Agents pay with real test USDC on Base Sepolia through the standard x402 flow; no mainnet money moves yet. Mainnet payments, starting with Base, come next. Prices are early and may change.

Closing

For an agent, the whole loop is three steps: see the price, pay exactly that, get the data. x402 provides the payment handshake, and Testril adds per-block pricing, refunds (coming soon), and an NFT that pays you when your cached data gets used. If you're building agents that need onchain data, see testril.si.