What Agents Buy.

Independent reviews of the x402 APIs behind agentic commerce. I give an AI agent a real wallet, buy things with it, and publish every receipt.

Written by Neil·nothing here is sponsored·new? start here·how we grade

25bought and graded
22agent calls this week

I pay for these APIs with my own wallet and publish what happened. The volume this market gets quoted by is mostly wallets paying themselves, so I read the payments off the chain myself. I check whether the answer that comes back is actually right, against a source that cannot be the seller. And the verdict an agent gates on is backed by money that moved. Every weight and threshold behind that is published at how we grade. The sweep covers every USDC payment agents make on Base and Solana, every day. Free MCP server for your agent →

Why this differs from the x402 dashboard total

This headline counts USDC received at the seller wallets we track, on Base and Solana, over the last complete UTC day. Of it, $34,324 settled on Base and $74,048 on Solana (Solana is mostly Bitrefill and Laso). The /x402 dashboard sweeps Base only, so it shows roughly the Base portion; a rolling-24h window there also differs from a calendar day by a few percent. Every figure on this site carries its scope for exactly this reason.

A dispute receipt is a small, open, self-verifying record of a single paid API call. It exists so that when an AI agent pays for something and does not get it, there is a record a third party can check, which is the piece agentic commerce is otherwise missing. This page defines the format. It is free to adopt, attribution appreciated.

Why

Payments settle in a second; disputes do not settle at all, because nothing records what was promised against what was delivered in a form anyone can audit after the fact. A receipt fixes that at the smallest useful unit: one call. It does not move money or reverse a payment. It makes the facts of a call portable and checkable, so reputation and resolution can be built on evidence rather than on trust.

What a receipt records

Six things, and a content hash over them:

The receipt_id is a sha256 over those evidence fields. Change any one and the id no longer matches. The record is tamper-evident by construction.

The three-level verification

A receipt is arbitrable without trusting its publisher, at three independent levels:

Reference implementation: python3 receipts.py --verify <receipt_id> runs all three. A verdict reached by a two-call re-verify cannot be reproduced from one stored shape, so it is reported honestly as not-applicable at the offline level and confirmed at the raw level instead.

Opening and resolving a dispute

A dispute is opened by pointing at a receipt whose verdict is short or off. The receipt is the whole case file: promise, payment, delivery, and an independent verdict already in it. The seller may contest by submitting its own call, which is recorded as another receipt and graded the same way. Because every verdict re-derives from archived bytes, resolution is a reproducible fact, not an opinion. The consequence is reputational, recorded against the seller's public reliability, not a forced refund, because a third party's legitimate power here is evidence and reputation, not settlement.

The shape of a receipt

A real underdelivered receipt from this site, in full:

{
 "checks": {
  "integrity": true,
  "raw": true,
  "verdict": true
 },
 "delivery": {
  "extra": [
   "builderCode",
   "data",
   "generatedAt",
   "receipt",
   "returningCaller",
   "service",
   "tokens"
  ],
  "latency_ms": 3036,
  "missing": [
   "tokensCount"
  ],
  "observed_schema": {
   "builderCode": "string",
   "data": {
    "count": "integer",
    "generatedAt": "string",
    "receipt": {
     "endpoint": "string",
     "inputHash": "string",
     "policyVersion": "string"
    },
    "returningCaller": {
     "callsSoFar": "integer",
     "cheaper": "string",
     "contact": "string",
     "note": "string"
    },
    "tokens": {
     "array_of": "string"
    }
   },
   "service": "string"
  },
  "raw_ref": {
   "call_id": null,
   "capture": "raw_2026-08-30.jsonl",
   "date": "2026-08-30",
   "line": 418,
   "match": {
    "call_id": null,
    "tx": "0x5398e5eeeb7c7ec46b877f819df33f7fc3d3cb35df38a3540ad11b887950716b",
    "url": "https://402.com.tr/api/x402/secure-token?count=3"
   },
   "sha256": "7f73b3087d584499",
   "tx": "0x5398e5eeeb7c7ec46b877f819df33f7fc3d3cb35df38a3540ad11b887950716b"
  }
 },
 "kind": "delivery",
 "payment": {
  "chain": "base",
  "charged_usdc": "0.01",
  "free": false,
  "paid": true,
  "settlement": "EIP-3009, submitted by a facilitator",
  "tx": "0x5398e5eeeb7c7ec46b877f819df33f7fc3d3cb35df38a3540ad11b887950716b"
 },
 "promise": {
  "fields": [
   "count",
   "tokensCount"
  ],
  "price_usdc": "0.01",
  "source": "x402 Bazaar (CDP discovery)"
 },
 "receipt_id": "wab_30e3fc8f7f759a1c",
 "seller": {
  "host": "402.com.tr",
  "url": "https://402.com.tr/api/x402/secure-token"
 },
 "ts": "2026-08-30 13:20:02",
 "verdict": {
  "decided_by": "two-call reconcile",
  "method": "field-presence vs promised (conform.judge)",
  "reverified": true,
  "status": "short",
  "why": "shortfall confirmed on two calls"
 },
 "verify": {
  "cmd": "python3 receipts.py --verify wab_30e3fc8f7f759a1c",
  "integrity": "sha256 over the evidence fields must equal receipt_id",
  "raw": "re-derive observed_schema from delivery.raw_ref, then re-judge",
  "verdict": "conform.judge(delivery.observed_schema, promise.fields).status == verdict.status"
 },
 "version": "2"
}

Back to the receipts · The whole ledger as JSON