AgentRail is a drop-in middleware plus a hosted control plane. The middleware detects AI agents,
gates each request by purpose, and charges per call over HTTP 402 (x402 USDC, AP2, or Bedrock);
the control plane holds your pricing, policies, payment rails, and shadow/live mode — change them
without a redeploy. This guide takes you from npm install to your first paid agent request.
The path: create a project (get an API key) → install the SDK → add one line to your app → set pricing in the dashboard → test → run in shadow → flip to live.
You'll need:
@agentrails/nextjs, @agentrails/cloudflare, @agentrails/hono) and ports for Python, Go, PHP, Ruby, Java, .NET, Rust, and Elixir share the same control plane — see all SDKs.Sign in to the dashboard with your work email — we send a one-time magic link, no password. Then create your first project (a name, optionally your site URL). A project owns your pricing, policies, payout wallet, analytics, and API keys.
On creation you're shown an API key (agr_live_…). It is shown once — copy it now and store it as the AGENTRAIL_API_KEY environment variable. This key links your running app to your dashboard.
A project can hold many keys — issue one per deployment, site, or service, and traffic is attributed per surface in your analytics.
Prefer another stack? The framework adapters and language ports (@agentrails/nextjs, @agentrails/cloudflare, @agentrails/hono, the Python/Go/Ruby/Java/.NET/Rust/Elixir SDKs, and @agentrails/mcp for MCP servers) all talk to the same control plane and dashboard.
Availability: the Node/Express SDK (@agentrails/sdk) is published today. The framework adapters and other-language ports are fully implemented and tested but not yet published to their registries (npm, PyPI, crates.io, …), and the MCP adapter is in preview. Check all SDKs for each one's current status.
Mount the middleware once. In hosted mode, pass only your API key — policies, pricing, payment rails, and shadow/live mode all come from the control plane.
That's the whole integration. The SDK auto-refreshes config from the control plane (no redeploy when you change pricing) and streams events — visits, blocks, payments, extractions — back to your dashboard. Within a few seconds the onboarding checklist auto-ticks Install and Integrate from the SDK's heartbeat.
Mount it before your routes. agentrail() returns standard Express middleware; the returned function also exposes .controlPlane (the hosted client) so you can call .controlPlane.stop() on a clean shutdown.
Hit a priced route as if you were an AI agent — declare a known crawler user-agent and a purpose:
In live mode you get 402 Payment Required with price headers and an x402 payment challenge. Humans (no agent signature) pass straight through — only detected agents are gated. That first gated request — the 402 and its blocked event — auto-advances the test step on your checklist.
In the dashboard, define policies — one per path pattern. A policy decides the price and which agent purposes are allowed.
| Field | Example | Meaning |
|---|---|---|
| Path pattern | /api/products/:sku | which resource this rule covers — exact, /api/reports/* prefix, or :param |
| Tier | metered | free · metered · premium |
| Price | 5 | cents per call (0 = free but still gated by purpose & mode) |
| Allowed purposes | ["browsing","answer"] | gate by why the agent is here — e.g. allow answering, block training |
Policies are versioned with one-click rollback, and changes reach your live SDK within seconds — no deploy. See Policies & purposes for the full reference.
To take real USDC over x402 (instead of the built-in demo rail), open Payouts in your project settings:
Start on Base Sepolia with the public testnet facilitator — real signed payments, no real money at risk — then switch to Base mainnet when you're ready.
Every project starts in shadow mode. Flip to live when your pricing looks right.
AgentRail observes and logs agent traffic and shows what it would charge. No 402s, zero risk. Run here for a day to sanity-check pricing against real traffic.
Flip the toggle and agents get a 402 + payment challenge, pay, and get access. Money flows (or is authorized) per your Payouts setting.
Roll out one priced route at a time. You can also pin mode in code with the mode option (see Configuration) — otherwise it's driven by the dashboard.
Every option accepted by agentrail(config). In hosted mode you typically pass only apiKey; the rest are for self-hosting and advanced control.
| Option | Type | What it does |
|---|---|---|
apiKey | string | Hosted mode. Project key (agr_live_…) — pulls policies/pricing/mode and streams events. |
controlPlaneUrl | string | Override the control-plane URL. Default https://app.agentrail.com. |
policies | object | Self-hosted. Static policy table, { "/path": { priceCents, purposeAllow, tier? } }. Merged under any hosted policies. |
validators | object | Self-hosted. Map of { rail: validatorFn } — see Self-hosted mode. |
validatePayment | fn | Single legacy validator (use validators for multi-rail). |
paymentMethods | string[] | Override the advertised X-Payment-Methods list. |
onEvent | fn | Called for every visit / blocked / payment / extraction event. |
treatPathAsAgent | fn | Mark paths as agent-only, e.g. p => p.startsWith('/api/agent/'). |
headerPrefix | string | Prefix for the SDK's response headers. Default X-AgentRail. |
mode | 'shadow' | 'live' | Force enforcement mode. Default: derived from the control plane. |
verifier | Verifier | false | Agent-identity verification (reverse-DNS + IP allowlist). Pass false to disable. |
After the middleware runs, req.agentrail carries the detection result for the request. Read it to branch your own logic, and call recordExtraction() to log what an agent pulled.
req.agentrail fields:
isAgent | boolean — classified as an agent (confidence ≥ 50). |
confidence | 0–100 detection score. |
identity | { operator, product, purpose, source } or null. source = how we knew (user-agent / self-declared / heuristic / endpoint-inferred). |
verified | strength of identity proof: rdns · ip-allowlist · signed · receipt · null. |
signals | human-readable reasons that contributed to the score. |
automationLikelihood | 0–1 "how automated does this look" score — catches stealth agents with browser-shaped UAs. |
recordExtraction(facts) | log what the agent extracted (array or string). No-op for humans. |
Path patterns come in three shapes:
/api/data/api/reports/*/api/products/:skuTiers: free (no charge, still gated by purpose & mode), metered (per-call price), premium (higher-priced resources). To block an agent, restrict the allowed purposes below — a request whose purpose isn't allowed is denied and logged as a blocked event.
Purposes describe why an agent is calling. Allow or deny each per policy:
* browsing answer training search-index extraction
["*"] allows any purpose. A common setup: allow browsing and answer, charge for them, and block training.
How agents are recognized, and what AgentRail sends back.
Agents are detected by known user-agent fingerprints, self-declared headers, MCP protocol signals, and behavioral heuristics. Two self-declared request headers are the emerging standard:
X-Agent-Identity | who the agent is, e.g. openai/chatgpt. |
X-Agent-Purpose | why it's calling — one of the purposes. |
On a priced request without valid payment, AgentRail responds 402 Payment Required with price headers (the required price and accepted X-Payment-Methods) and an x402 challenge in the body. The SDK's own informational headers use the X-AgentRail prefix (configurable via headerPrefix).
The 30-second mental model:
You only ever configure your receiving address. The agent brings and signs its own wallet — that separation is the point: you can monetize agents you've never met.
Supported rails: the built-in demo rail (no setup), x402 (Coinbase, on-chain USDC), AP2 (Google signed mandates), and AWS Bedrock agent payments. Hosted mode wires x402 for you; self-hosting lets you mix rails (see below).
Running a Model Context Protocol server? The MCP adapter gates tool calls with the same control plane:
A priced tool with no valid payment returns a structured "payment required" result carrying an x402 challenge; the agent pays in the call's _meta and retries. Works with Node and Python MCP servers.
The MCP adapter (@agentrails/mcp) is in preview and not yet published to npm — see all SDKs.
Don't want the hosted dashboard? Skip apiKey and pass your own policy table plus payment validators. The SDK runs entirely in your infrastructure — no calls home.
Builders for each rail: makeDemoValidator(), makeX402Validator(), makeAp2Validator(), makeBedrockValidator(). Each takes its own config (merchant address, payee id, region, keys). Provide a seenStore in production for replay protection that survives restarts.
Everything shows up in real time:
Traffic & revenue over time, plus a filterable event explorer.
Which deployment or language each agent call came from.
Who's hitting you (OpenAI, Anthropic, Perplexity, …), paying vs. blocked.
The structured facts agents pulled from your priced resources.
| Variable | Used by | Notes |
|---|---|---|
AGENTRAIL_API_KEY | Hosted mode | Your project key (agr_live_…). Passed to agentrail({ apiKey }). Keep it secret. |
AGENTRAIL_CONTROL_PLANE_URL | Optional | Point the SDK at a self-hosted control plane (same as the controlPlaneUrl option). Default https://app.agentrail.com. |
MERCHANT_WALLET | Self-hosted x402 | Your own convention — the public address passed to makeX402Validator({ recipientAddress }). |
No. You configure a public receiving address; the demo rail needs nothing. Real USDC is opt-in.
No — only detected agents are gated; humans pass through untouched.
Yes — pricing, rails, and shadow/live live in the dashboard and propagate in seconds.
17 known agents by fingerprint (OpenAI, Anthropic, Google, Apple, Meta, Perplexity, …), self-declared headers, MCP signals, and behavioral heuristics.
Not building yet? Join the waitlist and we'll be in touch.