Permit402

Permit402 docs

Charge AI agents per call for your API or MCP server. Agents pay in USDC using the x402 standard, and the money goes straight to your wallet.

Want to see it first? Try the two-minute live demo.

Overview

Your API keeps working exactly as it does today. Permit402 adds a price to the endpoints or tools you choose. When an agent calls one, it's asked to pay; once it has paid, the call goes through. The agent is only charged if your API succeeds.

There are two ways to run the toll:

Hosted gateway Available now

No code. We give you a gateway URL that sits in front of your API.

  • Set up in about ten minutes
  • One small change to your API: check a header
  • Agent traffic passes through Permit402

In your app Coming soon

Install a small Permit402 package in your server instead.

  • Traffic never leaves your servers
  • Same dashboard, prices and stats
  • Node (Express, Hono) and Cloudflare Workers first

The rest of these docs cover the hosted gateway.

How it works

You don't need to know anything about crypto to use Permit402. Here are the pieces, in plain English.

AgentSoftware acting for someone, such as an AI assistant, a coding agent or an automated workflow. It calls your API the way any program would.
HTTP 402"Payment Required". A web status code reserved for payments since the 1990s and finally put to use. The gateway answers a paid request with 402 and a price.
x402The open standard, started by Coinbase, that says how a 402 describes a price and how an agent sends the payment back. Agents that support it pay automatically, with no sign-up and no API key.
USDCA digital US dollar: one USDC is designed to be worth one US dollar. It's what agents pay with, so your prices are in dollars.
BaseThe payment network USDC moves on. It's built by Coinbase, and payments settle in seconds for a fraction of a cent. Base Sepolia is its test version, where the USDC is free and worthless.
WalletYour account on Base, identified by an address starting 0x. Payments land there, and you can move them to Coinbase and convert to pounds, euros or dollars.
FacilitatorA service that checks each payment and puts it on the network. Permit402 uses Coinbase's for live payments, and the public x402.org facilitator on the test network. Neither holds the money: the payment goes from the agent's wallet straight to yours.
GatewayYour Permit402 address, e.g. permit402.com/g/forecast-co. It knows your prices, asks agents to pay, and passes paid calls on to your API.

One paid call, step by step

Agent ──GET /v1/forecast──▶ Gateway                        Your API
Agent ◀──402: "$0.01 USDC to 0xYou"── Gateway
Agent ──same request + signed payment──▶ Gateway
                                         Gateway ──checks payment (Coinbase)
                                         Gateway ──request + secret header──▶ Your API
                                         Gateway ◀──────── 200 OK + data ──── Your API
                                         Gateway ──settles: $0.01 to 0xYou
Agent ◀──200 OK + data + receipt── Gateway

If your API returns an error, the last step never happens and the agent keeps its money.

What you need

An API or MCP serverReachable on the public internet over https://. It can be anything: Node, Python, Go, a serverless function.
A wallet address on BaseWhere your earnings go. It starts with 0x. The easiest way is the Coinbase app: Receive → USDC → Base network, then copy the address. Any Ethereum wallet works, such as MetaMask or Rabby. We never hold your money and never need your keys.
Ten minutesAnd the ability to add one small check to your API's code or config.

Quick start

  1. Create an account. Open the dashboard and press Create account. You'll be shown an admin key beginning tk_. That key is your login, and it's only shown once, so save it in your password manager.
  2. Create a gateway. Press New gateway and fill in:
    NameAnything you like, e.g. "Forecast API".
    What's behind itAn HTTP API or An MCP server.
    Your API's URLThe base URL of your API, e.g. https://api.yourcompany.com.
    Your walletYour 0x… address on Base.
    Short descriptionOptional. One sentence that agents read, e.g. "7-day forecasts for any UK town".
    List in the directoryOptional. Shows your gateway in the public Permit402 directory once it's verified.
    Requests with no priceBlock them (the default) or Pass through free. See Setting prices.
    Gateway name in the URLOptional. 3–40 lowercase letters, digits and dashes, e.g. forecast-co.
  3. Add prices. For example GET /v1/forecast at $0.01. Details in Setting prices.
  4. Protect your API. Copy the secret from the gateway's checklist and make your API reject requests without it. Code in Protecting your API.
  5. Test it with free test USDC. New gateways start on the Base Sepolia test network. See Testing.
  6. Verify and go live. Prove you own the API, then switch to real USDC. See Going live.

Then give agents your gateway URL instead of your API's URL:

https://permit402.com/g/forecast-co/v1/forecast?city=York
                       └── gateway ─┘└──── same path and query as your API ────┘
→ forwarded to https://api.yourcompany.com/v1/forecast?city=York

Setting prices

Each price has a method, a path pattern and an amount. When a request comes in, prices are checked top to bottom and the first match wins, so put specific rules above general ones.

MethodPatternPriceMatches
GET/v1/forecast$0.01GET /v1/forecast?city=York
POST/v1/reports/*$0.25POST /v1/reports/annual, POST /v1/reports/2026/q3
*/v1/premium/*$0.05Any method under /v1/premium/
  • Wildcards: * matches anything, including slashes.
  • Forgiving matching: case and a trailing slash don't matter, so /V1/Forecast/ still pays the /v1/forecast price. HEAD requests are priced like GET.
  • The query string is ignored for matching but passed on to your API.
  • Amounts are in US dollars of USDC, written like $0.01, from $0.001 to $100. Up to 100 prices per gateway.

Requests that match no price

Block them returns 404, so only the paths you price are reachable through the gateway. Pass through free forwards them to your API at no charge, which is useful for health checks, docs or free tiers.

Until you verify your API, unpriced requests are always blocked, whichever option you choose. This stops anyone using an unverified gateway as a free proxy to someone else's site.

Protecting your API

Agents could skip the toll by calling your API's own URL directly. To prevent that, every request from your gateway carries a secret header:

x-permit402-secret: <your gateway's secret>

Make your API refuse any request that doesn't carry it. Find the secret in the dashboard, under your gateway's Set-up checklist, and keep it in an environment variable. If it ever leaks, press Rotate and update your API.

import express from "express";
const app = express();

app.use((req, res, next) => {
  if (req.get("x-permit402-secret") !== process.env.PERMIT402_SECRET) {
    return res.status(403).json({ error: "Use the Permit402 gateway" });
  }
  next();
});

app.get("/v1/forecast", (req, res) => {
  const payer = req.get("x-permit402-payer"); // wallet that paid, on paid calls
  res.json({ city: req.query.city, days: [/* … */] });
});

If some of your API should stay open to everyone (say, your website), apply the check only to the paths you sell through the gateway.

Using your own domain

Instead of permit402.com/g/forecast-co, agents can use an address on your own domain, such as https://mcp.permit.yourcompany.com. It behaves exactly the same. Developers and agents tend to trust your name more, and if you ever leave Permit402 you just point the record elsewhere and nothing breaks for them.

  1. On your gateway's page, under Your own domain, enter the address you want and press Connect. Use a subdomain, not your bare domain. It also can't be the same address as your API: if your API is mcp.yourcompany.com, use something like mcp.permit.yourcompany.com.
  2. Add the CNAME record the dashboard shows you, wherever you manage your domain's DNS:
    Type    Name         Target
    CNAME   mcp.permit   customers.permit402.com
    If your DNS is on Cloudflare, set the record to DNS only (grey cloud).
  3. Wait a few minutes. Cloudflare checks the record and issues the HTTPS certificate automatically. Press Check now, or reopen the page. When it shows Live, your domain becomes the gateway URL everywhere: the dashboard, llms.txt, the directory and the server.json for the MCP Registry.

Your permit402.com/g/… address keeps working as well. A domain that isn't connected within 3 days is released, so nobody can hold on to an address they don't control.

Testing

New gateways run on Base Sepolia, a test network where USDC is free and worthless. Nothing real is charged until you switch to live.

  1. Open the live demo. It creates a test wallet in your browser.
  2. Get free test USDC from faucet.circle.com: choose USDC and Base Sepolia, then paste the demo wallet's address.
  3. Paste your gateway URL into the demo's address box, e.g. https://permit402.com/g/forecast-co/v1/forecast?city=York, and press Pay and call.
  4. You should see your API's response, a view payment link, and the payment in your dashboard a few seconds later.

From code, use any x402 client. With the official SDK:

npm i @x402/fetch @x402/evm viem

import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.TEST_WALLET_KEY);
const pay = wrapFetchWithPaymentFromConfig(fetch, {
  schemes: [{ network: "eip155:84532", client: new ExactEvmScheme(account) }],
});
const res = await pay("https://permit402.com/g/forecast-co/v1/forecast?city=York");
The demo page tests GET requests. For other methods use code like the above. x402 clients refuse payments over $1 by default; raise their spending limit if you charge more.

Going live

1. Prove you own the API

So that nobody can sell access to an API that isn't theirs, you verify each gateway once. The checklist shows a token and a URL on your API's domain:

https://api.yourcompany.com/.well-known/permit402.txt

Serve the token as plain text at that URL, either as a static file or a one-line route, then press Verify. Redirects to another domain aren't followed. If you later move the gateway to an API on a different domain, you'll need to verify again.

2. Switch to live

Once verified, press Switch to live. From then on agents pay real USDC on Base, straight to your wallet.

During the beta: live payments are being switched on gradually. If the button says live payments aren't available yet, everything else works on the test network in the meantime.

How agents find you

An agent can only pay for your API if it knows the API exists. There's no single standard for this yet, so Permit402 covers the main routes for you and makes the rest a copy-and-paste job.

Done for you automatically

<gateway>/llms.txtA plain-text summary written for AI: what you sell, your prices and how to pay. It follows the llms.txt proposal, which many AI tools read.
<gateway>/.well-known/x402The same price list as JSON, for programs.
x402 BazaarEvery 402 your gateway sends describes the endpoint in the x402 discovery format. Once you're live, Coinbase's facilitator can list paid endpoints in its Bazaar directory, which agents with wallets search.
Permit402 directoryIf you tick List in the directory, your gateway appears on our public directory page, at permit402.com/directory.json and in permit402.com/llms.txt. Only verified gateways appear, so nobody can list an API that isn't theirs.

Point to it from your own website

Agents often start at your main website. Add a short section to /llms.txt on your site, creating the file if you don't have one, so they find your paid API instead of scraping pages. The dashboard writes this for you under Help agents find you:

## For AI agents
- [Forecast API](https://permit402.com/g/forecast-co/llms.txt): 7-day forecasts for any UK town. Pay per call with x402 (USDC).

Also mention it wherever developers look: your API docs, your OpenAPI file and your developer portal. Give agents the gateway URL, never your API's own URL.

Listing in the MCP Registry

If you sell an MCP server, list it in the official MCP Registry. It's the public catalogue that MCP marketplaces and AI apps pull from, backed by Anthropic, GitHub, Microsoft and others. It's still in preview, so its details may change. It stores only a description and your server's URL, not your code.

  1. Install the publisher tool. On a Mac: brew install mcp-publisher. For other systems, see the registry's quick start.
  2. Copy your server.json from the dashboard (Help agents find you) and replace YOUR-GITHUB-USERNAME. It points the registry at your gateway URL, so agents that find you there pay as normal:
    {
      "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
      "name": "io.github.your-username/forecast-co",
      "title": "Forecast Co",
      "description": "7-day forecasts for any UK town, paid per call with x402",
      "version": "1.0.0",
      "remotes": [
        { "type": "streamable-http", "url": "https://permit402.com/g/forecast-co" }
      ]
    }
  3. Sign in: mcp-publisher login github. This proves you own the io.github.your-username/ name. The registry can also verify your own domain instead (names like com.yourcompany/…); see its authentication guide.
  4. Publish: mcp-publisher publish. Each time you change the file, raise its version and publish again.

People vs agents

Permit402 doesn't try to tell people and bots apart. It doesn't need to, because it works with two front doors:

People

Use your website and apps exactly as today. Nothing changes and nobody is charged.

Agents

Use your gateway URL, which you advertise as described above, and pay per call.

For an API or MCP server, that's all you need: only software calls them, and the secret header makes sure that software comes through the gateway.

When bots scrape your website instead

Some bots will ignore your signposts and read your normal web pages. If you want them to use your paid API instead, your website has to recognise them and answer differently. These are the ways to recognise a bot, strongest first:

Signed requestsSome agents cryptographically sign their requests (the emerging Web Bot Auth standard). These can't be faked. Your CDN or bot-protection service checks them for you.
Published addressesMajor AI companies publish the IP ranges their crawlers use. A request from those ranges really is that company's bot.
User agentHonest bots name themselves, e.g. GPTBot, ChatGPT-User, ClaudeBot, Claude-User, PerplexityBot, CCBot. This is easy to fake, so treat it as a hint and check each company's published list.
BehaviourSpeed, volume and missing browser features. This catches hidden scrapers but is never certain. Use it to show a challenge, not to charge.

Bots that identify themselves are the ones that will pay, so point those to your gateway. Bots that hide won't pay anyway, so block or challenge them. Here's a simple example for an Express website that sends recognised AI bots to your paid API instead of serving the page:

const AI_BOTS = /GPTBot|ChatGPT-User|OAI-SearchBot|ClaudeBot|Claude-User|PerplexityBot|CCBot/i;
const GATEWAY = "https://permit402.com/g/forecast-co";

app.use("/forecasts", (req, res, next) => {
  if (!AI_BOTS.test(req.get("user-agent") ?? "")) return next(); // people: carry on
  res.status(402)
     .set("Link", `<${GATEWAY}/llms.txt>; rel="describedby"`)
     .json({
       message: "This data is available to AI agents through our paid API.",
       api: GATEWAY,
       how_to_pay: `${GATEWAY}/llms.txt`,
       prices: `${GATEWAY}/.well-known/x402`,
     });
});
A user-agent check is a starting point, not protection: a bot can pretend to be a browser. If your site is behind a CDN or bot-protection service, use its verified-bot features instead. The In your app package, coming soon, will include this as a ready-made option.

Reading your dashboard

Choose a period at the top: the last 7, 30 or 90 days, or all time. The Your gateways page adds up every gateway. Each gateway's page shows these numbers:

EarnedUSDC actually paid to your wallet. Live earnings are real money. Test earnings, from the Base Sepolia test network, are counted separately and are worth nothing.
Paid callsCalls that were paid for and succeeded.
QuotesTimes an agent was told the price (a 402). Agents often ask for a price first and pay on the next try, so this is usually higher than paid calls.
RatePaid calls as a share of quotes. A low rate can mean your price is too high, or that agents are only browsing.
Failed, not chargedPaid attempts where your API returned an error, so the payment was never taken. If this grows, check your API.
Payments rejectedPayments the gateway refused: invalid, for the wrong amount or network, already used once (a replay), or failed to settle. Nobody was charged.
Free calls / BlockedRequests that matched no price, either passed to your API free or refused, depending on your setting.
Agents reading your listingReads of your gateway's llms.txt and price list. It's a sign of interest from agents and the tools that index them.

By endpoint breaks all of this down per price, so you can see which endpoints or tools earn. Changing a price's amount keeps its history. Changing its method or path starts a new row.

Download payments (CSV) exports every payment in the chosen period, with time, amount, payer wallet and a link to the receipt on the blockchain, ready for a spreadsheet or your accountant.

The dashboard can't see agents calling your API directly and being refused by your secret-header check. That happens on your own server, so check your server logs for it.

MCP servers

Choose An MCP server when creating the gateway, and point it at your server's Streamable HTTP endpoint, e.g. https://mcp.yourcompany.com/mcp. Then price tools by name instead of paths:

ToolPrice
radar_image$0.10
history_*$0.05 (wildcards work)
  • In tools/list, agents see the price added to each paid tool's description.
  • Calling a paid tool without paying returns the price. x402 MCP clients then pay inside the tool call (_meta["x402/payment"]) and get a receipt back in the result.
  • The payment only settles if the tool succeeds. A tool error means no charge.
  • Batched JSON-RPC requests aren't supported. Send one request at a time.

What agents see

  1. The agent calls a paid URL and gets 402 Payment Required, with the price in the PAYMENT-REQUIRED header: amount, network, your wallet and the payment scheme.
  2. It signs a USDC payment and retries with a PAYMENT-SIGNATURE header.
  3. The gateway checks the payment, calls your API, and settles only if your API answers with a status below 400. The receipt comes back in PAYMENT-RESPONSE.

Each payment buys exactly one call: replaying it is refused. Agents can discover your prices for free at <your gateway URL>/.well-known/x402.

Headers and limits

Your API receives

x-permit402-secretYour gateway's secret. Reject requests without it.
x-permit402-gatewayThe gateway's name in the URL.
x-permit402-payerOn paid calls, the wallet address that paid.
Everything elseThe agent's other headers, method, path, query and body are passed through. Cookies and payment headers are removed.

Agents receive

Your responseStatus, headers and body as your API sent them, except that Set-Cookie is removed and the response is sandboxed so it can't run scripts on our domain.
x-permit402-chargedtrue or false on paid routes.
PAYMENT-RESPONSEThe settlement receipt, when charged.

Limits

Request body10 MB
Your API's response time60 seconds
Gateways per account10 during the beta
Price changesReach every location within a few seconds

Questions

Do you hold my money?
No. Payments go from the agent's wallet straight to yours. Permit402 never holds funds.
What does it cost?
Nothing during the beta, and we don't take a cut of payments.
What if my API is down or returns an error?
The agent isn't charged. A payment only settles when your API returns a status below 400.
Can I pause charging?
Yes. Pause in the dashboard stops the gateway within a few seconds. Resume brings it back.
I lost my admin key.
Keys can't be recovered because we only store a fingerprint of them, so keep yours in a password manager. If you think it has leaked, sign in and press Change admin key: the old key stops working straight away.
Which agents can pay?
Anything that speaks x402 version 2: the official x402 SDKs, x402 MCP clients and agent wallets built on them.