Correction: “76% dead” was our bug, not the market’s

Published 2026-07-30 · the permanent home of this correction · live data · methodology

On 2026-07-18 we published an audit of the x402 agent-payment economy headlined “76% is dead.” That figure measured our own parser, not the ecosystem. Our prober read payment requirements only from the HTTP response body; x402 v2 moved them into the PAYMENT-REQUIRED header. Live services were recorded as dead. 23133 endpoints are live today and the dead share is 19%. Everything below is reproducible from public endpoints.
1,869endpoints wrongly marked dead
166operators affected
3,920false history records removed
19%dead share, corrected

Update 2026-08-06: the dead share moved 38% → 37%, and why

A platform audit found that our own blocked verdict was being counted as “dead”. blocked is not an observation about a service — it is our refusal to send a request to that address under our SSRF policy. Counting it against the service writes our own behaviour into someone else’s track record, which is precisely the class of error that produced “76% dead” in the first place.

67 endpoints were affected. They are no longer counted as dead, are no longer given an avoid verdict, and are reported separately as blockedByPolicy in /status.json. The published dead share changes from 38% to 37% — a real move of 0.42 percentage points, the rest is rounding.

Update 2026-08-10: the dead share moved 38% → 19%, and it is the same error a third time

Our prober sends GET to every endpoint. 38.1% of the CDP Bazaar index declares a non-GET method when we measured it on 2026-08-10 (5,337 rows, almost all POST; 43.7% on 2026-08-17, so the share is growing), which the catalog publishes in extensions.bazaar.info.input.method. A GET against a POST-only route returns 404 or 405, and our prober recorded that as no-402 — dead.

5760 of our no-402 verdicts are endpoints the catalog declares as non-GET. The response codes are exactly what a method mismatch looks like: 2,902 × 404, 1,825 × 405, 428 × 200, 292 × 400. That verdict described our request, not their service.

This is the third appearance of one error: writing our own behaviour into someone else's track record. First the parser that read only the response body (“76% dead”). Then our SSRF blocked verdict (38% → 37%). Now the method. Each time the correction moved the number down, and each time it was found by us rather than by a user.

Affected endpoints are now reported separately as methodMismatch in /status.json and are excluded from the denominator — they are not dead, they are unmeasured. The published dead share moves from 38% to 19%.

What is still not fixed. The right repair is to probe with the declared method, not to exclude those endpoints. We have not done that: sending POST to several thousand third-party endpoints is a state-changing request against systems we do not own, and it needs a deliberate decision rather than a quiet code change. Until then, treat 19% as a lower bound on the dead share and 5760 endpoints as genuinely unknown.

We are flagging this because the 38% figure was cited in a pull request against the x402 specification. A number that changes quietly is worth less than one that changes with a note.

The same audit found three more places where we published something we had not measured, all now fixed: 976 of 1,039 npm packages carried a “low downloads” flag produced by our own rate-limited counter rather than by their actual popularity (three of them have 71k–95k weekly downloads); 1,108 records were filed under “free” because a missing catalog price was read as zero instead of using the price our own probe had measured; and 475 public pages printed “uptime 100%” from one or two observations, while the paid product in the same codebase correctly refuses to state a percentage below three. Service pages no longer emit a schema.org Review rating for third-party services at all.

The mechanism

In x402 v1 the challenge lives in the JSON body. In v2 it moved into a base64-encoded PAYMENT-REQUIRED response header, and the body became a server implementation detail — many v2 services return no accepts in the body at all. A body-only parser sees HTTP 402, finds no requirements, and concludes the endpoint is broken.

curl -sD - -o /dev/null https://api.onesource.io/api/chain/block-number \
  | grep -i '^payment-required' | sed 's/^[^:]*: //' | base64 -d

That returns a complete, valid challenge. We had published this endpoint with a trust score of 8/100, 0% uptime and the advice “do not pay: dead or invalid.” Among the 1,869 affected endpoints was pro-api.coingecko.com.

The same bug distorted our comparison against the 402index catalog. We had been publishing that only ~30% of what it lists as “healthy” really is. Corrected, the figure is 86%. The catalog was substantially more honest than we said.

What we changed

Parser. Both sources are read; the header wins when they differ, because that is what a v2 client pays against. A disagreement between them is now recorded as a signal in its own right.

History. Uptime was computed from past verdicts, and for these services every past verdict was our bug. We removed 3,920 malformed records from 1,869 endpoints that now return a valid header challenge, kept all unreachable and no-402 records (the bug could not produce those), and stamped each repaired record with historyRepairedAt, historyRepairedEntries and a note — visible in the free /verify response, so anyone reading a track record can see that it was edited and why.

Confidence. Uptime is null below three observations, with an explicit insufficient flag. A track record you cannot state is better than one you invent.

Time series. Each daily snapshot carries a probeVersion, and deltas across a version boundary are suppressed with a stated reason — otherwise our own fix reads as the market doubling overnight.

Prior publications. Archived daily reports produced by the old prober carry a banner telling readers not to cite their liveness numbers, and /llms.txt carries a machine-readable correction next to the link to the original article. The article itself is on a third-party platform under a personal account; until its author adds a notice, treat this page as the correction of record for it.

Four more mistakes of the same kind

While building detectors for endpoints that return a valid 402 but are not payable products, we made three further errors within hours — each one our code encoding an assumption about the protocol instead of the protocol — plus one about language.

1. We called a standard scheme unpayable

We treated exact as the only settleable scheme. The specification has four: exact, upto, auth-capture, batch-settlement. The service we flagged uses upto — normal, in-spec, and by on-chain volume one of the largest receivers in the ecosystem. Three separate claims in that alert were false. The real distinction is outside the spec (settlement bypasses the facilitator, funds are not in escrow) versus in-spec but not exact (a default client cannot pay it without work — a compatibility note, not an accusation).

2. We read an authorization ceiling as a price

The same service advertises amount: 1000000000. In upto that is the maximum the service may draw, not the cost of a call. We compared a ceiling against other services’ per-call prices and called the difference an absurd price. Ceilings now live in a separate field and never enter price comparisons.

3. We described a mechanism we never tested

We wrote that placeholder URLs return 402 “before the route is resolved” and that a payer “gets a 404.” Both were guesses. A genuinely nonexistent path on those hosts returns 308 or 502, not 402 — the route did match, and the placeholder was accepted as a parameter value. What a payer receives we do not know, because we did not pay. The claim is now limited to what is observable.

4. We attached intent to companies we had just been wrong about

Our feed labeled named businesses with “bait-and-switch pricing,” “price gouging,” “honeypot receiver,” “possible hijack.” Intent cannot be demonstrated from an HTTP response, and we had just been wrong about mechanism three times in one day. Labels now describe the observation, and where an innocent explanation exists it is stated alongside: routine key rotation and a compromise are indistinguishable from outside.

What “live” actually means

Every one of these errors came from treating “returned a 402” as “is a payable product.” It is not the same claim. This is the checklist we run now. It is meant to be copied — apply it to your own index.

CheckWhy it exists
1Parse the challenge from both the response body and the PAYMENT-REQUIRED header, preferring the headerv2 moved it out of the body; body-only readers report live services as broken
2Compare the two when both are presentIf they disagree, a v2 client pays what the header says — not what a body-only check displays
3Check the scheme against specs/schemes/Outside the spec means settlement bypasses the facilitator; in-spec-but-not-exact is a client compatibility matter, not a risk
4Know whether amount is a price or a ceilingupto and auth-capture state a maximum authorization, not a per-call cost
5Check that the network is mainnetA testnet sandbox priced in dollars is not a product
6Check the URL for unfilled path placeholders:id, {id}, /example are strings from documentation
7Know the token's decimals per chainUSDC is 6 decimals on most chains and 18 on BSC; assuming 6 everywhere is a 1012 error
8Count distinct operators, not endpointsA single host can list hundreds of routes
9State the observation count next to any uptime figureA percentage computed over one observation is not a track record
10Version your measurement method and mark the break in the dataOtherwise your own fixes read as movement in the market

Our own numbers under that checklist

We report 23133 live endpoints. Inside that number: 1508 are documentation placeholders — and honesty requires the next sentence: 604 of them are a single host (api.gocreativeai.com). Without it, 904 placeholders across 169 domains. Reporting the larger figure and stopping there would be exactly the inflation we criticise. A further 131 are on test networks, 45 advertise a scheme outside the spec, and one has a body/header disagreement. Those 23133 endpoints resolve to only 1917 distinct hosts, and the top two account for 8% of them.

So we stopped leading with the larger number. 21476 of those 23133 endpoints, across 1820 operators, are things an agent can actually buy — the rest are documentation placeholders, testnet sandboxes or schemes outside the spec. Both figures are published side by side: payableEndpoints next to healthyEndpoints in /status.json, and the landing page, the observatory and the embeddable widget now lead with the payable one. Keeping the bigger figure in front would have been the same inflation this page is about.

Limits worth stating plainly: our observations begin 2026-07-06, which is shallow. Other trackers have longer history and broader coverage, and where our numbers differ the longer series is more likely to be right about trends. We are confident only about what we can re-probe today.

Verify all of it yourself

# ecosystem totals, composition, catalog comparison
curl -s https://pulsefeed.dev/status.json | jq '.ecosystem, .catalogAudit'

# one endpoint, free
curl -s 'https://pulsefeed.dev/verify?endpoint=https://api.onesource.io/api/chain/block-number' | jq

# every anomaly currently observed (395 right now)
curl -s https://pulsefeed.dev/incidents.json | jq '.byCategory'

# the schemes the spec actually defines
curl -s https://api.github.com/repos/x402-foundation/x402/contents/specs/schemes \
  | jq -r '.[] | select(.type=="dir") | .name'

The dataset is CC-BY-4.0 on Hugging Face. If you find an error on this page, tell us — that is now demonstrably the fastest way to improve this dataset.

PulseFeed · independent measurement of x402 payment endpoints and MCP servers · home · status · observations · methodology · llms.txt