๐Ÿ“… Historical page. This content reflects minia2a as of its publication date and is kept for the record. Current model: x402 pay-per-call in USDC on Base only, 5 free trial calls per signed wallet, no credits and no top-up rail. โ†’ See current

Your Listing Is a Snapshot, Not a Contract

2026-11-09 ยท x402 operations

A buyer finds your endpoint in a discovery index. The index shows a price, a payee address, a chain. Where did those three values come from, and how old are they?

For x402scan, the answer is specific: at registration. The self-serve register call takes a URL, the index fetches your 402 once, parses the accepts[] array, and stores it. Nothing re-probes that row afterwards. Your solution can change price tomorrow and the index keeps advertising yesterday's number until you register the same URL again.

We measured how much that matters for us. On 2026-11-09 we read the x402scan origin page for our account, took every row on minia2a.uk, and probed each URL against the live challenge to compare four things: the atomic amount, the payee, the rail (network + asset), and whether the URL still answers 402 at all.

The population

measurementvalue
rows under minia2a.uk1,123
snapshot age, median0 days
snapshot age, max65 days
rows older than 30 days113
rows older than 45 days70
accepts per row1 (all 1,123)

Two things stand out. First, the median age is zero โ€” most of our rows were registered recently, which is what a healthy self-serve flow looks like. Second, the tail is long: 113 rows were snapshotted more than a month ago, 70 more than six weeks ago, the oldest 65 days. Any of those could have been advertising a price we no longer charge, and nothing in the index would say so.

The result

verdictrows
identical to the live 4021,122
price or payee drift0
dead (no 402, no explanation)0
retired (404 that names a replacement)1
transient / unusable0

Not one row was wrong. That is not luck: our 402 is computed per request from the live database, so the challenge a probe sees today is the challenge a buyer pays today, and our prices have not moved since those rows were registered. The stale snapshots are stale in date only โ€” the values inside them still agree with the server.

That is exactly the shape of a latent bug. The mechanism that would publish a wrong price exists; it simply has not fired yet, because nobody changed a price. The next price change makes 113 rows lie simultaneously, and the only notice will be a buyer complaining about a charge it did not expect.

The one dead row

https://minia2a.uk/x402/language-detect returns 404. We delisted that service because it answered "english" for every Latin-script language โ€” French, German, Spanish, Italian and Portuguese all came back English after a confident-looking detection pass.

A 404 is a fine answer to a probe. It is a terrible answer to a buyer, because the buyer arrived from a listing that promised a service. So the 404 body carries the explanation and the replacement:

{
  "delisted": true,
  "error": "Service not found",
  "id": "language-detect",
  "hint": "language-detect delisted โ€” it answered \"english\" for every
           Latin-script language ... Use x402-ai-language, which is correct
           for those and also returns the script."
}

Whoever follows that dead row lands on a live endpoint that does the job. That is the difference between a dead link and a redirect: the row stays dead, but the journey does not. If you delist a listed endpoint and your 404 is a bare page, you have converted an index into a maze.

The trap in checking whether you are listed

x402scan writes rows through two paths, and they land in different buckets:

The registration check is keyed on (url, method). So asking "is this URL registered?" with one method and calling it a day under-reports โ€” and under-reporting is the direction that makes you register everything a second time.

Our own measurements of the same account, on the same day, across three methods:

queryregistered
GET only29 of 105
GET + POST16 of 132
GET + POST + ""89 of 132

The first two numbers were both wrong, and the second was lower than the first despite asking about more endpoints โ€” a bigger population with an incomplete union. Today, over our 144 demand-backed endpoints (286 candidate URLs), the union is complete: 144 registered, 0 missing, with the buckets at ""=132, GET=94, POST=94.

What we did not do

1,123 of our 1,856 catalog services are in that index; 733 are not. Some of the 733 have never taken a single call. We did not mass-register them. An index gets less useful every time it gains a row nobody searches for, and a provider that floods one to raise a number is optimizing the provider's graph, not the buyer's. Discovery is a shared resource; spam spends it.

Limits of this audit

The rule

A listing is a photograph of your 402 taken by someone else. The 402 is the contract. If you cannot make the index notice that the contract changed, you owe it โ€” and your buyers โ€” a scheduled re-read of the photograph.

The practical version, for anyone running a pay-per-call endpoint: register the same URL again to force a re-probe, do it after any price or payee change, and audit the rows you already have on the same schedule you audit your own documentation. And make sure a dead row points somewhere alive โ€” the index will keep the dead link for as long as it likes.