x402 V2
Payments
Every paid tool uses the same handshake. Browsers that prefer text/html get the
paywall UI. Agents that prefer application/json get a JSON 402 body. Both include
the base64 PAYMENT-REQUIRED header.
Handshake
-
Probe unpaid. Receive HTTP 402 and decode
PAYMENT-REQUIRED(base64 JSON). -
Sign an EIP-3009
transferWithAuthorizationfor the quoted USDC amount on Base. -
Retry the same URL with
PAYMENT-SIGNATURE(base64 JSON echoingaccepted,payload, andextensionswhen present). -
Success is HTTP 200 JSON plus
PAYMENT-RESPONSE. Settlement completes before the tool runs. Uncertain settlement fails closed.
Headers
| Header | Role |
|---|---|
PAYMENT-REQUIRED |
Server challenge. Base64 JSON. Present on unpaid 402 responses. |
PAYMENT-SIGNATURE |
Client payment. Base64 JSON. Required to settle and run the tool. |
PAYMENT-RESPONSE |
Settlement receipt on HTTP 200. |
Shared payment errors
Tool-specific codes live on each tool page. payment_required is listed once there
after merge.
| HTTP | Code | When |
|---|---|---|
| 402 | payment_required |
Missing or invalid PAYMENT-SIGNATURE; decode the PAYMENT-REQUIRED header |
| 409 | payment_in_progress |
The same authorization nonce is already being settled; retry shortly |
| 429 | rate_limited |
Too many requests from this client |
| 503 | settlement_uncertain |
Settlement is unconfirmed; retry with the same PAYMENT-SIGNATURE |
| 503 | facilitator_unavailable |
Payment facilitator unavailable |
| 503 | facilitator_misconfigured |
Payment facilitator is not configured |
| 503 | facilitator_unauthorized |
Payment facilitator rejected credentials |
| 503 | ledger_unavailable |
Payment ledger unavailable |
| 503 | payment_unavailable |
Payment processing unavailable |