Plans & Variants
How a sellable plan is put together — variants, credit grants, and what retiring one actually does.
Quick take
- Customers subscribe to a variant, never to a plan
- The variant carries billing cycle, billing mode, trial days, and the overdue settings
- Credit grants and entitlements attach to the variant
grant_intervaltakes a keyword or an ISO 8601 duration likePT5H— minimum 5 minutes- Retiring stops new subscriptions; existing ones keep running untouched
Plans & Variants
A plan is the thing you sell. A variant is one way to buy it. Everything a customer actually gets — credits, trial length, billing cycle — hangs off the variant, not the plan.
The shape
Plan "Pro"
├── Variant monthly, prepaid, 14-day trial
│ ├── Credit grant 50,000 credits every billing_cycle
│ └── Entitlements seats: 10, api_access: true
└── Variant yearly, prepaid, 14-day trial
├── Credit grant 700,000 credits every billing_cycle
└── Entitlements seats: 25, api_access: true
Customers subscribe to a variant, never to a plan. The plan is the name on the box.
The plan
A plan holds very little: a name, a status, and whether it is your default.
| Field | Meaning |
|---|---|
name | What you call it. |
status | active or retired. |
is_default | The plan new customers land on when you have not chosen one. |
You cannot retire your default plan. Make another plan the default first, then retire the old one.
The variant
The variant carries the commercial terms.
| Field | Meaning |
|---|---|
billing_cycle | daily, weekly, monthly, yearly, or one_time. |
billing_mode | prepaid (credits up front) or postpaid (usage billed after). |
trial_days | Days of trial. Above zero, a new subscription starts in trialing. |
renewal_due_days | How long a renewal can sit unpaid before the subscription goes overdue. |
grace_period_days | How long an overdue subscription keeps working. |
allow_usage_while_overdue | Whether an overdue customer can keep spending. |
status | active or retired. |
Credit grants
A grant is a standing instruction: give this customer this many credits, this often.
| Field | Meaning |
|---|---|
credits | Millicredits per grant. |
grant_interval | How often. See below. |
grant_type | recurring, one_time, or trial. |
expires_after_seconds | How long each granted block lasts. Empty means it never expires. |
accumulation_cap | The most that can pile up unspent. |
rollover_percentage | How much unspent credit carries into the next period. |
max_rollover_cycles | How many periods credit can keep rolling. |
Grant intervals
grant_interval takes one of five keywords:
dailyweeklymonthlybilling_cycle— grant on each renewal, matching the variant’s cycleon_activation— grant once, when the subscription starts
Or it takes an ISO 8601 duration, which is any value starting with P:
| Value | Means |
|---|---|
PT5H | Every 5 hours |
PT4H | Every 4 hours |
P3D | Every 3 days |
P1W | Every week |
Custom intervals exist for products that refill on a clock rather than a calendar — a five-hour usage window, for example. The smallest allowed custom interval is 5 minutes. Anything shorter is rejected, because it would turn the scheduler into a hot loop.
Anything that does not start with P and is not one of the five keywords is rejected.
Entitlements
Grants give credits. Entitlements give everything else: seat counts, feature flags, fixed limits. They attach to the variant too.
That is its own topic — see Plan-Variant Entitlements.
Retiring a plan or a variant
Set status to retired. Here is exactly what that does, and what it does not do.
It stops new subscriptions. Subscribing to a retired variant is refused. This is the point of retiring: the plan is no longer for sale.
It does not touch existing subscriptions. Customers already on that variant keep their subscription, keep their grants, and keep renewing. Nothing is cancelled and nothing is migrated. If you want existing customers moved, move them yourself with an upgrade or downgrade.
It does not delete anything. The plan, its variants, and its grants all still exist. Retiring is a visibility change, not a deletion.
The catalog is shared across environments
This is the part that catches people. Plans, variants, and grants have no environment. There is one copy, and both sandbox and live read it.
Retire a plan while testing in sandbox and you have retired it in live. Change a grant amount in sandbox and live customers get the new amount on their next renewal.
Read Environments & the Shared Catalog before you edit a plan you did not create today.
Building one
The order matters, because each step attaches to the one before it.
- Create the plan.
- Add a variant to the plan.
- Add a credit grant to the variant.
- Add entitlements to the variant.
- Subscribe a customer to the variant.
The dashboard walks this in one flow under Plans. Every step is also a single API call if you would rather script it.
Common mistakes
Don't expect retiring a plan to move or cancel its subscribers
Retiring only stops new subscriptions. Existing customers keep their subscription and keep renewing. Migrate them yourself with an upgrade or downgrade.
Don't edit a plan in sandbox to see what happens
The catalog is shared. There is one copy of every plan, variant, and grant, and live reads the same row you just changed.
Don't use a custom grant interval shorter than 5 minutes
It is rejected. Anything faster would turn the grant scheduler into a hot loop.
Don't try to retire your default plan
It is refused. Make another plan the default first, then retire the old one.
Loading…