Skip to main content

Map your pricing to a policy

Start from your pricing page, or the one you want. Every line on it maps to a piece of a policy.

The pricing page​

Starter (free)Team ($49/mo)Enterprise
Projects3UnlimitedUnlimited
AI assistant50k tokens a month2M tokens a month, then $20 per millionContract
Seats15 included, $12 per extra seatContract
API100k requests a monthContract
CSV exportYesYesYes
PDF exportYesYes
SSOYes
Token packs1M tokens for $15

Step by step​

  1. List what you count. Each countable thing is a credit: projects, AI tokens, seats, requests. Put the price on the credit when you charge for it past an allowance, and the cost when it costs you something. When a model's input and output are priced differently, give each its own credit (sonnet_input, sonnet_output); see AI costs per model.
  2. One plan per column. The plan customers get by default gets default: true.
  3. One entitlement per row. Use the same entitlement name in every plan, so your code doesn't care which plan a customer is on.
    • A Yes (a feature) is an entitlement with no limit.
    • A number is a limit. Pick the mode: hard when the plan stops there, soft when usage past it is billed, observe when it's only tracked.
    • Unlimited is a feature (no limit), or an observe limit when you still want to count it.
    • A blank is no entitlement in that plan: the call is denied.
  4. Monthly allowances reset. resets: true, reset_sch: 'monthly:1' for calendar months, or reset_inc: 30days for 30 days from first use.
  5. The plan fee is a subscription entitlement metered in a credit priced at the fee. See Plan fees.
  6. Packs are topups.
  7. Enterprise is usually a plan with generous limits that you adjust per customer with overrides and gives, rather than a plan per customer.
  8. Protection you don't sell (a rate limit, an abuse ceiling) can share the row's entitlement when the two limits are the same, or get an entitlement of its own when they differ. See Rate limits.

The policy​

policy: {
credits: {
project: { label: 'Project' }
// You charge $20 per million tokens, and they cost you $8 per million.
ai_token: { label: 'AI token', price: { amount: 0.00002 }, overhead_cost: 0.000008 }
seat: { label: 'Seat', price: { amount: 12 } }
request: { label: 'API request' }
team_month: { label: 'Team plan, monthly', price: { amount: 49 } }
}
plans: {
starter: {
label: 'Starter'
default: true
entitlements: {
projects: { limit: { credit: 'project', value: 3 } }
ai_assistant: {
limit: {
credit: 'ai_token', value: 50_000
resets: true, reset_sch: 'monthly:1'
}
}
seats: { scope: 'org', limit: { credit: 'seat', value: 1 } }
export_csv: {}
}
}
team: {
label: 'Team'
entitlements: {
subscription: {
limit: {
credit: 'team_month', mode: 'soft', value: 0
resets: true, reset_sch: 'monthly:1'
}
}
// unlimited, still counted
projects: { limit: { credit: 'project', mode: 'observe', value: 0 } }
ai_assistant: {
limit: {
credit: 'ai_token', mode: 'soft', value: 2_000_000
resets: true, reset_sch: 'monthly:1'
}
}
seats: { scope: 'org', limit: { credit: 'seat', mode: 'soft', value: 5 } }
api: {
limit: {
credit: 'request', value: 100_000
resets: true, reset_sch: 'monthly:1'
}
}
export_csv: {}
export_pdf: {}
}
topups: {
tokens_1m: { credit: 'ai_token', value: 1_000_000, price: { amount: 15 } }
}
}
enterprise: {
label: 'Enterprise'
hidden: true
entitlements: {
projects: { limit: { credit: 'project', mode: 'observe', value: 0 } }
ai_assistant: {
limit: {
credit: 'ai_token', mode: 'soft', value: 20_000_000
resets: true, reset_sch: 'monthly:1'
}
}
seats: {
scope: 'org'
limit: { credit: 'seat', mode: 'soft', value: 50 }
}
api: {
limit: {
credit: 'request', mode: 'soft', value: 5_000_000
resets: true, reset_sch: 'monthly:1'
}
}
export_csv: {}
export_pdf: {}
sso: {}
}
}
}
}

Your code is the same for every plan:

await limitr.ensureCustomer(orgId, 'team', 'org');
// On their org's plan
await limitr.ensureCustomer(userId, '', 'user', name, [orgId]);

if (!(await limitr.allow(userId, 'projects', 1))) return upgrade('projects');
if (!(await limitr.allow(userId, 'export_pdf'))) return upgrade('export_pdf');

Pricing models​

ModelIn a policy
Usage-based (pay for what you use)A soft limit with value: 0: every unit is billed at the credit's price.
AI usage per modelA credit per model and direction, each billed at its own price. See AI costs per model.
Allowance plus overageA soft limit at the allowance, resetting monthly. Bill meter-overage.
Hard caps per tierHard limits; the upgrade is the way past them.
SeatsA seats entitlement with scope: 'org', increment on invite and decrement on removal. See Seats.
Prepaid creditsLimits at 0, priced credits, and a shared credit granted by topups. See Prepaid credits.
Flat feeA subscription entitlement priced at the fee.
Volume discountsA credit with tiered, volume, or stairstep pricing.
HybridAny mix of the above in one plan: a fee, seats, and metered AI usage.
Spend limitsSpend caps, per customer or shared across an org.
Free trial of a featureA give with an expiry.

Before you ship it​

  • Validate it: Limitr.new throws on mistakes, and valid() checks it in CI.
  • Test it: write the behavior you expect as tests.
  • Check its margin: marginSnapshot(plan, usage) prices hypothetical usage for a plan (Cost and margin).