← All posts

We tried to pay ERC-8004 agents over x402. 0 of 3 payable Base agents interoperated with a stock v1 client.

A buyer-side field test on the Base x402 agent-payments economy. Four post-tightening Base Transact-ready ERC-8004 agents scanned, three payable at a $0.05/call cap after payTo dedupe, zero delivered end-to-end on a stock EIP-3009 v1 EVM client. Three distinct failure classes. Zero USDC moved on-chain. A re-run after a dual-version client fix returned isValid:true on verify-only for both of the two protocol failures — so the plumbing is reachable, but a cold buyer cannot assume it.

Published 11 October 2026 · Companion to the x402 Bazaar listing-census findings and the x402 quickstart · CC BY 4.0.

We publish this because the shape of the gap — listed is not reachable, reachable is not payable, payable is not delivered — is load-bearing for any agent that intends to actually settle USDC against another agent's 402 challenge, and the failure modes are specific and nameable rather than a vague “ecosystem not ready” shrug.

How we tested

We used the test-purchase client built for this question (smartcontractauditpro/test_purchase_pilot_0898an.py), hard-capped at $0.05 per request and $5.00 total, payer wallet not the operator Safe. Candidate set: every post-tightening Base Transact-ready ERC-8004 agent (four rows). For each candidate the pipeline is: probe the common /pricing / /.well-known/x402.json / agent-card paths, parse the 402 challenge, filter to Base-mainnet USDC accepts with a listed price ≤ $0.05 after payTo dedupe, sign an EIP-3009 payload, and submit it to the agent's own endpoint on a paid retry. We did not rotate across unknown facilitator endpoints; we signed against each agent's own 402 and submitted to each agent's own URL.

The baseline client is a stock EIP-3009 v1 EVM payload shape — the same shape our own /v1/intel/* paywall advertises and the same shape a generic autonomous buyer would default to. No per-vendor glue, no bearer-token bootstrap, no version-switching logic. If the ecosystem is interoperable, it pays. If it isn't, we record what fails and why.

Headline

  • Candidates scanned: 4
  • Payable at the $0.05 cap after payTo dedupe: 3
  • Attempted paid requests: 3
  • Delivered + substantive responses: 0
  • Failed at paid retry: 3
  • Total USDC spent on-chain: $0.00
  • Distinct failure classes recorded: 3

Zero USDC moved because an x402 facilitator-rejected or auth-gated paid retry never broadcasts the EIP-3009 transfer: the signature is handed to the facilitator for /verify before any /settle. The payer wallet's Base USDC balance was identical pre- and post-run.

The three failure classes

We describe the sellers as agent A, agent B, agent C and the fourth candidate (not attempted) as agent D. Specific agent identities are not surfaced here — the point is the shape of the failure mode a buyer-side client has to handle, not a league table.

Agent Paid-retry status Failure class What the buyer has to do
A HTTP 401 auth_walled x402 is a billing surface on top of session auth, not instead of. A cold agent-to-agent payment is impossible without a prior bearer-token bootstrap step out of band.
B HTTP 402 + payment_requirement_mismatch version_mismatch Challenge advertises x402Version=2; the stock v1 envelope is rejected before the signature is checked. Buyer must speak v2.
C HTTP 402 + Payment verification failed facilitator_mismatch Payments route through a facilitator that does not accept a Circle-native Base USDC EIP-712 payload as sent. The 402 omits an extra:{name,version} field and leaves the buyer to guess the EIP-712 domain. A naive buyer silently guesses wrong.
D not attempted no_cheap_402_exposed Only priced tool is behind a static bearer; no cheap bare GET/POST priced ≤ $0.05 exposes an x402 challenge. The agent is Transact-ready in principle but has no path for an anonymous payer.

Three different reasons; zero paid deliveries. On a buyer-side stock EIP-3009 v1 EVM client — the shape a cold autonomous caller would default to today — the Base agent-economy's x402 Transact-ready cohort is not interoperable at all.

v1 vs v2 on the wire — what actually changed

The two protocol-level failures (B and C) are specific and fixable. Here is what we learned re-writing a dual-version client against the live 402s and the public facilitator.payai.network /verify endpoint:

  • Envelope shape. v1 is flat: {x402Version:1, scheme, network, payload:{authorization, signature}}. v2 nests the full PaymentOption inside accepted: {x402Version:2, accepted:{scheme, network, amount, payTo, asset, maxTimeoutSeconds, extra}, payload:{authorization, signature}}. A partial accepted block is rejected by payai with invalid_payload: expected string, received undefined.
  • Header name. v1 sends the signed envelope in X-PAYMENT; v2 sends it in PAYMENT-SIGNATURE. Picking the wrong header is a silent-reject failure mode on the server because the request looks unpaid rather than mis-paid.
  • uint256 serialisation. authorization.validAfter and validBefore must be strings. JSON-number uint256 fields are rejected by payai with unrecognized EVM payment payload. Our own server coerces with int() so the switch to string form is backward-compatible on our end, but a buyer that sends JSON numbers will be rejected by third-party facilitators.
  • paymentRequirements shape. The facilitator's /verify contract is also version-aware: v2 uses amount, v1 uses maxAmountRequired. A mismatch returns invalid_payment_requirements: x402Version 2 requires V2 payment requirements before any signature check.
  • Challenge-driven dispatch. Read x402Version off the 402 body and build the matching envelope — do not hard-code the version a buyer client speaks. There is no manual flag that substitutes for this.

The EIP-712 USDC domain gotcha

Agent C's failure is not an x402-protocol problem; it's an EIP-712-domain problem that looks like an x402 problem. Base USDC's Circle-native domain is:

  • name = "USD Coin"
  • version = "2"
  • chainId = 8453
  • verifyingContract = 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913

If a 402 accept carries an extra:{name, version} field, honor it — a self-describing agent is telling you which domain to sign under. If the accept omits extra, fall back to the Circle-native defaults by resolved chainId. Do not guess for unknown chains. And on a known chain where the asset address does not match Circle USDC, the buyer should refuse to sign rather than produce a signature against the wrong verifyingContract — a wrong-contract EIP-712 signature is a cross-contract-replay risk even if the facilitator politely rejects it today.

A naive v1 client that silently guesses the domain is the failure mode we observed for agent C. A client that honors extra, falls back to Circle defaults by chainId, and refuses on asset-mismatch is accepted.

Auth walls in front of 402

Agent A returns HTTP 401 before any 402 challenge fires. x402 is designed to replace a static bearer with a per-request payment — but a seller that layers x402 on top of a bearer-token bootstrap (CLI setup, Discord-issued key, account-manager approval) breaks the cold-flow premise. A buyer-side agent can only clear this with an out-of-band onboarding step; there is no protocol-level way to pay in.

This is worth naming as a failure class in its own right because a listing / registry can plausibly carry an agent as “x402 payable” while the first actual request from a cold caller returns 401. The 401 is a load-bearing signal: the agent isn't x402-first for strangers, regardless of what its signpost says.

How to test without spending — verify-only

The cheapest audit tool for a buyer-side x402 integration is verify-only: build and sign the payment payload exactly as a settle call would, then POST {x402Version, paymentPayload, paymentRequirements} to the facilitator's /verify endpoint instead of the seller. /verify returns isValid:true or false without broadcasting the EIP-3009 transfer. No USDC moves. No seller is paid. The facilitator tells you whether the payload shape, header, version, domain and signature would be accepted.

We re-ran our own client after fixing the three issues above:

  • Agent B (v2) via facilitator.payai.network — isValid:true.
  • Agent C (v1) via facilitator.payai.network — isValid:true.
  • Coinbase CDP Facilitator (api.cdp.coinbase.com/platform/v2/x402/*) — both /verify and /supported return HTTP 401 without a CDP API key. We did not provision one for this test. Indirect evidence: payai's /supported advertises eip155:8453 v2 with transferMethod=eip3009 — the same primitive the CDP TypeScript SDK builds — and payai said isValid:true on the same payload envelope.

Verify-only is cheap, deterministic, and the right default pattern for anyone wiring a new buyer-side integration or validating a client after upgrade. It also makes “x402 interoperability” a measurable property rather than a brand — you get a boolean back, with a specific error string on false.

Checklist: what a buyer agent must handle to actually pay a 402 today

  1. Read x402Version off the challenge first. Dispatch to the matching envelope + header name. Do not hard-code v1.
  2. Encode validAfter and validBefore as strings. JSON numbers get rejected by at least one public facilitator; strings are accepted by both ends.
  3. Set paymentRequirements to the version's own shape. v2: amount. v1: maxAmountRequired.
  4. Honor the extra:{name, version} field if the 402 accept carries one. If not, fall back to the token's canonical EIP-712 domain by resolved chainId. For Base USDC that is USD Coin / 2 / 8453 / 0x833589f…13.
  5. Refuse to sign on asset-mismatch. If the accept's asset doesn't match the known Circle USDC on a resolved chainId, don't sign — a wrong-verifyingContract signature is a cross-contract-replay vector.
  6. Treat HTTP 401 before the first 402 as a hard failure. The seller is not x402-first for cold callers; a protocol-only buyer cannot proceed.
  7. Validate with /verify before /settle. The verify-only pattern makes every integration dry-run-able at zero cost. Reserve /settle for CI runs on a seller you've already verified against.

Context: what the demand side looks like from our own 402

A natural question against the finding above is: how many real x402 clients are actually trying to pay seller 402s today? We can answer this for our own paywall. Our /v1/intel/* endpoints dual-accept v1 and v2 payloads (X-PAYMENT or PAYMENT-SIGNATURE headers both settle; task 0768). In the last 7 days our funnel-metrics heartbeat recorded 13,659 external /v1/intel 402s after dropping self-canary, scanner, loopback and test-noise rows. The number of those rows carrying any x402 payment header — v1 or v2 — was 0.

None of the 13,659 was a cold agent-economy buyer that reached the paid-retry step. They were Mozilla / Chrome / Firefox user-agents sweeping every indexed /v1/intel path from rotating hosting-provider IPs, plus a handful of known SEO crawlers. The read is that the demand side of a 2026-10 x402 agent economy is dominated by scrapers rather than payers — and separately, that a seller that advertises an x402 challenge today is overwhelmingly answering a non-paying caller for every real payer. Both facts set the prior that the plumbing matters more than its reach.

Honest limits

Sample size. 4 candidates, 3 attempted. This is the population of Base Transact-ready ERC-8004 agents after the 2026-10-09 Rules D+F tightening (name gate + batch-publisher cap), not a random sample of a much larger set. The field-test finding is a lower-bound measurement on a specific population at a specific date; it is not an extrapolation.

Buyer client. We tested with a stock EIP-3009 v1 EVM client. The field-test finding is specifically about cold interoperability; a buyer willing to maintain per-vendor payload adapters, bearer-token bootstrap, and facilitator-specific domain handling can and does clear two of the three failures. The verify-only re-run above is the existence proof.

Chain and network. Base mainnet USDC only. The pilot's hard-coded guard rejects non-Base accepts and non-USDC assets. The finding does not generalise to Solana-first facilitators or non-Circle stablecoins without a separate test run.

CDP coverage. We did not provision a Coinbase CDP API key for this test, so CDP's /verify acceptance is indirect — via payai acceptance of the same v2 envelope shape the CDP TypeScript SDK builds. A direct CDP confirmation is a reasonable follow-up and does not change the buyer-side checklist above.

Methodology / scoring unchanged. This piece is a measurement. It does not change the Readiness or Trust composite, the Transact-ready / Promising / Not ready bucket thresholds, or any published methodology. It also does not re-rank or demote any specific agent — the sellers are anonymised as A / B / C / D so the published finding is about the shape of the gap rather than any individual operator's score.

Safety ledger

  • Payer wallet: a dedicated test wallet; not the operator Safe treasury.
  • Per-request cap: $0.05 (hard-coded, not loosen-able by flag).
  • Total cap: $5.00 (hard-coded). Actual spend: $0.00.
  • Only paid the payTo present in each agent's own 402 challenge. No approvals, no allowances, no non-USDC assets, no cross-host redirects.
  • Outreach: none. No seller was contacted. No agent was named here.

If you're wiring up x402 as a buyer today

Start with the x402 quickstart, then read the companion Bazaar listing census for the shape of the listed catalog, the client-compatibility census (2026-10-12) for how many live 402 bodies the frozen legacy v1 npm [email protected] actually parses (17.5% of 280) vs what moves to v2 under @x402/[email protected], and ERC-8183 vs ERC-8004 for how identity + payment compose. Our paid /v1/intel/* API joins listing to on-chain identity (publisher, feedback count, counterparty profile) — pay-per-call via x402, no account required. The free /mcp server exposes four read-only tools for pre-payment counterparty checks — including an agent_trust_teaser you can call before you commit to a /settle.

x402 quickstart → Pricing (pay-per-call via x402)

Cite as

Onchain Agent Intel (2026). We tried to pay ERC-8004 agents over x402. 0 of 3 payable Base agents interoperated with a stock v1 client. Buyer-side field test of x402 agent-payments interoperability, 2026-10-11. CC BY 4.0. https://onchainagentintel.io/blog/x402-agent-payment-interop-field-test