x402 Tutorial: Add Payments to Your API in 15 Minutes
Imagine monetizing your API the same way you'd add authentication—with just a few lines of code. That's exactly what the x402 protocol makes possible. In this hands-on tutorial, we'll transform a regular API endpoint into a pay-per-call service that accepts USDC payments on Base.
What You'll Build
By the end of this tutorial, you'll have:
- An API endpoint protected by x402 payments
- Automatic payment verification
- A working payment flow that accepts USDC
Prerequisites
Before we start, make sure you have:
- Node.js 18+ installed
- A basic understanding of REST APIs
- A wallet address to receive payments (we'll use Base network)
Understanding the x402 Flow
The x402 protocol leverages HTTP's rarely-used 402 status code ("Payment Required"). Here's how it works:
- Client requests your API endpoint
- Server responds with 402 and payment details
- Client creates a payment voucher (signed message)
- Client retries with the voucher in headers
- Server verifies and processes the request
- Facilitator settles the payment on-chain
This "optimistic" approach means requests aren't blocked waiting for blockchain confirmations—payments settle asynchronously.
Step 1: Set Up Your Project
Let's create a new project:
mkdir x402-api-demo && cd x402-api-demo
npm init -y
npm install express @perkos/x402-server
The @perkos/x402-server package provides middleware that handles all the payment logic.
Step 2: Create a Basic Server
Create server.js:
import express from 'express';
import { x402 } from '@perkos/x402-server';
const app = express();
// Your wallet address on Base
const PAYEE_ADDRESS = 'YOUR_WALLET_ADDRESS';
// Configure x402 middleware
const paymentMiddleware = x402({
payeeAddress: PAYEE_ADDRESS,
network: 'base',
acceptedTokens: ['USDC'],
});
// Free endpoint (no payment required)
app.get('/health', (req, res) => {
res.json({ status: 'ok' });
});
// Paid endpoint: $0.001 per call
app.get('/api/premium-data',
paymentMiddleware({ amount: '0.001', currency: 'USD' }),
(req, res) => {
res.json({
data: 'This is premium content!',
timestamp: new Date().toISOString(),
paymentId: req.x402?.paymentId
});
}
);
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
That's it! With about 20 lines of code, your endpoint now requires payment.
Step 3: Test the Payment Flow
Start your server:
node server.js
Try calling the endpoint without payment:
curl http://localhost:3000/api/premium-data
You'll get a 402 response with payment instructions:
{
"status": 402,
"message": "Payment Required",
"payment": {
"amount": "0.001",
"currency": "USD",
"network": "base",
"payee": "0x...",
"tokens": ["USDC"]
},
"facilitator": "https://facilitator.perkos.xyz"
}
Step 4: Making Payments from a Client
On the client side, you'd handle this with the x402 client library:
import { x402Client } from '@perkos/x402-client';
const client = x402Client({
wallet: yourWalletProvider, // ethers.js signer, viem, etc.
});
// Automatic payment handling
const response = await client.fetch(
'http://localhost:3000/api/premium-data'
);
console.log(response.data);
The client automatically:
- Detects the 402 response
- Creates an EIP-712 signed voucher
- Retries with the payment header
- Returns the actual response
Step 5: Different Pricing Models
The x402 middleware supports flexible pricing:
// Per-call pricing
app.get('/api/translate',
paymentMiddleware({ amount: '0.01', currency: 'USD' }),
translateHandler
);
// Dynamic pricing based on request
app.post('/api/generate-image',
paymentMiddleware(req => ({
amount: req.body.quality === 'hd' ? '0.05' : '0.01',
currency: 'USD'
})),
imageHandler
);
// Free tier with limits
app.get('/api/data',
paymentMiddleware({
amount: '0.001',
currency: 'USD',
freeQuota: 100, // First 100 calls free per day
}),
dataHandler
);
Step 6: Monitoring Payments
Track your earnings in real-time:
import { x402, onPayment } from '@perkos/x402-server';
// Payment webhook
onPayment((payment) => {
console.log(Received ${payment.amount} USDC);
console.log(From: ${payment.payer});
console.log(Endpoint: ${payment.path});
});
Security Considerations
The x402 protocol includes several security features:
- EIP-712 Signatures: Payments are cryptographically signed
- Nonce Management: Prevents replay attacks
- Facilitator Verification: Trusted settlement layer
- Timeout Protection: Vouchers expire after configurable time
Common Patterns
API Key + x402 Hybrid
app.get('/api/premium',
apiKeyAuth, // Your existing auth
paymentMiddleware({ amount: '0.001', currency: 'USD' }),
handler
);
Subscription Override
app.get('/api/data',
paymentMiddleware({
amount: '0.001',
currency: 'USD',
skipIf: (req) => hasActiveSubscription(req.user)
}),
handler
);
Deployment Checklist
Before going to production:
- Use environment variables for wallet addresses
- Set up monitoring for payment events
- Configure rate limiting alongside payments
- Test on Base Sepolia before mainnet
- Document your pricing for API consumers
What's Next?
You've just built a payment-enabled API in 15 minutes. The x402 protocol opens up possibilities like:
- Micropayment-based AI services
- Pay-per-query databases
- Usage-based SaaS pricing
- Agent-to-agent commerce
Resources
The future of API monetization is here, and it takes just 15 minutes to get started.


