Docs / plans
Configuring Plans
Plans are the core of your billing configuration. Each plan represents a pricing tier that customers can subscribe to.
Basic Plan Structure
plans: - id: pro name: Pro headline: For growing teams prices: monthly: { amount: 2900 } yearly: { amount: 29000 } limits: projects: 25 api_calls: 50000 features: - Up to 25 projects - Priority supportPlan Properties
| Property | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier (^[a-z][a-z0-9_]*$) |
name | string | Yes | Display name |
headline | string | No | Short tagline for pricing page |
description | string | No | Longer description |
type | enum | No | personal, team, or enterprise |
public | boolean | No | Show on pricing page (default: true) |
default | boolean | No | Mark as default plan |
trial_days | integer | No | Trial period in days |
prices | object | Yes | Pricing configuration |
limits | object | No | Entitlement values |
features | array | No | Marketing bullet points |
upgrades_to | array | No | Valid upgrade paths |
metadata | object | No | Custom key-value data |
Plan ID Guidelines
The id field must be: - Lowercase letters and numbers only - Start with a letter - No spaces (use underscores) - Unique across all plans - Stable (don't change after launch)
# Goodid: proid: enterprise_plusid: team_starter# Badid: Pro # uppercaseid: "Pro Plan" # spacesid: 1st_plan # starts with numberPricing Models
Flat Rate
Simple fixed price per billing period. Amounts are in cents.
prices: monthly: { amount: 2900 } # $29/month yearly: { amount: 29000 } # $290/yearFree Tier
prices: monthly: { amount: 0 }Per-Unit (Seats)
Price multiplied by quantity:
prices: monthly: per_unit: 1200 # $12 per seat unit: seat min: 1 # Minimum 1 seat max: 100 # Maximum 100 seats included: 1 # First seat freeTiered Pricing
Progressive pricing with volume discounts:
prices: monthly: tiers: - up_to: 10 amount: 2000 # $20/seat for 1-10 - up_to: 50 amount: 1500 # $15/seat for 11-50 - up_to: unlimited amount: 1000 # $10/seat for 51+ mode: graduated # or: volumeModes: - graduated — each tier's price applies only to units within that tier - volume — the final tier's price applies to ALL units
Trial Periods
Offer free trials:
plans: - id: pro name: Pro trial_days: 14 prices: monthly: { amount: 2900 }You can also set a default trial period in settings:
settings: trial_days: 14plans: - id: pro # Inherits 14-day trial from settingsBilling Periods
Plans can have any combination of billing periods:
prices: monthly: { amount: 2900 } quarterly: { amount: 7900 } yearly: { amount: 29000 }One-Time Payments (Lifetime Plans)
For lifetime access or one-time purchases, use billing_model: one_time:
plans: - id: pro_lifetime name: Pro Lifetime headline: Pay once, use forever billing_model: one_time prices: one_time: { amount: 7900 } # $79 once limits: projects: unlimited features: - Lifetime access - All future updatesKey differences from subscriptions: - Uses billing_model: one_time instead of default subscription - Price key is one_time instead of monthly/yearly - No trial period (doesn't make sense for one-time) - Creates a Stripe Payment Intent, not a Subscription
This is useful for: - Lifetime deals - One-time setup fees - Digital products - Early-bird offers
Feature Lists
Marketing-friendly feature lists for pricing pages:
plans: - id: pro features: - Up to 25 projects - Advanced analytics - Priority email support - Custom domains - API accessThese are purely for display — actual access control uses limits.
Plan Limits
Define what the plan includes using entitlements:
# First, define entitlementsentitlements: projects: type: int unit: project api_requests: type: rate unit: request sso: type: bool# Then use them in plansplans: - id: pro limits: projects: 25 api_requests: { limit: 1000, per: minute } sso: falseSpecial values: - unlimited — no limit - Integer — fixed limit - Boolean — feature on/off - Rate object — { limit: N, per: period }
Plan Types
Categorize plans for filtering:
plans: - id: starter type: personal - id: pro type: team - id: enterprise type: enterpriseUpgrade Paths
Define valid upgrade destinations:
plans: - id: starter upgrades_to: - pro - enterprise - id: pro upgrades_to: - enterprisePlan Metadata
Store custom data:
plans: - id: enterprise metadata: contact_sales: true custom_contract: true sla_tier: premiumPlan Versioning
When you change pricing for an existing plan, you may want to keep old subscribers on their current price (grandfathering). Use the version field to manage this:
plans: - id: pro version: 2 prices: monthly: { amount: 2900 } - id: pro_v1 version: 1 public: false prices: monthly: { amount: 1900 }version— integer identifying the plan version. New subscribers get the latest version.public: false— hides the old version from your pricing page. Existing subscribers stay on it until they upgrade.
Plan Ordering
Plans are displayed in the order they appear in the config:
plans: - id: starter # Left - id: pro # Center (recommended) - id: enterprise # RightComplete Example
plans: - id: free name: Free headline: Get started for free type: personal public: true default: true prices: monthly: { amount: 0 } limits: projects: 3 team_members: 1 api_requests: { limit: 100, per: minute } sso: false features: - Up to 3 projects - Basic analytics - Community support - id: pro name: Pro headline: For growing teams type: team trial_days: 14 prices: monthly: per_unit: 1900 unit: seat min: 1 included: 1 yearly: per_unit: 15900 unit: seat min: 1 included: 1 limits: projects: 25 team_members: 25 api_requests: { limit: 1000, per: minute } sso: false features: - Up to 25 projects - Advanced analytics - Priority email support upgrades_to: - enterprise - id: enterprise name: Enterprise headline: Custom solutions type: enterprise prices: monthly: { amount: 0 } limits: projects: unlimited team_members: unlimited api_requests: { limit: 50000, per: minute } sso: true features: - Unlimited everything - Dedicated success manager - SLA guarantee metadata: contact_sales: trueBest Practices
- Start simple — begin with 2-3 plans, add more as needed
- Clear differentiation — each plan should have obvious value over the previous
- Stable IDs — never change plan IDs after customers subscribe
- Descriptive features — write features from the customer's perspective