HTTP 402 Payment Required, and why it took 30 years to use

RoundhouseReviewed .md
In short

HTTP 402 Payment Required is a status code reserved in the 1997 HTTP/1.1 specification and deliberately left undefined. It went unused because there was no way for a browser to pay a stranger automatically. Stablecoins and signature-based transfers supplied one, and x402 is the first widely deployed definition of what a 402 response should contain.

Contents
  1. What does 402 mean in the HTTP specification?
  2. Why did it stay unused for so long?
  3. What changed?
  4. How does x402 define the response?
  5. Is 402 the right status code for this?
  6. Frequently asked questions
  7. Where to check this yourself

What does 402 mean in the HTTP specification?#

Almost nothing, and that was on purpose. RFC 7231 and its predecessors list 402 as "reserved for future use". There is no defined response body, no defined header, and no defined way for a client to retry having paid.

The code has been sitting in the specification since HTTP/1.1 was standardised in 1997, implemented by nobody, waiting for a payment system that never arrived.

Why did it stay unused for so long?#

Because every payment mechanism available assumed a human in the loop.

A card payment needs a card, a billing address and often a challenge. A bank transfer needs an account relationship. Both need a dispute process, which needs an identifiable payer. None of that can be completed by a browser at the moment it receives a response, in the time budget of an HTTP request.

So the web routed around it. Metered access became accounts and API keys, content became advertising, and small payments became impossible because the fixed cost of taking one exceeded the payment.

Note

The problem was never technical in the HTTP sense. Attaching a header to a retry is trivial. The problem was that the payment instrument did not exist, and three decades of micropayment proposals failed on that same point.

What changed?#

Three things arrived at once.

Stablecoins made the unit sensible. A payment denominated in a volatile asset cannot be a price. A dollar-denominated token on a fast chain can be.

Signature-based transfers removed the gas requirement. EIP-3009 and its equivalents let a buyer authorise a transfer without holding the chain's native token or sending a transaction, so paying became something a client can do in milliseconds with one signature.

The buyer stopped being a person. This is the one that actually mattered. An agent discovering an endpoint and wanting one call cannot sign up. It has no email, no card and no patience. For that buyer, an account is not a mild inconvenience; it is the thing that prevents the transaction entirely.

How does x402 define the response?#

x402 fills in what the RFC left blank. A 402 response carries a JSON body with an accepts array, and each entry is a complete, machine-readable offer: the scheme, the network, the asset contract, the amount in the asset's smallest unit, the address to pay, and how long the offer stands.

HTTP/1.1 402 Payment Required
Content-Type: application/json

{
  "x402Version": 1,
  "accepts": [
    {
      "scheme": "exact",
      "network": "base",
      "maxAmountRequired": "10000",
      "asset": "0x833589...2913",
      "payTo": "0xA1B2...",
      "resource": "https://api.example.com/v1/search",
      "maxTimeoutSeconds": 60
    }
  ]
}

The client picks one entry, signs an authorisation matching it, and resends the original request with the signature attached. The accepts schema covers each field and the traps in them, chiefly that the amount is in smallest units and not dollars.

Is 402 the right status code for this?#

It is the right one in the sense that matters: it is unambiguous and it was reserved for exactly this. A few details are worth knowing.

PropertyHow x402 handles it
Retry semanticsThe client retries the identical request with a payment header
IdempotencyThe payment is bound to the resource, so a payment for one path does not unlock another
Caching402 responses should not be cached, since terms and expiry are per-request
DiscoveryThe 402 body is itself the price list, so no separate pricing endpoint is needed

That last row is underrated. A server that answers 402 with full terms is self-describing to a buyer that has never seen it before, which is why agent discovery can work by probing an endpoint rather than by reading a catalogue.

Frequently asked questions#

Is x402 part of the HTTP standard?#

No. HTTP reserves the status code; x402 defines a convention for what the response body and the retry header contain. The protocol is governed by the x402 Foundation, hosted by the Linux Foundation since April 2026, rather than by the IETF.

Do other 402 schemes exist?#

Yes. L402, which came out of the Lightning Network ecosystem, uses 402 with macaroon-based tokens, and several proprietary schemes have used the code internally. x402 is the one with broad multi-party deployment.

Will a browser handle a 402 automatically?#

Not today. No mainstream browser implements a payment handler for 402, so in practice the client is an SDK, an agent runtime or a server-side fetch wrapper rather than a browser tab.

Does a 402 response leak anything sensitive?#

It publishes your price and your receiving address, which are both things you intended to publish. The thing to avoid is varying the terms per caller in a way that reveals who the caller is, since a 402 is often served before any authentication.

Can I return 402 without supporting x402?#

You can, but a client that sees a 402 with no recognisable body cannot do anything except fail. If you are going to use the code, use a format something can parse.

Where to check this yourself#

The simplest check is to call a priced endpoint and read the 402 it returns. Roundhouse publishes one at GET /v0/test/x402 that charges a cent, and the first x402 payment guide walks through the whole exchange including the headers. The services directory lists other endpoints that answer 402 with real terms.

Reading this as an agent?

Every page here has a markdown twin at the same URL plus .md. Same words, no navigation, no markup to strip. And the settlement record this article describes is a live index you can query rather than a claim you have to take on trust.

  • GET https://roundhouseai.io/resources/http-402-payment-required-explained.mdthis page, as markdown
  • GET https://roundhouseai.io/llms.txtevery surface on roundhouseai.io
  • GET https://api.roundhouseai.io/v0the index: endpoints and schema
  • GET https://api.roundhouseai.io/v0/test/x402$0.01 over x402, and it mints your own key with no account

/docs/api has the limits and the SQL surface. /v0/account, /v0/endpoints and the capability layer answer without a key.

Read next