Your x402 endpoint settles payments but never appears in the Bazaar
The most reported x402 seller failure is also the quietest one: the
endpoint passes validate, real payments settle, and the discovery catalog never
mentions it. Nothing errors. Nothing logs. It is just not there.
How a Bazaar row actually gets written
Three mechanics explain almost every "not indexed" report, and all three are documented — one section deep, where nobody reads until they are stuck:
- Rows are written by settlement, not by deployment. A resource enters the catalog after a real payment settles against it while its 402 carries a valid declaration. Deploying a perfect endpoint writes nothing. No call has settled — no row.
- Indexing is per resource. One settled call on
/convert/adoes not list/convert/b. We proved this on our own sibling service: five endpoints deployed identically, and for a day exactly one — the only one that had ever settled a payment — was in the catalog. One small self-test call per endpoint lit up the other four. - Rejection is silent. When the facilitator's validation declines your declaration, nothing reaches your logs (x402#3045 is the long-running thread on exactly this). The endpoint keeps taking payments and simply never appears.
Crawl latency after a qualifying settlement is minutes-scale — we have measured roughly two to eleven minutes on our own endpoints. If it has been hours, the settlement was not the problem; the declaration is.
The fix ladder, in the order the failures actually occur
Each rung names the check that catches it, so you can buy exactly one answer if that is all you need.
- No v2 header at all. A v1-only endpoint is not broken — current clients
pay it fine — but CDP indexing reads the
PAYMENT-REQUIREDheader, so v1-only means payable but unlisted. (V2_HEADER_PRESENT) - No
extensions.bazaar. In v2, the presence of this extension IS the discovery opt-in. There is nodiscoverableflag any more — a CDP engineer confirmed on x402#3045 that it is "not a valid field". (V2_BAZAAR_PRESENT) infodoes not validate againstschema. The spec requires the facilitator to validate one against the other before cataloging, and this exact mismatch is the silent delisting: usually aconstthat no longer matches after a rename, a required field the example dropped, or"additionalProperties": falsemeeting a field the example added. (V2_BAZAAR_INFO_VALIDATES; the self-contradiction variant has its own guide.)- The network identifier is in the wrong form. v2 wants CAIP-2
(
eip155:8453); a bare"base"in a v2 envelope fails the provider's required network preflight. (V2_NETWORK_SUPPORTED) - The declared verb disagrees with the probe. The catalog's validator
replays your declared input; a declaration that says
PUTon a resource that was probed withPOSTfails a required preflight. (V2_BAZAAR_INPUT_METHOD)
Verify it yourself, free
The full catalog is a public API. Your listing is either in it or it is not:
curl -s "https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources?limit=1000" \
| grep -c "your-host.example.com"One caution from operating against this API: the documented ?payTo= filter is
accepted and ignored — the response is the same unfiltered page whatever you pass. Page through
with limit and offset and search the whole catalog; that is the only
read that cannot lie to you.
The shortcut
The free GET /check lists all 82 published checks.
POST /lint ($0.25) runs every one against
your live 402 and returns a specific fix per finding, with a separate
bazaar_ready verdict so a payment-fine-but-unlisted endpoint is never told it is
"broken". POST /presence ($0.15)
answers the other half: whether the catalog, the explorer, and the chain can actually see you
right now — with the evidence attached.