ByAUJay
x402 + Edge Compute: Paywalled Endpoints for Serverless and Workers
Short summary: Decision-makers can now attach crypto-native, per-request pricing to any HTTP endpoint using the x402 protocol and deploy it globally on edge runtimes (Cloudflare Workers, Vercel Functions with Edge runtime, Fastly Compute). This post shows how to ship 402 → pay → retry paywalls in minutes, compare x402 with Lightning’s L402, and harden for production with facilitator patterns, caching, observability, and security.
Why this matters now
For the first time, HTTP’s long-dormant 402 Payment Required status has a concrete, open protocol: x402. A server returns 402 with structured payment requirements; the client pays on-chain and retries with an X-PAYMENT header; the server verifies/settles and serves the content. Coinbase maintains the open specification (Apache-2.0), with a facilitator API for verification/settlement and SDKs; it’s chain-agnostic and already used by edge/agent platforms. (github.com)
Edge compute makes these paywalls feel instantaneous: Workers and Edge Functions run near users, support low-latency headers/streams, and can offload settlement to background tasks—critical for per-request monetization of APIs, data, or AI tools. (workers.cloudflare.com)
x402 in one minute
- Protocol: servers respond 402 with a Payment Required Response (supported schemes/networks, amount, resource metadata). Clients pay, then resend with X-PAYMENT; servers verify/settle and may include X-PAYMENT-RESPONSE in the 200 OK response. (github.com)
- Facilitator: optional service that verifies and settles payment so your serverless app doesn’t run blockchain code. Coinbase’s facilitator currently offers fee-free USDC settlement on Base, with
and/verify
endpoints. Emerging guidance prefers trusting/settle
over/settle
for security. (docs.cdp.coinbase.com)/verify - Clients: wrap fetch to automatically handle 402 challenges and payment retries; libraries exist across ecosystems (x402-fetch, thirdweb, Cloudflare Agents). (developers.cloudflare.com)
x402 contrasts with Lightning’s L402 (formerly LSAT), which uses 402 plus macaroons and Lightning invoices; L402 powers production services via the Aperture proxy and supports dynamic/fixed pricing at the proxy layer. Both light up HTTP 402; they differ in payment rails and token formats. (docs.lightning.engineering)
Why edge runtimes are the right home for paywalled endpoints
- Global, low-latency challenge/response. Workers and Edge Functions issue 402 quickly, clients pay, then retry locally—no origin roundtrip required. (workers.cloudflare.com)
- Streaming and background tasks. Return the 200 response fast while doing non-critical work in the background (logs, analytics, optional settlement pipelines) via waitUntil and tail handlers. Vercel Edge supports streaming with a 25s time-to-first-byte requirement and a 300s streaming window. (developers.cloudflare.com)
- Predictable costs. Vercel Edge CPU-based pricing by execution units; Cloudflare Workers charges for CPU time; Workers’ Durable Objects provide strongly consistent state for receipts/credits at edge. (vercel.com)
Architecture: 402 → pay → retry with a facilitator
- Client requests /premium. Server returns 402 + JSON “accepts” array for scheme/network, maxAmountRequired, resource, description, mimeType. (github.com)
- Client selects an option, constructs a Payment Payload, pays, and resends the request with X-PAYMENT. (github.com)
- Server verifies via local logic or POST /verify to a facilitator; recommended production path is to block until /settle completes (or deliver with a streamed/watermarked response until settle returns). (docs.cdp.coinbase.com)
- Server returns 200 with resource and optional X-PAYMENT-RESPONSE (tx hash, network). (github.com)
MDN still lists 402 as “reserved,” which is exactly what x402 standardizes—so expect some tooling to treat it as unusual unless you add explicit handling. (developer.mozilla.org)
Implementation patterns on edge runtimes
1) Cloudflare Workers + Hono: 402 in 30 lines
Install the middleware and facilitator client, protect routes, and persist receipts with Durable Objects.
// wrangler.toml excerpts compatibility_date = "2025-12-01" [[durable_objects.bindings]] name = "RECEIPTS" class_name = "ReceiptsDO"
// src/worker.ts import { Hono } from "hono"; import { paymentMiddleware } from "x402-hono"; import { waitUntil } from "cloudflare:workers"; type Env = { RECEIPTS: DurableObjectNamespace; // optional: FACILITATOR_URL, CDP_API_KEY_ID, CDP_API_KEY_SECRET }; const app = new Hono<{ Bindings: Env }>(); // 1) Protect an endpoint with x402 app.use( "/reports/daily", paymentMiddleware("0xYourBaseUSDCAddress", { "/reports/daily": { price: "$0.05", network: "base", // or "base-sepolia" for test config: { description: "Daily premium report", mimeType: "application/json", }, }, }) ); // 2) Serve content and persist receipt after settlement app.get("/reports/daily", async (c) => { const res = new Response(JSON.stringify({ ok: true, data: "..." }), { headers: { "Content-Type": "application/json" }, }); // Optional: settle out-of-band & persist (if your middleware only verified) const doId = c.env.RECEIPTS.idFromName("global"); const stub = c.env.RECEIPTS.get(doId); const paymentHeader = c.req.header("x-payment") || ""; waitUntil(stub.fetch("https://do/record", { method: "POST", body: paymentHeader })); return res; }); export default { fetch: app.fetch, }; // src/receipts.ts (Durable Object) export class ReceiptsDO { state: DurableObjectState; constructor(state: DurableObjectState) { this.state = state; } async fetch(req: Request) { if (req.method === "POST") { const header = await req.text(); await this.state.storage.put(`receipt:${Date.now()}`, header); return new Response("ok"); } return new Response("not found", { status: 404 }); } }
- Cloudflare Agents docs show using paymentMiddleware (Hono) and wrapFetchWithPayment for agent-to-endpoint calls. The same primitives work in your Worker. (developers.cloudflare.com)
- Use
for background persistence/settlement to avoid blocking the 200 response; Cloudflare now allows direct import of waitUntil and documents ctx.waitUntil with examples. (developers.cloudflare.com)waitUntil - For long responses, stream with ReadableStream after returning headers to keep TTFB low. (developers.cloudflare.com)
- Durable Objects give you globally consistent storage for receipts/credits; free tier limits exist, plan for usage. (developers.cloudflare.com)
Security note: upgrade x402-hono ≥ 0.5.2 due to a fixed vulnerability in older versions. Latest stable lines show no known issues. (advisories.gitlab.com)
2) Vercel Functions (Edge runtime): manual x402 flow
Next.js route handler with the Edge runtime, keeping header sizes within limits.
// app/api/premium/route.ts export const runtime = "edge"; const facilitatorUrl = "https://api.cdp.coinbase.com/v2/x402"; // example export async function GET(req: Request) { const payment = req.headers.get("x-payment"); // If no payment header → send 402 with payment requirements if (!payment) { const body = { x402Version: 1, accepts: [ { scheme: "exact", network: "base", maxAmountRequired: "100000", // 0.1 USDC (6 decimals) resource: new URL(req.url).pathname, description: "Premium endpoint", mimeType: "application/json", }, ], }; return new Response(JSON.stringify(body), { status: 402, headers: { "Content-Type": "application/json", "Cache-Control": "no-store" }, }); } // Verify + settle (recommended) using facilitator const verify = await fetch(`${facilitatorUrl}/verify`, { method: "POST", headers: { "Content-Type": "application/json", /* add CDP auth if needed */ }, body: JSON.stringify({ x402Version: 1, paymentHeader: payment, paymentRequirements: { scheme: "exact", network: "base", maxAmountRequired: "100000", resource: "/api/premium", description: "Premium endpoint", mimeType: "application/json", }, }), }).then((r) => r.json()); if (!verify.isValid) { return new Response(JSON.stringify({ error: "invalid payment" }), { status: 402 }); } const settle = await fetch(`${facilitatorUrl}/settle`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ x402Version: 1, paymentHeader: payment, paymentRequirements: { scheme: "exact", network: "base", maxAmountRequired: "100000", resource: "/api/premium", description: "Premium endpoint", mimeType: "application/json", }, }), }).then((r) => r.json()); if (!settle.success) return new Response("settlement failed", { status: 402 }); return new Response(JSON.stringify({ premium: "ok" }), { headers: { "Content-Type": "application/json", "X-PAYMENT-RESPONSE": btoa(JSON.stringify(settle)), "Cache-Control": "private, no-store", }, }); }
- Vercel Edge runtime limits request headers (≤ 64 headers, ≤ ~16 KB total) and requires sending the initial response within 25 seconds; you can stream up to 300 seconds. Keep X-PAYMENT compact and settle quickly. (vercel.com)
- Facilitator endpoints: POST /verify and /settle; Coinbase’s facilitator on Base offers fee-free USDC settlement (subject to change). Favor
for security over/settle
alone. (docs.cdp.coinbase.com)/verify
3) Fastly Compute@Edge: 402 challenge and header constraints
Fastly’s JavaScript runtime supports constructing custom responses/headers; note header count/size limits (e.g., response headers ≈ 96 entries, up to 128 KB). This matters if you embed large payment metadata in 402 or X-PAYMENT-RESPONSE. (js-compute-reference-docs.edgecompute.app)
// src/index.js (Fastly JS Compute) import { Router } from "@fastly/expressly"; addEventListener("fetch", (event) => event.respondWith(app(event))); async function app(event) { const req = event.request; const url = new URL(req.url); if (url.pathname === "/paid") { const xpay = req.headers.get("x-payment"); if (!xpay) { const paymentBody = JSON.stringify({ x402Version: 1, accepts: [{ scheme: "exact", network: "base", maxAmountRequired: "50000", resource: "/paid" }], }); return new Response(paymentBody, { status: 402, headers: { "Content-Type": "application/json", "Cache-Control": "no-store" }, }); } // call facilitator /verify + /settle from here… return new Response(JSON.stringify({ ok: true }), { headers: { "Content-Type": "application/json" } }); } return new Response("not found", { status: 404 }); }
- You can attach/modify headers freely in Compute; plan for header size to avoid overflow. (antoinebrossault.com)
4) AWS API Gateway + Lambda: it’s just HTTP
Your Lambda integration can return statusCode 402 with a JSON body and custom headers; API Gateway passes it through. There’s no native x402 integration—just treat it as a standard 4xx with custom semantics per your docs. MDN notes 402 is “reserved,” which is precisely why x402 standardizes the semantics. (docs.aws.amazon.com)
Client tooling for agent and browser flows
- Wrap fetch: x402-fetch and cloud integrations make clients auto-pay after a 402 challenge. Cloudflare’s Agents docs include TypeScript examples; thirdweb offers a fetch wrapper that plugs into wallets and RPC infra. (developers.cloudflare.com)
- Multi-runtime kits: packages exist for Express, Hono, Next, Axios. Keep the core “x402” package pinned with integration peers to match versions. (npmjs.com)
- Solana-first builders: Sol402 spins up a pay-per-request proxy that settles USDC on Solana; follows the same 402→pay→retry handshake (PayAI-compatible), making it ideal for agentic traffic. (sol402.app)
Choosing rails: x402 vs L402
- x402 is chain-agnostic, currently popular with EVM USDC on Base via Coinbase’s facilitator (fee-free as documented), and expanding to Solana and additional schemes like “upto” (pay up to an amount for metered workloads). It specifies X-PAYMENT and X-PAYMENT-RESPONSE header formats and facilitator APIs. (docs.cdp.coinbase.com)
- L402 (Lightning) pairs macaroons with Lightning invoices using HTTP 402 challenges; the Aperture reverse proxy enforces pricing and auth for gRPC/REST, used by production services like Loop/Pool. If you’re Bitcoin/Lightning-native, L402 is a proven path with surge and per-path pricing. (github.com)
Enterprises can run both in parallel: e.g., an edge 402 router that offers x402 USDC on Base and L402 Lightning for BTC users, selecting by Accepts list or geo. (github.com)
Pricing, latency, and UX tips
- Keep the 402 body small. On Vercel Edge, watch header counts and total header bytes; on Fastly, response header count and size have hard caps. Use terse descriptions and avoid bloated schemas in the 402 body. (vercel.com)
- Stream when possible. Start the 200 response promptly and stream content; Vercel Edge requires sending headers within 25s; you can continue streaming up to 300s. Cloudflare Workers streaming APIs reduce buffering and memory. (vercel.com)
- Cache rules: Never cache 402 responses at shared caches; add
. For paid responses, preferCache-Control: no-store
or keyed caching on a short-lived receipt ID; avoid Vary-on-cookie at CDNs, use custom headers if needed. (fastly.com)private, no-store - Edge cost models: Vercel Edge charges for CPU units; Workers charges for CPU and Durable Object usage. Compare your per-request margin (e.g., $0.01 USDC) with average CPU time and settlement overhead. (vercel.com)
Security and compliance guardrails
- Verify, then settle—preferably settle before fulfilling. Coinbase’s team recommends not trusting
alone; only consider funds committed once/verify
returns success. If you must optimize TTFB, watermark/limit output until settle completes. (github.com)/settle - Pin SDK versions. A known issue affected older x402-hono versions; upgrade ≥ 0.5.2 (latest releases show no known issues). Track packages like @coinbase/x402 for frequent updates. (advisories.gitlab.com)
- Observability: Log X-PAYMENT and X-PAYMENT-RESPONSE (without secrets) and store a normalized record (wallet, amount, txHash, network, resource) in Durable Objects or your data store.
- Policy and attestations: Expect optional facilitator-driven KYC/geo and more payment flows (subscriptions, top-ups, “upto” metering) on the roadmap; plan for feature flags by region/segment. (x402.gitbook.io)
Chain selection: when to use which
- Base (EVM) + USDC: Strong fit for US audiences and EVM ecosystems; Coinbase facilitator provides verify/settle and zero-fee merchant settlement (as documented at time of writing). Great for enterprise accounting with a stable unit of account. (docs.cdp.coinbase.com)
- Solana + USDC: Sub-second finality and sub-cent fees unlock aggressive micropayments and agent-heavy traffic; Sol402 provides a turnkey proxy builder with PayAI-compatible flows. (solana.com)
- Lightning (L402): Ideal for BTC-native users and machine-to-machine Lightning ecosystems; Aperture provides a mature reverse proxy for metered APIs. (github.com)
Practical example: 48-hour pilot plan
Day 1
- Pick one endpoint (e.g., /v1/summarize). Decide price ($0.01).
- Deploy a Cloudflare Worker, protect /v1/summarize with x402-hono, and store receipts in a Durable Object. Add strict no-store on 402 and 200 responses. (developers.cloudflare.com)
- Wire facilitator /settle and block response until success. Keep X-PAYMENT-RESPONSE for audit. (docs.cdp.coinbase.com)
Day 2
- Integrate client wrappers in your calling apps/agents (x402-fetch or thirdweb) to auto-pay.
- Load test: ensure 402 and 200 paths stay under edge limits (header sizes, first-byte SLA). On Vercel, confirm response starts < 25s; on Workers, confirm streaming chunked responses and waitUntil processing. (vercel.com)
- Roll out to 5% of traffic and monitor cost-per-paid-call vs compute and facilitator latencies.
Beyond x402: L402 for Lightning-heavy users
If your users are Lightning-first, L402 provides a proven flow with Aperture as a 402 reverse proxy for gRPC/REST backends. You can set per-path fixed or dynamic pricing, and macaroons allow fine-grained caveats (e.g., per-method constraints). Several production services (Loop, Pool) use it today. Consider offering both x402 and L402 to maximize addressable segments. (github.com)
Emerging best practices (what we’re deploying for clients)
- One paywall, many chains: advertise multiple “accepts” entries in the 402 response (e.g., Base USDC, Solana USDC); let clients pick the cheapest/fastest rail. (github.com)
- Async hardening: if you must deliver immediately after verify, stream a partial response and complete only when /settle succeeds; time out and fall back to a smaller response if not settled in N seconds. (vercel.com)
- Keep headers lean: serialize payment payloads compactly to stay under Edge header limits (Vercel header count/size; Fastly header size/count). (vercel.com)
- No-store everywhere: mark 402 and paid responses with no-store/private; avoid cache poisoning or leaking paid content. Use custom headers for vary logic instead of cookies at CDNs. (fastly.com)
- Version pins and SBOM: lock @coinbase/x402 and x402-hono versions; monitor advisories (GHSA-3j63-5h8p-gf7c). (advisories.gitlab.com)
- Settlement-first policy: “never trust verify” for high-value content; require successful /settle before data leaves the edge. (github.com)
The agent economy angle
Cloudflare Agents and multiple SDKs already support wrapping fetch so autonomous agents pay and retry automatically. On Solana, turnkey builders like Sol402 position x402 for millisecond-grade agent loops with USDC. This is the backbone of “machine-commerce” where bots buy API calls and data with no OAuth or human-in-the-loop. (developers.cloudflare.com)
What to watch next
- Protocol growth: new schemes like “upto” for metered/token-based workloads; Solana “exact” scheme parity; support for EIP-4337 smart wallets and UserOperations to let smart accounts pay seamlessly. (x402.gitbook.io)
- Neutral infrastructure: facilitator marketplaces and discovery layers; optional attestations/KYC for enterprise gating. (docs.cdp.coinbase.com)
Final take
x402 makes “pay-per-request” a first-class web primitive, and edge runtimes make it feel instant. If you run premium APIs, datasets, or inference, you can ship a compliant paywall this week: return 402 with x402 payloads, accept on-chain USDC, verify/settle via a facilitator, and deliver from the edge—no accounts, no cards, no heavy auth. Pair it with L402 where Lightning is strong, and you have global coverage with minimal friction. (github.com)
7Block Labs has production templates for Cloudflare Workers, Vercel Edge, and Fastly (with either x402 or L402), plus observability, receipts, and billing exports. If you want a 48-hour pilot or a multi-region rollout with compliance and rate cards, we’re here to help.
References and resources
- x402 protocol spec and GitHub, headers, and facilitator APIs. (github.com)
- x402 HTTP 402 concepts and open, Apache-2.0 docs. (x402.gitbook.io)
- Coinbase facilitator verify/settle and network support. (docs.cdp.coinbase.com)
- Cloudflare Agents x402 usage for Workers/agents. (developers.cloudflare.com)
- Vercel Edge runtime limits (headers, streaming windows). (vercel.com)
- Fastly Compute header limits and response construction. (docs.fastly.com)
- L402 (Lightning) and Aperture proxy for 402 paywalls. (github.com)
- Solana x402 context and Sol402 builder for USDC pay-per-request. (solana.com)
- MDN background on HTTP 402’s reserved status. (developer.mozilla.org)
Like what you're reading? Let's build together.
Get a free 30‑minute consultation with our engineering team.

