Note · 2026-09-21
How x402 payments actually work, with a real HTTP 402 response
x402 turns the dormant HTTP 402 status code into a machine-payable handshake — call an endpoint, get a 402 with a payment quote in the response headers, pay in USDC, retry with proof, get your data. Walked through with an unpaid request against one of our own live routes.
Short answer: x402 is a three-step HTTP exchange, not a new protocol on top of HTTP. You call an endpoint like any API. If it needs payment, it answers 402 Payment Required (a status code that has existed in the HTTP spec since 1997 but almost nobody used) with a JSON quote — asset, amount, network, address — either in the body or a PAYMENT-REQUIRED header. Your client (or an x402-aware library) signs a USDC transfer for that exact amount, retries the same request with an X-PAYMENT header carrying the signed payment, and the server verifies it with a facilitator and returns the real response. No account, no API key, no invoice — the 402 round trip is the checkout.
A real 402, unpaid
This is what you get calling one of our own live routes with no payment attached:
POST https://qf-api.quietforge-studio.workers.dev/v1/sudoku
→ HTTP/2 402
payment-required: <base64 JSON, decoded below>
response body: {}
Decoded, the payment-required payload is:
{
"x402Version": 2,
"error": "Payment required",
"resource": {
"url": "https://qf-api.quietforge-studio.workers.dev/v1/sudoku",
"description": "Generate 1-20 classic 9x9 sudoku puzzles...",
"serviceName": "Quietforge Sudoku API"
},
"accepts": [{
"scheme": "exact",
"network": "eip155:8453",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "10000",
"payTo": "0x3F5115236f25618c16021E983acaAF2CAaa1A35e",
"maxTimeoutSeconds": 300,
"extra": { "name": "USD Coin", "version": "2" }
}]
}
Every field there is load-bearing for a client deciding whether to pay:
network: "eip155:8453"— Base mainnet, usually expressed as a CAIP-2 chain ID like this one, though some x402 servers just write the bare wordbase.asset— the ERC-20 contract address of USDC on Base, not a symbol — an address the client can pin and verify, rather than trusting a human-readable ticker.amount: "10000"— atomic units. USDC has 6 decimals, so10000= $0.01.payTo— our wallet address. This is the entire "merchant account": no Stripe, no bank, no signup.scheme: "exact"— pay exactly this amount for exactly this resource. It's the only scheme in wide use today; the spec proposes others (e.g.upto) but we haven't seen one live yet.
The three steps
1. Call unpaid. Get back 402 + the quote above. This step is free and rate-limit-friendly — it's how a client (or a search/indexing bot) can discover what something costs without paying. 2. Pay and retry. An x402 client library (the x402 Python/TypeScript SDKs, x402-fetch, x402-axios, or a wallet-integrated agent framework) signs a USDC transfer authorization for the exact amount/asset/network/payTo, base64-encodes it, and resends the identical request with an X-PAYMENT header. No new HTTP verb, no separate payment API call. 3. Verify and settle. The server hands the X-PAYMENT value to a facilitator (we use PayAI's; Coinbase's CDP facilitator is the other common one) which checks the signature and broadcasts the on-chain transfer. Only once that comes back valid does the server return the actual response — the sudoku puzzles, the PDF, the dataset audit. If verification fails, you get another 402, not a 500 or a silent bad response.
Why 402 and not "just add a Stripe checkout"
The point of using the status code instead of a redirect-to-checkout flow is that the whole exchange stays inside one HTTP request/response cycle a machine can drive without a human clicking anything. A checkout URL assumes a browser and a person; a 402 header assumes nothing but an HTTP client and a wallet. That's the specific thing x402 is for: machine-to-machine payment, where the caller is another program or an autonomous agent, not a person filling in a card form. It composes with MCP tool calls, cron jobs, and agent pipelines the same way any other HTTP header does — which is also why it settles in a stablecoin (USDC) rather than a card network: card rails assume a human cardholder and a dispute process, an on-chain USDC transfer just needs a valid signature.
Try it without paying
Every paid route on our Docs API answers a real 402 like the one above — curl any of them with no X-PAYMENT header and you'll get the live quote. One route, POST /v1/dataset-audit/preview, has a free variant (no payment, reduced output) so you can see a real response shape before wiring up a payer. We also publish a free MCP server that wraps the read-only parts of this without needing an x402 client at all. If you're pricing your own x402 route, see our companion note on what 400 live x402 endpoints actually charge — median is $0.01.