x402 Preflight

x402 Preflight · blog · status codes

What each HTTP status code means when your API sells over x402

On a paid endpoint the status code is not housekeeping. It is the contract. A buying agent arrives with a wallet, no account and no key: it makes one request, and the response decides whether it can spend. If that response does not carry a readable payment challenge, the endpoint cannot be bought — however good the service behind it is.

This is a field guide to the codes a checker sees in the wild, ordered by how often they show up. For each one: what the agent sees, what it usually means for a paid endpoint, and what to fix.

The codes at a glance

CodeWhat the agent seesUsual causeVerdict
402A payment challengePayment middleware doing its jobHealthy, if the challenge is readable
200The payload, freeMiddleware missing on the route, or a proxy answering firstRed flag when a price is advertised
405Method not allowedThe listing advertises one verb, the paid route uses anotherThe agent stops before the price
400Bad requestA route template left unsubstituted, or a body field missingUsually the caller's bug, not the seller's
404Not foundWrong path in the listing, or a template never filled inDead listing
401 / 403Login required / refusedAn auth gate mounted before the payment middlewareThe agent never reaches the 402
410GoneThe route was retired and the listing stayedGhost listing
500 / 503Server error / unavailableA crash, a bad deploy, maintenance or capacityNothing to buy

402 Payment Required — the only response that means “you can buy”

This is the correct answer to an unpaid call. In x402 v2 the challenge travels in the PAYMENT-REQUIRED header, and the body usually carries the accepted requirements as JSON.

The endpoint is healthy when the agent can read all four facts without guessing: the amount, the network (for example eip155:8453 for Base), the asset (the USDC contract address) and the receiver (payTo). If those are present and consistent, the agent can build a payment. If the challenge offers the same price on two networks, that is not a contradiction: they are alternatives for the same route, and the agent picks one.

The most common way to get a 402 and still break the sale is to serve it after an auth check. The status looks right in a browser, but the agent never gets there. Payment comes first; credentials, if any, come later.

200 OK — the endpoint answers, and nobody pays

A plain 200 on a route that advertises a price is the most expensive defect on this page: every caller gets the result for free, and the listing quietly earns nothing.

The usual causes are boring. The payment middleware is mounted on some routes but not that one. The route is declared before the middleware in the framework's order. A proxy, a CDN cache or a static file answers first and shadows the API path. In each case the fix is the same: the paid route must reach the payment layer before anything returns a payload.

There is one legitimate exception: a GET that acts as a metadata storefront — it publishes what the service does, what it costs and which verb charges — while the paid operation lives on POST. That is a design choice, not a defect. What makes it work is that the listing advertises the verb that actually charges.

405 Method Not Allowed — the listing and the service disagree about the verb

The classic case: the catalogue says GET, the service charges on POST. The agent follows the listing, takes a 405, and stops before it ever sees a price.

A 405 that carries Allow: POST is a hint, not a challenge. A well-behaved checker will follow that hint once and find the 402 — but a buyer agent that trusts the listing will not. Either publish the charging verb in the listing, or answer the advertised verb with the payment challenge.

400 Bad Request — usually the caller's fault

On a paid endpoint, a 400 is more often a problem with the request than with the service. The two habitual culprits are a route template that was never substituted — the URL still contains :address, {id} or <id> — and a body field the server requires before it evaluates payment.

Treat a 400 as “not verifiable” until you pass a real sample value for the parameter and the body the endpoint expects. Reporting it as a defect wastes the seller's time and yours.

404 Not Found — the route is not there

The path in the listing does not exist. Either the listing points at the wrong path, the URL is a template that was never filled in, a deploy moved the route, or a worker is mounted on a different path than the one published.

One case that looks like a 404 but is not a dead route: a resource that answers 404 on GET and 402 on POST. That is the method disagreement above. Before declaring a listing dead, try the verb that charges.

401 and 403 — a login gate in front of the payment gate

401 asks for credentials; 403 refuses them. Both arrive before the payment challenge, and that ordering is the problem: an agent that pays per call with x402 has no account and no key, so it will never reach the 402.

The fix is an ordering fix. Mount the payment middleware before the auth gate, and keep the auth gate for the free or human surface. If the whole route requires an account, it is not an x402 endpoint — and the listing should say so.

410 Gone — a listing pointing at a retired route

The route existed and was deliberately removed; the catalogue kept publishing it. A 410 is a clear signal, so honour it: update or delete the listing. A dead entry costs the seller nothing visible and costs every buyer agent a wasted call.

500 and 503 — nothing to buy

A 500 is a handler that crashed. A 503 is a service that is down, at capacity or in maintenance. In both cases the agent sees a failure where a price should be, and no payment is possible.

There is nothing to fix on the buyer side. On the seller side, uptime is part of the product: an agent that hits a failing paid endpoint retries, then stops calling it. A price that cannot be reached is worse than a price that is too high.

Two failures that are not HTTP codes

A 402 whose challenge cannot be parsed. The status is right, but the agent cannot extract amount, network, asset and receiver — the header is missing, the shape is non-standard, or the price is ambiguous. From the outside it looks like a working paywall; from the agent's side it is a closed door. The fix is a standard x402 v2 challenge in PAYMENT-REQUIRED with readable requirements.

A dead listing. The catalogue still publishes the resource while the route answers 404 or 410. No individual response is wrong — the catalogue data is stale. Refresh the discovery metadata after a deploy; crawlers will pick it up on their own schedule, and until then the entry keeps sending buyers into a wall.

Check it without a wallet

A read-only check is one request. No wallet, no credentials, no payment:

curl -s -X POST https://x402.chikocorp.com/api/preflight/inspect \
  -H 'content-type: application/json' \
  -d '{"resource_url":"https://your-api.example.com/resource","method":"GET","max_price_usd":1}'

A clean result means four things: the challenge is present, the price is readable, network and asset and receiver are consistent with the policy you passed, and the discovery metadata does not contradict the live challenge. It does not prove that a purchase settles or that delivery happens — those are separate checks, and any report that claims otherwise is selling you certainty it does not have.

Frequently asked questions

Why does my x402 endpoint return 200 instead of 402?

Either the payment middleware is not mounted on that route, or something in front of it answers first: a proxy, a CDN cache or a static file shadowing the API path. The one legitimate exception is a GET that acts as a metadata storefront while the paid operation lives on POST.

My listing says GET but my service charges on POST. Is that broken?

The endpoint is fine; the listing is what the agent follows, and it will take the GET first. A 405 with Allow: POST is a hint, not a price. Publish the charging verb, or answer the advertised verb with the challenge.

Is a 401 a problem if my API already uses API keys?

Yes, if the auth gate sits before the payment middleware. An agent that pays per call over x402 has no account, so it never reaches the 402. Mount payment first and keep auth for the free or human surface.

What does a 402 with no readable price look like to an agent?

A closed door. The status says payment is required, but the agent cannot build a payment without amount, network, asset and receiver. The fix is a standard v2 challenge with readable requirements.

How common is each of these codes in practice? We probed all 26,692 endpoints in the x402 Bazaar: the census and its numbers.

More answers for x402 API developers — back to x402 Preflight.