SaaS Stack
← All updates

Usage-based billing, in v1.2.0

The second feature after v1 is out. SaaS Stack can now charge for usage as well as for plans: so many AI messages, exports or API calls included each month, then a price for each one beyond. It works with Stripe and with Polar, and it is tagged v1.2.0.

Why usage

A flat price fits most features. It does not fit the ones that cost you each time someone uses them, like a call to a language model. Charge too little and heavy users cost you money; charge everyone for the heaviest user and you lose the light ones. An allowance with a price beyond it is the usual answer, and it is fiddly to build: counting, the billing period, the provider’s meters, retries, and not charging twice.

What you get

  • Declared on the plan: usage: { aiMessages: { included: 500, pricePerUnit: 2 } } next to the plan’s price and features. bun run billing:sync creates the meter and the metered price at Stripe or Polar.
  • One call from any module: usage.record(workspace.id, 'aiMessages'), before doing the work. Past an allowance that cannot be exceeded, it answers 402 with a sentence saying when more are available, so a refusal costs you nothing.
  • Only the overage reaches the provider, through the job queue, so none is lost when the provider is down, and each unit is charged once even if a report is sent twice.
  • Monthly allowances on every plan, yearly ones included, lined up with the subscription’s invoices.
  • Usage on screen: the overview, the billing page and the assistant show what is used this month, in the web app and the mobile app. The pricing page and plan picker say what each plan includes.
  • The assistant metered per message: Pro includes 500 a month, then 2¢ each; Business 2,000, then 1¢. Change the numbers in one place.
  • A new skill, meter-usage, so your coding agent adds a meter of its own the same way.

The allowance is decided by the API, not the provider, so it behaves the same with Stripe and Polar. See Charge for usage to use it, and Billing for how it works.

Upgrading

Merge v1.2.0, run bun run db:migrate, decide what you meter, and run bun run billing:sync. Subscriptions from before the release keep the prices they bought, so their usage is counted but not charged until you move them. UPGRADING.md has the full list, and your coding agent can apply it with the upgrade-kit skill.

Next

API keys: keys owned by a workspace, with a role and an optional expiry, accepted by every route under the same checks as a session, with API calls countable as usage. The roadmap has the order after that.

Get the next one by email

Only project updates. Unsubscribe with one click.