Skip to main content
This guide helps you migrate from x402 v1 to v2. The v2 protocol introduces standardized identifiers, improved type safety, and a more modular architecture.
v2 is now the recommended version. While v1 continues to work, we encourage all users to migrate to v2 for the latest features and improvements.
Official v2 Specification: The authoritative protocol specification is at github.com/coinbase/x402/specs. For CDP facilitator API schemas, see the x402 Facilitator API Reference.

Overview

Aspectv1v2
Payment HeaderX-PAYMENTPAYMENT-SIGNATURE
Response HeaderX-PAYMENT-RESPONSEPAYMENT-RESPONSE
Network FormatString (base-sepolia)CAIP-2 (eip155:84532)
Version Fieldx402Version: 1x402Version: 2
Packagesx402, x402-express, x402-axios@x402/core, @x402/express, @x402/axios, @x402/evm

Compatibility Matrix

Use this matrix to understand which SDK versions work with which facilitators and protocol versions.

SDK Packages

Legacy (designed for v1)

PackageRecommended Migration
x402@x402/core
x402-express@x402/express
x402-next@x402/next
x402-hono@x402/hono
x402-fetch@x402/fetch
x402-axios@x402/axios

Current (use v2 by default)

PackageNotes
CORE
@x402/coreCore x402 primitives
PAYMENT SCHEMES
@x402/evmEVM implementation of exact payment scheme
@x402/svmSolana implementation of exact payment scheme
CLIENT LIBRARIES
@x402/fetchHandles both v1 and v2 automatically
@x402/axiosHandles both v1 and v2 automatically
SERVER MIDDLEWARE
@x402/expressv2 default. Use .registerV1() for v1 clients
@x402/nextv2 default. Use .registerV1() for v1 clients
@x402/honov2 default. Use .registerV1() for v1 clients
UI
@x402/paywallModular paywall UI for EVM and Solana
EXTENSIONS
@x402/extensionsProtocol extensions like Bazaar (discovery layer)
PYTHON
x402Monolithic SDK with all functionality
GO
github.com/coinbase/x402/goMonolithic SDK with all functionality

Facilitators

Facilitatorv1v2Networks
https://www.x402.org/facilitatorBase Sepolia, Solana Devnet (testnet only)
https://api.cdp.coinbase.com/platform/v2/x402Base, Base Sepolia, Solana, Solana Devnet

Headers

Purposev1 Headerv2 Header
Payment signature (client → server)X-PAYMENTPAYMENT-SIGNATURE
Payment response (server → client)X-PAYMENT-RESPONSEPAYMENT-RESPONSE
Payment requirements (server → client)(in body)PAYMENT-REQUIRED
v2 libraries check for both v1 and v2 headers for backward compatibility, but new implementations should use v2 headers.

For Buyers

Before (v1)

import { withPaymentInterceptor } from "x402-axios";
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { baseSepolia } from "viem/chains";
import axios from "axios";

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const walletClient = createWalletClient({
  account,
  chain: baseSepolia,
  transport: http(),
});

// v1 pattern
const api = withPaymentInterceptor(
  axios.create({ baseURL: "https://api.example.com" }),
  walletClient,
);

const response = await api.get("/paid-endpoint");

After (v2)

import { x402Client, wrapAxiosWithPayment } from "@x402/axios";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
import axios from "axios";

const signer = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`);

// v2 pattern: Create client and register scheme separately
const client = new x402Client();
registerExactEvmScheme(client, { signer });

// Wrap axios with payment handling
const api = wrapAxiosWithPayment(
  axios.create({ baseURL: "https://api.example.com" }),
  client,
);

const response = await api.get("/paid-endpoint");

Key Changes

  1. Package rename: x402-axios@x402/axios
  2. Function rename: withPaymentInterceptorwrapAxiosWithPayment
  3. Wallet setup: Use x402Client with registerExactEvmScheme helper instead of passing wallet directly
  4. No chain-specific configuration: The v2 client automatically handles network selection based on payment requirements

For Sellers

Before (v1)

import { paymentMiddleware, FacilitatorConfig } from "x402-express";
import express from "express";

const app = express();

const facilitatorConfig: FacilitatorConfig = {
  url: "https://x402.org/facilitator",
};

app.use(
  paymentMiddleware(facilitatorConfig, {
    "GET /weather": {
      price: "$0.001",
      network: "base-sepolia", // v1 string format
      config: {
        description: "Get weather data",
      },
    },
  }),
);

After (v2)

import express from "express";
import { paymentMiddleware } from "@x402/express";
import { x402ResourceServer, HTTPFacilitatorClient } from "@x402/core/server";
import { registerExactEvmScheme } from "@x402/evm/exact/server";

const app = express();
const payTo = "0xYourAddress";

// v2 pattern: Create facilitator client and resource server
const facilitatorClient = new HTTPFacilitatorClient({
  url: "https://x402.org/facilitator"
});

const server = new x402ResourceServer(facilitatorClient);
registerExactEvmScheme(server);

app.use(
  paymentMiddleware(
    {
      "GET /weather": {
        accepts: [
          {
            scheme: "exact",
            price: "$0.001",
            network: "eip155:84532", // v2 CAIP-2 format
            payTo,
          },
        ],
        description: "Get weather data",
        mimeType: "application/json",
      },
    },
    server,
  ),
);

Key Changes

  1. Package rename: x402-express@x402/express
  2. Configuration structure: Route config now uses accepts array with explicit scheme, network, and payTo
  3. Network format: base-sepoliaeip155:84532 (CAIP-2 standard)
  4. Resource server: Create x402ResourceServer with facilitator client and register schemes using helper functions
  5. Price recipient: Explicitly specify payTo address per route

Network Identifier Mapping

v1 Namev2 CAIP-2 IDChain IDDescription
base-sepoliaeip155:8453284532Base Sepolia Testnet
baseeip155:84538453Base Mainnet
ethereumeip155:11Ethereum Mainnet
sepoliaeip155:1115511111155111Ethereum Sepolia Testnet
solana-devnetsolana:devnet-Solana Devnet
solanasolana:mainnet-Solana Mainnet

Package Migration Reference

v1 Packagev2 Package(s)
x402@x402/core
x402-express@x402/express
x402-axios@x402/axios
x402-fetch@x402/fetch
x402-hono@x402/hono
x402-next@x402/next
(built-in)@x402/evm (EVM support)
(built-in)@x402/svm (Solana support)

Header Changes

If you’re implementing custom HTTP handling, update your header names:
// v1
const payment = req.header("X-PAYMENT");
res.setHeader("X-PAYMENT-RESPONSE", responseData);

// v2
const payment = req.header("PAYMENT-SIGNATURE");
res.setHeader("PAYMENT-RESPONSE", responseData);

Troubleshooting

”Cannot find module” errors

Ensure you’ve installed all v2 packages:
# For buyers
npm install @x402/axios @x402/evm

# For sellers (Express)
npm install @x402/express @x402/core @x402/evm

Payment verification failures

  • Check you’re using CAIP-2 network identifiers (eip155:84532 not base-sepolia)
  • Verify your payTo address is correctly configured
  • Ensure the facilitator URL is correct for your network (testnet vs mainnet)

Mixed v1/v2 compatibility

The facilitator supports both v1 and v2 protocols. During migration, your v2 server can still accept payments from v1 clients, but we recommend updating clients to v2 for full feature support.

Next Steps