Mapping Your Pricing Model to a Policy
The first step.
The first real work in a Limitr integration isn't writing code — it's thinking. Before you call allow() or write a YAML file, you need to translate your existing pricing model into policy concepts.
This guide walks through that translation process. By the end you'll have a clear picture of what your credits, entitlements, and plans should look like, and why.
Limitr Cloud exposes an easier workflow for creating and maintaining credits and plans. That said, it's still important to map your pricing model with intention from the start — some things are easier to change than others once customers are running against a policy.
Start with what you're selling, not how you're enforcing it
The most common mistake is starting with enforcement code and working backward to the policy. That produces a policy that mirrors your current implementation — which means it inherits all the same problems: limits in the wrong place, credits that conflate different resources, plans that are hard to extend.
Start instead with two questions:
What does your product deliver? Not features, not plans — the actual unit of value customers consume. AI output, API calls, storage bytes, compute seconds, seats, reports. This maps to credits.
What are customers allowed to consume? What does each plan include? What happens at the boundary — do they get blocked or do they get billed? What resets, and when? This maps to entitlements and limits.
Answer both questions before you open the policy editor.
Identify your credits
Credits are the units your pricing is built on. Every limit is denominated in a credit. Every meter tracks consumption in a credit.
For each thing your product delivers, ask:
Discrete or abstract?
A discrete credit maps to something real with a known cost: an input token, a GPU second, a megabyte stored. It should have overhead_cost (what you pay the provider per unit) and price (what you charge per unit in overage). This is how Limitr tracks margin per customer.
An abstract credit is a conceptual unit your business or customers understand: "AI Credits", "messages", "compute units", "successful runs". It maps to discrete credits through the exchange table, and may or may not have a price.
Most products need both — one or more discrete credits per resource type, and optionally one abstract credit per customer-facing unit.
Should you split it?
The default instinct is to combine — "tokens are tokens", "API calls are API calls." This is almost always wrong for anything with meaningful cost variation.
Policies support hundreds of credits. It's easier to manage a policy with flexibility built in, which may mean a different discrete credit type per endpoint, per outcome, or per feature.
Split credits when:
- The cost profile differs (input tokens are 4x cheaper than output tokens for most models)
- The pricing model differs (tiered output, flat input)
- You want independent limits (cap Sonnet separately from Haiku)
- You need per-resource visibility in margin tracking
Don't split when the resource is genuinely uniform and you have no reason to treat its components differently.
Common splits that pay off:
| Split | Why |
|---|---|
| AI input / AI output tokens | Different cost, different price, often different limit logic |
| Storage / bandwidth | Storage accumulates; bandwidth resets monthly |
| Standard API / expensive API calls | Different cost profile, different plan access |
| Per-model credits | Different price points across models |
| Premium AI tools / standard workflows | Different context per workflow |
Map your plans
For each plan, work through every entitlement:
What does this plan include? The baseline allocation — 500,000 tokens/day, 5 seats, 1 GiB storage. This becomes limit.value.
What happens at the boundary?
| Mode | When to use it |
|---|---|
hard | Block immediately. No overage. Use for free tiers, trial limits, hard caps. |
soft | Allow overage and bill for it. Use for Growth and Enterprise plans where customers pay for what they use. A soft limit of 0 generates overage immediately. |
observe | Meter with no enforcement. Use for enterprise "unlimited" tiers, usage reporting, or to gain visibility before deciding to enforce. |
What resets, and when?
- Consumption metrics (tokens, API calls, compute time) reset. Set
resets: trueandreset_incto match your billing window. - State metrics (storage, seats) don't reset. Set
resets: false— the meter reflects what's currently in use.
Feature flag or metered resource? An entitlement with no limit is a boolean gate — the customer either has it or doesn't. Use this for feature access (pdf_export, sso, advanced_analytics) where the question is plan eligibility, not consumption.
A working example
Suppose your current pricing looks like this:
Starter — $49/mo: 500K AI tokens/day, API access, basic integrations Growth — $149/mo: 2M AI tokens/day, overage at $0.004/1K tokens, all integrations, priority support Enterprise — Custom: Unlimited tokens, custom limits, SSO, audit log, dedicated support
Credits
You're selling "AI tokens" — but tokens aren't uniform. Input and output have different costs. Split them:
credits:
ai_input:
overhead_cost: 0.000003 # $3/1M tokens (your cost)
pricing_model: flat
price: { amount: 0.000004 }
stof_units: int
resets: true
ai_output:
overhead_cost: 0.000015 # $15/1M tokens (your cost)
pricing_model: flat
price: { amount: 0.00002 }
stof_units: int
resets: true
Your pricing page says "$0.004/1K tokens" in overage — that's an average across input and output. You can honor that average by setting both credit prices to 0.000004, or split the price accurately. Accurate is better: it protects your margin as output ratios shift.
Plans
plans:
starter:
entitlements:
api_access:
description: API access # boolean flag — no limit
basic_integrations:
description: Basic integrations # boolean flag
ai_input:
limit:
credit: ai_input
mode: hard # Starter hits a wall — no overage
value: 500000
resets: true
reset_inc: 1day
ai_output:
limit:
credit: ai_output
mode: hard
value: 200000
resets: true
reset_inc: 1day
growth:
entitlements:
api_access:
description: API access
advanced_integrations:
description: Advanced integrations # Growth-only feature flag
ai_input:
limit:
credit: ai_input
mode: soft # Growth overages and gets billed
value: 2000000
resets: true
reset_inc: 1day
ai_output:
limit:
credit: ai_output
mode: soft
value: 800000
resets: true
reset_inc: 1day
enterprise:
entitlements:
api_access:
description: API access
advanced_integrations:
description: Advanced integrations
sso:
description: SAML/SSO # Enterprise-only flag
audit_log:
description: Audit log access # Enterprise-only flag
ai_input:
limit:
credit: ai_input
mode: observe # Meter everything, enforce nothing
resets: true
reset_inc: 1day
ai_output:
limit:
credit: ai_output
mode: observe
resets: true
reset_inc: 1day
Notice what happened: "Unlimited tokens" on Enterprise becomes observe mode — not a missing entitlement or an arbitrarily high limit. You still want the meter for margin tracking and Cloud dashboards. You just don't want enforcement.
In Limitr Cloud, you can create a pricing rule that overrides the cost of any credit for dynamic groups of customers — for example, any customer with metadata.account_type == "enterprise" gets 100% off AI input tokens for the next 42 days — without changing the plan or writing code.
The decisions that are hard to change later
Some policy decisions are easy to evolve — you can change a limit value or add a plan without touching your application code, especially with Cloud. Others require more upfront thought because changing them later affects customer state.
Credit granularity is hard to change. If you start with a single ai_token credit and later want to split input and output, every customer's meter is in the wrong unit. Design credits at the granularity you'll want for reporting and margin tracking, even if your current pricing page doesn't expose that detail.
Entitlement names are referenced in code. policy.allow(userId, 'ai_tokens') is in your request handlers. If you rename ai_tokens to ai_input later, that's a code change and a deploy. Choose names that are stable and specific enough to survive plan evolution. Credits evolve independently — you can always change the credit (and therefore the price) for an entitlement without touching code.
Hard limits on Growth are a trap. If your Growth plan has hard limits today but you want to introduce overage billing later, you'll need to change the limit mode. That's a policy change — easy with Cloud, but it affects all Growth customers immediately. Think about where you want the enforcement boundary before you ship.
The exchange table is additive. You can always add new credits and exchange paths. However, changing the value of an existing exchange pair affects how existing grants are drawn. Set customer-facing credit exchanges up correctly from the start.
Checklist
Run through this before you write the policy file:
- Every resource your product delivers is represented as a credit
- Resources with different cost profiles are separate credits
- Resources with different reset behavior are separate credits
- Every plan's limits are expressed as
hard,soft, orobserve— not just a value - Feature access is modeled as boolean entitlements (no limit), not high-value hard limits
- Enterprise "unlimited" is
observe(or a Cloud pricing rule), not a missing entitlement - Entitlement names are stable and descriptive enough to live in your codebase long-term
overhead_costvalues reflect real provider costs, not approximations
Once this list is clear, the policy file writes itself.