Skip to main content

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

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:

SplitWhy
AI input / AI output tokensDifferent cost, different price, often different limit logic
Storage / bandwidthStorage accumulates; bandwidth resets monthly
Standard API / expensive API callsDifferent cost profile, different plan access
Per-model creditsDifferent price points across models
Premium AI tools / standard workflowsDifferent 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?

ModeWhen to use it
hardBlock immediately. No overage. Use for free tiers, trial limits, hard caps.
softAllow 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.
observeMeter 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: true and reset_inc to 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.

Cloud pricing rules

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, or observe — 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_cost values reflect real provider costs, not approximations

Once this list is clear, the policy file writes itself.