YOUR API CANNOT TAKE MONEY TODAY. PASTE ONE MIDDLEWARE SNIPPET AND IT CAN.
No billing system, no plans, no invoices, no signup for the buyer. The middleware answers unpaid requests with a 402 that states the price and your address; the caller pays and retries; your handler runs. You keep running the same server on the same domain.
The snippet
Pick your framework. In every case the change is the middleware plus one PAYOUT_ADDRESS in your environment — your route handler itself is not modified.
Express
npm i @x402/express @x402/core @x402/stellarimport express from "express";
import { paymentMiddleware, x402ResourceServer } from "@x402/express";
import { ExactStellarScheme } from "@x402/stellar/exact/server";
import { HTTPFacilitatorClient } from "@x402/core/server";
const app = express();
const resourceServer = new x402ResourceServer(
new HTTPFacilitatorClient({ url: "https://x402.org/facilitator" }),
).register("stellar:pubnet", new ExactStellarScheme());
app.use(
paymentMiddleware(
{
"POST /v1/summarize": {
accepts: {
scheme: "exact",
price: "$0.01",
network: "stellar:pubnet",
payTo: process.env.PAYOUT_ADDRESS,
},
description: "Summarize a URL",
},
},
resourceServer,
),
);
// Your handler is unchanged. It only runs once the call is paid for.
app.post("/v1/summarize", (req, res) => res.json({ summary: "…" }));
app.listen(3000);Hono
npm i @x402/hono @x402/core @x402/stellarimport { Hono } from "hono";
import { paymentMiddleware, x402ResourceServer } from "@x402/hono";
import { ExactStellarScheme } from "@x402/stellar/exact/server";
import { HTTPFacilitatorClient } from "@x402/core/server";
const app = new Hono();
const resourceServer = new x402ResourceServer(
new HTTPFacilitatorClient({ url: "https://x402.org/facilitator" }),
).register("stellar:pubnet", new ExactStellarScheme());
app.use(
paymentMiddleware(
{
"POST /v1/summarize": {
accepts: {
scheme: "exact",
price: "$0.01",
network: "stellar:pubnet",
payTo: process.env.PAYOUT_ADDRESS,
},
},
},
resourceServer,
),
);
app.post("/v1/summarize", (c) => c.json({ summary: "…" }));
export default app;Next.js
npm i @x402/next @x402/core @x402/stellar// app/api/summarize/route.ts
import { NextRequest, NextResponse } from "next/server";
import { withX402, x402ResourceServer } from "@x402/next";
import { ExactStellarScheme } from "@x402/stellar/exact/server";
import { HTTPFacilitatorClient } from "@x402/core/server";
const resourceServer = new x402ResourceServer(
new HTTPFacilitatorClient({ url: "https://x402.org/facilitator" }),
).register("stellar:pubnet", new ExactStellarScheme());
const handler = async (_: NextRequest) =>
NextResponse.json({ summary: "…" });
// withX402 settles only after your handler returns < 400, so a failed
// request is not charged for.
export const POST = withX402(
handler,
{
accepts: {
scheme: "exact",
price: "$0.01",
network: "stellar:pubnet",
payTo: process.env.PAYOUT_ADDRESS!,
},
},
resourceServer,
);FastAPI
uv add 'x402[fastapi,evm]'import os
from fastapi import FastAPI
from x402 import x402ResourceServer
from x402.http import HTTPFacilitatorClient
from x402.http.middleware import fastapi_payment_middleware
from x402.mechanisms.evm.exact import ExactEvmServerScheme
app = FastAPI()
server = x402ResourceServer(HTTPFacilitatorClient())
server.register("eip155:*", ExactEvmServerScheme())
routes = {
"POST /v1/summarize": {
"accepts": {
"scheme": "exact",
"price": "$0.01",
"network": "eip155:8453",
"payTo": os.environ["PAYOUT_ADDRESS"],
}
}
}
@app.middleware("http")
async def x402_middleware(request, call_next):
return await fastapi_payment_middleware(routes, server)(request, call_next)
@app.post("/v1/summarize")
async def summarize():
return {"summary": "…"}The Python SDK ships EVM, Solana and TON mechanisms — there is no Stellar mechanism in it yet, so a Python server charges on Base and we add the Stellar leg on the router side. Nothing about that changes where the money lands: it is still your address.
What you get on the far side
Charging is only half of it — an endpoint nobody can find does not earn. From this single integration you are listed in the MPP Router catalog and visible across the x402 surface: x402scan, the Bazaar and MPPScan. Agents discover your service and pay for it themselves, with no account on your side and no API key to issue.
What we ask you for
Service name
How it appears in the catalog and to buying agents.
API base URL
The server you already run. We route to it; we never host it.
The routes to charge, and their prices
Per call, in USD. Charge some routes and leave the rest free if you like.
A payout address per chain
At least one. This is where buyers' money lands — on your key, not ours.
What stays yours
Your server stays yours. Your key stays yours. Payments land directly on your address — nothing custodial on our side. We handle discovery, routing, the paywall snippet and the dashboard.
What happens next
- 1We check your endpoint answers a well-formed 402 challenge, that the price matches, and that the payTo address is the one you registered.
- 2One minimal paid call runs against your service as a real buyer. The money lands in your wallet, not ours.
- 3You are listed in the MPP Router catalog, at /services and in llms.txt, with you as the operator.
- 4The same integration makes you visible across the x402 surface — x402scan, the Bazaar and MPPScan.