A developer filed an issue on one of our repos titled "Publisher docs and CLI disagree with live seller API." They had tried to list an API on our x402 marketplace, followed the published instructions, and got HTTP 400.
Our first instinct was that they had the wrong route. They claimed the seller endpoint was POST /api/register with header-based signature auth, which did not match what we believed our own API to be.
So we tested it against the live gateway instead of arguing from memory.
POST /api/register
{"name":"...","endpoint":"https://...","priceCents":5,"wallet":"0x..."}
X-Wallet-Signature: 0x...
X-Signature-Ts: 1755...
→ {"error":"name, wallet and signature required"}
That is the buyer registration error. The endpoint ignored endpoint and priceCents entirely. We sent the identical request with the two signature headers removed and got a byte-for-byte identical response — proof the handler never reads those headers at all.
The reporter's conclusion about which route works was wrong. But their complaint was exactly right, and here is why they believed it: that route and that header scheme are what our own canonical agent guide told them to use.
Four surfaces, four different failures
Once we knew the canonical guide was wrong, we checked every document that describes publishing. Each was broken, and no two were broken the same way.
| Document | What was wrong |
|---|---|
AGENTS.md (canonical, linked everywhere) |
Wrong route (a buyer alias), wrong field name (priceCents vs price_cents), two required fields missing, plus a documented header-auth scheme that is no longer honoured |
llms.txt |
Correct route, example omitted a required field → 400 |
agent-cookbook.html |
Correct route, same missing field → 400 |
mcp-x402.html |
Missing endpoint and signature (both required), wrong field name, invalid category value — four errors in one call |
There was no working documented path. If you read our documentation and tried to sell an API on our marketplace, you could not do it.
The error message made it worse
The field everyone was missing is description, which must be at least 20 characters. Here is what the API returns for an empty request:
POST /api/v1/publish-service {}
→ {"error":"name, endpoint, wallet and signature required"}
description is not in that list. It is enforced but not announced. A developer doing the sensible thing — reading the error and adding exactly the fields it names — still gets a 400, with a new error that finally mentions the real requirement.
This is the part I find most instructive. A wrong example is one problem. A wrong example plus an error message that under-reports the contract is a loop that punishes the exact debugging strategy a competent developer would use.
Why this matters more for agents than for humans
A human who hits a 400 has options. They read the error, try variations, search for someone with the same problem, check the HTML on another page, or email support. Humans route around bad documentation. It costs them time, and some fraction succeed anyway.
An agent does not do this. It reads AGENTS.md or llms.txt, constructs the call exactly as specified, gets a 400, and stops. If it retries, it retries the same wrong shape.
For an autonomous client, the documentation is the interface. A wrong llms.txt is not a docs bug — it is an outage that returns 200.
This is worth sitting with if you are building anything agent-facing. The ecosystem is investing heavily in machine-readable discovery: llms.txt, agent cards, .well-known manifests, OpenAPI specs. All of that infrastructure assumes the content is true. We had all of those files. Several were confidently describing an API that would reject you.
What the numbers looked like
Our catalog has 1,644 active services. Twelve are hosted outside our own infrastructure. The rest are ours.
The buyer side — whose documentation was correct throughout — has 775 registered wallets and has served 21,155 free trial calls.
I am not going to claim documentation is the sole cause of that asymmetry. Publishing an API is a bigger commitment than calling one, and this is an early market on both sides. But the simplest explanation for near-zero external supply is that the on-ramp returned an error to everyone who tried it, and we should have caught it long before a user did.
To be equally honest about the rest of the funnel, since it is the number that actually matters: those 21,155 trial calls correspond to 54 settled paid transactions and 3.522 USDC of real on-chain volume. Fixing the seller path does not fix that. Demand generation is a separate and harder problem.
What we changed
-
AGENTS.md— rewrote the publish section with the correct endpoint, full required-field list, and signing message. Explicitly marked the dead header-auth scheme as no longer honoured, so anyone who copied it earlier can tell why it stopped working. -
llms.txt, cookbook, MCP guide — corrected every publish example and called out the undocumenteddescriptionminimum where developers will be looking when they hit it. -
llms-full.txt— a hand-written snapshot that had drifted, and was somehow shorter than the summary it was meant to expand. Now generated from the live catalog hourly, with the 402 example captured from a real challenge at generation time rather than written by hand. -
CLI — it had no publish command at all; its
registercommand is buyer-side, which is precisely the confusion the reporter hit. Addedpublishwith client-side validation so a missing description fails immediately with a legible message.
One thing we did not fix: the catalog does not record an HTTP method, so a service published to be called with POST reads back indistinguishably from a GET service and generic clients call it with GET. That is a gateway change, not a docs one. Until it ships it is written down, and the CLI warns about it after a successful publish. Naming a known defect beats letting a publisher discover it from silent failures.
The general lesson
If you run anything agents are supposed to use autonomously, the test is not "is the documentation good." The test is: can a machine that reads only your documentation complete the task? That question has a yes-or-no answer, it can be checked automatically, and we were not checking it.
The fix that generalizes is not "write better docs." It is to stop hand-maintaining files that describe a system that changes. Our discovery surface now regenerates from live state on a schedule, with examples captured from real responses. Anything still hand-written is a snapshot, and every snapshot drifts from the moment it is written.
Ours drifted for weeks, in public, while telling agents exactly how to fail.
Top comments (0)