How to Make API Calls Payable: x402 for AI Agents with thirdweb

A step-by-step implementation guide to the x402 payment protocol — turn any API endpoint into a payable resource that AI agents can pay for autonomously, on-chain, with thirdweb as the facilitator.

x402 payment protocol flow between an AI agent, an API server, and a payment facilitator

TL;DR: x402 revives the HTTP 402 Payment Required status code into a working payment layer. Your API responds 402 with a price, the client (often an AI agent) signs an on-chain payment and retries the request with a payment header, and a facilitator — thirdweb, in this guide — verifies and settles that payment before your API returns the real response. No API keys, no subscriptions, no manual invoicing: just pay-per-call.

What Is x402?

x402 is an open-source payment protocol built directly on top of HTTP. The 402 status code has existed in the HTTP spec since 1997 but was never standardized for real use — it just sat there reserved for “future use.” x402 finally gives it a job: signal to a client that a resource requires payment, describe exactly how much and in what token, and let the client pay and retry in the same request/response cycle.

That matters most for AI agents. A human can sign up for a SaaS plan, enter a credit card, and wait for an API key. An autonomous agent calling dozens of tools and data providers on your behalf can't do any of that — it needs to discover a price, authorize a payment programmatically, and move on, all within a single tool call. x402 is designed exactly for that machine-to-machine commerce pattern.

How the Payment Flow Works

Three parties are involved in every x402 transaction:

  • Client — the AI agent (or app) making the API request and, when required, signing a payment.
  • Resource server — your API, the thing being protected. This is the code you write.
  • Facilitator — a third party (thirdweb) that verifies the payment signature and settles it on-chain using a server wallet, so you never have to touch blockchain infrastructure directly.

The request/response sequence looks like this:

  1. The client calls your API normally, with no payment attached.
  2. Your server responds with 402 Payment Required, including the price, accepted token, and network in the response.
  3. The client signs a payment authorization for that exact amount and retries the request, this time with a payment header attached (X-PAYMENT or PAYMENT-SIGNATURE).
  4. Your server hands that header to thirdweb's facilitator, which verifies the signature and settles the transaction on-chain using your configured server wallet.
  5. Once settlement succeeds, your server returns the real 200 response.

Why thirdweb as the Facilitator

x402 is chain-agnostic and facilitator-agnostic — you can run your own facilitator, or use a hosted one. thirdweb's facilitator stack is a strong default because it:

  • Supports payments across 170+ EVM chains through thirdweb's chain list, without you managing RPCs per chain.
  • Accepts any ERC-20 token that implements ERC-2612 permit or ERC-3009 authorization — which covers USDC on every supported chain.
  • Settles gaslessly using EIP-7702, so your server wallet doesn't need to hold native gas tokens on every chain you accept payments on.
  • Drops straight into existing x402 middleware ecosystems (x402-express, x402-hono, x402-next) as a drop-in facilitator.

iLaunch note: when we scope on-chain payment work for clients, thirdweb's facilitator is usually the fastest path to production — it removes the multi-chain RPC and gas-management problem entirely, which is normally the part that turns a two-day integration into a two-week one.

Step 1: Paywall Your API (Server Side)

You'll need a thirdweb account with a project secret key, and a server wallet address to receive funds — create both from the thirdweb dashboard.

Install the SDK

npm install thirdweb

Configure the facilitator

import { createThirdwebClient } from "thirdweb";
import { facilitator } from "thirdweb/x402";

const client = createThirdwebClient({
  secretKey: process.env.THIRDWEB_SECRET_KEY,
});

const thirdwebFacilitator = facilitator({
  client,
  serverWalletAddress: "0xYourServerWalletAddress",
  waitUntil: "confirmed", // "simulated" | "submitted" | "confirmed"
});

Protect a single endpoint

In a Next.js route handler, read the payment header off the incoming request and hand it to settlePayment() along with what the endpoint costs:

// app/api/premium-content/route.ts
import { settlePayment } from "thirdweb/x402";
import { arbitrumSepolia } from "thirdweb/chains";
import { thirdwebFacilitator, client } from "@/lib/x402";

export async function GET(request: Request) {
  const paymentData =
    request.headers.get("PAYMENT-SIGNATURE") ||
    request.headers.get("X-PAYMENT");

  const result = await settlePayment({
    resourceUrl: "https://yourapi.com/api/premium-content",
    method: "GET",
    paymentData,
    payTo: "0xYourServerWalletAddress",
    network: arbitrumSepolia,
    price: "$0.10",
    facilitator: thirdwebFacilitator,
    routeConfig: {
      description: "Access to premium API content",
      mimeType: "application/json",
      maxTimeoutSeconds: 3600,
    },
  });

  if (result.status === 200) {
    return Response.json({ data: "premium content" });
  }

  // 402, or an invalid/missing payment — hand the requirements straight back
  return Response.json(result.responseBody, {
    status: result.status,
    headers: result.responseHeaders,
  });
}

Protect multiple routes with middleware

If you're paywalling more than one endpoint, run the same check in Next.js middleware instead of repeating it per route:

// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { settlePayment } from "thirdweb/x402";
import { arbitrumSepolia } from "thirdweb/chains";
import { thirdwebFacilitator } from "@/lib/x402";

export async function middleware(request: NextRequest) {
  const result = await settlePayment({
    resourceUrl: request.nextUrl.toString(),
    method: request.method.toUpperCase(),
    paymentData:
      request.headers.get("PAYMENT-SIGNATURE") ||
      request.headers.get("X-PAYMENT"),
    payTo: "0xYourServerWalletAddress",
    network: arbitrumSepolia,
    price: "$0.01",
    facilitator: thirdwebFacilitator,
  });

  if (result.status === 200) {
    const response = NextResponse.next();
    Object.entries(result.responseHeaders).forEach(([key, value]) => {
      response.headers.set(key, value as string);
    });
    return response;
  }

  return NextResponse.json(result.responseBody, {
    status: result.status,
    headers: result.responseHeaders,
  });
}

export const config = {
  matcher: ["/api/paid/:path*"],
};

iLaunch approach: for client projects with more than a couple of paid routes, we default to the middleware pattern and keep pricing config in one place — it's the difference between adding a new payable endpoint in five minutes versus rewriting the paywall logic every time.

Step 2: Usage-Based Pricing for AI Endpoints

A flat price works for static content, but AI inference endpoints usually don't have a fixed cost — a 200-token completion and a 4,000-token completion aren't the same price to serve. x402 supports this with the "upto" scheme: the client authorizes payment up to a maximum, you do the work, then settle for the actual amount.

const paymentArgs = {
  resourceUrl: "https://yourapi.com/api/ai-completion",
  method: "POST",
  paymentData,
  payTo: "0xYourServerWalletAddress",
  network: arbitrumSepolia,
  scheme: "upto",
  price: "$0.10",     // maximum charge
  minPrice: "$0.01",  // floor
  facilitator: thirdwebFacilitator,
};

// 1. Verify the agent authorized up to the max — before doing any work
const verifyResult = await verifyPayment(paymentArgs);
if (verifyResult.status !== 200) {
  return Response.json(verifyResult.responseBody, {
    status: verifyResult.status,
    headers: verifyResult.responseHeaders,
  });
}

// 2. Do the actual (expensive) work
const { answer, tokensUsed } = await callExpensiveAIModel();

// 3. Settle for what it actually cost
const settleResult = await settlePayment({
  ...paymentArgs,
  price: tokensUsed * 0.00001,
});

This is the pattern to reach for any time you're charging for LLM calls, compute time, or anything else where cost is only known after the work is done.

Step 3: How an AI Agent Actually Pays

Once your API is paywalled, the agent calling it needs a way to detect the 402, sign a payment, and retry. thirdweb documents two production paths for this:

Option A: Give the agent an MCP server

The simplest way to equip an agent with payment capability is thirdweb's remote MCP server — it exposes fetchWithPayment and listPayableServices as tools your agent framework can call directly, no custom payment logic required:

import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { ChatOpenAI } from "@langchain/openai";

const model = new ChatOpenAI({ model: "gpt-4.1" });

const mcpServers = {
  thirdweb: {
    url: `https://api.thirdweb.com/mcp?secretKey=<your-project-secret-key>&tools=fetchWithPayment,listPayableServices`,
  },
};

const mcpClient = new MultiServerMCPClient(mcpServers);
const tools = await mcpClient.getTools();

const agent = createReactAgent({
  llm: model,
  tools,
  prompt:
    "Use fetchWithPayment to fetch endpoints. Discover available endpoints with listPayableServices.",
});

Option B: Call the payment API directly

If you're not using an MCP-based agent, you can wrap any 402-protected endpoint with thirdweb's hosted fetchWithPayment API, which handles the 402 detection, signing, and retry for you:

fetch(
  "https://api.thirdweb.com/v1/payments/x402/fetch?from=0xAgentWalletAddress&url=https%3A%2F%2Fyourapi.com%2Fapi%2Fpremium-content&method=GET&maxValue=1000000",
  {
    method: "POST",
    headers: { "x-secret-key": "<your-project-secret-key>" },
  }
);

For a frontend app rather than an autonomous agent, thirdweb also ships a React hook, useFetchWithPayment, that wraps native fetch and handles wallet connection, 402 detection, and payment signing with built-in UI — useful if humans (not just agents) will hit the same paywalled endpoints.

Payment Schemes, Networks & Tokens

  • exact — the client pays a fixed, specified amount. Use this for static content and fixed-cost actions.
  • upto — the client authorizes up to a maximum, and you settle the real cost afterward. Use this for AI inference and anything usage-metered.
  • Networks — 170+ EVM chains via thirdweb's chain list; non-EVM support (Solana) exists through a separate facilitator configuration.
  • Tokens — any ERC-20 supporting ERC-2612 permit or ERC-3009 authorization; USDC is supported this way on every chain.

Testing Before You Go to Mainnet

Build against a testnet first — the examples above use arbitrumSepolia. thirdweb also runs a live x402 Playground where you can send test payments against a paywalled endpoint without writing an agent first.

Common pitfalls

  • Forgetting to forward result.responseHeaders on a 402 response — the client needs those headers to know how to pay.
  • Hardcoding a flat price on variable-cost AI endpoints instead of using the upto scheme — you either overcharge or eat the loss.
  • Missing THIRDWEB_SECRET_KEY in your server environment, which silently breaks facilitator calls.
  • resourceUrl/method not matching the actual incoming request — payment verification is tied to the exact resource being requested.

You Now Have Everything You Need to Ship This

That's the full loop: paywall an endpoint with settlePayment(), price it statically or dynamically, and equip an agent to pay for it via thirdweb's MCP server or the direct payment API. The hard parts — multi-chain settlement, gasless transactions, signature verification — are handled by the facilitator, which is exactly why x402 is realistic to ship in days, not months.

That said, wiring this into a real product means real money moving through it — pricing strategy, wallet security, error handling for failed settlements, and monitoring all matter more here than in a typical integration. iLaunch has already built and shipped x402 and on-chain payment integrations for clients in production, not just in a demo repo, so if you'd rather have it built correctly the first time than debug settlement edge cases in production, that's exactly the kind of work we do.

Want Payable APIs Built and Shipped for You?

iLaunch designs, builds, and ships production-ready AI and Web3 integrations — including x402 payment flows — for startup founders who'd rather ship than debug on-chain edge cases alone.

Book a Call

FAQ

What is x402?

x402 is an open-source payment protocol that repurposes the long-dormant HTTP 402 "Payment Required" status code into a real, on-chain payment layer for APIs. A server responds 402 with payment requirements, the client signs a payment, and the server settles it before returning the actual content.

Do I need to run my own blockchain infrastructure to accept payments?

No. A facilitator (like thirdweb) verifies payment signatures and settles transactions on-chain on your behalf using a server wallet you configure. You just call settlePayment() in your API route or middleware — thirdweb handles the chain interaction.

Which tokens can I charge in?

Any ERC-20 token that supports ERC-2612 permit or ERC-3009 authorization, which covers USDC on every chain thirdweb supports (170+ EVM chains). You can price a route in USD (e.g. "$0.10") and it settles in USDC by default, or specify a custom ERC-20 asset.

Can I charge AI agents dynamically, based on actual usage?

Yes, using the "upto" scheme instead of "exact". You call verifyPayment() to confirm the agent authorized up to a maximum amount, do the expensive work (e.g. an LLM call), then call settlePayment() for the actual cost — useful for metering AI inference by tokens used.

Is x402 locked into thirdweb specifically?

No, x402 is an open protocol with multiple facilitator implementations. thirdweb is one facilitator option, and it's the one this guide uses because it handles gasless settlement across 170+ EVM chains out of the box and integrates with existing x402 middleware like x402-express, x402-hono, and x402-next.

How does an AI agent actually pay, in practice?

The most straightforward documented path is thirdweb's remote MCP server, which exposes fetchWithPayment and listPayableServices as tools an agent framework (e.g. LangChain) can call directly. There's also a direct /v1/x402/fetchWithPayment API for wrapping any external paid endpoint programmatically.