x402: Monetizing Content for AI Agents with HTTP 402
How to set up x402 payment protocol on a static site — letting AI agents pay USDC per API call while humans browse for free. A practical walkthrough using Cloudflare Workers and Base.
HTTP status code 402 has been “reserved for future use” since 1999. Twenty-seven years later, it finally has a job.
The x402 protocol uses that dusty status code to let AI agents pay for web content programmatically. An agent requests a resource, gets a 402 response with a price and payment instructions, sends a crypto payment, and receives the content. No API keys, no subscriptions, no human in the loop.
I set this up on a content site recently and the implementation was surprisingly clean. Here’s how it works and what I learned.
The Problem: AI Agents Need Content, Creators Need Revenue
AI agents are increasingly browsing the web on behalf of users. They fetch articles, compare products, research topics. But the economic model is broken — the agent gets the content, the creator gets nothing. Ad-supported monetization doesn’t work when there’s no eyeball to show ads to.
Paywalls don’t work either. Traditional paywalls require user accounts, credit cards, cookie-based sessions. An AI agent can’t (and shouldn’t) create accounts on every site it visits.
x402 solves this with a machine-native payment flow: the agent pays per request using stablecoins, and the server returns the content. No accounts. No sessions. No subscriptions. Just value exchange at the protocol level.
How x402 Works
The flow is elegant in its simplicity:
1. Agent: GET /api/articles/investing-basics
2. Server: 402 Payment Required
{
"price": "$0.01",
"currency": "USDC",
"network": "base",
"recipient": "0x...",
"facilitator": "https://x402.org/facilitator"
}
3. Agent: Signs USDC payment → sends to facilitator
4. Facilitator: Verifies payment → returns receipt
5. Agent: GET /api/articles/investing-basics
Authorization: x402 <receipt>
6. Server: 200 OK + full article content
The facilitator is a trust layer that verifies the payment happened without the content server needing to interact with the blockchain directly. Coinbase runs a free facilitator that handles up to 1,000 transactions per month — enough for any small publisher getting started.
The Architecture
I wanted a specific setup: humans browse the site for free (it’s a static site on Cloudflare Pages), but AI agents accessing the API pay per request. Two audiences, two economic models, one domain.
The Cloudflare Worker intercepts requests to /api/* routes and applies the x402 payment middleware. Everything else passes through to the static site untouched.
The Stack
- Hono — lightweight HTTP framework that runs on Cloudflare Workers
- x402-hono — middleware package that handles the 402 flow
- USDC on Base — stablecoin payments on Coinbase’s L2 (low fees, fast settlement)
- Cloudflare Workers — edge compute, no cold starts, free tier generous
Pricing Strategy
I set three tiers:
| Endpoint | Price | Rationale |
|---|---|---|
GET /api/articles | Free | Discovery — agents need to browse the catalog |
GET /api/articles/:slug | $0.01 | Single article, low friction |
GET /api/search?q= | $0.02 | More compute, searches across all content |
The free listing endpoint is critical. If agents can’t discover what’s available without paying, they won’t bother. Make discovery free, charge for depth.
Implementation
Setting Up the Worker
The core implementation is surprisingly minimal:
import { Hono } from "hono";
import { cors } from "hono/cors";
import { paymentMiddleware } from "x402-hono";
const app = new Hono();
// CORS for agent access
app.use("/api/*", cors());
// Free: list all articles
app.get("/api/articles", (c) => {
const list = articles.map(a => ({
slug: a.slug,
title: a.title,
description: a.description,
contentUrl: `/api/articles/${a.slug}`,
}));
return c.json({ count: list.length, articles: list });
});
// Paid: full article content
app.use("/api/articles/:slug", paymentMiddleware({
price: "$0.01",
network: "base",
recipient: process.env.RECIPIENT_ADDRESS,
}));
app.get("/api/articles/:slug", (c) => {
const slug = c.req.param("slug");
const article = articles.find(a => a.slug === slug);
if (!article) return c.json({ error: "Not found" }, 404);
return c.json({ ...article, content: article.fullContent });
});
export default app;
The paymentMiddleware handles everything: returning the 402 response with payment details, validating receipts, and only passing through to your handler when payment is confirmed. You write your API as if it’s free — the middleware adds the paywall.
Security Hardening
Since this endpoint faces the open internet and handles financial transactions, I added several security layers:
// Security headers on all responses
app.use("*", async (c, next) => {
await next();
c.header("X-Content-Type-Options", "nosniff");
c.header("X-Frame-Options", "DENY");
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
});
// Rate limiting per IP
app.use("*", rateLimit({
windowMs: 60_000,
max: 30
}));
// Input sanitization on search queries
app.get("/api/search", (c) => {
const raw = c.req.query("q") || "";
const q = sanitize(raw, 200).toLowerCase();
if (!q) return c.json({ error: "Invalid query" }, 400);
// ... search logic
});
Never trust input from agents. They’re software making HTTP requests — the same injection attacks that work on human-facing APIs work here. Sanitize everything, rate-limit aggressively, validate before processing.
Important: hardcode your prices in the middleware configuration. Never accept a price from the request body. An agent (or attacker) could pass "price": "$0.00" and get free content.
Wrangler Configuration
Deploying to Cloudflare Workers:
[vars]
NETWORK = "base"
RECIPIENT_ADDRESS = "0x..."
FACILITATOR_URL = "https://x402.org/facilitator"
Sensitive values like wallet addresses go in environment variables, not code. The facilitator URL points to Coinbase’s free service.
What the Agent Sees
From the AI agent’s perspective, the flow looks like a standard HTTP retry with a payment step:
import httpx
from x402 import PaymentClient
client = PaymentClient(wallet_key=os.environ["AGENT_WALLET_KEY"])
# First request — gets 402
response = httpx.get("https://example.com/api/articles/investing-basics")
if response.status_code == 402:
# Parse payment requirements from response
payment_info = response.json()
# Sign and submit payment
receipt = client.pay(
amount=payment_info["price"],
recipient=payment_info["recipient"],
network=payment_info["network"],
)
# Retry with receipt
response = httpx.get(
"https://example.com/api/articles/investing-basics",
headers={"Authorization": f"x402 {receipt}"}
)
article = response.json()
print(article["content"]) # Full markdown content
Agent frameworks are starting to build x402 support natively, so this handshake will eventually be invisible — the agent just “buys” content like a human clicks through a paywall.
Testing
Testing x402 locally is straightforward:
# Start local dev server
wrangler dev
# Test free endpoint
curl http://localhost:8787/api/articles
# Test paid endpoint (should return 402)
curl -v http://localhost:8787/api/articles/some-article
The 402 response includes everything an agent needs to make payment. For integration testing, Base Sepolia (testnet) lets you test the full payment flow without real money.
What I Learned
1. Discovery Must Be Free
My first version put the paywall on every endpoint, including the article listing. No agent ever got past the first request. Agents need to know what’s available before they’ll pay for it. Free discovery, paid depth.
2. Price Low, Volume High
$0.01 per article is practically frictionless for an agent with a budget. $1.00 per article means the agent will try to find a free alternative. For content monetization, micro-payments only work if they’re genuinely micro.
3. The Facilitator Is The Bottleneck
The Coinbase facilitator is free but has a 1,000 transaction/month limit. For a small site that’s fine. For anything with real traffic, you’ll need to either run your own facilitator or negotiate higher limits.
4. Not All Agents Support x402 (Yet)
Most AI agents today don’t have wallets or payment capabilities. This is infrastructure for the near future — agents with budgets that can autonomously spend on information. OpenAI’s operator model and Anthropic’s computer use are heading in this direction, but we’re early.
5. Static Sites Are Perfect For This
The dual-audience architecture (static pages for humans, paid API for agents) works beautifully with Cloudflare’s stack. The static site costs nothing to host. The Worker runs on the free tier. Your only cost is the domain name.
The Bigger Picture
x402 is part of a broader shift in how the web monetizes content. The current model — ads for humans, nothing for machines — doesn’t scale into an agent-first world. As more web traffic comes from AI agents acting on behalf of users, content creators need a way to capture value from that traffic.
The protocol is still early. The ecosystem of wallets, facilitators, and agent frameworks that support x402 is small. But the primitives are solid: HTTP-native, stablecoin-based, no accounts required. It’s the kind of infrastructure that’s boring to set up now and obvious in hindsight later.
If you run a content site — especially one with structured, high-value information — setting up an x402 API endpoint takes about an afternoon. The cost is near-zero (free Cloudflare tier, free facilitator). The upside is being ready when agents start paying for content at scale.
We’re building the economic plumbing for a web where both humans and machines are first-class citizens. HTTP 402 finally has its moment.