Skip to main content
A grant is a single deposit of credits into a customer’s balance, from one source, with its own priority and (optionally) its own expiry. A customer’s balance is the sum of all their open grants — and when usage is deducted, UnitPay has to decide which grant to draw from first. That decision is the priority convention.

What a grant is

Every credit a customer holds arrived as a grant. Grants come from different sources and stack:
  • Plan grant — the recurring allowance from a plan (the Lovable “1,000 credits/month”), refilled each cycle.
  • Daily drip — a small plan-level grant that refills every day.
  • Rollover — unused balance carried over from a prior period.
  • Contract grant — the committed allocation on an SLG/enterprise contract.
  • Promotional — a one-off grant you issue by hand (referral reward, goodwill, coupon).
  • Package — credits the customer bought as a self-serve top-up. See Top-ups.
Each grant keeps its own record — its source, amount, remaining balance, and expiry — so you can always see exactly where a balance came from. This shows up as the per-grant breakdown behind a customer’s balance (see Wallets & the ledger).

The priority convention

When usage is deducted, grants are consumed in priority order — lowest number first. Priorities are configurable per credit_grant_rules; the defaults encode a sensible convention that differs slightly between PLG (self-serve) and enterprise:
PriorityGrant typePLGEnterprise
0Daily drip (plan-level)consume first
5Rollover (from expired contract)consume first
10Plan grant / Contract grantmain allocationcommitted spend
30Promotionalbefore packagesbefore packages
50Package (self-serve top-up)preserve as bufferoverflow
100Package (post-contract)dead last
The logic behind the numbers: burn the things that expire or reset soonest, and preserve what the customer paid cash for. Daily drips vanish tomorrow, so they go first. Purchased packages don’t expire and represent real money, so they sit at the back as a buffer.

FIFO within a priority

When two or more grants share the same priority, UnitPay breaks the tie FIFO:
expiresAt ASC  →  createdAt ASC
The grant that expires soonest is drawn down first; if two expire at the same time (or neither expires), the older grant goes first. This guarantees that a customer never loses credits to expiry while newer, longer-lived credits sit unused.
The same principle governs the dollar-side balance deduction order: shorter intervals before longer ones, so expiring allocation is always spent before permanent allocation.

How the sources stack

A single customer routinely holds several grants at once, and they draw down in convention order:
Example (PLG)
A customer has a daily drip (priority 0, 50 credits, expires tonight), a monthly plan grant (priority 10, 1,000 credits), and a package they topped up with (priority 50, 500 credits).

Usage burns the 50 drip credits first, then the 1,000 plan credits, and only touches the purchased 500 once everything cheaper-to-lose is gone — so the credits they paid for are the last to disappear.
Example (enterprise)
A contract customer has rollover from a lapsed contract (priority 5), their contract grant (priority 10), and overflow packages (priority 50, then 100). Rollover — which would otherwise expire — is consumed before the committed contract spend, and purchased packages absorb the overflow last.

See also

Credits overview

The full track → resolve → deduct → ledger path.

Wallets & the ledger

Where grants and deductions are recorded.

Denominations

Unit vs. fiat credits — and the rule never to mix them.

Top-ups

Where package credits sit in the deduction order.