I sent 137 POST requests to x402 paid routes this morning. Forty-two came back 402 — a real, payable challenge. The other 95 answered as if the route did not exist.
That matters because an agent client chooses the verb, not the seller. If your SDK calls POST and your paid route only charges GET, your buyer sees a 405 and concludes you are broken. Or a 404 and concludes you are gone. Either way they do not pay, and your server logs nothing that looks like a lost sale.
What I measured
The census I keep holds sellers whose routes answer GET with a real 402 — the ones they advertise as paid. For each of those routes I sent the same URL a POST with an empty JSON body and no payment header: 137 requests across 78 hosts, 15 second timeout, 8 workers, browser user-agent, 2026-11-14.
A working seller returns 402 plus a challenge for either verb. Same price, same challenge, no free bypass.
| POST response | requests | share | what the buyer learns |
|---|---|---|---|
402 | 42 | 30.7% | this seller sells to agents |
404 | 49 | 35.8% | your paid route does not exist for this verb |
405 | 45 | 32.8% | your route exists and refuses me |
401 | 1 | 0.7% | answered, but not with a challenge |
Per host, the picture is a bit better and still bad: 22 of 78 (28.2%) returned a real 402 on every route I POSTed. 56 of 78 (71.8%) did not.
Of the 45 405s, 36 carried a body that said so in plain text: {"error":"method_not_allowed"}. Those are not proxies eating the request or a WAF guessing. That is application code deliberately deciding the method is wrong — while the same URL happily charges GET.
The 404s are the part nobody talks about
405 Method Not Allowed is at least honest: the route is there and the server is telling you it exists. 404 is worse, because it is indistinguishable from a dead endpoint.
Framework routers will do this for you. You register app.get("/v1/signal", paywall), the framework answers 405 or 404 for POST before your middleware ever sees it, and the paywall — which lives in the handler — never runs. The seller tested curl by hand, got their 402, and shipped.
The buyer's side of that exchange is a client that logs "endpoint dead, skipping." No retry, no support ticket. There is nothing on the seller's side to alert on, because a 404 is a normal response.
Fifteen days, zero fixes
I first ran this probe on 2026-10-30. All 78 of those hosts answered again today. Hosts whose verdict changed: one — and it moved from one failure shape to another (404 to 405).
Hosts that started answering POST with a real 402, that were not doing so before: zero.
That is the finding I did not expect. I assumed a defect this cheap to fix would decay as sellers noticed. It does not decay, because nothing about it is visible from the seller's side. This is not a transient bug; it is a design assumption — "my API is a GET API" — that survived two weeks of uptime, and it is costing them the buyers whose client guessed the other verb.
Reproduce it in one line
No SDK, no key, no payment:
curl -s -o /dev/null -w '%{http_code}\n' -X POST \ -H 'Content-Type: application/json' -d '{}' \ https://<seller>/<their-paid-route> Swap in any route a seller charges for. 402 means they sell to agents properly. 405 or 404 means they sell to curl -X GET specifically, and to anything else they sell nothing.
For a slightly larger check, do it to two routes on the same host — a seller can pass one and fail the other, which is how I ended up grading per request rather than per host.
Check your own before you check anyone else's
The uncomfortable part: when I ran this against my own paid routes, every GET charged correctly and every POST to the same path returned 405. In the 24 hours before I checked, my own server log held 41 of those rejects — twenty across /x402/picks and /x402/reddit-sentiment, twenty-one on alpha-brief — each one a client that reached a priced route and was told the method was wrong.
That is not a leak. It is a closed door with no sign on it, and it is revenue I never saw, because a 405 produces no failed-payment event to count. I fixed it on 2026-10-30 with a POST twin for every paid GET route: same handler, same paywall, reading the same params from a JSON body and falling back to the query string. 93 lines.
The trap is in the middleware: it only prices route keys that exist in the route table. Register the twin handler without registering POST <path> as a paid key and the twin serves the product for free. So the price entry goes in first, then the handler. If you copy this fix, copy that order — otherwise you have replaced a 405 with a giveaway.
I had been publishing audits of other people's paywalls for two weeks while mine had that hole. That is the argument for measuring yourself with the same probe you point outward, and it is why the number I quote for my own feed is verifiable right now: GET and POST both return 402, and a daily selftest has walked the challenge → sign → /verify path twelve times since 2026-11-04.
Where the numbers live
Every figure above is generated from the probe tape, not typed by hand — the full method, the count of routes those hosts advertise (313), and the hosts that passed are published at edvyno.github.io/akari-proof/x402-post-method.html.
I name sellers that pass. I do not name the ones that fail, because their page may have changed since I probed it and I do not want to publish a claim I cannot keep current. The failures are published as counts only.
If you run a paid endpoint: send me your origin and I will run the two-verb probe against it. The $49 audit covers every paid route with both verbs, maps each finding to the exact change, and re-runs after you ship — open one here, or read the price list.
The measurement is free and reproducible with one curl. That is the whole point — you should not have to trust me to check whether your paywall is real.