Pay with x402
How an agent pays for a priced page with a signed x402 authorization.
A site on DNA can price a page. An agent that requests it without paying gets
a 402 with terms. The agent signs a payment authorization, retries with it,
and gets the page and a receipt.
A 402 can list two methods: d3-pay, where a person approves the payment
(Pay with DNA), and x402 (this page). Use the first one you
support.
The exchange
- Request the page. You get a
402with the terms inpayment-required. - Pick one entry from
accepts, sign it, and retry withpayment-signature. - On success you get the page and
payment-response.
| Header | On | Value |
|---|---|---|
payment-required | the 402 | Base64 JSON: accepts[] and resource. The terms are here, not in the body. |
payment-signature | your retry | Base64 JSON: the signed authorization. Send x-payment instead if you speak x402 v1. |
payment-response | the paid response | Base64 JSON receipt naming the transaction. x-payment-response for v1. |
Terms
- The scheme is
exact. Networks are CAIP-2, such aseip155:8453. acceptshas one entry per token the site accepts, each the page's dollar price in that token's units. Pay with any of them.- Amounts are atomic units.
maxAmountRequiredhas no decimals; read them from the token. - Terms are valid for 300 seconds.
- The payment header is capped at 4096 bytes.
- Use a new nonce per attempt. A reused one returns
nonce_already_used. - A refusal includes the terms again, so you can fix the payload and retry without a new request.
ambiguous_routeandinvalid_pathinclude no terms, because no single price applies.- A request carrying both an x402 payment and a DNA credential is handled as x402.
- In a browser,
payment-requiredon the402andpayment-responseon the paid response are listed inaccess-control-expose-headers, so you can read them.
Errors
Each error is a JSON body with an error field.
| Status | error | Meaning and action |
|---|---|---|
402 | invalid_payload | The header didn't decode, or matched none of the offered terms. |
402 | invalid_payment_requirements | Two offered terms match your payload. Narrow the amount or the network. |
402 | nonce_already_used | Sign again with a new nonce. |
402 | insufficient_funds | The payer's balance is below the price. |
402 | other x402 reasons | The provider's standard reason, passed through, such as invalid_network or invalid_exact_evm_payload_signature. |
402 | settlement_refused | The provider refused for a reason outside the standard set. |
402 | ambiguous_route | The site prices this request twice. Tell the site; no retry fixes it. |
402 | invalid_path | The requested path couldn't be determined. Send /, \, and . unencoded. |
502 | payment_unavailable | A DNA failure. Sign again with a new nonce; the old authorization stays claimed. |
A 502 is a refusal: a request that presents a payment never falls through to
the page for free.