For providers not charging per call yet~15 min

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

install
npm i @x402/express @x402/core @x402/stellar
Express
import 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

install
npm i @x402/hono @x402/core @x402/stellar
Hono
import { 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

install
npm i @x402/next @x402/core @x402/stellar
Next.js
// 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

install
uv add 'x402[fastapi,evm]'
FastAPI
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

  1. 1We check your endpoint answers a well-formed 402 challenge, that the price matches, and that the payTo address is the one you registered.
  2. 2One minimal paid call runs against your service as a real buyer. The money lands in your wallet, not ours.
  3. 3You are listed in the MPP Router catalog, at /services and in llms.txt, with you as the operator.
  4. 4The same integration makes you visible across the x402 surface — x402scan, the Bazaar and MPPScan.

Get listed

Service nameHow it appears in the catalog and to buying agents.
API base URLYour server, your domain. We route to it; we never host it.
Routes to charge, and their pricesOne per line: method, path, price per call in USD.
Payout address, per chain
Stellar
Base
Solana
At least one. Payments land here directly — paste from your wallet rather than typing, since a wrong character sends money to a stranger and we cannot claw it back. No Stellar account yet? Leave it blank: we sponsor the account reserve and the USDC trustline for you.
EmailFor the setup reply and payment notifications. Nothing else.
Anything else? (optional)

This is a waitlist, not an automated signup. We reply by email to finish the setup with you.

Already charging with x402? If your endpoint already answers 402 on Base or Solana, you need one accepts[] entry, not a snippet — about 5 minutes.