Build1 publisher3 min readPublished
x402's Bazaar catalog refreshes a listed price only when a buyer pays
One operator's sweep of x402's Bazaar catalog found 20 of its 154 listings showing stale prices, including a $50 code audit listed at $0.01. Rows change only when a payment settles, so agents have to price from the live 402 challenge.
The Engineer · Build desk

What happened
- The author swept all 19,126 resources in the Bazaar catalog on the CDP facilitator, then checked each listing on their own host against the 402 challenge it serves now.
- Under the bazaar extension, the facilitator never fetches an endpoint to learn its price; it reads the payment payload the buyer sends at settlement.
- The 20 stale rows had not been updated in 19 to 26 days.
- Of the 154 listings, 89 showed a lastUpdated from the previous day, and the author's endpoints had 93 paid calls in the trailing week.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- decision Agent builders who rank or budget from catalog rows need a second price check at the live 402 challenge before any payment is signed.
- exposure Stale rows sit on endpoints nobody has bought lately, and the author says those carry the largest prices, so the worst errors land on the least-used services.
- constraint One seller's 154 rows are under 1% of the catalog, so the sweep cannot yet say how stale Bazaar is overall.
In the standard x402 client flow, a Bazaar row gives the client a candidate URL. The client fetches it, gets a 402, and builds the payment from the requirement in that challenge [11]. The row and the challenge carry the same fields: scheme, network, asset, amount and payee [15]. The post's author wrote: "One of them is a promise. The other is a photograph of a promise, taken the last time somebody paid." [14]
The extension spec sets when a row is written. A facilitator that receives a PaymentPayload carrying the bazaar extension should validate the info field against the supplied schema and then "Extract the discovery information" [5]. A payment creates the row, and only a later payment refreshes it, so an endpoint nobody buys keeps its last recorded price [6]. "The freshness of the catalog is a restatement of the payment history," the author wrote [9].
I think the design is sound. The facilitator never has to crawl sellers, and every row it holds came from a settled payment [4][6].
The 13% stale share in this sweep belongs to one seller [1]. It would carry over to the rest of the catalog only if other sellers had also changed prices on endpoints nobody has bought since. The post measured only rows on the author's own host [1].
The worst row understates its price by a factor of 5,000 [3]. A one-cent code audit is a price a human would squint at, and an agent sorting by cost picks it first [3]. If that agent skips the challenge and signs from the row, settlement fails with error text that points at the signature, not at the source of the number [12]. If it follows the standard flow, it builds the payment from the challenge, so the fifty-dollar price goes through unless something compares it with the figure the agent chose on [11][3]. The author's rule: "treat catalog prices as ranking hints, and treat any number you put in front of a human as something you re-read from the live challenge first." [13]
Sellers have cleanup of their own, though neither item breaks payments [20]. The SDK validates routeTemplate against `/^\/[a-zA-Z0-9_\/:.\-~%]+$/`. The author had been sending a service id there, and "x402-mime-type" fails the check in @x402/extensions 2.28.0 [16]. The facilitator does not reject such a record. It discards the field and falls back to the concrete URL, and the spec says the field must be absent for static routes [17]. The spec also reserves serviceName, tags and iconUrl "to enrich Bazaar search results with a human-readable name, topical tags, and an icon, without any out-of-band admin step" [18]. The official client echoes the whole resource object into the payload, so setting them on the server is enough [19].
What to watch
- A change to the bazaar extension or the CDP facilitator that refreshes listings without waiting for a settled payment.
- Sweeps of other sellers' hosts among the 19,126 resources, to test whether one seller's 13% stale share holds elsewhere.
- x402 client SDKs adding a check that compares the challenge amount against a budget before signing.