The question
Every few weeks another thread goes around claiming “N thousand agents are on-chain and payable right now.” The number is usually the raw IdentityRegistry mint count. That tells you how many have registered. It does not tell you whether any of them is actually answering an HTTP 402.
So we did the simplest observational thing you can do: for every ERC-8004 agent that advertises an x402 endpoint in its public metadata, send one unauthenticated request and record whether a valid 402 challenge comes back. No payment, no signature, no credentials. Just the piece of behaviour that a prospective buyer would observe before paying.
What we probed
We started from the 84 agents whose on-chain
metadata already contains a parsed x402_challenge
block in our shadow index. The block carries one or more of three
endpoint shapes:
accepts[].resource— a canonical URL that returns a 402.endpoints[].path— a path template to join with a base URL.resources[]— a bare URL list.
We extracted every candidate URL, deduped within the agent,
globally deduped on (url, method),
capped each host at 15 endpoints for politeness, and capped the
overall set at 600. The final probe list was
412 endpoints across 40 hosts, covering all 84
agents.
Each endpoint got one request. GET for
accepts.resource and
resources[], the advertised method
for endpoints[] (POST/PUT/PATCH
with an empty body). Every request carried a signed
User-Agent
(onchainagentintel.io/0946-x402-probe,
with a contact mailbox), accepted JSON, and crucially
never sent an X-PAYMENT
header. We did not sign anything, we did not submit a
payment, we did not try to escalate past 402.
Pacing was 2 req/s with an auto-slowdown rule if more than 20% of the last 50 responses came back 429. The slowdown never triggered — we observed zero HTTP 429 across the full run. Wall-clock: 4 minutes 24 seconds.
What counts as a “valid challenge”
The x402 draft
(draft-bb-httpbis-http-status-402)
says a server advertising x402 should return
status 402 with a parseable
accepts[] list of payment
requirements. We parsed accepts[]
from three shapes you'll find in the wild:
- JSON body with top-level
accepts. - JSON body with
x402.acceptsnested. - Header
Payment-Required: <base64-of-accepts-list>.
A probe row was marked valid iff the response was
402 AND we recovered a non-empty accepts[]
from any of the three shapes.
The numbers
| Metric | Count | % of 412 |
|---|---|---|
| Endpoints probed | 412 | 100 |
| Reachable (any HTTP status returned) | 412 | 100 |
| Returned HTTP 402 | 280 | 68 |
| Returned a valid x402 challenge | 270 | 66 |
| Served discovery doc (HTTP 200 at the probe URL) | 18 | 4 |
| HTTP 404 | 60 | 15 |
| HTTP 405 (method not allowed — endpoint exists, our method wrong) | 33 | 8 |
| HTTP 503 | 13 | 3 |
| HTTP 400 / 401 | 8 | 2 |
HTTP-402 latency across responses: median 171 ms, p90 677 ms, max 5.77 s.
Rolled up to agents:
| Registered chain | Agents advertising x402 | Agents with ≥ 1 valid 402 | Hit rate |
|---|---|---|---|
| Base | 76 | 55 | 72% |
| Ethereum mainnet | 8 | 3 | 38% |
| TOTAL | 84 | 58 | 69% |
58 of 84 ERC-8004 x402-advertising agents returned at least one valid, parseable 402 challenge when a prospective buyer pokes them cold.
The multi-chain surprise
ERC-8004 is often cited as “Base + Ethereum, maybe BNB.”
The accepts[] entries we observed
say something different. Here's what the 58 payable-now agents
accept USDC on (one agent can appear on multiple rows):
| USDC-accepting network | Agents (of 58) |
|---|---|
| Base | 56 |
| Ethereum | 5 |
| Solana | 17 |
| XRPL | 7 |
| Algorand | 7 |
| BNB | 5 |
| Polygon | 5 |
| Starknet, Sui, Tron, Near, Stacks, Aptos, Bitcoin, Stellar, Rootstock, Filecoin, TON | 5 each |
| Arbitrum, Avalanche | 2 each |
Five of the 58 advertise USDC on 15+ networks — these are gateway-operator agents aggregating many downstream services behind one wallet. 17 of the 58 accept USDC on Solana. The frontier of x402 payability is already visibly broader than the Base + Ethereum story.
payTo consistency
For 70 endpoints we had both an advertised
payTo in the on-chain metadata
AND a payTo in the live 402 body.
On all 70 the two matched. Zero divergence. When
these agents advertise a wallet, hitting the endpoint confirms the
same wallet.
That matters because it's the honesty check a human can perform without paying anything: before you send USDC, you can cross-check the on-chain declared payTo against the live 402 and refuse to pay if they diverge.
Price distribution
Across 348 USDC-denominated accepts
entries, the per-call price distribution:
| Range | Entries |
|---|---|
| Below $0.01 | 62 |
| $0.01 – $0.05 | 168 |
| $0.05 – $0.10 | 49 |
| $0.10 – $0.50 | 37 |
| $0.50 – $1.00 | 6 |
| $1.00 and above | 26 |
Median: $0.02. If you bought every endpoint once in USDC, the total cash cost would be $336.71.
The interop lesson our own 402 taught us
One honest finding worth stating up front:
our own 402 challenge was unparseable by canonical npm
[email protected] until
2026-10-12. The 2026-10-11 probe was observational on
other sellers; a day later, when we re-ran a parse pass
on ourselves, our paywall was emitting
network: "base-mainnet" and
outputSchema: null. The canonical
client rejects both — the x402 v1 spec expects
network: "base" (the Base x402
facilitator chainId-8453 identifier), and
outputSchema must be omitted
rather than nulled. The fix landed on 2026-10-12 (task 0960): emit
network: "base", drop
outputSchema when there is no
response-shape commitment, keep every other field unchanged.
We publish this as a self-authored interop lesson. A cold buyer with a stock npm client is held to the same bar our outside probes held every seller to. If the shape doesn't parse, “payable” is false regardless of whether the seller's wallet is live. 10 of the 412 endpoints we observed were HTTP 402 with unparseable accepts shapes — the same failure class we were tripping on ourselves. The fix is almost always “match the v1 field types exactly;” the v1 draft is strict about omit-vs-null and about canonical network slugs.
Caveats worth stating out loud
-
26 of 84 agents returned no valid 402. We're
not naming them individually — some are correctly serving
an x402 discovery doc at the probe URL (HTTP 200 with an
accepts[]body is a legitimate shape; it just means we didn't walk one level deeper to the actual paid endpoint). Others returned 404/405/503 at the advertised path. A second-pass probe that walks discovery docs and tries alternate methods would recover a chunk of the first group. - Gateway-operator concentration. The 58 payable- now agents are distributed across ~45 distinct wallets, not 58. Five Base agents share a single operator wallet. Any public “payable” marker needs to disclose when a wallet collects for multiple agents, not treat each registration as independent.
- One moment in time. Infra decays. A 2026-10-11 probe does not guarantee anything about 2026-11-11. If a surface uses observational probes for a public signal, it needs a cadence and a “last verified at” timestamp.
- Not a security audit. A valid 402 means someone is answering the protocol. It is not a claim about ownership, custody, operator identity, or whether the service behind the endpoint does what the metadata says.
What this means for buying an agent service
If you're an x402 client wiring a buyer wallet into your runtime, the practical shape is:
- Point your client at an ERC-8004 agent you care about.
-
Confirm the on-chain metadata's advertised
payTomatches the live 402 body'spayTo(zero divergence in our 70-row sample). -
Confirm the price in the
accepts[]is what you expected (median $0.02; one in six is above $0.10). - Pay and go.
If you want the pre-flight check industrialised rather than
hand-rolled, the data behind this post lives in our API. The free
MCP server exposes a
list_payable_x402_endpoints tool
that returns exactly the payable set we probed, filterable by
chain — call it before you commit to a
/settle. See the
x402 quickstart for a
three-step buyer-side walkthrough, and
pricing
for the pay-per-call paid API.
Reproducibility
Every numeral in this post comes from a single probe run on 2026-10-11, raw rows retained. No methodology change was shipped as a result of this post. Published 2026-10-12 with the one-day-later self-authored interop lesson folded in (our 402 shape fix, task 0960). The companion internal note on probe method and per-row aggregates is retained for cite-back.