Quickstart for Sellers
This guide walks you through integrating with x402 to enable payments for your API or service. By the end, your API will be able to charge buyers and AI agents for access.
Prerequisites
Before you begin, ensure you have:
- A crypto wallet to receive funds (any EVM-compatible wallet)
- Required for mainnet use until other facilitators go live
- Node.js and npm, or Python and pip installed
- An existing API or server
1. Install Dependencies
Node.js
Express:
Install the x402 Express middleware package:
npm install x402-expressNext.js:
Install the x402 Next.js middleware package:
npm install x402-nextHono:
Install the x402 Hono middleware package:
npm install x402-honoPython
Install the x402 Python package:
pip install x4022. Add Payment Middleware
Integrate the payment middleware into your application. You will need to provide:
- The routes you want to protect
- Your receiving wallet address
Node.js
Express
import express from "express";
import { paymentMiddleware, Network } from "x402-express";
const endpoint = "https://facilitator.codenut.ai";
const app = express();
app.use(paymentMiddleware(
"0xYourAddress", // your receiving wallet address
{ // Route configurations for protected endpoints
"GET /weather": {
// USDC amount in dollars
price: "$0.001",
network: "base",
// Optional: Add metadata for better discovery in x402 Bazaar
config: {
description: "Get current weather data for any location",
inputSchema: {
type: "object",
properties: {
location: { type: "string", description: "City name" }
}
},
outputSchema: {
type: "object",
properties: {
weather: { type: "string" },
temperature: { type: "number" }
}
}
}
},
},
{
url: endpoint,
}
));
// Implement your route
app.get("/weather", (req, res) => {
res.send({
report: {
weather: "sunny",
temperature: 70,
},
});
});
app.listen(4021, () => {
console.log(`Server listening at http://localhost:4021`);
});Next.js
import { paymentMiddleware, Network } from 'x402-next';
const endpoint = "https://facilitator.codenut.ai";
// Configure the payment middleware
export const middleware = paymentMiddleware(
"0xYourAddress", // your receiving wallet address
{ // Route configurations for protected endpoints
'/protected': {
price: '$0.01',
network: "base",
config: {
description: 'Access to protected content',
// Optional: Add schemas for better discovery
inputSchema: {
type: "object",
properties: {}
},
outputSchema: {
type: "object",
properties: {
content: { type: "string" }
}
}
}
},
},
{
url: endpoint,
}
);
// Configure which paths the middleware should run on
export const config = {
matcher: [
'/protected/:path*',
]
};Hono
import { Hono } from "hono";
import { serve } from "@hono/node-server";
import { paymentMiddleware, Network } from "x402-hono";
const endpoint = "https://facilitator.codenut.ai";
const app = new Hono();
// Configure the payment middleware
app.use(paymentMiddleware(
"0xYourAddress", // your receiving wallet address
{ // Route configurations for protected endpoints
"/protected-route": {
price: "$0.10",
network: "base",
config: {
description: "Access to premium content",
}
}
},
{
url: endpoint,
}
));
// Implement your route
app.get("/protected-route", (c) => {
return c.json({ message: "This content is behind a paywall" });
});
serve({
fetch: app.fetch,
port: 3000
});Python
FastAPI
import os
from typing import Any, Dict
from dotenv import load_dotenv
from fastapi import FastAPI
from x402.fastapi.middleware import require_payment
from x402.types import EIP712Domain, TokenAmount, TokenAsset
# Load environment variables
load_dotenv()
app = FastAPI()
# Apply payment middleware to specific routes
app.middleware("http")(
require_payment(
path="/weather",
price="$0.001",
pay_to_address="0xYourAddress",
network_id="base",
facilitator_url="https://facilitator.codenut.ai",
# Optional: Add metadata for better discovery in x402 Bazaar
description="Get current weather data for any location",
input_schema={
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"}
}
},
output_schema={
"type": "object",
"properties": {
"weather": {"type": "string"},
"temperature": {"type": "number"}
}
}
)
)
@app.get("/weather")
async def get_weather() -> Dict[str, Any]:
return {
"report": {
"weather": "sunny",
"temperature": 70,
}
}Flask
import os
from flask import Flask, jsonify
from dotenv import load_dotenv
from x402.flask.middleware import PaymentMiddleware
from x402.types import EIP712Domain, TokenAmount, TokenAsset
# Load environment variables
load_dotenv()
app = Flask(__name__)
# Initialize payment middleware
payment_middleware = PaymentMiddleware(app)
# Apply payment middleware to specific routes
payment_middleware.add(
path="/weather",
price="$0.001",
pay_to_address="0xYourAddress",
network="base",
facilitator_url="https://facilitator.codenut.ai",
# Optional: Add metadata for better discovery in x402 Bazaar
description="Get current weather data for any location",
input_schema={
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"}
}
},
output_schema={
"type": "object",
"properties": {
"weather": {"type": "string"},
"temperature": {"type": "number"}
}
}
)
@app.route("/weather")
def get_weather():
return jsonify({
"report": {
"weather": "sunny",
"temperature": 70,
}
})Payment Middleware Configuration Interface
interface PaymentMiddlewareConfig {
description?: string; // Description of the payment
mimeType?: string; // MIME type of the resource
maxTimeoutSeconds?: number; // Maximum time for payment (default: 60)
outputSchema?: Record; // JSON schema for the response
customPaywallHtml?: string; // Custom HTML for the paywall
resource?: string; // Resource URL (defaults to request URL)
}When a request is made to these routes without payment, your server will respond with the HTTP 402 Payment Required code and payment instructions.
3. Test Your Integration
To verify:
- Make a request to your endpoint (e.g.,
curl http://localhost:3000/your-endpoint). - The server responds with a 402 Payment Required, including payment instructions in the body.
- Complete the payment using a compatible client, wallet, or automated agent. This typically involves signing a payment payload, which is handled by the client SDK detailed in the Quickstart for Buyers.
- Retry the request, this time including the
X-PAYMENTheader containing the cryptographic proof of payment (payment payload). - The server verifies the payment via the facilitator and, if valid, returns your actual API response (e.g.,
{ "data": "Your paid API response." }).
4. Enhance Discovery with Metadata (Recommended)
When using the CDP facilitator, your endpoints are automatically listed in the x402 Bazaar, our discovery layer that helps buyers and AI agents find services. To improve your visibility and help users understand your API:
Tip: Include descriptive metadata in your middleware configuration:
description: Clear explanation of what your endpoint doesinputSchema: JSON schema describing required parametersoutputSchema: JSON schema of your response formatThis metadata helps:
- AI agents automatically understand how to use your API
- Developers quickly find services that meet their needs
- Improve your ranking in discovery results
Example with full metadata:
{
price: "$0.001",
network: "base",
config: {
description: "Get real-time weather data including temperature, conditions, and humidity",
inputSchema: {
type: "object",
properties: {
location: {
type: "string",
description: "City name or coordinates (e.g., 'San Francisco' or '37.7749,-122.4194')"
},
units: {
type: "string",
enum: ["celsius", "fahrenheit"],
default: "fahrenheit"
}
},
required: ["location"]
},
outputSchema: {
type: "object",
properties: {
temperature: { type: "number", description: "Current temperature" },
conditions: { type: "string", description: "Weather conditions (sunny, cloudy, rainy, etc.)" },
humidity: { type: "number", description: "Humidity percentage" }
}
}
}
}Learn more about the discovery layer in the x402 Bazaar documentation.
Summary
This quickstart covered:
- Installing the x402 SDK and relevant middleware
- Adding payment middleware to your API and configuring it
- Testing your integration
Your API is now ready to accept crypto payments through x402.