Payments Β· AI Agents Β· Networking
πŸ’³
x402 Β· Cloudflare Monetization Gateway
Per Request Settlement at the Edge
HTTP 402 emblem: a cyan 402 status code above a pink signed receipt line

The Request Is the Purchase: Architecture of HTTP 402 Metered Access for Agents

An agent with a wallet and no account asks your API for one thing. For decades HTTP had a status code reserved for exactly this moment and no convention for using it. On 30 September 2026 Cloudflare moved a gateway into beta that answers with a price, takes a signed payment on the retry, and settles before the response leaves the edge. This is the architecture of that exchange: the headers, the order in which money moves, the billing models the protocol encodes, and what your origin has to verify, meter and log once the paywall lives in the proxy.

ansi Β· wordmark Β· http 402
β–ˆβ–ˆβ•—  β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘      β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•
β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘      β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•”β•β•β•β•
β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘      β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘
β•šβ•β•  β•šβ•β•   β•šβ•β•      β•šβ•β•   β•šβ•β•

β–ˆβ–ˆβ•—  β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ•—β•šβ•β•β•β•β–ˆβ–ˆβ•—
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•
β•šβ•β•β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•
     β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
     β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β•β•

Overview

Say you run a document rendering API. It turns HTML into PDF, and today it sells monthly plans: a signup form, an API key, a card on file, a dashboard with usage graphs. At 03:10 an agent working for somebody you will never meet needs one PDF. It has no account with you and no intention of making one. It has a wallet and a budget. Under your current design it hits your signup page, fails, and goes to a competitor whose endpoint answered with a price instead of a form.

That gap is what Cloudflare's Monetization Gateway, announced in closed beta on 30 September 2026, is built to close. Its blog post describes it as a "paywall for agents": a domain owner writes a pricing rule, and requests that match it get an HTTP 402 Payment Required response carrying the terms. The buyer signs a payment authorization from a wallet, retries the same request, the payment settles in USDC on Base through Coinbase's x402 facilitator, and the origin's response comes back. No redirect to a checkout. No account. API2PDF, one of the launch users the post names, is a document rendering service very much like the one above.

The interesting part is not the stablecoin. It is where the purchase now lives. In the subscription design, identity, pricing, entitlement and billing are application concerns backed by a database. In the 402 design, the request is the purchase: the price is quoted in a response header, the authorization rides in a request header, and settlement happens between your proxy and a facilitator while the request is still open. That moves real architecture out of your application and into the edge, and it creates failure modes subscription billing never had: a payment that settles after your handler already did the work, a retry that must not charge twice, a price that changes between the 402 and the paid retry.

πŸ’¬

The Quote

A 402 with a base64 PAYMENT-REQUIRED header listing what the seller accepts: scheme, network, amount in atomic units, asset, recipient, timeout.

✍️

The Authorization

The client retries with PAYMENT-SIGNATURE: one chosen option plus a signed, time bounded, single use authorization from its wallet.

βš–οΈ

The Settlement

A facilitator verifies and settles through /verify and /settle. The protocol defines when that happens relative to your handler, and it matters.

🧾

The Receipt

PAYMENT-RESPONSE on the way out carries the result: success, transaction reference, network, payer. That header is your only per call receipt.

The Paywall Moved to the Proxy

Earlier pieces in this catalog looked at payments from the buyer side, and at payment rails like Daraja where the merchant system owns the callback. This one takes the seller side of a protocol where the merchant system might never see the payment at all. With a gateway in front, your origin receives a request that has already been priced and authorized, plus a signed statement saying so. Your origin stops being the paywall and becomes the meter. Design it like one: verify the statement, do the work, report what it cost, and never assume you will be asked twice.

A Status Code With Two Conventions

MDN still describes 402 Payment Required as "a nonstandard response status code reserved for future use," created with digital cash and micropayment systems in mind, with "no standard use convention." It also notes that "no browser supports a 402." Payment APIs have used it for years as a generic failed payment error. None of that gave a client enough information to actually pay.

Two conventions now try to fill it, and an agent developer will meet both. They agree on the shape of the exchange: request, 402 challenge, client pays, client retries, server verifies and answers with a receipt. They disagree on the headers.

Aspect x402 (v2) Payment auth scheme (MPP)
Challenge PAYMENT-REQUIRED header, base64 JSON WWW-Authenticate: Payment with id, realm, method, intent, request
Credential PAYMENT-SIGNATURE header, base64 JSON Authorization: Payment, base64url JSON with challenge, source, payload
Receipt PAYMENT-RESPONSE Payment-Receipt on 2xx
Retry safety payment-identifier extension, 409 on reuse with a different payload Servers SHOULD accept Idempotency-Key
Spec status Protocol v2 in the x402 Foundation repository Individual Internet Draft, revision 01 dated 17 March 2026, expired 18 September 2026
Who ships it Coinbase and Cloudflare, founding members of the x402 Foundation Authors from Tempo Labs and Stripe

The draft's authors are Brendan Ryan, Jake Moxey and Tom Meagher of Tempo Labs with Jeff Weinstein and Steve Kaliski of Stripe. It is method neutral by design: specific payment methods and intents are registered separately. x402 bundles more into the protocol itself: schemes, networks, a facilitator API and a discovery API. Cloudflare's Agents SDK documentation lists both as supported protocols. If you sell through the Monetization Gateway, you are on x402, and that is the protocol the rest of this piece follows.

Same Status, Different Contract

A 402 by itself tells a client nothing about how to pay. The headers are the contract. Treat the status code as routing and the headers as the API. A client that handles one convention and receives the other sees an opaque 4xx, which is exactly what browsers have done with 402 all along.

The Wire Format

x402 splits itself into three layers. Types are the data structures (PaymentRequirements, PaymentPayload, SettlementResponse). Logic is the scheme and network specific rule for forming and checking a payment. Representation is the transport: HTTP, MCP or A2A. On HTTP, every piece of protocol data travels in three headers. The transport spec says it directly: "Response bodies are a server implementation concern."

CLIENT (agent) RESOURCE SERVER (your edge) FACILITATOR β”‚ β”‚ β”‚ 1 │── GET /render ──────────────▢│ β”‚ │◀─ 402 PAYMENT-REQUIRED ─────│ accepts[]: scheme, network, β”‚ β”‚ (base64 JSON) β”‚ amount, asset, payTo, β”‚ β”‚ β”‚ maxTimeoutSeconds, extra β”‚ 2 β”‚ pick one accepts[] entry β”‚ β”‚ β”‚ sign authorization β”‚ β”‚ β”‚ (wallet, time bound, β”‚ β”‚ β”‚ random 32 byte nonce) β”‚ β”‚ 3 │── GET /render ──────────────▢│ β”‚ β”‚ PAYMENT-SIGNATURE (base64) │── POST /verify ──────────────▢│ β”‚ │◀─ { isValid, payer } ─────────│ 4 β”‚ β”‚ run the handler β”‚ 5 β”‚ │── POST /settle ──────────────▢│ β”‚ │◀─ { success, transaction } ───│ 6 │◀─ 200 PAYMENT-RESPONSE ─────│ β”‚ β”‚ + the resource β”‚ β”‚ Default "authorization" flow: verify, resource, settle, respond. The client never talks to the facilitator. The seller never holds keys that can move the buyer's funds beyond what the buyer signed.

Here is a decoded PAYMENT-REQUIRED header, taken from the v2 specification's own example. Note the amount: 10000 atomic units of a six decimal token is one cent.

{
  "x402Version": 2,
  "error": "PAYMENT-SIGNATURE header is required",
  "resource": {
    "url": "https://api.example.com/premium-data",
    "description": "Access to premium market data",
    "mimeType": "application/json"
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:84532",
      "amount": "10000",
      "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
      "payTo": "0x209693Bc6afc0C5328bA36FaF03C514EF312287C",
      "maxTimeoutSeconds": 60,
      "extra": { "name": "USDC", "version": "2" }
    }
  ],
  "extensions": {}
}

Every field in an accepts entry carries a design decision.

The fields that matter to a seller

  • network is a CAIP-2 identifier. eip155:8453 is Base mainnet and eip155:84532 is Base Sepolia. The spec encourages non blockchain networks to follow the same pattern, with ach:us and sepa:eu as its examples, and Cloudflare's credit backed network is cloudflare:402.
  • amount is a string in atomic units. Never a float, never a display price. Your pricing code should produce integers from the start.
  • payTo is a wallet address or a role constant. "merchant" means the network settles on your behalf.
  • maxTimeoutSeconds bounds how long the quote stays good. It is the only thing in the protocol that speaks to price stability between the 402 and the paid retry.
  • accepts is an array. You can quote the same resource on several networks or schemes and let the client choose. Every entry you list is one you must be able to settle.

The client's retry carries a PaymentPayload: the one accepts entry it chose (echoed back as accepted), plus a scheme specific payload. For the exact scheme on EVM chains, that payload is an EIP-712 signature over an EIP-3009 authorization with six fields: from, to, value, validAfter, validBefore and nonce. The settlement result comes back in PAYMENT-RESPONSE with success, transaction, network, payer and, when relevant, the amount actually settled.

Headers Have a Size Budget

Cloudflare's network binding in the x402 repository warns that "HTTP intermediaries may reject headers larger than 2KB," and trims its payloads for that reason: it omits extension schemas and drops optional resource fields. If your accepts array lists five networks with long descriptions, some proxy between you and the agent may strip or reject it. Quote the few options you actually want to settle, and keep descriptions in documentation rather than in every 402.

When the Money Moves

This is the part of x402 that decides your failure modes, and it is easy to miss. The current v2 specification defines three payment flows that differ in when settlement happens relative to your handler running.

Flow Ordering Who carries the risk
authorization (default) verify β†’ resource β†’ settle β†’ respond Seller. The work is done before the funds move. If settlement fails, the compute is spent.
upfront settle β†’ resource β†’ respond Buyer. Funds move before the work. If the handler fails, the buyer needs a refund path.
escrow settle β†’ resource β†’ settle β†’ respond Shared. A first settle holds a ceiling, a second records the final charge.

The spec adds one invariant for all three: at least one check, either a verify or a settle, must run before the resource executes. In its words, "The resource never executes with nothing checked." And it is explicit that /verify is read only. It "MUST NOT commit payment state or write onchain state." A successful verify means the signature, balance, amount, time window and recipient all checked out at that moment, and that a simulated transfer would succeed. It does not mean you have been paid.

01

Verify

The facilitator checks the EIP-712 signature, the payer's balance, an exact amount match, the time window and the recipient, then simulates transferWithAuthorization.

02

Run the handler

Your origin renders the PDF, runs the query or generates the tokens. This is where the seller spends real money on compute.

03

Check the outcome

The reference middleware for Express, Hono, Fastify and Next.js skips settlement when the handler returns a status of 400 or above. A failed call costs the buyer nothing.

04

Settle

The facilitator calls the token contract with the signed authorization. On failure, the HTTP transport answers 402 with a failed PAYMENT-RESPONSE, after the work is done.

05

Respond

The resource goes back with PAYMENT-RESPONSE carrying the transaction reference. Only now does the buyer have the resource and the seller have the funds.

Step 4 is the seller's exposure. Between verify and settle, the buyer's balance can drop, another settlement with the same wallet can land first, or the facilitator can be unavailable. Each of those means your handler did paid work and the response goes out as a 402. For a one cent render that is noise. For a call that triggers an expensive model run, it is a reason to choose a different flow, cap concurrent unsettled requests per payer, or return the result only after settlement succeeds, which the default ordering already does.

Verify Is a Promise, Settle Is a Payment

Subscription systems train you to treat "authorized" as "paid," because the card network holds the funds. EIP-3009 authorizations do not reserve anything. The tokens stay in the payer's wallet until /settle moves them. Design your handler so that the expensive part either happens after settlement, or is cheap enough to lose.

Four Schemes, Four Billing Models

A scheme is x402's word for a billing model. The repository now carries four, and the choice between them is a product decision wearing a protocol name.

exact: a fixed price per call

The buyer signs an authorization for exactly the quoted amount. On EVM it uses EIP-3009 transferWithAuthorization, so the transfer is gasless for the buyer and the facilitator submits it. Verification fails with invalid_exact_evm_payload_authorization_value_mismatch if the amounts differ by a single unit.

  • Replay protection: EIP-3009 uses a random 32 byte nonce rather than a sequential one, and the token contract refuses to accept a nonce twice. The EIP explains why: with sequential nonces, a transaction submitted with a nonce too high "will revert and fail immediately," which breaks concurrent use.
  • Time bounds: validAfter and validBefore limit the window in which the authorization can be submitted.
  • Fits: search queries, document renders, single data lookups. Anything where cost is known before the work starts.

upto: a ceiling, then the real amount

The buyer authorizes a maximum. The seller settles for actual consumption, which "MAY be 0." On EVM this uses Permit2 exclusively, because EIP-3009 "requires exact amounts at signature time." The amount field is phase dependent: at verify time it is the maximum, at settle time it is what to charge, and the facilitator "MUST verify that this amount does not exceed the authorized maximum."

  • Single use: each authorization settles at most once. No streaming, no per chunk settlement, no recurring charges.
  • One time setup: Permit2 needs the buyer to approve the Permit2 contract once, either directly with their own gas or through a sponsored extension.
  • Fits: LLM token generation, bandwidth, compute priced after the fact.

batch-settlement: commit now, settle later

Verification checks a commitment and access is granted immediately. Value moves later through the network's redemption process. The spec names the reason this exists: per request settlement fails when "gas fees exceed the value of individual requests" or when "block confirmation time is incompatible with HTTP response latency." It supports two trust models: capital backed (escrow, payment channels) and credit backed, where a network intermediary vouches for an identity.

  • Cloudflare's binding: network cloudflare:402, asset USD, payTo set to "merchant". Clients sign the request with HTTP Message Signatures (RFC 9421) using Signature-Agent, Signature-Input and Signature, with the web-bot-auth tag and Ed25519 keys published at a .well-known directory. Cloudflare acts as merchant of record and bills the identity behind the signature agent.
  • Clients with a preauthorized agreement can send the payment headers on the first request and skip the 402 entirely.

auth-capture: holds, captures and refunds

The newest scheme in the repository (v1.1, 18 August 2026) adds a lifecycle: authorize, charge, capture, void, refund and a buyer side reclaim. Its own comparison table says exact is not reversible and auth-capture is. Captures are only valid up to extra.captureDeadline, refunds up to extra.refundDeadline, and once the capture deadline passes the client can reclaim its own hold, "so a resource server that abandons a payment cannot strand it forever."

  • Fits: delayed delivery, buyer protection, metered work where you want card style semantics on a stablecoin rail.
Scheme Amount known Funds move Reversible Seller needs
exact Before the call Per request, at settle No A stable price per route
upto After the call Per request, at settle No A meter inside the handler
batch-settlement Per commitment Later, out of band Network defined Trust in the network's redemption
auth-capture Up to a held maximum Hold, then capture Void, refund, reclaim Durable state per payment and deadlines

The Gateway as Seller

You can run x402 yourself with the reference middleware: Cloudflare's Agents SDK documents x402-hono for Workers and paidTool for charging per MCP tool call. The Monetization Gateway takes the other route. It speaks the protocol at Cloudflare's edge, and your origin only sees requests that already passed verification.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ CLOUDFLARE EDGE ─────────────┐ agent ──────────▢│ monetization rule matches? β”‚ β”‚ no ──▢ normal proxy path ─────────────┼──▢ origin β”‚ yes, no PAYMENT-SIGNATURE β”‚ agent ◀── 402 ───│ ──▢ PAYMENT-REQUIRED quote β”‚ β”‚ yes, PAYMENT-SIGNATURE present β”‚ β”‚ ──▢ verify with x402 facilitator β”‚ β”‚ ──▢ add PAYMENT-CONTEXT (signed JWT)┼──▢ origin β”‚ β”‚ β”‚ β”‚ β”‚ validate JWT β”‚ β”‚ do the work β”‚ ◀── response (+ PAYMENT-SETTLEMENT β”‚β—€β”€β”€β”€β”€β”˜ β”‚ for variable pricing) β”‚ β”‚ ──▢ settle (USDC on Base) β”‚ agent ◀── 200 ───│ origin response returned after settle β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ The origin never touches a wallet. It reads one header, writes one header.

Rules are the price list

Pricing lives in monetization rules that, per the blog, "match any part of a request, such as the URL, headers, or query parameters." The rules documentation adds user agents, IP addresses, geolocation and cookies, with request body matching on Enterprise plans. Each rule picks an audience, "Everyone" or "Verified Bots," and a pricing model.

  • Fixed maps to the exact scheme: "The gateway settles the signed amount."
  • Variable maps to upto: it "authorizes a maximum price. Your origin discloses and settles the actual amount."
  • Units: one atomic unit is $0.000001. The minimum settlement is $0.001 (1,000 units) and the maximum price is $100 (100,000,000 units).

The origin contract: two headers

Inbound, PAYMENT-CONTEXT: a JWT the gateway adds to paid requests. Validate it against the JWKS at https://payments.cloudflare.com/certs with Ed25519. The docs are blunt: "Do not parse the token without verifying its signature. Reject requests when JWT validation fails," and "If PAYMENT-CONTEXT is absent, treat the request as unpaid and unverified."

Outbound, PAYMENT-SETTLEMENT: for variable pricing only, a JSON value with the actual amount as a string in atomic units, set "before sending response headers." The amount must satisfy 0 <= actual <= authorized maximum. Zero settles nothing. Do not set it when the status is 400 or greater, and do not set it at all for fixed pricing.

Here is the shape of an origin handler for a variable price route, written against the documented contract. The JWT verification helper stands in for whichever library you use. The header names, the JSON shape { "amount": "..." }, the JWKS location, the algorithm and the bounds come from Cloudflare's payment validation page, which also notes that the gateway strips PAYMENT-SETTLEMENT before the response reaches the buyer.

// Origin behind Monetization Gateway, variable (upto) pricing.
// Contract: verify PAYMENT-CONTEXT, do the work, report PAYMENT-SETTLEMENT.
// verifyEd25519Jwt is your JWT library of choice: pinned JWKS, Ed25519 only,
// keys cached per the endpoint's Cache-Control header.
const JWKS_URL = "https://payments.cloudflare.com/certs";

export async function handle(req) {
  const token = req.headers.get("PAYMENT-CONTEXT");
  if (!token) return new Response("unpaid", { status: 402 });   // never trust a missing header

  let ctx;
  try {
    ctx = await verifyEd25519Jwt(token, JWKS_URL);
  } catch {
    return new Response("bad payment context", { status: 401 });
  }

  const result = await renderPdf(await req.text());              // the paid work
  if (!result.ok) return new Response("render failed", { status: 500 });
  // status >= 400: no PAYMENT-SETTLEMENT header, so nothing is charged

  const actual = BigInt(result.pages) * 2000n;                   // $0.002 per page, atomic units
  return new Response(result.pdf, {
    status: 200,
    headers: {
      "Content-Type": "application/pdf",
      "PAYMENT-SETTLEMENT": JSON.stringify({ amount: actual.toString() }),
    },
  });
}
Assume the Proxy Can Be Bypassed

The gateway only protects routes that traffic reaches through Cloudflare. Anyone who learns your origin address can call it directly, without a 402 and without paying. That is why the JWT check is not optional decoration. An origin that serves a paid route without validating PAYMENT-CONTEXT is a free API with a paywall painted in front of it. Lock origin ingress to the proxy as well, and treat the JWT as the second lock, not the only one.

Eligibility is narrow during the beta. Sellers must be based in the United States, with Cloudflare accounts older than 60 days and zones older than 30 days, proxied through Cloudflare, with a credit card on file. The blog says buyers must be US based as well, with "support for new geographies on the way." The roadmap items it lists are identity primitives, agent discoverability, transaction logs and payment rails beyond x402, Base and USDC.

Retries, Replays and Moving Prices

Agents retry. Networks drop responses. An agent that sent a signed payment and saw a timeout cannot know whether you settled. Three mechanisms keep that from becoming a double charge or free service.

The nonce stops a replayed payment

The same exact authorization cannot settle twice, because the token contract rejects a used nonce. A replayed PAYMENT-SIGNATURE header fails settlement. That protects the buyer's funds. It does not protect your handler, which in the default flow runs before settlement and would do the work again before the duplicate fails.

The payment identifier stops a repeated purchase

The payment-identifier extension lets the client attach an id of 16 to 128 characters and reuse it on retries. The server advertises it in the 402 and can make it required. The behavior table is short:

  • New id: process normally.
  • Same id, same payload: return the cached response.
  • Same id, different payload: 409 Conflict.
  • required: true and no id: 400 Bad Request.

The extension also says to bind each id to a fingerprint covering scheme, network, asset, amount, payTo, path, method and any order identifier, and to scope the key "by tenant, merchant, route, or facilitator account." An id alone is not an authorization key.

The timeout bounds a moving price

Between your 402 and the paid retry, you might change a rule. The client signed the old amount. For exact, verification requires the signed amount to match the requirements the server checks it against, so a stale signature fails with a value mismatch and the client gets a fresh 402. maxTimeoutSeconds tells clients how long a quote holds. Cloudflare's network binding adds that when the timeout is "omitted or set to 0, the network makes no timing guarantees on price validity," and clients "should not cache pricing information across requests."

Failure What the protocol does What you still own
Handler returns 5xx Reference middleware skips settlement on status >= 400. Gateway: do not send PAYMENT-SETTLEMENT. Making sure a partial result is not returned with a 200
Settle fails after the handler ran 402 with a failed PAYMENT-RESPONSE The compute you spent. Cap per payer exposure.
Client retries after a timeout Nonce blocks a second transfer, not a second execution Require payment-identifier and cache responses by fingerprint
Price changed between quote and retry exact rejects the mismatch Sensible maxTimeoutSeconds, and rule changes that do not surprise clients
Variable amount reported above the ceiling Gateway settles the authorized maximum A meter you trust, and alerts when you hit the ceiling often
Direct hit on the origin Nothing. The 402 lives at the edge. JWT validation and origin lockdown

The Unit Economics of a Tenth of a Cent

Micropayments have always died on fixed costs per transaction. x402 changes who pays some of them, not whether they exist.

Cost Reality Check

Facilitator list price: Coinbase's CDP facilitator documentation lists "1,000 transactions free per month, then $0.001 per transaction," and says the facilitator "pays gas fees for settling payments." Buyers do not need gas for exact settlements.

The floor problem: the gateway's minimum price is $0.001. If a settlement at that price paid the CDP list fee, the fee would equal the whole charge. Cloudflare's documentation does not say who bears facilitator fees inside the gateway, or whether the CDP list price applies there. Ask before you price a route at the floor.

Variable routes: a $0.002 per page render that averages five pages settles $0.010 per call, ten times the floor. Pricing per call rather than per unit, or batching work into larger calls, keeps fixed costs a small share.

Credit backed alternative: batch-settlement on cloudflare:402 exists precisely because "gas fees exceed the value of individual requests" for some workloads. It trades onchain finality per call for one bill from the network.

Find the Call Worth Selling Alone

Subscription pricing lets a hundred cheap calls ride on one expensive plan. Per request pricing cannot hide anything. Every priced route has to be worth its own transaction. The product question becomes which single endpoint delivers enough value that an agent will pay for it with no relationship at all. Keep subscriptions for people who want them, and add the metered lane for machines beside them.

Operating a Metered Endpoint

Reconcile against the receipt

PAYMENT-RESPONSE carries the transaction hash, network, payer and, for variable settlements, the settled amount. Log it next to your own request ID and the meter reading that produced the amount. That record is how you answer "why was I charged" without a customer account to look things up in. Transaction logs are on Cloudflare's roadmap, not in the beta.

Treat the payer address as an identity, carefully

Without accounts, the payer's wallet address is the closest thing you have to a customer ID. It is good for rate limits and exposure caps per payer. It says nothing about who the human or company behind it is. The x402 spec points at Sign In With Ethereum for "authenticated pricing models," and the credit backed Cloudflare network ties payments to an RFC 9421 signing identity instead.

Expect compliance checks you do not control

The CDP facilitator runs Know Your Transaction (KYT) checks and declines payments involving sanctioned or high risk addresses. Some payments will fail at verify for reasons that have nothing to do with your code. Surface the facilitator's error reason in your logs rather than collapsing every failure into "payment failed."

Test on Base Sepolia, write rules as code

The spec's examples use eip155:84532, Base Sepolia, for a reason. Run the full loop there, including handler failures, retries with the same identifier and a rule change mid quote, before you put a mainnet payTo in a 402. Keep your monetization rules in reviewed configuration. A typo in a match expression is either free service or a 402 on your health check.

01

Pick one route

The single call an agent would pay for on its own. Fixed if the cost is known, variable if it is metered.

02

Lock the origin

Ingress only through the proxy, plus PAYMENT-CONTEXT validation on every paid route.

03

Make the handler honest

Non 2xx on failure, no settlement header on errors, an integer meter for variable routes.

04

Make retries safe

Require a payment identifier, cache responses by fingerprint, return 409 on mismatches.

05

Log the receipt

Transaction hash, payer, amount and your request ID, in one row you can query later.

Where the Sources Disagree

Four places where the primary sources say different things or leave a gap. Build to the conservative reading in each case.

Is MPP compatible with x402?

Cloudflare's Agents payments page says MPP "maintains backward compatibility with x402" and that MPP clients "can consume existing x402 services without modification." The two specs use different headers: x402 puts its challenge in PAYMENT-REQUIRED, and the Payment auth scheme draft uses WWW-Authenticate: Payment. Compatibility therefore depends on a client implementing both conventions, not on the wire formats matching. Test the specific client you care about.

A variable amount above the ceiling

The x402 upto spec says the facilitator "MUST verify" the settle amount does not exceed the authorized maximum, which reads as a rejection. Cloudflare's gateway documentation says that if the origin reports more than the maximum, it "settles the authorized maximum instead." The buyer is never charged above what they signed either way, but your meter and your revenue can silently disagree. Alert on it.

Fixed price routes that fail at the origin

The x402 reference middleware does not settle when the handler returns 400 or above, and the gateway docs say not to send PAYMENT-SETTLEMENT on such responses for variable routes. For fixed price routes behind the gateway, the documentation pages fetched for this article do not say whether an origin error skips settlement. Assume the conservative case until Cloudflare documents it, and do not let a failed render return 200.

The state of the alternative standard

Cloudflare's docs call MPP an open protocol, but the Payment auth scheme's IETF draft is an individual submission with no working group, and revision 01 expired on 18 September 2026. x402's v2 spec lives in a foundation repository rather than a standards body. Neither convention is an RFC today.

Key Takeaways

Principles

  1. The request is the purchase. Quote in PAYMENT-REQUIRED, authorize in PAYMENT-SIGNATURE, receipt in PAYMENT-RESPONSE. There is no session to hang billing state on, so design every paid route as a complete transaction.
  2. Know your flow before you write the handler. In the default authorization flow the work happens before the money moves. Choose upfront or escrow, or cap exposure per payer, when the work is expensive.
  3. Verify is not payment. A successful verify is read only and reserves nothing. Only settle moves funds.
  4. Pick the scheme from the cost model. exact for known prices, upto for metered work, batch-settlement when per call settlement costs more than the call, auth-capture when you need refunds.
  5. The origin is the meter, and the meter must lock its own door. Validate PAYMENT-CONTEXT on every request and restrict origin ingress. The 402 only exists at the edge.
  6. Retries need identity, not just nonces. Nonces stop a second transfer. A required payment-identifier with a request fingerprint stops a second execution.
  7. Errors must look like errors. Return 4xx or 5xx on failure and never attach a settlement amount to them. A 200 with a broken body is a charge for nothing.
  8. Price above the fixed costs. A $0.001 route can cost as much to settle as it earns. Find out who pays facilitator fees before you price at the floor.
  9. Log the receipt as your customer record. Transaction hash, payer, amount and request ID are all you will have when someone asks what they paid for.

In this catalog