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 creditsimport 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.
| Pack | Price | Credits | pack_id |
|---|---|---|---|
| $150 pack | $150 | 150,000 | booster_150k |
| $600 pack | $600 | 650,000 | booster_650k |
| $2,000 pack | $2,000 | 2,400,000 | booster_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-on | Price | resource key |
|---|---|---|
| Priority | $99 | billing.addon.priority |
| Slot | $19 | billing.addon.slot |
| Hook | $49 | billing.addon.hook |
| Period history export | $29 | billing.export.asset_period |
Related
Arena
The Arena — where a player's own call is locked before the outcome and graded against the house's frozen prediction. XP, ranks, quests, badges, the season and the board. Reads are free; plays follow the standard payment law.
Economy funnel
The operator report over the real economy funnel — question opened, free question consumed, decision run, call locked, call graded, XP, quest, badge, settled purchase and second paid run — plus the activation metric. Operator-only (x-admin-key); no user tracking.