The quote is a single x402 version 2 offer, carried in the standard PAYMENT-REQUIRED header and repeated identically in the JSON body, so a buyer-side guard that compares the two sees one offer. We ran the stock @x402/fetch and Python x402 clients against a live handle, and each one read the quote, signed and retried with no code written for SpendTheBits.
Runnable TypeScript, Python and curl examples are published at https://github.com/jkambo1986-collab/x402-handle-examples.
Pay a handle from code
- 1
Read the quote first, with no wallet: request the handle URL and base64-decode the PAYMENT-REQUIRED response header.
The decoded JSON lists one entry per network the seller can be paid on, each with the amount in USDC base units, the token contract and the payTo address.
- 2
Install a stock client: npm install @x402/fetch @x402/evm viem for TypeScript, or pip install "x402[evm,requests]" for Python.
- 3
Register the network you hold USDC on, for example eip155:8453 for Base, with the key of the paying wallet.
A handle quotes several networks at once. A stock client signs the first one it supports and does not check balances, so naming your network avoids signing for a chain the wallet is empty on.
- 4
Request the handle URL through the wrapped fetch or requests session. The client handles the 402, signs the authorization and retries.
The paying wallet needs USDC but no gas token: the payment is a signed EIP-3009 authorization that the facilitator submits.
- 5
Read the PAYMENT-RESPONSE header on the 200 response. It names the settlement transaction, the network and the payer.
Good to know
- A refusal that mentions "execution reverted" almost always means the paying wallet holds less USDC on that network than the price.
- The buyer and the seller must be different addresses. A wallet cannot pay its own handle.
- Re-sending the same signed authorization returns the same response and does not charge twice.
- The handle URL works with or without its trailing slash and never redirects, so clients that refuse redirects on a payment request are fine.
- Settlement is routed per network behind the same URL: USDC on Arc settles through Circle's facilitator, and Base, Polygon, Arbitrum and Solana through Coinbase's. The client does nothing different.
- Browser-based clients work: the endpoints send CORS headers, accept the payment headers on preflight, and expose PAYMENT-REQUIRED and PAYMENT-RESPONSE to page scripts.
Frequently asked
No. The endpoints are public by design. The signed payment is the only authorization, and the 402 response tells the client everything it needs.
The manifest at https://x402.spendthebits.com/.well-known/x402 lists every public resource, and /llms.txt and /openapi.json describe the same catalogue for tool routers. None of them is required to pay a URL you already have.
Version 2 is the default: the handle URL quotes one version 2 offer in the PAYMENT-REQUIRED header and the body, and clients pay with PAYMENT-SIGNATURE. Version 1 payments (X-PAYMENT) are still accepted, and a legacy client that needs a version 1 quote can use the same path on the API host, https://backend-production-716d3.up.railway.app/x402/@handle/resource/.
Get SpendTheBits
A fully non-custodial wallet for 13 chains, free on iOS and Android. Your keys never leave your phone.
