Skip to main content

X402: HTTP-native stablecoin payments

X402 is an open payment protocol from Coinbase that reactivates the HTTP 402 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 Solana instead of sats on the Lightning Network.

Key properties

  • Stablecoin-denominated. Payments settle in USDC on Solana, 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. Solana 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 payment header to the original request and re-submits. x402 v2 clients send PAYMENT-SIGNATURE; the server also accepts the v1 X-PAYMENT header. The server verifies + settles via a facilitator and returns 200 with a PAYMENT-RESPONSE header 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 Python x402[httpx] clients. Learn more at x402.org.

markdown2pdf.ai and X402

markdown2pdf.ai accepts both L402 (Lightning) and X402 (USDC on Solana). Pick whichever rail your agent already has a wallet for.
  • L402: 5 sats per PDF, instant via Lightning.
  • X402: $0.40 USDC per PDF, instant via Solana. This is the minimum charge X402 allows, so Lightning is the cheaper rail.
You pay per document. Re-submitting the same markdown reuses the paid receipt — our server dedupes on a sha256 of the markdown body for both rails.

Flow

1

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. The response also carries an X-Accept-Payment: lightning, x402 header and a base64 PAYMENT-REQUIRED header holding the x402 v2 payment requirements.
2

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, amount, scheme). The server speaks x402 v2, so the field is amount, in USDC base units (6 decimals): "400000" is 0.40 USDC. Read the price from here, not from the offer’s top-level amount.
3

Sign a 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.
4

Re-submit POST /markdown with the payment header.

Send the exact same request body, plus PAYMENT-SIGNATURE: <base64> (x402 v2) or X-PAYMENT: <base64> as a header.
5

Server verifies + settles via the facilitator, returns 200.

A successful response carries PAYMENT-RESPONSE: <base64> — the base64-encoded SettleResponse with the on-chain transaction hash. Your agent can log this for auditing, or ignore it and proceed straight to polling the job status.
Alternative shortcut. If your client already speaks x402 natively and does not want to parse the L402 envelope, it can ignore the outer body entirely and read accepts[] straight from offers[].metadata.x402.accepts — no second round-trip required. We also expose a dedicated POST /payment_request/x402 endpoint for clients that prefer an explicit per-offer lookup.

REST example

Python, using x402[httpx]. Install it with the Solana extra, pip install "x402[httpx,svm]", then set SOLANA_SIGNER_KEY to your wallet’s base58 private key (64-byte keypair as exported by most Solana wallets).
The 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 Solana, 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.
Either way, the document generation backend is identical — the choice is purely about how you want to pay.