Listen to this article

TL;DR HTTP 402 sat dormant in the spec for thirty years. Now two competing protocols are racing to activate it for machine-to-machine payments. I built a server that implements both, settled real transactions on Base and Tempo, and compared what happened. x402 delegates everything to a facilitator: clean for developers, centralized by design. MPP verifies payments directly on-chain: harder to build, no intermediary. The protocol that wins will be the one that ships framework middleware first, not the one with the better spec.


When the architects of the web laid down HTTP status codes in the 1990s, they left one conspicuously vacant. HTTP 200 meant success. 404 became cultural shorthand for "not found". 402, "Payment Required", was reserved for future use and never activated. The web was built to move documents. Moving money was left to application-layer hacks: credit card forms, subscription paywalls, API key management. For thirty years, the internet's payment infrastructure was bolted on top of a protocol that had no native concept of paying for access.

The breaking point vs the protocol solution: HTTP 402 activating native payment routing

Two protocols are now racing to fill that vacancy. I have written about x402 twice, once when Coinbase announced x402 in January, again when they shipped V2 in March. Both posts were analysis. This one is different. I built a server that implements both x402 V2 and MPP, settled real payments on both chains, and compared what the code actually looked like.

The server runs at agora.steven-geller.com. Four endpoints: a haiku, a quote, a fact, a Torus symbol. Each costs 0.001 in the chain's native stablecoin. You pick the protocol, click purchase, and watch the full handshake play out: the 402 challenge, the payment, the settlement, the content delivery. Every transaction settles on a real blockchain with a link to the block explorer. x402 settles USDC on Base Sepolia. MPP settles pathUSD on Tempo Moderato.

The 402 handshake sequence: GET, 402 challenge, signed payment, 200 content delivery

x402 invented its own HTTP

x402 V2 returns a 402 with a Payment-Required header containing a base64-encoded JSON blob. Inside: the x402 version, accepted payment schemes, network identifier (eip155:84532 for Base Sepolia), recipient address, token contract, timeout. The client constructs a Payment-Signature header with a signed EIP-712 payload and retries. The server forwards this to a facilitator at x402.org/facilitator for verification and on-chain settlement.

The entire protocol lives in proprietary headers. Nothing in the HTTP ecosystem understands them: CDNs, proxies, browser devtools all treat Payment-Required as an opaque blob. You need x402-specific tooling to inspect or route based on payment state. The trade-off is speed. V2 shipped three months after V1 with breaking changes to the header format, CAIP-2 chain identifiers, wallet-based identity, and integration with World for cryptographic proof-of-personhood. That last piece addresses a real problem in the agent economy: how do you prevent sybil attacks on pay-per-use APIs? An agent can now present a World ID proof to demonstrate it acts on behalf of a verified human, letting service providers differentiate pricing and trust levels without knowing who the human is. Try shipping that through an RFC process.

x402 v2 solving high-frequency friction: per-request payments vs SIWx session-based efficiency

The Rust ecosystem is good. x402-axum dropped into my existing Axum server in about twenty lines. x402-reqwest handles the client side transparently. Both worked the first time. The facilitator does the hard work: nonce management, transaction simulation, gas estimation, on-chain settlement. My API server never touches blockchain state directly.

x402 architecture: the facilitator triangle between client, facilitator, and server

That facilitator is both the strength and the vulnerability. Clean separation of concerns. But it is a centralization point and a latency bottleneck. The transaction hash in the x-payment-response header comes from the facilitator's settlement, not the client's wallet directly. If x402.org goes down, the protocol stops working for everyone using the hosted facilitator.

MPP wants to be HTTP itself

MPP takes the opposite approach. It proposes a Payment HTTP authentication scheme via an IETF draft. The server returns WWW-Authenticate: Payment with structured parameters: id, realm, method, intent, expires, request. The client responds with Authorization: Payment containing a base64url-encoded credential. Standard HTTP auth semantics. Any proxy or debugging tool that understands WWW-Authenticate understands the structure, even if it does not understand the payment method inside.

The method field is where MPP gets interesting. It is pluggable. Tempo is one method. Stripe is another. Visa contributed card payment specs. Lightspark extended it to Bitcoin Lightning. The protocol defines the challenge-response envelope. The actual settlement is between the client and whatever payment rail the method specifies. An agent buying API access could pay with USDC on one call, a Visa token on the next, Lightning on the third. Same HTTP semantics, different settlement rails.

Stripe MPP enterprise hybrid flow: crypto rails and fiat rails converging through the payment method abstraction

The design also points toward session-based authorization: rather than signing every micro-transaction individually, an agent could authorize a spending limit for a session. That is where the real efficiency gain lives for agents making thousands of API calls per minute. Per-request challenge-response adds latency that compounds at volume. I did not implement sessions (the SDKs are three days old), but the architecture accommodates it.

In practice today, pluggable means you build everything yourself. For my Tempo implementation, the server calls eth_getTransactionReceipt on the Tempo RPC, parses the receipt logs for a Transfer event matching the right token, recipient, and amount. That is real verification: the server checks the blockchain directly, no facilitator in the path. But I had to write ~625 lines of manual RLP encoding, raw JSON-RPC calls, ERC-20 calldata construction, HMAC challenge binding, and receipt parsing from scratch. There is no equivalent of x402-axum for MPP.

The challenge-binding difference tells you everything

x402 does not cryptographically bind its challenge to the request. The Payment-Required header describes what to pay, but replay protection comes entirely from the facilitator, which tracks payment nonces and expiration times. If the facilitator is down, there is no fallback.

MPP binds every challenge to the server via HMAC-SHA256. The id parameter is computed from the realm, method, intent, request parameters, and expiration, keyed with a server secret. When the client echoes the challenge back, the server can verify it was issued by this server, for this request, and has not expired, without any external call. Stateless verification.

But HMAC binding alone does not prevent replay at the payment layer. A valid transaction hash could be reused across multiple challenges. I had to add a consumed-transaction-hash set to reject previously seen hashes. The spec does not mention this. It is the kind of thing you only discover by building.

Protocol comparison table: x402 v2 vs Machine Payments Protocol across architecture, HTTP mechanics, settlement, identity, pricing, and audience

What I got wrong

I assumed MPP would be easier because the IETF spec is cleaner. It was not. The spec defines the envelope but says nothing about how to verify a Tempo payment. That is left to the method implementor, which means you. The x402 ecosystem did the hard work: middleware, client libraries, hosted facilitator. MPP's ecosystem is a spec document and a three-day-old SDK.

I also assumed the latency difference would be dramatic. x402 needs a facilitator round-trip. MPP just needs a direct RPC call. In practice, x402 testnet purchases averaged ~600ms. MPP purchases averaged ~1,200ms. MPP was slower because Tempo block times are longer than the facilitator's cached verification, and because raw JSON-RPC does not pipeline the way a proper provider would. The protocol is not the bottleneck. The infrastructure is.

Developer reality check: x402 averaging 600ms vs MPP averaging 1200ms implementation latency

Tempo's chain is EVM-compatible but expensive in gas. A simple pathUSD transfer costs ~300,000 gas, roughly three times what the same operation costs on Ethereum L1. On testnet this is free. On mainnet the ratio matters at volume.

Security is your problem

Neither protocol spec says much about operational security. Building Agora forced me to handle it: rate limiting to prevent wallet draining, consumed-transaction-hash tracking for replay protection, HMAC constant-time comparison to prevent timing attacks, sanitized error messages so internal RPC URLs never reach the client, SVG sanitization on the Torus endpoint. None of this is protocol-specific. All of it is necessary the moment you put a payment endpoint on the public internet.

The agentic security stack: network-level machine learning, smart contract account abstraction, and hardware secure enclaves

What this means

If you need agents paying for APIs this quarter, use x402. The tooling exists. Twenty lines of Rust and you have payment-gated endpoints. The facilitator handles settlement.

If you are designing a payment standard that needs to work across fiat, crypto, cards, and Lightning, watch MPP. The method abstraction is the right design. But watch and build on are different verbs. Wait for the SDKs.

Market dynamics: the Cloudflare chokepoint between millions of AI agents and millions of websites

The protocol that wins the agent economy is the one that ships middleware for Express, Axum, FastAPI, and Rails. x402 has that today. MPP does not yet. Framework middleware is the distribution channel for payment protocols the same way npm packages are the distribution channel for JavaScript libraries.

Protocol coexistence: the agentic workflow across data acquisition, synthesis, and point of sale phases

But the deeper shift is what happens to the rest of the web when 402 actually works. AI agents do not see banner ads. They are immune to persuasive design. They do not click. When a machine requests a resource, it either gets the data or it gets a price. The entire ad-funded web assumes a human on the other end with eyeballs to monetize. When agents become a meaningful share of HTTP traffic, that assumption breaks. Content providers will need to charge for access directly, and 402 is the mechanism that makes that possible at protocol level. A status code that sat dormant for thirty years turns out to be what machine-to-machine commerce needed. The browser never needed native payments. Agents do.

Synthesis: the five trillion dollar shift from legacy settlement to on-chain finality