ByAUJay
From API Keys to Onchain Micropayments: Migrating a SaaS Endpoint to x402
A practical, decision-maker’s guide to replacing API keys and subscriptions with per-request, onchain micropayments using the HTTP-native x402 protocol. You’ll learn how the flow works, how to ship a production integration on Base/Solana, and what to watch out for when you go live.
Why migrate now
- HTTP-native payments exist. x402 revives HTTP 402 Payment Required and standardizes how servers challenge for payment and how clients respond—over plain HTTP, no accounts or API keys. (x402.gitbook.io)
- Settlement is fast and predictable. On Base, typical L2 block inclusion is ~2 seconds, with later L1 batch inclusion (~2 minutes) for stronger finality; Coinbase’s hosted facilitator settles USDC on Base with no facilitator fees. (docs.base.org)
- Tooling is real and multi-vendor. Neutral community docs, CDP’s facilitator/API, third-party facilitators (PayAI), and SDKs for Node/Python lower time-to-value. (x402.gitbook.io)
The result: you can charge per call, per kilobyte, per millisecond, or per task—without issuing, rotating, and securing API keys or running a subscription stack. (github.com)
The x402 mental model (in 45 seconds)
- Client calls your endpoint.
- If payment is required, you respond with HTTP 402 and a Payment Required Response JSON describing accepted payment options (network, asset, maxAmountRequired, payTo, mimeType, outputSchema, maxTimeoutSeconds, etc.). (github.com)
- Client retries with an X-PAYMENT header: a base64-encoded JSON “Payment Payload” containing the scheme/network and a signed authorization (EIP‑3009 on EVM) or chain-specific payload. (github.com)
- Your server verifies and settles via a facilitator’s /verify and /settle endpoints, then returns 200 OK with X-PAYMENT-RESPONSE containing settlement details (e.g., tx hash) as base64 JSON. (docs.cdp.coinbase.com)
x402 is transport- and chain-agnostic; the most common production pairing today is USDC on Base. (docs.cdp.coinbase.com)
Choosing your rails: networks, assets, facilitators
- Network:
- Base mainnet for production: fast L2 block inclusion (~2s), enterprise-grade compliance/KYT via CDP’s facilitator, and fee-free USDC settlement at the facilitator layer. (docs.base.org)
- Solana for low fees and agent-heavy workloads; community facilitators exist and tooling is emerging. (x402.gitbook.io)
- Asset:
- USDC (EVM): uses ERC‑3009 “TransferWithAuthorization,” enabling gasless, signature-based transfers the facilitator can submit on behalf of the user. (eips.ethereum.org)
- SPL tokens (Solana): supported by community/partner facilitators; no EIP‑712 domain config needed. (x402.gitbook.io)
- Facilitator:
- CDP-hosted (prod, Base/Solana support; requires CDP keys on mainnet). (docs.cdp.coinbase.com)
- Community (Base Sepolia/Solana devnet; no keys; great for testing). (docs.cdp.coinbase.com)
- Self-hosted (full control; any EVM/Solana). (docs.cdp.coinbase.com)
Migration blueprint: API keys → x402 in one sprint
Below is a reference migration for a single paid endpoint (e.g., GET /v1/premium). Repeat per route.
1) Add server middleware (Node/Express)
Install packages and wire the payment middleware. Use the community facilitator for testnet; swap to CDP for mainnet.
npm install x402-express # for CDP-hosted facilitator (mainnet) npm install @coinbase/x402
import express from "express"; import { paymentMiddleware } from "x402-express"; // For mainnet with CDP (requires CDP_API_KEY_ID/SECRET): // import { facilitator } from "@coinbase/x402"; const app = express(); app.use( paymentMiddleware( "0xYourReceivingAddress", { "GET /v1/premium": { price: "$0.01", // or a TokenAmount in atomic units network: "base-sepolia", // "base" on mainnet config: { description: "Premium JSON", mimeType: "application/json", maxTimeoutSeconds: 60, // outputSchema helps agents self-validate: outputSchema: { type: "object", properties: { data: { type: "string" } } } } } }, { url: "https://x402.org/facilitator" } // community testnet facilitator // For mainnet: facilitator // from @coinbase/x402 ) ); app.get("/v1/premium", (req, res) => { res.json({ data: "Hello, paid world!" }); }); app.listen(4021);
This setup returns HTTP 402 with a Payment Required Response when the client hasn’t paid, and accepts X-PAYMENT on retry. (x402.gitbook.io)
Python (FastAPI/Flask) packages provide the same middleware ergonomics if your stack is in Python. (x402.gitbook.io)
2) Understand the 402 response and the X-PAYMENT header
The 402 body enumerates accepted paymentRequirements (scheme, network, maxAmountRequired, payTo, asset, mimeType, outputSchema, etc.). Clients must create a Payment Payload and send it in X-PAYMENT (base64 JSON). (github.com)
On success, return 200 OK with X-PAYMENT-RESPONSE (base64 JSON) that includes settlement info such as tx hash. (github.com)
3) Update the client call sites (automatic retries with payment)
Wrap your client with an x402-aware fetch/axios that detects 402, signs an authorization, retries with X-PAYMENT, and decodes X-PAYMENT-RESPONSE.
import { wrapFetchWithPayment, decodeXPaymentResponse } from "x402-fetch"; import { createWalletClient, http } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { baseSepolia } from "viem/chains"; const account = privateKeyToAccount(process.env.PRIVATE_KEY!); const fetchWithPayment = wrapFetchWithPayment(fetch, account); const resp = await fetchWithPayment("https://api.example.com/v1/premium"); const body = await resp.json(); const receipt = decodeXPaymentResponse(resp.headers.get("x-payment-response") || ""); console.log({ body, receipt });
These wrappers abstract the base64 header encoding/decoding and facilitator verification/settlement. (x402.gitbook.io)
4) Move to mainnet: facilitator and keys
- Switch network: base-sepolia → base, solana-devnet → solana (if applicable).
- Use CDP’s facilitator package and set CDP_API_KEY_ID/CDP_API_KEY_SECRET for production. (npmjs.com)
- CDP’s facilitator performs fee-free USDC settlement on Base and provides compliance/KYT guardrails. (docs.cdp.coinbase.com)
Pricing models and the right scheme
x402 is scheme-based. Today you’ll encounter two practical schemes:
- exact: client pays exactly the price declared in the 402. Great for fixed price calls/files. Backed by EIP‑3009 on EVM. (docs.payai.network)
- upto: client authorizes “up to” a maximum; you verify first, do the work, then settle the exact amount. Ideal for dynamic workloads (AI token usage, per-row scans). (portal.thirdweb.com)
Example (upto flow, conceptually): verify → perform work → settle the precise amount; reject if the final price exceeds maxAmountRequired or if the authorization window expires. (portal.thirdweb.com)
Notes on tokens and signatures (EVM):
- USDC implements ERC‑3009. Your facilitator builds an EIP‑712 message for TransferWithAuthorization/ReceiveWithAuthorization; users sign off-chain, the facilitator sponsors gas and submits. (eips.ethereum.org)
- For non‑USDC tokens, some stacks also support ERC‑2612 permit flows; check your facilitator’s docs. (portal.thirdweb.com)
Security checklist (steal this for your runbook)
- Validate everything against the Payment Requirements you sent: resource URL, payTo, asset address, and maxTimeoutSeconds—not just amount. Reject if any mismatch. (github.com)
- Enforce authorization windows. EIP‑3009 uses validAfter/validBefore; reject replays outside the window or with previously used nonces. (eips.ethereum.org)
- Prefer receiveWithAuthorization in contracts (if you settle payments into a smart contract) to avoid front‑running risks documented in the EIP‑3009 security notes. (eips.ethereum.org)
- Set mimeType and outputSchema in your 402 so agents know exactly what they’re buying and can assert response shape. This reduces disputes and improves agent UX. (github.com)
- Return X-PAYMENT-RESPONSE with tx hash and network; log it to your billing ledger for reconciliation and refunds. (github.com)
- Idempotency: use your own idempotency key (e.g., X-Idempotency-Key) and tie it to the payment nonce to dedupe work if clients retry. (Best practice; complements x402’s nonce semantics.)
- Rate limits and anti-abuse: keep your existing WAF/rate-limits; x402 is a payment layer, not a full abuse mitigator.
- If you allow multi-credit or post‑paid semantics, encode and validate per‑credit entitlements server-side; some community proxies expose patterns for reusing a single X-PAYMENT token until credits are exhausted. (docs.proxy402.com)
Operational expectations
- Latency budget: with Base, expect ~2s to durable L2 inclusion; end-to-end, most facilitator settlements return well under a few seconds. Consider whether you:
- gate the response on settlement (lowest fraud risk), or
- for upto, verify first, do work, then settle at the end (best UX for dynamic jobs). (docs.base.org)
- Observability: capture “402 → verify → settle → 200/X-PAYMENT-RESPONSE” spans; persist tx hash, payer, network. Many clients expose decode helpers for X-PAYMENT-RESPONSE. (x402.gitbook.io)
- Compliance: CDP’s facilitator adds KYT/OFAC screening and enterprise SLAs; helpful for US-regulated teams. (docs.cdp.coinbase.com)
Concrete examples you can copy
Example 1 — Minimal Express server (fixed price)
Shown earlier; production bump is swapping the facilitator and network. The same patterns exist for Next.js middleware and Hono/Cloudflare Workers. (x402.gitbook.io)
Example 2 — Python FastAPI (fixed price)
from fastapi import FastAPI from x402.fastapi.middleware import require_payment app = FastAPI() app.middleware("http")( require_payment( path="/v1/premium", price="$0.001", # 0.1¢ pay_to_address="0xYourAddress", network="base-sepolia", # "base" on mainnet ) ) @app.get("/v1/premium") def premium(): return {"data": "paid content"}
This responds with 402 + paymentRequirements and accepts X-PAYMENT on retry; you’ll return 200 with X-PAYMENT-RESPONSE on success. (x402.gitbook.io)
Example 3 — Dynamic pricing with upto (AI/token usage)
Pseudocode shape:
// 1) Client receives 402 with maxAmountRequired (e.g., $0.10) // 2) Client sends X-PAYMENT authorizing up to that amount (scheme: "upto") // 3) Server verify -> run -> settle exact const verification = await facilitator.verify(payload, requirements); // scheme: "upto" if (!verification.isValid) return res.status(402).json(paymentRequirements); // Do the expensive work; compute final price in atomic units (≤ maxAmountRequired) const atomic = computeAtomicPriceFromUsage(usage); // Finalize the charge const settlement = await facilitator.settle(payload, { ...requirements, maxAmountRequired: atomic }); if (!settlement.success) return res.status(402).json(paymentRequirements); res.set("X-PAYMENT-RESPONSE", encodeSettlement(settlement)); return res.json(result);
Thirdweb’s November 2025 update documents upto for dynamic pricing; the pattern above maps cleanly to AI inference workloads. (portal.thirdweb.com)
Real-world deployments and patterns to consider
- RPC aggregation (production pattern): an x402-powered RPC gateway routes across 8+ providers (Helius, Triton, QuickNode, Alchemy, Infura), charges ~$0.0001 per call, and settles under ~3s, demonstrating autonomous, per-call billing without API keys. Use it as a reference for multi-provider, pay-per-call design. (x402labs.cloud)
- Payment channels on Solana (experimental): a Solana payment-channel variant of x402 targets sub‑10ms verification for API calls; a single server method can verify both on‑chain “exact” and “channel” schemes. Consider this if you need ultra‑low latency and can accept channel lifecycle management. (boberpay.com)
- IoT/offline patterns: BLE-based device flows push authorization offline, later relayed to settle on Base/other chains—useful for robots/sensors. (x4pay.org)
Under the hood: what your team should know
- The Payment Required Response schema is standardized and extensible; you can advertise response schema and MIME type to set expectations for human users and AI agents. (github.com)
- The facilitator interface is a simple REST pair—POST /verify and POST /settle—with network- and scheme-aware semantics. You can vendor-switch or self-host without changing your application contract. (docs.cdp.coinbase.com)
- On EVM, EIP‑3009 powers x402’s gasless transfer authorizations. Study its security notes (unique nonces; validAfter/validBefore; prefer receiveWithAuthorization in contracts). (eips.ethereum.org)
- On Base, plan UX around ~2s L2 inclusion for “confirmed” work and ~2 minutes for the “anchored” state to Ethereum L1. Many SaaS use 2s gating for responsiveness and rely on ledger reconciliation for outliers. (docs.base.org)
Migration risks and how to de-risk them
- Break-glass path: deploy behind a proxy or feature flag; if facilitator/network has an incident, bypass to a free tier or temporary API-key check.
- Double-spend/replay: strictly bind the Payment Payload to your resource string and payTo; track and reject reused nonces. (github.com)
- Token surface area: if you venture beyond USDC, confirm ERC‑3009/2612 support and domain parameters (name/version) for EIP‑712 signing. (x402.gitbook.io)
- Contract settlement: if your endpoint triggers onchain actions, use receiveWithAuthorization in your contracts and simulate before settle. (eips.ethereum.org)
Bonus: agent and marketplace readiness
- Agent-friendly: client SDKs for fetch/axios/Python auto-handle 402→X‑PAYMENT→X‑PAYMENT‑RESPONSE, and Model Context Protocol (MCP) glue exists so agents can pay for tools autonomously with guardrails. (x402.gitbook.io)
- Discovery: the “Bazaar” concept is emerging so agents can discover x402 endpoints and their pricing automatically—plan to publish accurate metadata (description, mimeType, outputSchema). (x402.gitbook.io)
- Trust layer: ERC‑8004 is evolving to standardize agent identity, reputation, and validation on EVM; x402 provides the money rail while 8004 anchors discovery/feedback. If you want agents to rate you with proof‑of‑payment, watch this space. (eips.ethereum.org)
What 7Block Labs recommends as “current best practice” (Dec 2025)
- Start on Base with USDC and the CDP facilitator; move to self-hosted/community facilitators only when you need custom networks or policies. (docs.cdp.coinbase.com)
- Use exact for fixed-price calls; switch to upto for AI/token-metered workloads—verify before work, settle after. (portal.thirdweb.com)
- Always set mimeType, description, maxTimeoutSeconds, and outputSchema in your 402. These fields increase successful “first-pay” conversions by reducing ambiguity for human users and agents. (x402.gitbook.io)
- Log X-PAYMENT-RESPONSE and expose the tx hash in user dashboards for transparent receipts and faster support. (github.com)
A conservative two-week rollout plan
- Days 1–3: Testnet integration (Base Sepolia); wrap one low-risk endpoint with x402 middleware; wire dashboards to parse X-PAYMENT-RESPONSE. (x402.gitbook.io)
- Days 4–6: Client updates with x402-fetch/axios; run synthetic load; tune maxTimeoutSeconds and price. (x402.gitbook.io)
- Days 7–9: Mainnet switch (Base + CDP facilitator); add guardrails (feature flag; free-fallback path). (docs.cdp.coinbase.com)
- Days 10–14: Expand coverage to 3–5 endpoints; experiment with upto on a metered route; add success receipts to billing UI. (portal.thirdweb.com)
Closing thought
x402 lets your API monetize like a utility—one HTTP request at a time—with open, composable infrastructure rather than proprietary accounts and keys. With a small middleware change and a client wrapper, you can pilot pay‑per‑call within days, then iterate into dynamic pricing and agent‑native commerce as your needs grow. (github.com)
References and specs cited
- x402 protocol overview, headers, schemas, and flow (Payment Requirements, X-PAYMENT, X‑PAYMENT‑RESPONSE; /verify and /settle). (github.com)
- Community quickstarts for sellers and buyers; middleware and wrappers. (x402.gitbook.io)
- CDP facilitator, networks, and compliance notes. (docs.cdp.coinbase.com)
- Base finality timing. (docs.base.org)
- EIP‑3009 fundamentals and security considerations. (eips.ethereum.org)
- Dynamic pricing (upto scheme) patterns. (portal.thirdweb.com)
- Examples of x402 in the wild (RPC aggregator; channels; IoT). (x402labs.cloud)
Like what you're reading? Let's build together.
Get a free 30‑minute consultation with our engineering team.

