DEV Community

Cover image for Make AI agents pay your API per call — one command, no API keys (x402 + USDC)
ScriptMasterLabs
ScriptMasterLabs

Posted on

Make AI agents pay your API per call — one command, no API keys (x402 + USDC)

AI agents can't sign up for your API. They can't fill in a billing form, verify an email or paste a key into a dashboard. But they can hold a wallet and sign a payment.

That's what x402 is for. It's the HTTP 402 Payment Required status code, finally put to use. Your server answers a request with 402 and a price. The agent signs a USDC payment and retries. Your server settles the payment and returns the content. No accounts, no keys, no invoices.

This post shows the fastest way I know to ship it: one command that builds a paid API, a paid MCP server or a paid file store. It runs on Express, Hono, Next.js, Cloudflare Workers or FastAPI.

npm create @scriptmasterlabs/x402 my-api
Enter fullscreen mode Exit fullscreen mode

No global install. Prefer to run it straight from source? npx gitlab:script-master-labs-llc-group/x402-kit my-api or npx github:Timwal78/x402-kit my-api do the same thing.


What you can build

Mode What it does
--mode mcp A paid MCP server. Mix free and paid tools; agents pay per tool call.
--mode wrap A paywall in front of an API you already run, with no changes to that API.
--mode file Sell files: PDFs, datasets, ebooks, audio. Each file can have its own price.

Pick a stack with --stack express | hono | next | workers | fastapi.

1. Create a paid MCP server

npm create @scriptmasterlabs/x402 my-mcp -- --stack express --mode mcp --pay-to 0xYourWallet --price 0.01
cd my-mcp
npm install
npm start
Enter fullscreen mode Exit fullscreen mode

--pay-to is the wallet that receives USDC on Base. Payments go straight to it; the facilitator never holds your money. If you leave it out, paid routes answer 503 seller_not_configured until you set PAY_TO in .env. The kit never falls back to a placeholder wallet.

2. See the 402

Call the paid tool without paying:

curl -i -X POST localhost:3000/mcp -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"text_stats","arguments":{"text":"hello agents"}}}'
Enter fullscreen mode Exit fullscreen mode
HTTP/1.1 402 Payment Required
PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6Mi...
Enter fullscreen mode Exit fullscreen mode

The challenge, which says what to pay, how much, in what asset and to which wallet, is in the JSON body and in the base64 PAYMENT-REQUIRED header. Any standard x402 client can read it, sign, and retry with a PAYMENT-SIGNATURE header.

The free tool (ping) answers right away. tools/list labels the paid tools with their price, so agents know before they call.

3. Add your own tools

Open src/tools.mjs:

export const tools = [
  {
    name: 'ping',
    description: 'Free health check.',
    handler: async () => ({ ok: true }),
  },
  {
    name: 'text_stats',
    description: 'Word, sentence and character counts plus the top words.',
    priceUsd: '0.01',               // remove this line and the tool is free
    inputSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'] },
    handler: async ({ text }) => { /* ... */ },
  },
];
Enter fullscreen mode Exit fullscreen mode

If a handler throws, the caller gets a tool error and is not charged. The kit only settles a payment after your code succeeds.

4. Take a real payment ($0.01 self-test)

Fund a throwaway wallet with a little USDC on Base, then:

BUYER_PRIVATE_KEY=0x<throwaway wallet> npx @scriptmasterlabs/create-x402 pay http://localhost:3000/mcp \
  --method POST --data '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"text_stats","arguments":{"text":"hello agents"}}}'
Enter fullscreen mode Exit fullscreen mode

pay uses the stock x402 Foundation client (@x402/fetch + @x402/evm). It reads the 402, refuses anything above --max-usd (default $0.05), pays, and prints the settlement transaction with a Basescan link.

Then open http://localhost:3000/x402/receipts. Every settled payment is listed there with its transaction hash.

5. Already have an API? Wrap it

npm create @scriptmasterlabs/x402 my-proxy -- --stack hono --mode wrap \
  --upstream https://api.yourservice.com --pay-to 0xYourWallet --price 0.02
Enter fullscreen mode Exit fullscreen mode

Every request is proxied to your upstream after payment. In .env you can:

  • set per-route prices: ROUTE_PRICES={"/v1/search":"0.05"}
  • keep some routes free: FREE_PATHS=/health,/docs*
  • send your upstream key server-side: UPSTREAM_AUTH_HEADER=Authorization: Bearer <key>. Buyers never see it.

6. Add it to an existing project

npx @scriptmasterlabs/create-x402 add
Enter fullscreen mode Exit fullscreen mode

This drops a dependency-free core into your project, plus an X402.md with the wiring:

// Express
app.get('/report', paid(x402, '0.02', 'One full report'), handler);

// Hono / Next.js route handlers / Cloudflare Workers
return x402.protect(request, { priceUsd: '0.02' }, () => Response.json(data));
Enter fullscreen mode Exit fullscreen mode

Python projects get x402_seller.py with await x402.protect(request, "0.02", "One report", handler).

7. Let your coding agent do it

Every generated project ships an AGENTS.md. Give Claude Code or Cursor one sentence:

Run npm create @scriptmasterlabs/x402 my-api to make my API charge AI agents per call, then follow the generated AGENTS.md.

8. Deploy and get found

  • Render: a render.yaml blueprint is included. Workers: npx wrangler deploy. Next.js also runs on Vercel.
  • After deploying, set PUBLIC_URL to your https URL.
  • Every server exposes free discovery routes: /.well-known/x402 (machine-readable paid resources) and /llms.txt (for AI crawlers).
  • Each 402 challenge includes a bazaar discovery declaration, so facilitators that index on settlement list your resource after its first paid call.
  • /x402/badge.svg is a live "N paid calls · $X" badge for your README.

About the facilitator (and a disclosure)

A facilitator verifies the signed payment and broadcasts it on-chain. The kit's default is OMNIGATE (https://mcp-x402.onrender.com), the facilitator my company, Script Master Labs, runs for USDC on Base and Arc.

What that means for you:

  • Standard x402 clients settle as they are. OMNIGATE's 0.005 USDC fee is optional. A payment that doesn't attach it is settled with the fee waived, within a published daily limit. Live terms are at /supported.
  • Your price goes to your wallet in full. OMNIGATE never holds the money.
  • It's one line of config. FACILITATOR_URLS is a comma list tried in order. To keep the facilitator you use today and only fall back to OMNIGATE when it errors:
FACILITATOR_URLS=https://your-current-facilitator.example,https://mcp-x402.onrender.com
Enter fullscreen mode Exit fullscreen mode

How it was tested

Before publishing, every stack and mode was scaffolded and paid with the stock x402 client against the live facilitator, plus a real $0.01 USDC settlement on Base through a kit-built app. Both wallets in that settlement were ours, so it proves the kit works end to end, not that anyone else uses it yet.

npm: @scriptmasterlabs/create-x402 · Repo and issues: https://gitlab.com/script-master-labs-llc-group/x402-kit (GitHub copy: https://github.com/Timwal78/x402-kit)

If you build something with it, I'd like to see it.

Top comments (0)