Farther ShoreDocs
Go to Farther Shore
Design and operate commerce
Entitlements vs economics
Cohorts & releases
Plan transitions
Connect Stripe
Subscriptions & usage
Plan changes
Billing strategies
Pricing catalogs
Funding & allowances
Economic agreements
Commercial releases
Bill preview API
Usage & billing policy
Ledger & settlement
Subscription + overage
Freemium that converts
Add a trial
Add a spend cap
OutcomePrerequisitesChange the planVerifyCommon failuresRecoverNext stepsAgent prompt
Change a price
Prepaid wallet
Meter AI tokens
commerce HTTP contracts
Status
Docs/Cookbook/Add a spend cap

Add a spend cap

Bound how much a plan's metered usage can cost — by funding it and blocking at zero.

Outcome

A plan has an explicit spend ceiling: metered usage draws down a fixed amount of value and the gateway denies further billable work at zero. Use this to limit a subscriber's — and your — exposure on metered plans.

Prerequisites

  • A meter and pricing catalog the plan binds
  • A chosen ceiling in dollars
  • Approval for a billing change

Change the plan

A spend cap in the new model is funding plus a block policy. Prepay (or include) exactly the value the subscriber may spend and set fs.exhaustion.block; the gateway reserves each request's economic maximum against that value before forwarding it, so the cap holds before the origin is called rather than after the invoice.

For a subscription that includes a fixed monthly usage budget and must stop there, use custom (an included bucket with block is not a hybrid shape, which requires overage):

ts
fs.plan("pro-capped", {
  kind: fs.plan.kind.custom,
  price: fs.money.usd(49).monthly(),
  usagePricing: tokenPricing.current(),
  funding: { buckets: [fs.included(fs.money.usd(200))] },
  spendPolicy: { onExhaustion: fs.exhaustion.block },
  grants: [chat],
  limits: [requests.perMinute(600)],
});

For a wallet the subscriber funds themselves, use prepaid with topUp: true — the cap is whatever they have paid for. Every route the plan can spend on must declare a bound (maxOutputUnits, chunkPolicy, or a post-stream settlementMax) so the reservation is finite; the compiler rejects an unbounded one.

Validate and test on preview:

bash
farthershore build --format json
git push -u origin HEAD:env/spend-cap-preview
farthershore business show acme --env spend-cap-preview --format json

Verify

Confirm the preview contract's pro-capped plan is kind: "custom" with a $200 included bucket and block exhaustion. Exercise usage near the cap with a preview subscriber: the bill preview's allowance remainingNanos falls with each request, and the first request that cannot be covered is denied credit_exhausted (402) before it reaches your origin.

Common failures

  • Build fails with PLAN_KIND_CONTROL_MISMATCH: hybrid requires exhaustion.overage; a blocking allowance is custom or prepaid.
  • Build fails with ADMISSION_OUTPUT_BOUND_REQUIRED: a route the plan can spend on has an unbounded measure — add maxOutputUnits.
  • Usage continues past the cap: the plan is overage, not block; read the release's spendPolicy.
  • Plan list is unchanged: the preview build may not have applied yet.

Recover

Revert the preview commit. If released, the new bucket amount applies to new issuances; existing subscribers keep their current-period bucket. Prepare and approve a forward correction.

Next steps

See billing strategies, funding & allowances, monetary admission, and plans.

Agent prompt

Give the metered pro plan a $200 monthly spend cap: a kind-custom plan with a $200 included bucket and exhaustion.block, every spend route bounded with maxOutputUnits. Validate in preview, prove the credit_exhausted denial, and require approval before release.

PreviousAdd a trialNextChange a price

On this page

OutcomePrerequisitesChange the planVerifyCommon failuresRecoverNext stepsAgent prompt