HTTP 402 Payment Required: reserved for 25 years, now in use
TL;DR: key takeaways
- HTTP 402 has been in the spec since 1997 and reserved for future use ever since. x402 is the first serious attempt to give it a job.
- The flow is three legs: request, 402 with a quote, retry with a signed payment header.
- The status code carries no opinion on whether you should pay. That decision is yours, and it is where the losses happen.
- Four things go wrong in practice: quote overruns, asset mismatches, expired quotes and replayed nonces.
There is a status code in HTTP that has been sitting in the spec since 1997 doing nothing at all. HTTP 402 Payment Required was written down, reserved for future use, and then left alone for a quarter of a century because nobody could agree what payment on the web should look like. Agents settled the argument by needing an answer. This is what HTTP 402 does now, how the exchange actually works on the wire, and the four ways it goes wrong once real money is involved.
Twenty-five years of "reserved for future use"
The code appears in HTTP/1.1 with a note that it is reserved. RFC 9110, the current HTTP semantics specification, still describes it that way. Twenty-five years is a long time for a placeholder.
Plenty of things were tried in the gap. Micropayment schemes, browser wallet standards, per-article paywalls. All of them foundered on the same rock: a human being will not approve a payment of four-tenths of a penny. The transaction cost of the decision dwarfs the transaction.
Agents do not have that problem. A program approving 600 sub-cent payments a day is not annoyed. It is just running.
That is the whole reason HTTP 402 came back. Not better cryptography, not cheaper settlement: a buyer who does not mind being asked.
How the HTTP 402 flow actually works
Three legs. That is all.
Leg one: the client asks.
GET /v1/market-data?symbol=BRENT HTTP/1.1
Host: api.example.com
Leg two: the server quotes. It answers with HTTP 402 and a machine-readable statement of what it wants: the maximum it will accept, the asset, where to send it, and how long the quote is good for.
HTTP/1.1 402 Payment Required
Content-Type: application/json
{
"accepts": [{
"scheme": "exact",
"network": "base",
"asset": "0x833589f...",
"maxAmountRequired": "4000",
"payTo": "0xA1b2...",
"maxTimeoutSeconds": 60,
"nonce": "c8f1e0a2"
}]
}
Leg three: the client pays and retries. Same request, with a header carrying a signed authorisation.
GET /v1/market-data?symbol=BRENT HTTP/1.1
Host: api.example.com
X-PAYMENT: eyJzY2hlbWUiOiJleGFjdCIsInNpZ25hdHVyZSI6...
The server verifies, settles, and returns the data. Sub-second, no redirect, no session, nobody asked.
The x402 specification and its reference implementation are the authoritative sources for the exact field names, which have moved between versions. Pin the version you implement.
What the status code deliberately does not do
Read leg two again. The server said what it wants. It did not say whether paying is a good idea.
That is correct protocol design (HTTP 402 is a transport concern, not a treasury policy) and it is also exactly where the money goes missing. Every question that actually matters lives outside the flow:
- Is $4,000 in minor units the price you expected, or a decimals bug?
- Is
api.example.coma service you have ever paid before? - Is this the eleventh identical request in four minutes because a webhook was dropped?
- Has this agent already spent its month?
Nothing in the exchange can answer any of those. The client is a program that was told to fetch market data, and it has been given a price. It pays.
"The protocol asks 'can you pay'. The interesting question is 'should you'. Nobody should expect a status code to answer the second one, but a great many integrations are built as though it does."
the Spend7 engineering team
The four things that go wrong
These are the failure shapes worth writing code against.
| Failure | What happens | Typical cause |
|---|---|---|
| Quote overrun | Client authorises more than maxAmountRequired | Decimals confusion, or a payment requirement substituted in a response nobody validated |
| Asset mismatch | Payment in an asset or on a network the server did not quote | Hardcoded defaults surviving a config change |
| Expired quote | Authorisation submitted after the timeout | Slow retry logic, or a stale response replayed |
| Nonce replay | Same nonce presented twice for one merchant | Buggy retry, or a deliberate double-submit |
Table: the four x402 defects that appear in practice. Spend7 scores rail defects at up to 60 points out of 100 and can mark them decisive.
The quote overrun deserves special attention because of how quietly it succeeds. A server that quoted 4,000 minor units and receives an authorisation for 4,000,000 has no particular reason to complain. Money arrived. It was more money than expected. The failure surfaces on your side, later, in a reconciliation.
USDC has six decimals. Get that wrong in either direction and you are off by a factor of ten thousand.
A short, expensive story
A team wires up an x402 client for a data feed. Testing goes well. The quoted price is 4,000 minor units ($0.004) and everything settles.
They ship. Two weeks later someone notices the feed has cost $2,400 rather than the expected $1.70.
The bug: a helper that converted "dollars" to "minor units" assumed two decimals, because every payments library the author had used before was built for fiat. Every payment authorised 10,000× the quote. The server accepted all of them, because why would it not.
A quote-overrun check would have caught the first one. Comparing the authorisation to maxAmountRequired is not clever; it is just a comparison nobody was making, because the code that built the authorisation was also the code that read the quote, and it was equally wrong about both.
That is the general lesson. The check has to be somewhere other than the code that made the mistake.
Should you use HTTP 402?
Fair question, and the answer is genuinely "it depends".
It fits when the buyer is a program, the amounts are small enough that a human approval loop is absurd, and you want per-request pricing rather than a subscription and an API key.
It does not fit when a person is present and can be sent to a checkout, when you need chargebacks in the card sense, or when your counterparties are a fixed, small set you could simply invoice.
Demand is still early. When we measured US search volume with Google Ads Keyword Planner on 8 August 2026, "http 402" ran at 880 searches a month with a competition index of 1, while "x402 payment protocol" managed 30. People are looking up the status code far more than the scheme built on it, which suggests most of that traffic is developers meeting a 402 in the wild and wondering what hit them.
Common pitfalls
Assuming the quote is trustworthy because it arrived over TLS. TLS tells you who sent it, not that it is what you expected. Compare it to what you were willing to pay.
Retrying a 402 without a fresh quote. Quotes expire. A retry loop reusing a stale quote produces expired-authorisation errors that look like network flakiness and are not.
No idempotency across the retry. The whole design is "fail, pay, retry". If your client cannot tell a successful retry from a fresh attempt, you will pay twice: the single most common way agents lose money, and it is not an attack.
Treating 402 as an error. It is not a failure. It is the server telling you the price. Clients that route it into generic error handling either never pay or hammer the endpoint.
Next
If you are implementing a client, the x402 rail page covers what to send so protocol checks can run, and setting x402 spend limits is the practical follow-on for bounding what a runaway costs. If you are choosing between rails rather than committed to one, the comparison piece is shorter. And the API reference has the full intent shape including the quote fields.
Frequently asked questions
- What does HTTP 402 Payment Required mean?
- It is the status code a server returns to say the request is fine but you have not paid for it. It has existed since HTTP/1.1 was written in 1997 and was explicitly reserved for future use, because nobody agreed on how payment should work. RFC 9110 still describes it as reserved. What changed is that x402 supplied the missing half: a convention for what the server puts in the response and what the client sends back.
- Is HTTP 402 an official standard?
- The status code is, and has been for decades. The payment convention layered on top of it is not an IETF standard: x402 is an open specification published by Coinbase in May 2025, with an open-source implementation. That distinction matters when you are writing a client: you can rely on the status code's meaning, and you should pin the version of the payment scheme you implement.
- How is HTTP 402 different from a normal checkout?
- A checkout assumes a person is present to approve. HTTP 402 assumes nobody is: the server quotes machine-readably, the client pays programmatically, and the request retries. No redirect, no session, no consent screen. That is what makes it work for agents, and also why spend control has to live somewhere else, because nothing in the flow asks whether the payment is a good idea.
- What happens if the client pays the wrong amount?
- The server should reject it, but the failure mode people actually hit is paying too much rather than too little: an authorisation for more than the quoted maximum, usually a decimals bug. The server has no reason to refuse money, so an overrun tends to succeed quietly. This is why the quote and the authorisation should be compared by something that is not the code that produced them.
Score a payment before it settles
Spend7 returns allow, flag or deny in one call, with the signals that produced it. The free tier covers a single agent, its spend caps and its full decision log.