Skip to content
Loom Documentation

Credits And Billing

The ledger

Append-only. Entries are never updated or deleted — a correction is a new adjustment row, which keeps the whole history auditable.

Every write takes a row lock on the team inside a transaction, so two concurrent generations cannot both read the same balance and overspend. The denormalized teams.credit_balance is updated in the same transaction, so the two can never disagree.

CreditLedger::replayBalance() recomputes from history if you ever need to reconcile.

Reserve, then settle

A generation reserves credits before the provider is called and settles against real token usage afterwards:

  • Costs less than reserved → the surplus is refunded
  • Costs more → the shortfall is charged without a balance check; the work is already done, and a negative balance simply blocks the next run
  • Fails → the whole hold is released

Publishing is charged only when a build succeeds.

Gateways

Stripe for direct card billing. Paddle as merchant of record — it collects and remits international VAT, which is not a reasonable thing to build into a self-hosted script.

Both sit behind BillingProvider, so subscription handling, plan assignment and the monthly allowance behave identically whichever you configure.

Webhooks

Unauthenticated by necessity, so treated as hostile:

  • The signature is verified before the body is read as anything but bytes
  • Stale timestamps are refused, so a captured payload cannot be replayed later
  • Every event is recorded; a (provider, event_id) unique index makes a redelivery a no-op
  • An event that was received but never processed is retried — a failed handler is not silently swallowed

Point your gateway at POST /webhooks/stripe or POST /webhooks/paddle.

The allowance

Plan credits are granted once per billing period, keyed on the period start. A redelivered invoice webhook cannot double-grant — the single most expensive bug a billing integration can have.

Turning it off

LOOM_CREDITS_ENABLED=false removes metering entirely. A Regular licence keeps billing off regardless, since it covers one end product whose users are not charged.