Skip to main content
HomeLanding pagesHow to charge for AI agent services
LANDING PAGE

How to charge for AI agent services

7 min read·Last updated June 2, 2026

Charging is configured in the x402 adapter's pricing table, keyed by route. Each priced route gets an amount, a payToAddress, and a paymentRequestId; unpriced routes stay free. Put each distinct service on its own path to charge it differently, and the adapter returns a 402 and verifies the X-Payment header before the handler runs. Settlement is USDC on Base, per call.

What you will set up

A clear charging structure for an AI agent that sells one or more services, settled in USDC on Base. By the end you can charge a flat price for one service, charge different prices for different services, and run free routes alongside paid ones, all configured in one place. This page is about the mechanics of structuring charges, not the decision of whether to charge (that is how-to-monetize-ai-agent) or the full build (that is how-to-build-a-paid-ai-agent). The payment API product page is the broader reference.

The pricing table is the unit of charging

Everything about charging flows from one idea: the x402 server adapter charges by route, and the pricing table is where you declare what costs what. Each entry maps a METHOD path to a price, a payToAddress, and a paymentRequestId. A route in the table is paid; a route absent from it is free.

That single rule answers most charging questions. One price for everything on a path. Different prices mean different paths. A free tier is just routes you leave out of the table. There is no separate billing config, no per-customer plan, no metering engine, just a map of routes to prices that the adapter reads when it starts. Once you internalize that the table is the whole charging surface, structuring charges becomes a question of how you lay out your routes, which is a design decision you control completely.

Prerequisites

  • A Blockchain0x account with an agent created, so it has a wallet to receive into.
  • A sk_test_ key, the agent's wallet address (payToAddress), and a paymentRequestId for each priced route.
  • Node 18 or newer. The SDK targets >=18.
BASH
export B0X_API_KEY=sk_test_...
export B0X_PAYTO_ADDRESS=0x...

Charge for one service

Start with a single priced route. Register the adapter with one pricing entry.

TYPESCRIPT
import Fastify from "fastify";
import { createClient } from "@blockchain0x/node";
import { createX402Plugin } from "@blockchain0x/x402/server/fastify";

const sdk = createClient({ apiKey: process.env.B0X_API_KEY! });
const app = Fastify();

await app.register(createX402Plugin, {
  sdk,
  defaultNetwork: "testnet",
  pricing: {
    "POST /summarize": { amountUsdc: "0.02", payToAddress: process.env.B0X_PAYTO_ADDRESS!, paymentRequestId: "pr_summarize" },
  },
});

app.post("/summarize", async (req) => runSummarize(req.body)); // runs only once paid
await app.listen({ port: 8080 });

An unpaid call to /summarize gets a 402 quoting two cents; a paid call runs. That is charging for one service.

Charge different prices for different services

To charge different amounts, give each service its own route and its own pricing entry. The table holds as many as you need.

TYPESCRIPT
pricing: {
  "POST /summarize": { amountUsdc: "0.02", payToAddress: PAY, paymentRequestId: "pr_summarize" },
  "POST /research":  { amountUsdc: "0.10", payToAddress: PAY, paymentRequestId: "pr_research" },
  "POST /deep-report": { amountUsdc: "0.50", payToAddress: PAY, paymentRequestId: "pr_report" },
},

Now a cheap summary, a mid-priced research call, and an expensive deep report each charge their own amount, and each quotes its own price in its 402. This is how you express tiers: not a plan a caller subscribes to, but a set of routes priced to match the work each one does. Price each route from its real cost and value, the way how-to-monetize-ai-agent describes, and let callers pick the route that fits their need.

Run a free tier alongside paid

A free tier is routes you leave out of the pricing table. Keep discovery, health, and any cheap helper on unpriced paths so callers can find and evaluate the agent without paying.

TYPESCRIPT
app.get("/capabilities", async () => listServices()); // free: never in the pricing table
app.post("/summarize", async (req) => runSummarize(req.body)); // paid

This freemium shape is the one that converts: callers reach the free routes, see what the agent does, and pay only for the premium work. Gating discovery behind a charge is the most common way to lose callers before they ever pay, so keep the front door free.

Design routes around what you charge for

Because charging is per route, the way you lay out routes is the way you structure your pricing, so design them on purpose rather than by accident.

A good rule: one route per unit a caller would think of as one purchase. If a caller would say "I bought a summary" or "I bought a research report", each of those is a route. Do not bundle a cheap and an expensive operation onto one path, because you can only put one price on it and one of them ends up mispriced. Equally, do not split a single logical purchase across two paid routes, because then a caller pays twice for what they think of as one thing and feels nickel-and-dimed.

Watch out for routes whose cost varies wildly with input. A summarize route that costs a fraction of a cent on a paragraph but dollars on a book is hard to price as one number. Either cap the input so the cost stays in a tight band, or split it into a standard route and a large route at different prices. The goal is that every priced route has a cost you can predict well enough to set a fair price, because a route you cannot price confidently is one you will either lose money on or overcharge for.

Confirm and test

Test the charging structure on Base Sepolia before going live. For each priced route, call it with no payment and confirm the 402 quotes the right amount; then pay it from a test wallet and confirm the handler runs. Confirm the free routes return without a 402. Watch the payment.received events to see which services actually earn.

TYPESCRIPT
import { webhooks } from "@blockchain0x/node";
// in a raw-body webhook route:
const r = webhooks.verify({ headers: req.headers, rawBody: req.body, secret: process.env.B0X_WEBHOOK_SECRET! });
if (r.ok && r.eventType === "payment.received") recordEarning(JSON.parse(req.body.toString("utf8")));

When every route charges what you intended and the free routes stay free, swap to a sk_live_ key for Base mainnet and re-check the prices and wallet address on the live agent.

What the caller sees

It helps to picture the charge from the other side. A caller hits your priced route, gets a 402 that quotes the exact amount, network, and payee, settles it from their wallet, and retries with an X-Payment header to get the result. They never fill in a form, create an account, or store a card. From their runtime's view, your service is a route that costs a known amount per call, and paying it is one automatic step. That simplicity is the reason per-call charging reaches callers a signup funnel never would: the cost to a new caller of trying your service is one small, automatic payment rather than an onboarding flow.

Common pitfalls

Three traps when structuring charges.

One price for genuinely different work. Putting a cheap summary and an expensive report on the same path forces one price on both, so one subsidizes the other. Split them into routes.

Gating the free tier. Discovery and evaluation routes belong outside the pricing table. Charging for them costs you callers who would have paid for the real work.

Treating per-call as per-outcome. The adapter charges per request, so shape routes around units of value. If one call does wildly variable work, split it so each route's price matches its cost.

What to ship today

Register the adapter with one priced route, confirm an unpaid call gets the right 402 and a paid call runs, then add a second route at a different price to express a tier. Keep discovery free. Watch payment.received to see what earns. For pricing strategy, see how-to-monetize-ai-agent; for the full build, how-to-build-a-paid-ai-agent. Pricing for the platform is on the pricing page.

FAQ

Frequently asked questions.

How do I charge different amounts for different services?

Put each service on its own route and give each its own entry in the pricing table. Pricing is keyed by METHOD and path, so POST /summarize at one price and POST /research at another are two entries. Everything on one path shares one price, which is why distinct services get distinct paths.

Can I charge per outcome instead of per call?

The adapter charges per request to a priced route. To approximate per-outcome pricing, shape your routes so each represents a unit of value: a route that returns a finished report is one paid call for that outcome. For variable work, split it into routes whose prices reflect their cost, rather than trying to meter inside a single call.

Do callers need an account to be charged?

No. With x402 any caller whose runtime speaks the protocol pays per request with no signup. The 402 your route returns quotes the exact price; the caller settles and retries. You charge callers you never onboarded, which is what makes per-service charging reach a wide market.

Which network and token does it settle in?

USDC, 6 decimals, on Base. Use a sk_test_ key for Base Sepolia (eip155:84532) while building and a sk_live_ key for Base mainnet (eip155:8453) when you ship. Amounts are quoted in USDC decimals that the adapter converts to amountWeiUsdc. The only scheme is exact-usdc.

How do I change a price later?

Edit the entry in the pricing table the adapter reads at registration and redeploy that small config. There is no migration; the next 402 quotes the new amount. Keep changes gradual and watch the conversion from 402 to settlement so you can tell whether a price move helped or hurt.

Create your free agent wallet in 5 minutes.

First payment confirmed in under ten minutes. Free to start.