X402: HTTP-native stablecoin payments
X402 is an open payment protocol from Coinbase that reactivates the HTTP402 Payment Required
status code for machine-to-machine stablecoin payments. It is complementary to
L402 — same goal of programmable, accountless payments inside HTTP — just settling in
USDC on Base instead of sats on the Lightning Network.
Key properties
- Stablecoin-denominated. Payments settle in USDC on Base (EVM L2), so the amount a client sees in the 402 response is the exact number of dollars they will spend. No FX.
- On-chain and low-friction. Base mainnet settlement is sub-second and costs a fraction of a cent in gas. No counterparty risk after the facilitator returns success.
- Header-driven. The client attaches one base64
X-PAYMENTheader to the original request and re-submits. The server verifies + settles via a facilitator and returns200with anX-Payment-Responseheader carrying the settlement proof. - Agent-friendly. The flow is the same for humans and autonomous agents, and it’s
supported out of the box by the Coinbase SDK as well as the open
x402-axios,x402-fetch, and Pythonx402[httpx]clients. Learn more at x402.org.
markdown2pdf.ai and X402
markdown2pdf.ai accepts both L402 (Lightning) and X402 (USDC on Base). Pick whichever rail your agent already has a wallet for.- L402: 5 sats per PDF, instant via Lightning.
- X402: $0.01 USDC per PDF, instant via Base.
sha256 of the markdown body for both rails.
Flow
POST /markdown with your markdown content.
If you haven’t paid yet, the server returns
402 with a body that contains an offers[]
array. When X402 is enabled there are two entries — one for Lightning and one for X402.Read the X402 offer.
The X402 offer carries
payment_methods: ["x402"] and a metadata.x402 block with the
native x402 accepts[] array — the payment requirements the facilitator will validate
against (network, asset, payTo, maxAmountRequired, scheme).Sign an X-PAYMENT payload.
Use any x402-aware client (Coinbase SDK,
x402-axios, x402-fetch, or Python
x402[httpx]) to construct and base64-encode a PaymentPayload authorising the transfer.Re-submit POST /markdown with X-PAYMENT.
Send the exact same request body, plus
X-PAYMENT: <base64> as a header.REST example
Python, usingx402[httpx]. Replace EVM_SIGNER_KEY
with your Base wallet’s private key (any EVM signer that holds USDC on Base).
x402HttpxClient handles the 402 → sign → retry loop for you. If you want to do it
manually (e.g. to customise the flow), the recipe is:
When to pick X402 vs L402
Pick L402 if...
Your agent already holds sats and/or uses Lightning wallets such as Alby, LNbits, or
Fewsats. Lightning settlement is instant and fees are negligible. See the
L402 page.
Pick X402 if...
Your agent already holds USDC on Base, or you want dollar-denominated predictability.
X402 is well-supported by the Coinbase CDP SDK and by
x402-axios / x402-fetch on
the TypeScript side.
