Pay-Per-Request
In the Pay-Per-Request (or "Direct") model, agents pay for each individual API call at the moment of request.
This flow uses the standard HTTP 402 Payment Required status code to negotiate payment.
⚠️ Important: Use the x402 SDK
x402 uses EIP-2612 permit signatures (gasless meta-transactions), NOT raw ERC20 transfers. You should NOT manually construct transfer() transactions.
The x402 SDK handles all cryptographic signing automatically. Use the official SDK for your language:
How It Works
1. Initial Request (No Payment)
The agent attempts to access the endpoint without any payment. The server responds with 402 Payment Required.
curl -X GET https://api.x402layer.cc/e/super-ai-trader2. The 402 Challenge
The server returns payment requirements in the response body. The accepts array tells you exactly what to pay.
// HTTP 402 Payment Required
{
"x402Version": 1,
"accepts": [
{
"scheme": "exact",
"network": "base",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0x742d35Cc6634C0532925a3b844Bc9e7595f...",
"maxAmountRequired": "1000000",
"description": "Payment for API access",
"maxTimeoutSeconds": 3600
}
]
}3. SDK Handles Payment
The x402 SDK automatically: (1) signs an EIP-2612 permit, (2) encodes it as base64, and (3) attaches it to the X-Payment header.
// The SDK adds this header automatically:
X-Payment: eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW1lIjoiZXhhY3QiLC...Implementation with x402 SDK
The SDK wraps your HTTP client and handles payment negotiation automatically. You just make normal requests.
npm install @x402/fetch @x402/evm viemimport { wrapFetchWithPayment } from '@x402/fetch';
import { privateKeyToAccount } from 'viem/accounts';
// 1. Setup your wallet
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
// 2. Create payment-enabled fetch
const payFetch = wrapFetchWithPayment(fetch, account);
// 3. Make requests - SDK handles 402 automatically!
const response = await payFetch('https://api.x402layer.cc/e/super-ai-trader');
const data = await response.json();
console.log(data); // Your API response- First request gets 402 response
- SDK reads payment requirements
- SDK signs EIP-2612 permit using your private key
- SDK retries request with X-Payment header
- Server settles payment and returns data
Supported Networks
🔵 Base (EVM)
- • Uses EIP-2612 Permit for gasless signatures
- • Asset: USDC (
0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) - • No gas needed for signing
- • SDK:
@x402/evm
🟣 Solana
- • Uses SPL Token Transfer authorization
- • Asset: USDC (
EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v) - • Facilitator handles fee paying
- • SDK:
@x402/svm
Error Handling
try {
const response = await payFetch('https://api.x402layer.cc/e/some-endpoint');
if (!response.ok) {
// Check for payment-specific errors
const body = await response.json();
if (response.status === 402) {
console.log('Payment required:', body.accepts);
// SDK should handle this automatically
// If you see this, check your wallet balance
}
}
return await response.json();
} catch (error) {
if (error.message.includes('insufficient balance')) {
console.log('Not enough USDC in wallet');
}
throw error;
}Troubleshooting
❌ "Payment verification failed"
Your wallet may not have enough USDC, or the signature format is wrong. Make sure you're using the x402 SDK, not raw ERC20 transfers.
⚠️ Network Mismatch
Check if the endpoint accepts your network. If it says "network": "solana", you need a Solana wallet. Some endpoints support both.
✅ Best Practice
Always use wrapFetchWithPayment() or the Python PaymentClient. Never try to manually construct transactions.