Plans & Pricing

Plans bundle features and attach one or more prices. A plan can have monthly and yearly prices, seat‑based components, and usage‑based components. Subscriptions point to a specific plan version and an effective price.

When to use this

  • You’re designing product tiers (Free/Pro/Enterprise)
  • You need to mix base fees, per‑seat pricing, and usage overage
  • You want to publish plans in a pricing table and keep version history

Mental model

Think of a plan as the template. When a customer subscribes, we take:

  1. The plan’s features → copy them onto the subscription (source of truth)
  2. The chosen price → its components become the billing schedule
  3. Any usage‑based features → credits define what’s included; usage beyond that can bill overage

End of period, billing reads the price components, computes charges, and applies credits.

Pricing components

Lumen’s price DSL composes multiple components in a single price:

  • fixed: a flat fee per billing period
  • per_unit: per‑seat or per‑unit fee (supports minimum seats)
  • usage: metered usage priced via a metric (overage model)

Each component has its own recurrence rule (RRULE:), so you can bill different parts (e.g., base monthly, usage monthly, yearly seat bundles) independently.

Minimal shape (trimmed):

{
  "dsl_version": 1,
  "components": [
    {
      "type": "fixed",
      "label": "Pro - $29/month",
      "amount_cents": 2900,
      "recurrence_rule": "RRULE:FREQ=MONTHLY;INTERVAL=1"
    },
    {
      "type": "usage",
      "label": "API calls overage",
      "unit_label": "call",
      "metric_id": "met_...",
      "unit_cost_cents": 1,
      "recurrence_rule": "RRULE:FREQ=MONTHLY;INTERVAL=1"
    }
  ]
}

RRULE basics: FREQ=MONTHLY|YEARLY|WEEKLY|DAILY; avoid TZID; daily requires COUNT or UNTIL.

How billing works (from plan to invoice)

Here’s the life cycle for a typical subscription:

  1. Customer subscribes to a plan at a specific price
  2. The price’s components are scheduled (e.g., monthly base, monthly usage)
  3. During the period:
    • Your product emits events (e.g., api-call)
    • Metrics aggregate those events per customer
    • Credits provide “what’s included” for usage‑based features
  4. At billing time per component:
    • Fixed/per‑unit components post their amounts for the period
    • Usage components compare measured usage to credits
      • If linked credits cover usage → no overage line
      • If usage exceeds credits → an overage line is created from the usage component
  5. Invoices are generated with line items for each component; taxes and payment run afterward

Notes:

  • bill_immediately on a component charges when it’s added (e.g., seat increases) rather than waiting for period end
  • Each component maintains its own dates, so mixed monthly/yearly schedules work cleanly

Patterns you can ship today

  • Flat fee: single fixed component, monthly and/or yearly
  • Free allowance + overage: fixed or $0 base + usage component linked to a metric; allowance via credits
  • Seat‑based: per_unit with unit_label: "seat" (UI can scaffold seat metrics); optional minimum seats
  • Hybrid base + usage: combine fixed with usage for predictable base + pay‑as‑you‑go

Recurrence & cycles

Every component sets its own billing cycle via recurrence_rule. The system tracks component‑level details, so monthly and yearly items on the same price bill independently and appear as separate subscription detail rows.

Credits, allowances, and renewals

Credits define how much usage is included for numeric features. Two common setups:

  • Included allowance (no overage): Create usage credits for the feature but no usage price component. After credits are consumed, access is denied until renewal or more credits are granted.
  • Allowance + overage: Create usage credits and a usage price component. Credits cover the included amount; usage beyond credits is billed using the component’s unit_cost_cents.

Renewals can be tied to the billing cycle or to an RRULE on the credit definition. Expiry controls whether unused credits carry forward or reset. Trials are just temporary credit grants on a trial plan that auto‑migrates to the paid plan later.

UI vs API

  • UI (recommended): Create/Update Plan wires everything for you:
    • Creates the plan, prices (monthly/yearly), and attaches features
    • For usage features, creates metrics and credit definitions and links them correctly
    • Can surface the plan in Pricing Tables and set up trials
  • API: Create a plan, define prices with the DSL, define features/metrics/credits, and link them. Use this for mixed cycles, bespoke components, or migration tooling.

How the UI wires this

  • When you add a usage‑based feature and a usage price, the UI creates a metric (based on your event name), creates a plan‑scoped credit definition for the allowance, and links that credit definition to the usage price component with billing‑cycle renewals.
  • If you add a usage‑based feature without a usage price, the UI still creates the metric and a credit definition but uses an RRULE renewal (e.g., monthly) not tied to a usage component, resulting in a hard limit with no overage.
  • For seat‑based plans, the UI generates a seat‑count metric and uses per_unit components that reference that metric; minSeats and bill_immediately are applied as configured.

Versioning & migrations

  • Each change creates a new plan version; stablePlanId stays the same
  • Subscribers remain on their current version until migrated
  • Migrate with two strategies:
    • immediate (no price changes) – switch versions now
    • next_billing_cycle – schedule price‑mapped upgrades at renewal
  • Price mappings are required when target version uses different price IDs

Pricing Table integration

  • Enable “show in pricing table” to publish on your site
  • Display order is by lowest fixed price; enterprise plans are last
  • Buttons, badges, and “Contact Sales” behavior are configurable
  • Trial plans can show trial credit allowances alongside features

Trials

  • Create a trial plan linked to a parent plan
  • Trial credit allowances limit usage during trial; at end, auto‑migrate to the parent plan’s price and reset cycles

Common pitfalls

  • Missing metric on a usage component → overage can’t be computed
  • RRULE with timezone (TZID) → rejected; use pure UTC RRULE
  • Yearly options require their own yearly component; Lumen does not infer yearly from monthly
  • Forgetting credit definitions for usage features → entitlement checks won’t see included usage

See also