Entitlements
tmbilling knows what your customer pays for. Your application needs to know what they may do. Entitlements make that translation.
Instead of reading a plan id and keeping a hard-coded table of what each plan includes, your code asks one question and gets an answer.
Define a feature
A feature is a capability you gate on. Give it a key your code uses, and a type:
| Type | It holds | Example |
|---|---|---|
switch | On or off | sso, audit_log |
quota | A number acting as a ceiling | seats: 25, projects: 10 |
meter | A number consumed over the period | api_calls: 100000 |
/v1/businesses/{biz}/featuresGrant a feature on a plan
/v1/businesses/{biz}/products/{prod}/entitlementsAttaches a feature to a plan with a granted value — "Pro includes 25 seats". Keep your plan-and-feature matrix here, once, instead of in every service that needs it.
Override it for one subscription
/v1/businesses/{biz}/subscriptions/{sub}/entitlementsGives one subscription a different value from its plan — the negotiated exception, the customer you promised 50 seats on a plan that includes 25. Overrides are data, not a special case in your code.
Renew an allowance
A meter feature counts usage against its value. By default it counts the usage of the next
invoice. Give it a reset to count a window of its own instead: every N hours, days, weeks,
months, quarters, half years or years, from the subscription start or on the calendar (in the
business time zone), or never (all usage since the start).
{ "feature": "custom_styles", "value": "1", "reset": { "every": "month" } }
A subscription override can change the reset as well as the value. The check returns used (the
usage in the current window) and resets_at.
To renew the allowance with the plan credits, send the link instead of a schedule:
{ "feature": "custom_styles", "value": "1", "reset": { "same_as_credits": true } }
The link follows the credits. Each subscription uses the reset of the credits on its own price of the plan, so a later change to that price's reset changes the allowance too. A price with credits but no reset renews the allowance each billing term. A plan takes the link only when its active prices grant credits each period on one schedule: archived prices do not count. A new price, a price change or a restored price that gives the plan two schedules is refused while an allowance links to the credits. In the dashboard, Same as the credits sends the link and shows the schedule it follows. A schedule saved before the link existed stays a plain schedule.
A pause follows the same billing setting as the credits. When it moves the windows on by the paused time, a linked allowance renews at the same moment as its credits, and an allowance with its own schedule moves by the same rule: the open window runs on for the paused time. Otherwise the allowance windows do not move.
When a customer upgrades in the middle of a window, your billing settings decide the allowance: a new window starts at the upgrade (the default, so the full new allowance is available at once), the used count stays, or the limit is prorated over the window.
Ask what a subscription can do
/v1/businesses/{biz}/subscriptions/{sub}/entitlementsReturns the effective entitlements: the plan's grants with the subscription's overrides applied. Cache these per session.
/v1/businesses/{biz}/subscriptions/{sub}/entitlements/{key}/checkChecks one feature, optionally against a required amount — "does this subscription have at least 30 seats?". Call it at the point of the action, where you only need a yes or no.
if (plan === "pro") means editing every service the day you add a plan, rename one, or
grandfather a customer onto something custom.if (entitled("sso")) does not. The answer moves to the catalog, where changing it is a
configuration edit rather than a deploy.Related
Tax
Configure taxable regions and their component rates, select inclusive or exclusive pricing, handle withholding and exemptions, and see what an invoice records.
Analytics
One endpoint answers every number on a dashboard. Learn the measures, why a stock is not a flow, which unit a figure is in, and how a partial history says so.