npm packages are not installable yet: [email protected] can be published after 2026-09-16 10:30 UTC. Details
Public Beta — early access

Every call,
paid for.

Tollstile is open-source payment middleware for APIs and MCP tools. Price a route in one line, accept any 402 protocol, and keep every receipt in your own database.

$ npx create-tollstile
app/api/generate/route.ts · your existing app+4 −2
import { NextResponse } from "next/server";
import { paid } from "@tollstile/next";
import { toll } from "@/lib/toll";

export async function POST(request: Request) {
export const POST = paid(toll.price("$0.04"), async (request) => {
  const result = await generate(await request.json());
  return NextResponse.json(result);
}
});

Two imports and one wrapper. The body of your route handler stays as it is.

gate
closed
ledger state
— (the quote is signed, not stored)

Challenge. No payment yet. One signed quote, bound to this request, offered on every rail you accept.

HTTP/1.1 402 Payment Required {  "error": { "code": "payment_required", "action": "pay" },  "price": "$0.04",  "accepts": [{ "rail": "x402" }, { "rail": "mpp-stripe" }]}

Simplified exchange. Real challenges follow each rail’s specification. Run the real thing on demo.tollstile.com.

Seven parts, one gate.

Protocols decide how a payment is proven. Everything around that — who pays, when money moves, what happens when your handler fails — is what every merchant ends up building. Tollstile is that part.

  1. 01

    Price

    A signed quote fixes it. Never the client.

    toll.price("$0.04")
  2. 02

    Access

    Decide who has to pay at all.

    access: [subscriber(), …]
  3. 03

    Verify

    Check the proof on any rail you accept — once.

    rails: [x402(…), mppStripe(…)]
  4. 04

    Settle

    Choose when money moves, out loud.

    flow: "authorization"
  5. 05

    Fulfill

    Mark the moment the service actually exists.

    payment.fulfill()
  6. 06

    Refund

    Handler failed? Release or refund. Never twice.

    automatic
  7. 07

    Record

    Every transition, in your own database.

    ledger: postgresLedger(…)

The whole policy fits next to the handler.

tools/generate-image.ts@tollstile/mcp
import {
  createTollstile, subscriber, credits, payPerCall, limit,
} from "tollstile";
import { paidTool } from "@tollstile/mcp";
import { x402 } from "@tollstile/x402";
import { mppStripe } from "@tollstile/mpp";
import { postgresLedger } from "@tollstile/postgres";

const toll = createTollstile({
  rails: [x402(x402Options), mppStripe(stripeOptions)],
  ledger: postgresLedger({ query, transaction }),
  secret: process.env.TOLLSTILE_SECRET,
});

paidTool(server, "generate_image", { inputSchema },
  toll.price("$0.04", {
    access: [
      subscriber({ active }),
      credits({ balance }),
      payPerCall(),
    ],
    require: [limit({ spendPerDay: "$20" })],
  }),
  async (input, { payment }) => ({ content: await generateImage(input) }),
);
  1. L10

    Rails

    How agents can pay. Add or remove one without touching a handler.

  2. L11

    Ledger

    Where the truth lives. Your database, your schema.

  3. L16

    Price

    Declared by the server, checked against every proof.

  4. L17

    Access

    Tried in order. Subscribers pass, credits draw down, the rest pay per call.

  5. L22

    Require

    Conditions every request must meet, like a daily spend cap per payer.

Rails, now and next.

Every rail declares what it can do. A route that needs a capability its rail lacks refuses to start.

Full roadmap
Payment rails
RailPays withUseTarget
testLocal rail402 → 200 without a walletv0.1
x402 exactStablecoinFixed price per callv0.1
mpp chargeStablecoin · cardOne payment per callv0.1
x402 uptoStablecoinAuthorize a ceiling, settle what ranv0.1
mpp sessionStablecoinMany calls, one channel (experimental)v0.1
l402LightningBitcoin over Lightningv0.1
kyapayStablecoinAgent identity with paymentv0.1

The fine print, printed large.

Tollstile guarantees

  • A priced handler never runs without granted access or a verified payment.
  • Retries, replays, and crash recovery never settle or refund twice.
  • Every transition is written to your ledger before it is acknowledged.
  • When an outcome is unclear, the payment is marked unknown and reconciled.

Tollstile does not promise

  • Your handler running exactly once.
  • The response reaching the client.
  • Recovering costs your handler already incurred.
  • How a rail’s provider behaves.

Stripe moves the money.
Tollstile works the gate.

Use Stripe, Coinbase, or any provider behind a rail. Tollstile sits in your app, decides who gets through, and keeps the record. It charges nothing and never holds funds.

How Tollstile compares

Open the gate.