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

> Source: <https://dev.to/scriptmasterlabs01/make-ai-agents-pay-your-api-per-call-one-command-no-api-keys-x402-usdc-48ig>
> Published: 2026-11-05 20:45:16+00:00

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
```

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.

| 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`.

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

`--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.

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"}}}'
HTTP/1.1 402 Payment Required
PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6Mi...
```

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.

Open `src/tools.mjs`:

``` js
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 }) => { /* ... */ },
  },
];
```

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

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"}}}'
```

`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.

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

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

`ROUTE_PRICES={"/v1/search":"0.05"}`
`FREE_PATHS=/health,/docs*`
`UPSTREAM_AUTH_HEADER=Authorization: Bearer <key>`. Buyers never see it.

```
npx @scriptmasterlabs/create-x402 add
```

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));
```

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

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.

`render.yaml` blueprint is included. `npx wrangler deploy`. `PUBLIC_URL` to your https URL.`/.well-known/x402` (machine-readable paid resources) and `/llms.txt` (for AI crawlers).`/x402/badge.svg` is a live "N paid calls · $X" badge for your README.
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:

`/supported`` 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
```

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](https://gitlab.com/script-master-labs-llc-group/x402-kit)** (GitHub copy: [https://github.com/Timwal78/x402-kit](https://github.com/Timwal78/x402-kit))

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