Tollbridge Docs
API

Billing

Credits, the free allowance, booster packs and plan cycles — the ledger behind the price book.

Credits are the prepaid rail: one credit carries the credit_to_usd list-face anchor from GET /v1/pricing (single source — never restated here). Every paid endpoint accepts either an x402 payment or credits — send the x-tollbridge-payer header (the Base address holding the credits) instead of the PAYMENT-SIGNATURE header. When the balance cannot cover the call, the API answers with the standard x402 challenge plus detail.reason: "INSUFFICIENT_BALANCE" (balance, required_credits). A call that produces neither a decision nor a typed refusal reverses its debit.

:::warning Top-up rail unset on this deployment. Credit purchases require an x402 facilitator wired to this deployment; until one is configured the pack and plan routes advertise a challenge no client can settle. Do not treat them as the refill path. The working refill is an operator credit grant (POST /v1/billing/grants with the operator x-tollbridge-ops header; returns OPS_UNSET when no operator token is wired). The one-time free Scout tier still works. Read every draw, credit and reverse at GET /v1/billing/draws?payer= (newest first; a reversed debit carries reversed_at).

Per-call x402 is proven on Base mainnet. A paid ask settles end-to-end against the default facilitator (https://facilitator.payai.network, mainnet-capable, no credentials); override with TOLLBRIDGE_FACILITATOR_URL. Note the x402 foundation's public testnet facilitator does not register eip155:8453 and will reject a mainnet settle. :::

POST /v1/billing/scout (free)

The free allowance: your first 3 entry-tier questions are free per payer address — S01 Market regime, S05 Volatility expansion and S06 Funding anomaly, 1,000 credits each. One allowance per address, it never recharges, and a refusal never spends one of the three. Idempotent — a second call for the same payer returns the existing allowance.

curl -X POST https://api.tollbridge.app/v1/billing/scout \
  -H "Content-Type: application/json" \
  -d '{"payer": "0x0000000000000000000000000000000000000000"}'
# {"data": {"granted": true, "balance_credits": 3000}}   # 3 × 1,000 entry-tier credits
import httpx

r = httpx.post(
    "https://api.tollbridge.app/v1/billing/scout",
    json={"payer": "0x0000000000000000000000000000000000000000"},
).json()["data"]

GET /v1/billing/scout (free read)

Reports whether the free allowance is still available to a payer, alongside the balance. Never grants — the allowance itself stays the POST above.

curl "https://api.tollbridge.app/v1/billing/scout?payer=0x0000000000000000000000000000000000000000"
# {"data": {"payer": "0x…", "available": true, "balance_credits": 0, "credits_per_grant": 3000}}

GET /v1/billing/credits (free)

Balance and expiring lots for a payer — what the metering will actually spend.

curl "https://api.tollbridge.app/v1/billing/credits?payer=0x0000000000000000000000000000000000000000"
import httpx

bal = httpx.get(
    "https://api.tollbridge.app/v1/billing/credits",
    params={"payer": "0x0000000000000000000000000000000000000000"},
).json()["data"]  # {"balance_credits": ..., "lots": [...]}

POST /v1/billing/packs/{pack_id} (paid · per-pack price)

Buy a booster credit pack with x402 at the pack price (billing.pack.<pack_id> in GET /v1/pricing). Packs are priced at a premium on purpose — the plan effective rate always beats the pack rate. Credits land as a 60-day lot.

PackPriceCreditspack_id
$150 pack$150150,000booster_150k
$600 pack$600650,000booster_650k
$2,000 pack$2,0002,400,000booster_2m4

Pack purchases go on sale when Tollbridge opens; until then the route advertises a challenge this deployment cannot settle (see the warning above).

The response names both prices exactly: base_price_usd (and its backward-compatible alias price_usd) is the rung-0 list price, while current_price_usd is the amount the x402 challenge quotes at the current rung — the two are equal at rung 0 and diverge once the ladder turns. rung, currency and a settlement_note are returned alongside.

curl -X POST https://api.tollbridge.app/v1/billing/packs/booster_150k \
  -H "PAYMENT-SIGNATURE: <signed x402 payload>" \
  -H "Content-Type: application/json" \
  -d '{"payer": "0x0000000000000000000000000000000000000000"}'
# {"data": {"base_price_usd": 150, "current_price_usd": 187.5, "rung": 1,
#           "currency": "USDC", "settlement_note": "...",
#           "credits_added": 150000, "balance_credits": ...}}
import httpx

r = httpx.post(
    "https://api.tollbridge.app/v1/billing/packs/booster_150k",
    headers={"PAYMENT-SIGNATURE": payment_payload_b64},
    json={"payer": "0x0000000000000000000000000000000000000000"},
).json()["data"]

POST /v1/billing/plans/{plan_id} (paid · per-plan price)

Buy one billing cycle of a plan's credit allotment with x402 at the plan price (billing.plan.<plan_id> in GET /v1/pricing): Operator $99/150,000 credits, Desk $249/400,000, Desk Pro $499/1,000,000. Every plan is a 30-day cycle you top up yourself — no automatic renewal. The free Scout allowance is not rechargeable (PLAN_NOT_RECHARGEABLE). Recurring subscription billing (cards) is not deployed yet — stated honestly; the price book is live and the ledger is real, and plan purchases go on sale when Tollbridge opens.

curl -X POST https://api.tollbridge.app/v1/billing/plans/operator \
  -H "PAYMENT-SIGNATURE: <signed x402 payload>" \
  -H "Content-Type: application/json" \
  -d '{"payer": "0x0000000000000000000000000000000000000000"}'
import httpx

r = httpx.post(
    "https://api.tollbridge.app/v1/billing/plans/operator",
    headers={"PAYMENT-SIGNATURE": payment_payload_b64},
    json={"payer": "0x0000000000000000000000000000000000000000"},
).json()["data"]

TypeScript

import { Tollbridge } from '@tollbridge/sdk-typescript';

const toll = new Tollbridge({ baseUrl: 'https://api.tollbridge.app' });

const grant = await toll.billingScout({ payer });
const balance = await toll.billingCredits({ payer });
// paid calls on credits instead of x402:
const decision = await toll.decide(
  { asset: 'BTC', questionId: 'S02_liquidation_risk' },
  { payer, settleWith: 'credits' },
);

GET /v1/billing/draws (free read)

The payer-readable journal: every draw (debit), credit and refund, newest first, with the reverse stamp on a reversed debit.

curl "https://api.tollbridge.app/v1/billing/draws?payer=0x…&limit=50"
{
  "data": {
    "payer": "0x…",
    "count": 2,
    "draws": [
      { "id": 42, "kind": "refund", "amount": 1000, "reason": "ops:invalid_result", "ref": "refund:credits:<uuid>", "lot_id": 4, "created_at": "…", "reversed_at": null },
      { "id": 41, "kind": "debit",  "amount": -1000, "reason": "debit:decision.deep",  "ref": "credits:<uuid>",       "lot_id": 4, "created_at": "…", "reversed_at": "…" }
    ]
  }
}

POST /v1/billing/grants (operator only)

Operator grant and debit reverse, gated by the x-tollbridge-ops header (constant-time against the deployment's TOLLBRIDGE_OPS_TOKEN; OPS_UNSET when unset — never a public grant).

# restore a payer when the x402 rail cannot settle
curl -X POST https://api.tollbridge.app/v1/billing/grants \
  -H "x-tollbridge-ops: <operator secret>" -H "Content-Type: application/json" \
  -d '{"action":"grant","payer":"0x…","credits":100,"ref":"ops:topup-1"}'

# reverse a specific leaked debit (idempotent; never a second credit)
curl -X POST https://api.tollbridge.app/v1/billing/grants \
  -H "x-tollbridge-ops: <operator secret>" -H "Content-Type: application/json" \
  -d '{"action":"reverse","payer":"0x…","ref":"credits:<uuid>"}'

GET /v1/billing/rate-lock (free quote · payer header)

THE FOUNDERS' RATE (ADR-004 §2.3): a 12-month per-credit price lock, bought at the current rung's spot plus a +20% premium. The GET is the caller's quote — the locked rate while the lock lives, the ladder rate otherwise, plus the honest break-even math ("price certainty" language only, never an investment framing). Send X-Tollbridge-Payer: 0x….

curl https://api.tollbridge.app/v1/billing/rate-lock -H "X-Tollbridge-Payer: 0x…"

data: { quote, spot_usd_per_credit, lock: { sku, premium, months, purchase_usd_per_credit, break_even: { claim, turns_to_pay_off, note } } }.

POST /v1/billing/rate-lock (paid · x402 settles the fee)

Buy the lock for a payer: the fee is computed at purchase over the locked credits' spot (rate_lock_fee_usd), the lock is payer-bound and non-transferable. The fee IS the required payment — a first request returns the payment challenge at the exact fee, a settled request lands the lock (the response names the settling state honestly). Operators can issue the lock without a fee as an admin grant with the x-tollbridge-ops header (the same operator gate as the grants route; OPS_UNSET when no operator token is wired).

curl -X POST https://api.tollbridge.app/v1/billing/rate-lock \
  -H "X-Tollbridge-Payer: 0x…" \
  -H "Content-Type: application/json" \
  -d '{"credits": 150000}'

data: { credits, rung, fee_usd, locked_usd_per_credit, status: "settling" } (the admin-grant slot returns { granted: true, lock, … } with the lock already live).

MCP

Billing is REST/SDK-only in the v1 MCP catalog (the tools proxy intelligence + ledger reads 1:1 — stated honestly). Free price truth over MCP:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": { "name": "tollbridge_pricing", "arguments": {} }
}

Planned add-ons (not yet on sale)

Listed so the price book is complete; these go on sale when Tollbridge opens and are not purchasable today:

Add-onPriceresource key
Priority$99billing.addon.priority
Slot$19billing.addon.slot
Hook$49billing.addon.hook
Period history export$29billing.export.asset_period
  • Plan and pack economics: Pricing.
  • The x402 settlement flow: x402.

On this page