x402 Payments
The x402 protocol enables pay-per-request API access using cryptocurrency.
How It Works
The 402 Response
When free tier is exhausted, you receive:
{
"error": true,
"code": "PAYMENT_REQUIRED",
"price": "$0.01",
"priceUSD": 0.01,
"network": {
"name": "Base",
"chainId": 8453
},
"asset": "USDC",
"recipient": "0xF499102c8707c6501CaAdD2028c6DF1c6C6E813b",
"x402": {
"version": "1",
"facilitator": "https://api.cdp.coinbase.com/platform/v2/x402"
}
}
Payment Flow
1. Free Tier First
Every IP/wallet gets 100 free calls per day. No payment needed.
curl https://api.web3identity.com/api/ens/resolve/vitalik.eth
# Works! Returns data.
2. 402 Response
After exhausting free tier:
curl https://api.web3identity.com/api/ens/nick.eth
# Returns 402 with payment instructions
3. Sign Authorization
Sign an EIP-712 TransferWithAuthorization message permitting USDC transfer:
const signature = await wallet.signTypedData({
domain: { name: 'USDC', version: '2', chainId: 8453 },
types: { TransferWithAuthorization: [...] },
message: {
from: yourWallet,
to: recipientWallet,
value: priceInWei,
validAfter: 0,
validBefore: deadline,
nonce: randomNonce,
},
});
4. Retry with Payment
Send both headers with identical value (required by x402 adapter):
curl -X GET "https://api.web3identity.com/api/ens/nick.eth" \
-H "x-payment: <payment_json_base64>" \
-H "payment-signature: <payment_json_base64>"
Both Headers Required
The x402 adapter requires both x-payment AND payment-signature headers with the same payment payload. This is due to timing in the @x402/express middleware.
Raw Payment Example (Without SDK)
For developers implementing x402 manually:
import { createWalletClient, http, encodeAbiParameters } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { base } from 'viem/chains';
// 1. Make request, get 402
const res = await fetch('https://api.web3identity.com/api/ens/nick.eth');
if (res.status !== 402) { /* handle response */ }
const paymentReq = await res.json();
// paymentReq.priceUSD = 0.01
// paymentReq.recipient = "0xF499..."
// 2. Prepare EIP-3009 TransferWithAuthorization
const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
const deadline = Math.floor(Date.now() / 1000) + 3600; // 1 hour
const nonce = crypto.randomBytes(32);
// 3. Sign the authorization
const wallet = createWalletClient({
account: privateKeyToAccount(WALLET_KEY),
chain: base,
transport: http()
});
const signature = await wallet.signTypedData({
domain: {
name: 'USD Coin',
version: '2',
chainId: 8453,
verifyingContract: USDC_BASE
},
types: {
TransferWithAuthorization: [
{ name: 'from', type: 'address' },
{ name: 'to', type: 'address' },
{ name: 'value', type: 'uint256' },
{ name: 'validAfter', type: 'uint256' },
{ name: 'validBefore', type: 'uint256' },
{ name: 'nonce', type: 'bytes32' }
]
},
primaryType: 'TransferWithAuthorization',
message: {
from: wallet.account.address,
to: paymentReq.recipient,
value: BigInt(paymentReq.priceUSD * 1e6), // USDC has 6 decimals
validAfter: 0n,
validBefore: BigInt(deadline),
nonce: nonce
}
});
// 4. Build payment header
const payment = {
x402Version: 1,
scheme: 'exact',
network: 'eip155:8453',
payload: {
signature,
authorization: {
from: wallet.account.address,
to: paymentReq.recipient,
value: String(paymentReq.priceUSD * 1e6),
validAfter: '0',
validBefore: String(deadline),
nonce: '0x' + nonce.toString('hex')
}
}
};
const paymentHeader = Buffer.from(JSON.stringify(payment)).toString('base64');
// 5. Retry with payment
const paidRes = await fetch('https://api.web3identity.com/api/ens/nick.eth', {
headers: {
'x-payment': paymentHeader,
'payment-signature': paymentHeader // BOTH required
}
});
const data = await paidRes.json();
// Success! Payment settled via CDP facilitator
Pricing
| Endpoint Type | Price |
|---|---|
| ENS Resolution | $0.01 |
| Farcaster Profile | $0.01 |
| Token Prices | $0.001 |
| Batch Operations | $0.02 |
| Historical Data | $0.05 |
Why x402?
For Developers:
- No API key signup required
- Pay only for what you use
- Works with any wallet
For the API:
- Sustainable revenue model
- No free tier abuse
- Automatic settlement
SDK Support
The SDK handles payments automatically:
import { ATVClient } from '@atv-eth/x402-sdk';
const client = new ATVClient({
privateKey: process.env.WALLET_KEY,
});
// SDK handles 402 → sign → retry automatically
const profile = await client.getProfile('nick.eth');
Network Details
| Property | Value |
|---|---|
| Network | Base (Chain ID 8453) |
| Asset | USDC |
| Facilitator | Coinbase CDP |
| Settlement | Instant |
Related
- Authentication — SIWE for 2x limits
- Rate Limits — Free tier details
- SDK Overview — Automatic payment handling