# How agents read a 402: x402 vs MPP for paying per call

Search and Fetch desk. A ZeroClick publication (https://searchandfetch.com/about/). Published 2026-10-08.
Canonical: https://searchandfetch.com/articles/how-agents-read-a-402/

The first time an agent asks a paid API for data, it gets an HTTP 402 back instead of an answer. Two protocols, x402 and MPP, say what to do next: where to find the price, how to send proof of payment, and what happens when a payment fails. They differ on all three, so build a client that speaks both, and copy MPP's way of handling failure.

## What did a 402 mean before x402 and MPP?

Almost nothing. The HTTP standard treats the code as a placeholder: [RFC 9110](https://www.rfc-editor.org/rfc/rfc9110.pdf), published in June 2022, gives it one line, "The 402 (Payment Required) status code is reserved for future use." The [MPP draft](https://datatracker.ietf.org/doc/draft-httpauth-payment/00/) opens by saying as much: reserved, never standardized for common use.

A bare 402 tells an agent only that money is involved. Everything a buyer needs, how much, in what currency, to whom, and how to prove it paid, has to come from a protocol layered on top. That layer is what x402 and MPP each supply.

## What does an x402 server send with its 402?

A menu. The server answers with a JSON object of payment requirements, Base64-encoded, which the [x402 V2 specification](https://github.com/coinbase/x402/blob/main/specs/x402-specification-v2.md) defines. Alongside the protocol version and the resource, its heart is an `accepts` list: each entry is one way to pay, with a scheme such as `exact`, a network in CAIP-2 form such as `eip155:84532`, the amount in the token's atomic units, the asset, a `payTo` address and a `maxTimeoutSeconds`. Read the amount with care. For six-decimal USDC, `10000` means one cent, as the [MPP compatibility guide](https://mpp.dev/guides/use-mpp-with-x402) points out.

Where the menu travels is where the x402 docs part ways. The [x402 HTTP 402 page](https://docs.x402.org/core-concepts/http-402) puts it in a `PAYMENT-REQUIRED` header returned with the 402, and the [client and server page](https://docs.x402.org/core-concepts/client-server) puts it in the response body. Until the docs agree, read the header first and fall back to the body.

Paying is choosing. The agent picks one entry, signs a payment authorization for it, and retries the same request with a `PAYMENT-SIGNATURE` header carrying a Base64 payload that echoes the chosen requirement and adds the scheme's proof. For the EVM `exact` scheme, that proof is a signature plus an EIP-3009 authorization with a nonce and a validity window. The server verifies it, locally or through a facilitator, and settles.

One thing the specification leaves to you: it lists client-side budget management as out of scope. The spending cap is yours to write.

## What does an MPP challenge carry?

An HTTP authentication challenge with money in it. An MPP server answers with `WWW-Authenticate: Payment`, the header HTTP already uses to ask for credentials ([MPP challenges](https://mpp.dev/protocol/challenges)). The challenge names itself with an `id` and a `realm`, says how to pay with a `method` such as `tempo` or `stripe` and why with an `intent` such as `charge` or `session`, and carries a `request`: a base64url JSON object that typically decodes to an amount, a currency and a recipient. It may add an `expires` time, a body `digest`, server-defined `opaque` data, and a `header` naming where the proof should go.

A server can offer several challenges in one response, one per way to pay, and the client answers exactly one. The answer is a credential: base64url JSON that echoes the chosen challenge and adds a method-specific `payload` as proof. By default it rides in `Authorization: Payment`. When the challenge asks, it goes in `Payment-Authorization` instead, so an existing app token can keep `Authorization` ([HTTP transport](https://mpp.dev/protocol/transports/http)).

MPP also tells the client what to check before it pays. The [MPP protocol overview](https://mpp.dev/protocol) lists four things: the amount is reasonable, the recipient is the one expected, the currency is the one expected, and the validity window is appropriate. The human-readable `description` is not to be trusted for any of them.

## How do the two compare, step by step?

The rows below draw on the [x402 headers page](https://docs.x402.org/core-concepts/http-402), the [x402 specification](https://github.com/coinbase/x402/blob/main/specs/x402-specification-v2.md), MPP's [side-by-side comparison](https://mpp.dev/mpp-vs-x402) and the [MPP draft](https://datatracker.ietf.org/doc/draft-httpauth-payment/00/).

| Step | x402 | MPP |
|---|---|---|
| Price arrives in | Base64 JSON, in a `PAYMENT-REQUIRED` header or the body (the docs differ) | `WWW-Authenticate: Payment`, with a base64url `request` |
| Proof goes back in | `PAYMENT-SIGNATURE` header | `Authorization: Payment`, or an advertised alternate field |
| Receipt header | `PAYMENT-RESPONSE`, on success or failure | `Payment-Receipt`, on success only |
| Error model | `PAYMENT-RESPONSE` settlement result with error codes | RFC 9457 Problem Details |
| Payment rails | Registered blockchain network mechanisms | Stablecoins, cards, Lightning and custom methods |
| Idempotency | Optional Payment Identifier extension | Challenge identity plus `Idempotency-Key` guidance |

## What happens when a payment fails?

In MPP, a failed payment is just another 402. The server sends a fresh challenge and a Problem Details body that names what went wrong ([protocol overview](https://mpp.dev/protocol)): `verification-failed`, `payment-insufficient`, `payment-expired`, `malformed-credential`, or `invalid-challenge` for an id that is unknown, expired or already used. A `Retry-After` header can say when to try again. A 403 means something different: the payment was valid and policy refused access. And the [draft](https://datatracker.ietf.org/doc/draft-httpauth-payment/00/) forbids a `Payment-Receipt` header on any error response, so a receipt always means success.

In x402, the server tries to settle and reports the outcome in a `PAYMENT-RESPONSE` header whether it worked or not. The [settlement response](https://github.com/coinbase/x402/blob/main/specs/x402-specification-v2.md) carries a `success` flag, and on failure an `errorReason` and an empty transaction hash. The specification's reasons cover `insufficient_funds`, an authorization that has expired or is not yet valid, an amount mismatch, and an invalid signature.

This is where the two feel different to build against. In MPP the loop that handled the first 402 handles the retry too, because a failure arrives as a new 402. In x402 the agent reads a settlement result and then decides whether to sign again. We would write the MPP loop and fit x402 into it.

## Which one should your agent support?

Both, and the tooling makes that cheap. MPP's own [comparison page](https://mpp.dev/mpp-vs-x402) recommends MPP by default and x402 for services that want only on-chain payments; that is the protocol's own page making its case. The more useful fact is in MPP's [compatibility guide](https://mpp.dev/guides/use-mpp-with-x402): an `mppx` server can put MPP and x402 challenges on the same 402, and the `mppx` client prefers MPP but falls back to a compatible x402 `exact` offer. Support both and your agent is never the one that cannot pay.

The rails decide the rest. x402 stays on-chain but is not tied to one chain: any EVM network, plus Solana, Stellar, XRPL, Cardano and others ([networks page](https://docs.x402.org/core-concepts/network-and-token-support)). MPP adds [card payments](https://mpp.dev/mpp-vs-x402) to its methods, which matters for an agent whose human has a card and no wallet.

The minimums matter too, for anything priced per call. Stripe's [machine payments page](https://docs.stripe.com/payments/machine) sets them: 0.50 USD for a card payment, 0.01 USDC for a stablecoin payment, and sub-cent charges inside an MPP session as long as each settlement reaches 0.01 USDC. For a data call priced in cents, a card is the wrong rail.

Neither protocol is finished. MPP is an [Internet-Draft](https://datatracker.ietf.org/doc/draft-httpauth-payment/00/), which is a proposal rather than a standard: this draft was published in June 2026, lapses in December, and already has a successor on the datatracker. x402 lives under its own foundation and reached version 2 in December 2025, by its [version history](https://github.com/coinbase/x402/blob/main/specs/x402-specification-v2.md). Both will change under your client. So pin the header names and error codes you read to the spec version you wrote against, and put 21 December 2026 in your calendar, when this MPP draft expires.

## Frequently asked questions

### What does HTTP 402 Payment Required mean?

RFC 9110 reserves the 402 status code for future use and defines nothing more. Protocols such as x402 and MPP give it meaning by attaching a price and a way to pay.

### Where does an x402 client put proof of payment?

An x402 client retries the request with a `PAYMENT-SIGNATURE` header holding a Base64-encoded payment payload. The payload echoes the chosen payment requirement and carries the signed authorization.

### What does an MPP server return when a payment fails?

An MPP server answers with another 402 carrying a new `WWW-Authenticate: Payment` challenge, along with a Problem Details body that names the error, such as `verification-failed` or `payment-expired`. It never sends a `Payment-Receipt` on an error response.

### Does MPP support card payments?

Yes. MPP is payment-method agnostic, and [Stripe card payments](https://mpp.dev/mpp-vs-x402) are among its methods. Stripe sets a 0.50 USD minimum for card payments through Shared Payment Tokens, according to its [machine payments page](https://docs.stripe.com/payments/machine).

### Can one endpoint accept both x402 and MPP?

Yes, according to MPP's [compatibility guide](https://mpp.dev/guides/use-mpp-with-x402). An `mppx` server can send MPP and x402 challenges on the same 402, accept either credential format, and return the matching receipt header.
