Bill preview API
GET /portal/businesses/:businessId/me/bill-preview — the only subscriber money surface; runs the invoicing engine and honors disclosure.
GET /portal/businesses/:businessId/me/bill-preview — the only subscriber money surface; runs the invoicing engine and honors disclosure.
The bill preview is a core API over the rating engine and the ledger. It uses the same window projection and posting reads that invoicing uses, so preview equals invoice by construction — there is no client-side bill math to keep in sync, and no per-unit price is exposed for a subscriber to recompute.
GET /portal/businesses/{businessId}/me/bill-preview
"1234567890" = $1.23456789). Never parse them as floats.recurringFeeCents is the subscription's recurring-price pin, in cents.The response shape is chosen by the served plan's spendPolicy.disclosure,
read from the release the subscription is actually served under. Any lookup
miss — no activated release for the plan, member absent from that release,
projection missing or hash-invalid — resolves to opaque, never to the
disclosing branch.
disclosure: "transparent" (default){
"currency": "usd",
"disclosure": "transparent",
"recurringFeeCents": 3000,
"windows": [
{
"windowId": "rw_2026_08",
"windowStart": "2026-08-01T00:00:00.000Z",
"windowEnd": "2026-09-01T00:00:00.000Z",
"chargeCount": 1842,
"ratedNanos": "18420000000"
}
],
"totals": {
"ratedNanos": "18420000000",
"fundedNanos": "10000000000",
"receivableNanos": "8420000000"
},
"allowances": [
{
"kind": "included",
"state": "AVAILABLE",
"remainingNanos": "0",
"heldNanos": "0",
"consumedNanos": "10000000000",
"expiresAt": "2026-09-01T00:00:00.000Z"
}
]
}
| Field | Meaning |
|---|---|
windows[] | One entry per rating window: engine-exact recognized total (per-event floors plus the window remainder). |
totals.ratedNanos | Sum of window totals. |
totals.fundedNanos | Rated value paid by funding buckets (ledger postings). |
totals.receivableNanos | Amount due through the settlement rail after funding (debits minus credits). |
allowances[] | Every bucket for the subject: kind, state, remaining / held / consumed nanos, expiry. |
ratedNanos − fundedNanos may differ from receivableNanos when refunds,
corrections, or true-ups have posted; the ledger is authoritative for each.
disclosure: "opaque"{
"currency": "usd",
"disclosure": "opaque",
"recurringFeeCents": 10000,
"allowances": [
{
"kind": "included",
"state": "AVAILABLE",
"expiresAt": "2026-09-01T00:00:00.000Z",
"display": {
"kind": "multiplier",
"allowanceUnits": 5,
"remainingUnits": "3.25",
"consumedUnits": "1.75"
}
}
]
}
No windows, no totals, no nanodollar balances — nothing a subscriber could
divide by a known request count to recover a rate. display is either:
{ kind: "multiplier", allowanceUnits, remainingUnits, consumedUnits } when the
bucket was authored with fs.display.multiplier({ factor }) — units are the
authored factor, remaining and consumed are two-decimal strings; or{ kind: "fraction", consumedBasisPoints, remainingBasisPoints } (0..10000)
when the plan authored no display.Amounts owed on an opaque plan surface through the invoice, not the preview.
@farthershore/farthershore-js exposes the preview as
fs.billing.getBillPreview() and the useBillPreview() React hook; render
either branch by switching on disclosure. Do not compute a bill from
usePlans() or usage rows — the catalog is not returned to subscribers, and a
client-side estimate can never match the ledger.
RoundingDifference — the customer never pays
more than the exact rational total.windows; they will be rated under the
release they were admitted under, never at today's price.