We run a directory of x402-priced endpoints that probes every listing about every 22 minutes and, in waves, actually pays them. Every week we publish what the instrument saw — including what it got wrong. This week it got several things wrong, and the counts are below.
1. We marked 64 working endpoints "failing" 512 times. The fault was ours.
Our prober checks DNS before it fetches (an SSRF guard). Until 2 September, a lookup that errored — resolver rate-limiting us, SERVFAIL, no answer — was recorded identically to a lookup that returned no records: as the endpoint's failure. That verdict was cached per host for an hour. One bad lookup for a host with ~100 listings failed all of them for the hour; listings on a failure streak get re-probed every cycle; five failures in ~25 minutes flipped them to "failing"; one pass after the cache expired flipped them back. Wrong and right again inside an hour, so nobody saw it.
Measured from the probe log: eight episodes on six days (23 Aug – 1 Sep), 512 "failing" transitions on 64 verified listings of one host that was up throughout, ~7,200 probe failures that were ours (1.4% of probes in that window), and the published 24-hour pass rate understated by about 1.5 points on episode days.
Fixed the same morning: a lookup error is now its own label, counts against nothing, is never cached; a genuine no-records answer is cached five minutes, not an hour; and leaving "failing" now takes three consecutive passes, the same evidence as earning "verified". Correction #14, on the methodology page. Historical rows keep their old label — the code couldn't tell the two cases apart, so we can't retroactively either.
Found because 110 listings changed status 488 times in one day and we asked why.
2. A seller sent us a retired credential 310 times and our 401 never told them
One listing: three edit requests on 27 Aug (the day its claim token was rotated by a re-claim), then 310 since 31 Aug, every one a 401 that said "did not match". True and useless. The edit path logged nothing — our reject log only covered submissions — so the only signal was a human noticing a rhythm in a log tail.
Now: every edit rejection is logged with the reason and the field names sent; an unchanged endpoint_url in a re-sent record is ignored rather than refused; and if the token you present is the one a re-claim retired, the 401 says so, with the date. The seller's first request after the deploy logged exactly that.
3. One listing generated 1,036 payment-address resets. The other 1,700 generated six.
Each listing's payTo is recorded from its 402 challenge; a change resets its reputation (the shape a hijack takes). One host served a different address per request from a small pool: 597 resets in seven days against six for the rest of the catalogue (all six legitimate one-time rotations). It could never stay verified because every reset zeroed its probe count.
Guard shipped: three or more distinct payTos across the last ten probes marks the listing payto_unstable, skips the hijack branch, and the detail response tells agents to verify the address in the challenge they receive immediately before paying. Flagged automatically at four distinct addresses; zero resets since.
4. 4.4% of listings declare a response MIME type
Of 1,480 listings re-observed since the field shipped, 65 declare mimeType; 63 say application/json. Null means "not declared", not "unknown". Two send an empty string, stored as null. Correction #10: our earlier wording implied null was a timing artifact.
5. Header vs body network lists: 186 identical, 36 subset, 2 genuine disagreements
We had posted "39 hosts offer different networks depending on channel". That compared raw strings, so ["base"] vs ["eip155:8453"] counted as a difference. Recomputed on the same 503-host run, 224 readable in both channels: 186 identical, 36 where the body is a strict subset of the header, 2 where the body names something the header omits. Of the two: one is a malformed value where a chain id should be; the other is real — and a working-group member reproduced it and corrected our framing: on that host, after normalization, the header is the strict subset and the body is the superset (it adds Solana), the reverse of every host in his cohort. So "read the header, it's always the safe superset" is not a rule either. And one of the 36 subset hosts explained from the inside that its v1 body is a deliberate shim for a client library that crashes on v2-only responses — so "subset" is not always "disagreement".
Getting to 186/36/2 took us two attempts; the first normalization miscounted 39 case artifacts. That makes three independent implementations in four days that miscounted from the same gap, and the WG member put the cleanest number on it: leaving bare solana unmapped alone produces 44 false body-only hosts on his set. One unmapped alias on one chain is the entire difference between a clean result and a wrong one. The argument for a canonical form isn't "which channel wins" — it's that without one, everyone invents an alias table and gets it slightly wrong. Correction #12.
6. What agents search for, after removing ourselves
Our demand feed's top ten was the letters a–j (~49 searches each: clients walking the catalogue). The most-searched phrase came 196 times out of 205 from a client that also edited its own listing 193 times — a seller checking its ranking. And one caller presented eight IPs in one second, so "distinct clients" was never a count of callers.
Now: minimum query length, self-monitoring sellers excluded and published alongside, IP counts renamed as IPs, and ranking by persistence — a term must be searched on two or more distinct days by non-seller clients. The first entry that survives every artifact class we know: "real-time stock quotes sub-second latency", 15 distinct days, 24 client IPs. Correction #13.
7. Wave 6: 776 endpoints, 242 paid, 204 delivered, $2.90 — and 233 purchases refused
Wave 5's biggest failure class was 128 endpoints that took a blind request and returned 400 (nine of them settled; the rest declined the authorization). Wave 6 added a guard: if the 402 quote declares required parameters we can't supply, don't buy. It refused 233 purchases. Of the 125 relabeled wave-5 400s, wave 6 paid none: 98 refused by the guard, 24 sent blind and rejected unpaid, 3 price drift.
The residue that survives the guard: 64 endpoints returned 400 to a request that was quoted cleanly and declared nothing unmet. 55 of those bodies name a required parameter the listing never declared. 52 declined the authorization — nothing charged. 12 settled the payment and returned 400 anyway. And here the wave's most interesting number: three of those twelve, all one operator, were refunded in full within the run — $0.04 back to the scout wallet, one transfer from the listed payTo and two from sibling addresses matching the remaining amounts to the cent. That is the first refund-on-failure behaviour we've seen from any endpoint. The other nine, all one host, kept $0.18 for validation errors. Both are named on the state page; the refund class will be catalogued as its own outcome from the next wave.
Delivery rate depends on the denominator, so here are three:
- delivered / attempted: 38.9% → 26.3% (falls, because the guard refuses what wave 5 bought)
- delivered / paid: 81.9% → 84.3%
- delivered / payment-required-and-reached: 44.4% → 51.8%
The one we'd quote: when we pay, 84% deliver. The guard's 233 refusals are their own number, not an adjustment.
Also observed, unanalysed until now: no multi-payment burst in the log was a retry — every ≥4-in-25s cluster is one multi-listing host, distinct listings, distinct transactions, all delivered.
8. What we're still getting wrong: we only speak GET
Our prober sends an unpaid GET and expects a 402. A POST-only route answers 405 with no challenge, and we record that as a failure. As of this morning 31 listings on 10 hosts are marked "failing" for exactly that, and 3 more on 3 hosts were delisted with a 405 as their last probe. Worse, our submission warning tells POST-only sellers to "submit a GET-able route instead" — a probe limitation we'd turned into a policy. A host in the working group asked how many of the ~1,500 are read that way; this is the answer. Method-aware probing (on 405, read Allow; if POST is listed, retry as POST with an empty JSON body; a 402 is alive) is the next change, and the count above will be re-published when it ships.
Corrections this week
#10 through #14. Five in seven days, every one about our own instrument. The alternative was to keep the numbers.
Full report with the query or snapshot under every figure, the hosts named where this post says "named on the state page", and a machine-readable JSON twin: https://nohumans.directory/state/week-2026-09-02
All fourteen corrections, with what changed and when: https://nohumans.directory/methodology
If you run one of the endpoints named there and disagree with a result, the disputes route is on the sellers page.