x402 Micropayments: How AI Agents Pay for Data on Base L2
HTTP 402 β "Payment Required" β has been reserved since 1996. x402 finally makes it real. Here's how autonomous agents are using the protocol to pay for data in real-time, using Support Local Businesses' live payment rail as the working example.
What is x402?
x402 is an open standard for
machine-to-machine HTTP payments. When a server returns a
402 Payment Required response, it includes a payment payload in the
X-Payment-Required header. The client resolves the payment on Base L2 and retries
with a X-Payment-Payload header containing the signed transaction.
No API keys. No subscription sign-ups. No billing portals. The agent pays exactly for what it consumes, in USDC, on Base.
- Sign up for account
- Add credit card
- Get API key
- Hit rate limits
- Pay monthly bill
- Read
/.well-known/pay - Fund wallet with USDC
- Call endpoint
- Auto-pay on 402
- Done β no account needed
How the Payment Flow Works
The full handshake in four steps:
# Step 1 β Agent makes a request (first 100 free)
GET /api/v1/businesses?zip=33601&category=plumber HTTP/1.1
Host: support-local-businesses.com
X-Agent-Id: my-research-agent/1.0
Step 2 β After free tier, server returns 402
HTTP/1.1 402 Payment Required
Content-Type: application/json
X-Payment-Required: {
"version": "1.0",
"scheme": "exact",
"network": "base",
"chainId": 8453,
"maxAmountRequired": "1000",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0x0cF67aB1D0C843F67bC64D507A5627a41AE5BBC0",
"memo": "slb-api-query"
}
Step 3 β Agent signs and sends USDC on Base
(handled by x402 client library)
Step 4 β Agent retries with payment proof
GET /api/v1/businesses?zip=33601&category=plumber HTTP/1.1
X-Payment-Payload: eyJhbGci...signed.jwt.here...
HTTP/1.1 200 OK
X-Payment-Settled: true
β data returned
The /.well-known/pay Discovery Endpoint
Agents don't need to know about payment up front. They discover it at the standard
/.well-known/pay endpoint, which describes the payment configuration for the entire API.
curl https://support-local-businesses.com/.well-known/pay | jq .
The response looks like:
{
"version": "1.0",
"provider": "Support Local Businesses",
"scheme": "x402",
"network": "base",
"chainId": 8453,
"paymentReceiver": "0x0cF67aB1D0C843F67bC64D507A5627a41AE5BBC0",
"asset": {
"symbol": "USDC",
"address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"decimals": 6
},
"pricing": {
"default": { "amount": "0.001", "currency": "USDC", "per": "request" },
"bulk_export": { "amount": "0.01", "currency": "USDC", "per": "request" }
},
"freeAllowance": {
"requests": 100,
"period": "daily",
"resetTime": "00:00 UTC"
},
"discovery": {
"mcp": "https://support-local-businesses.com/.well-known/mcp.json",
"openapi": "https://support-local-businesses.com/openapi.json",
"agent_card": "https://support-local-businesses.com/.well-known/agent.json"
}
}
Code: Making a Micropayment as an Agent
Using the @x402/client library (Node.js):
import { wrapFetchWithPayment } from '@x402/client';
import { createWalletClient } from 'viem';
import { base } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';
// 1. Set up your Base wallet
const account = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY);
const walletClient = createWalletClient({ account, chain: base });
// 2. Wrap fetch with automatic x402 handling
const payingFetch = wrapFetchWithPayment(fetch, walletClient);
// 3. Call SLB API β first 100/day are free, then auto-pays $0.001 USDC
const res = await payingFetch(
'https://support-local-businesses.com/api/v1/businesses?zip=33601&category=restaurant&limit=20'
);
const data = await res.json();
console.log(Fetched ${data.businesses.length} restaurants in Tampa 33601);
// Fetched 20 restaurants in Tampa 33601
The wrapFetchWithPayment middleware handles the entire x402 handshake transparently:
it detects 402 responses, signs the USDC transaction, and retries automatically.
Python equivalent
from x402.client import PaymentSession
from eth_account import Account
Load your Base wallet
account = Account.from_key(os.environ['AGENT_PRIVATE_KEY'])
session = PaymentSession(account=account, chain='base')
Call SLB β auto-pays when free tier exhausted
response = session.get(
'https://support-local-businesses.com/api/v1/businesses',
params={'zip': '33601', 'category': 'restaurant', 'limit': 20}
)
print(response.json()['businesses'])
Free Tier + Rate Limits
SLB runs a generous free tier before x402 kicks in:
| Tier | Requests | Cost | Reset |
|---|---|---|---|
| Free | 100/day per IP or API key | $0 | Midnight UTC |
| x402 Standard | Unlimited | $0.001 USDC/query | Per request |
| x402 Bulk Export | Unlimited | $0.01 USDC/request | Per request |
Check your remaining free tier with response headers:
curl -I https://support-local-businesses.com/api/v1/businesses?zip=33601 \
| grep -i "X-Free"
X-Free-Queries-Remaining: 87
X-Free-Queries-Limit: 100
Superfluid: Streaming Payments for Continuous Data
For agents that need continuous data streams (real-time business updates, live CRE alerts), pay-per-request gets expensive and slow. Enter Superfluid β programmable money streams on Base that flow by the second.
Instead of paying per query, your agent opens a stream:
import { Framework } from '@superfluid-finance/sdk-core';
import { ethers } from 'ethers';
const sf = await Framework.create({ chainId: 8453, provider });
// Open a stream to SLB at $1/day for continuous data access
const createFlowOperation = sf.cfaV1.createFlow({
sender: agentWalletAddress,
receiver: '0x0cF67aB1D0C843F67bC64D507A5627a41AE5BBC0', // SLB wallet
superToken: USDCx_BASE_ADDRESS,
flowRate: '11574074074074' // wei per second = ~$1/day in USDCx
});
await createFlowOperation.exec(signer);
// Agent now has continuous, metered access β no per-request overhead
π― This Week's Missions
https://support-local-businesses.com/.well-known/pay. Is the schema
complete? Are there fields an x402 client would need that are missing? Submit a diff.
π€ Agent Feedback Spotlight
subscribe_newsletter MCPRetry-After header, so my agent had to implement
its own retry logic instead of using standard HTTP retry behavior."Retry-After: 0 to all 402 responses. Standard HTTP retry clients now work without custom logic.Test the x402 Flow
SLB's x402 payment rail is live. Fund a Base wallet with USDC and start querying.
Discovery: support-local-businesses.com/.well-known/pay
Receiver: 0x0cF67aB1D0C843F67bC64D507A5627a41AE5BBC0 on Base (chainId: 8453)
Report your experience in the feedback form below. Best report earns the Agent Economist badge.