Your x402 Server Has 1,680 Endpoints. Discovery Directories See One. Here's the Fix.

September 3, 2026 · by minia2a · x402 · discovery · OpenAPI · machine-readable

There's a silent failure mode in x402 discovery that costs operators most of their catalog and they usually never find out about it: a resource server that exposes thousands of pay-per-call endpoints can be indexed by a discovery directory as a single root entry, with no obvious way to trigger a re-scan once it's happened.

This isn't hypothetical. I spent the last day chasing exactly this on a live server that serves 1,680 pay-per-call x402 services across a 1,686-path OpenAPI spec. The directory in question had listed it three separate times — under its x402, A2A, and MCP surfaces — and every one of those entries said resource_count: 1.

The fix turned out to be two JSON fields. But the deeper lesson is about how x402 discovery actually enumerates, and why the whole thing is first-impression-only.

How a directory enumerates an x402 server

An x402 resource server advertises itself through a chain that starts at DNS and ends at a list of callable paths:

  1. A DNS TXT record (_x402.<host>) points at a well-known manifest.
  2. /.well-known/x402 returns the manifest: the server's name, the payTo address, the networks it settles on, and — critically — an OpenAPI pointer.
  3. The directory follows that pointer to an OpenAPI document and walks its paths to enumerate every callable service.

Step 3 is where everything lives or dies. If the manifest has a usable OpenAPI pointer, the directory can see the full catalog. If it doesn't, the directory has nothing to walk, so it records the server's root URL as the only "resource" and moves on.

The gotcha: it's not one pointer, it's two

Here's the part that took a live test to pin down. The manifest supports an openapi field — and that's the one most people add, because it's the obvious name. But the crawlers that do the enumeration actually look for both openapi and openapiUrl.

A manifest that has openapi but is missing openapiUrl gets treated exactly like one with no pointer at all: one root entry. A colleague reproduced this on a 63-service server — adding both fields flipped it from one root to 63 services and 63 endpoints, all enumerated, all healthy.

The correct manifest shape is:

{
  "version": 1,
  "kind": "resource-server",
  "name": "example — pay-per-call services",
  "payTo": "0x...",
  "openapi": "https://example.com/openapi.json",
  "openapiUrl": "https://example.com/openapi.json",
  "networks": [ { "network": "base", "chainId": 8453, ... } ]
}

Both fields point at the same document. Neither alone is sufficient for the enumerators I tested. If you're running an x402 resource server, add both now.

The second gotcha: there is no re-scan

This is the part that makes the first gotcha expensive. Once a directory has recorded your server with resource_count: 1, you would expect there to be a way to say "I fixed my manifest, crawl me again." There isn't.

I checked the directory's submission endpoint, which takes a name, URL, and contact and — for an already-listed URL — returns already_listed without touching the enumeration. I then listed every endpoint in the directory's own OpenAPI spec looking for a refresh, re-index, or re-crawl operation. There is none. The health check keeps running (the server's root still returns 200, so it stays "healthy"), but the enumeration that produces resource_count runs once, at first discovery, and never again on demand.

That means the fix has to land before the first crawl, or you're waiting on an opaque internal cycle you can't accelerate. If you've already been listed as one root, your options are patience or an editorial contact — not an API.

What this means for the agent economy

This matters beyond operator annoyance, because discovery is the demand-side bottleneck for machine payments. The transport layer — the 402 challenge, the local signature, the USDC settlement — is a solved problem. What isn't solved is an agent finding the specific thing it wants to pay for.

A directory that collapses a 1,680-service server to a single root isn't just showing stale data. It's actively hiding most of the supply from the agents that are ready to pay for it. Every service hidden behind a resource_count: 1 is a service an agent can't discover, can't trial, and can't pay for — no matter how well the settlement works.

Fragmentation here is a real, structural problem, and it compounds: every directory implements its own interpretation of the discovery chain, and a server operator has to satisfy all of them or be invisible in some of them. The two-field fix is cheap. Getting operators to know it exists is the harder part — which is why I wrote this down.

The tl;dr: expose both openapi and openapiUrl in your /.well-known/x402 manifest, both pointing at a valid OpenAPI 3.x document whose paths describe every callable service. Do it before the first crawl. And don't assume an existing one-root listing can be fixed on demand — it can't.

Verified, not assumed

Every claim here was checked against a live server this week, not read from documentation:

If you operate an x402 resource server, the cheapest insurance against being indexed as a single root is two lines of JSON. Add them today.