Prerequisites

Before you begin, ensure you have the following:

Create Your First Paid API

1

Install x402 packages

Create a new project and install the required packages:
mkdir my-paid-api && cd my-paid-api
pnpm init -y
pnpm add x402-express @coinbase/x402 express dotenv
Expected outcome: Project directory created with x402 dependencies installed.
2

Configure ES Modules

Update your package.json to enable ES modules:
{
  "name": "my-paid-api",
  "version": "1.0.0",
  "type": "module",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "x402-express": "^0.6.0",
    "@coinbase/x402": "^0.6.0",
    "express": "^5.1.0",
    "dotenv": "^17.2.2"
  }
}
Expected outcome: Package.json configured for ES modules.
3

Create environment configuration

Create a .env file in your project root:
FACILITATOR_URL=http://localhost:3000/facilitator
ADDRESS=0x1234567890123456789012345678901234567890
Replace ADDRESS with your testnet Sei wallet address. The FACILITATOR_URL should point to your facilitator service, but having a valid one is not required for this tutorial. If you want to test with a facilitator, you can run one locally. See the Facilitator Example
Expected outcome: Environment variables configured for your API.
4

Create a simple paid API server

Create server.js with a protected API endpoint:
import {config} from "dotenv";
import express from "express";
import {paymentMiddleware} from "x402-express";
config();

const facilitatorUrl = process.env.FACILITATOR_URL;
const payTo = process.env.ADDRESS;

if (!facilitatorUrl || !payTo) {
  console.error("Missing required environment variables FACILITATOR_URL and ADDRESS");
  process.exit(1);
}

const app = express();

app.use(
  paymentMiddleware(
    payTo,
    {
      "GET /weather": {
        // USDC amount in dollars
        price: "$0.001",
        network: "sei-testnet",
      }
    },
    {
        url: facilitatorUrl,
    },
   ),
);

app.get("/weather", (req, res) => {
res.send({
    report: {
        weather: "sunny",
        temperature: 70,
    },
  });
});

app.listen(4021, () => {
  console.log(`Server listening at http://localhost:${4021}`);
});

Expected outcome: Express server configured with x402 payment middleware.
5

Start and test your paid API

Start your server:
pnpm start
In another terminal, test the protected endpoint:
curl http://localhost:4021/weather
Expected outcome: You should receive a 402 Payment Required response with payment details, or an error if the facilitator is not running.
If you get a connection error, make sure your facilitator service is running at the configured URL, or set up a local facilitator using the Facilitator Example.
Example successful 402 response:
	{
		"x402Version": 1,
		"error": "X-PAYMENT header is required",
		"accepts": [
		{
			"scheme": "exact",
			"network": "sei-testnet",
			"maxAmountRequired": "1000",
			"resource": "http://localhost:4021/weather",
			"description": "",
			"mimeType": "",
			"payTo": "0x1234567890123456789012345678901234567890",
			"maxTimeoutSeconds": 60,
			"asset": "0x4fCF1784B31630811181f670Aea7A7bEF803eaED",
			"outputSchema": {
				"input": {
					"type": "http",
					"method": "GET",
					"discoverable": true
				}
			},
			"extra": {
			"name": "USDC",
			"version": "2"
			}
		}
		]
	}