The API Key Problem
Every API you've ever used follows the same pattern: sign up, get a key, attach it to requests, hope you don't get rate-limited. For humans, this is annoying. For AI agents operating autonomously, it's a dead end — they can't fill out registration forms or manage billing dashboards.
x402 fixes this by turning HTTP itself into a payment layer.
What is x402?
x402 is an open protocol by Coinbase that brings the long-dormant HTTP 402 Payment Required status code to life. The idea is simple:
- Client calls an API endpoint
- Server responds with
402and a payment requirement (price, token, network) - Client signs a USDC payment on Base
- Client retries the request with the payment proof in the header
- Server verifies payment via a facilitator and returns the response
No API keys. No accounts. No OAuth flows. Just money for data.
The facilitator (hosted at https://x402.org/facilitator) handles payment verification and settlement on-chain, so your server never touches private keys or payment logic.
Why This Matters for AI Agents
AI agents need to consume APIs autonomously. With x402:
- No registration — agents don't need accounts or API keys
- No billing management — payment happens per-request, inline
- Composable — any agent with a Base wallet can call any x402 API instantly
- Micropayments — charge $0.10 per call instead of $50/month subscriptions
- Permissionless — no approval process, no rate limit negotiations
This is the native payment layer for the agentic web.
Building an x402 API with Express.js
Let's build a pay-per-call API from scratch. I'll use real patterns from httpay.xyz, which runs ~100 x402-paywalled micro-APIs on Base.
1. Set Up the Project
mkdir my-x402-api && cd my-x402-api
npm init -y
npm install express x402-express cors
2. Create the Server
const express = require("express");
const cors = require("cors");
const { paymentMiddleware } = require("x402-express");
const app = express();
app.use(cors());
app.use(express.json());
// Your wallet address — where USDC payments land
const PAY_TO = "0x5f5d6FcB315871c26F720dc6fEf17052dD984359";
// Coinbase's x402 facilitator on Base
const facilitatorUrl = "https://x402.org/facilitator";
3. Define Your Endpoints
Write your route handlers as normal Express routes:
app.get("/api/fortune", (req, res) => {
const fortunes = [
"A mass adoption event approaches... your bags are not heavy enough.",
"The next 100x gem is already in your wallet. You just swapped it for a dog coin.",
"Your seed phrase is safe... but is your marriage?",
];
const fortune = fortunes[Math.floor(Math.random() * fortunes.length)];
res.json({
fortune,
luckyNumber: Math.floor(Math.random() * 69420),
luckyToken: ["ETH", "SOL", "DOGE", "PEPE"][Math.floor(Math.random() * 4)],
});
});
4. Add the Payment Wall
Here's where x402 comes in. The paymentMiddleware wraps your routes with payment verification:
const paywall = {
"/api/fortune": {
price: "$0.10",
network: "base",
description: "Crypto fortune cookie",
},
"/api/roast-my-wallet/:address": {
price: "$0.15",
network: "base",
description: "Roast someone's on-chain activity",
},
};
app.use(paymentMiddleware(facilitatorUrl, PAY_TO, paywall));
That's it. Any request to these endpoints without valid payment proof gets a 402 Payment Required response.
5. Start the Server
const PORT = process.env.PORT || 4020;
app.listen(PORT, () => {
console.log(`x402 API running on http://localhost:${PORT}`);
});
Calling x402 APIs
From JavaScript (with x402-axios)
import { wrapAxios } from "x402-axios";
import axios from "axios";
const client = wrapAxios(axios, wallet);
const { data } = await client.get("https://httpay.xyz/api/fortune");
console.log(data.fortune);
Testing with curl
curl -i https://httpay.xyz/api/fortune
# HTTP/1.1 402 Payment Required
# Returns: payment requirements (price, token, network, facilitator)
Scaling to 100 Endpoints
httpay.xyz runs ~100 endpoints from a single Express app. The paywall config scales cleanly:
const paywall = {
"/api/fortune": { price: "$0.10", network: "base", description: "Crypto fortune cookie" },
"/api/pickup-line": { price: "$0.10", network: "base", description: "Web3 pickup lines" },
"/api/gas-oracle": { price: "$0.25", network: "base", description: "Gas price oracle" },
"/api/market-mood": { price: "$0.50", network: "base", description: "Market sentiment" },
"/api/yield-finder/:token": { price: "$1.00", network: "base", description: "Best yield finder" },
};
Price tiers align with value: fun at $0.10, tools at $0.25, analysis at $0.50–$1.00.
Deploying
httpay.xyz runs on Vercel:
{
"rewrites": [{ "source": "/(.*)", "destination": "/api" }]
}
No special infrastructure needed. The facilitator is hosted by Coinbase. Your server just verifies payment proofs.
Try It / Build Your Own
- 🌐 Live API: httpay.xyz
- 📦 Source: github.com/Alfredz0x/alfreds-digital-bazaar
- 📖 x402 Protocol: x402.org
- 📦 Middleware:
npm install x402-express
The agentic web needs native payments. x402 makes it three lines of code. Go build something.
Top comments (0)