Docs / entitlements
Entitlements
Entitlements define what limits and features each plan includes. They're the bridge between your pricing and your application's access control.
What Are Entitlements?
Entitlements answer: "What can this customer do?"
- How many projects can they create?
- What's their API rate limit?
- Do they have access to SSO?
- Is audit logging enabled?
Defining Entitlements
Define entitlements at the top level, then reference them in plans:
entitlements: projects: type: int unit: project description: Number of active projects api_requests: type: rate unit: request description: API rate limit sso: type: bool description: Single sign-on supportplans: - id: pro limits: projects: 25 api_requests: { limit: 1000, per: minute } sso: falseEntitlement Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | enum | Yes | int, bool, or rate |
unit | string | No | Unit name for display |
description | string | No | Human-readable description |
Entitlement Types
Integer (int)
For countable limits:
entitlements: projects: type: int unit: project team_members: type: int unit: seat# In planslimits: projects: 25 team_members: 10 # or projects: unlimitedValues: - Any positive integer: 25 - unlimited: No limit
Boolean (bool)
For feature flags:
entitlements: sso: type: bool description: Single sign-on support audit_logs: type: bool description: Audit log retention# In planslimits: sso: true audit_logs: falseValues: true or false
Rate (rate)
For time-based limits:
entitlements: api_requests: type: rate unit: request# In planslimits: api_requests: { limit: 1000, per: minute }Rate object: - limit: Number of requests allowed - per: Time period (second, minute, hour, day)
Using Entitlements in Plans
entitlements: projects: type: int unit: project team_members: type: int unit: seat api_requests: type: rate unit: request sso: type: bool audit_logs: type: boolplans: - id: free name: Free limits: projects: 3 team_members: 1 api_requests: { limit: 100, per: minute } sso: false audit_logs: false - id: pro name: Pro limits: projects: 25 team_members: 25 api_requests: { limit: 1000, per: minute } sso: false audit_logs: true - id: enterprise name: Enterprise limits: projects: unlimited team_members: unlimited api_requests: { limit: 50000, per: minute } sso: true audit_logs: trueSpecial Values
Unlimited
Remove the limit entirely:
limits: projects: unlimited team_members: unlimitedZero
Explicitly set to zero (different from not defined):
limits: extra_storage: 0Entitlements in Addons
Addons can modify entitlement values:
addons: - id: extra_projects name: Extra Projects Pack price: { amount: 1000 } grants: projects: "+10" # Add 10 to existing limit - id: unlimited_projects name: Unlimited Projects price: { amount: 5000 } grants: projects: unlimited # Set to unlimited - id: sso_addon name: SSO Add-on price: { amount: 2000 } grants: sso: true # Enable featureGrant Syntax
| Syntax | Meaning |
|---|---|
"+10" | Add 10 to existing limit |
"-5" | Subtract 5 from existing limit |
25 | Set to exactly 25 |
true | Enable boolean feature |
unlimited | Remove limit entirely |
Best Practices
1. Use Descriptive Names
# Goodentitlements: max_team_members: type: int unit: member description: Maximum team members per workspace# Avoidentitlements: mtm: type: int2. Document Everything
entitlements: api_requests: type: rate unit: request description: API rate limit per minute for REST endpoints3. Plan for Growth
Add entitlements before you need them:
entitlements: # Current features projects: type: int unit: project # Future features (set to false for now) ai_features: type: bool description: AI-powered features (coming soon)4. Be Consistent
Use the same naming convention throughout:
# Consistent snake_caseentitlements: team_members: type: int api_requests: type: rate audit_logs: type: boolChecking Entitlements in Code
Your backend reads the billing config and checks limits:
// Example: Check if user can create another projectfunction canCreateProject(userPlan: string, currentCount: number): boolean { const plan = billingConfig.plans.find(p => p.id === userPlan); const limit = plan?.limits?.projects; if (limit === 'unlimited') return true; if (typeof limit === 'number') return currentCount < limit; return false;}// Example: Check rate limitfunction isWithinRateLimit( userPlan: string, requestsInWindow: number): boolean { const plan = billingConfig.plans.find(p => p.id === userPlan); const rateLimit = plan?.limits?.api_requests; if (!rateLimit) return true; return requestsInWindow < rateLimit.limit;}Complete Example
version: 1entitlements: # Numeric limits projects: type: int unit: project description: Number of active projects team_members: type: int unit: seat description: Team members per workspace storage_gb: type: int unit: GB description: Cloud storage allocation # Rate limits api_requests: type: rate unit: request description: API rate limit # Feature flags sso: type: bool description: Single sign-on (SAML/OIDC) audit_logs: type: bool description: Audit log retention custom_domains: type: bool description: Custom domain support priority_support: type: bool description: Priority support accessplans: - id: free name: Free limits: projects: 3 team_members: 1 storage_gb: 1 api_requests: { limit: 100, per: minute } sso: false audit_logs: false custom_domains: false priority_support: false - id: pro name: Pro limits: projects: 25 team_members: 25 storage_gb: 50 api_requests: { limit: 1000, per: minute } sso: false audit_logs: true custom_domains: true priority_support: true - id: enterprise name: Enterprise limits: projects: unlimited team_members: unlimited storage_gb: unlimited api_requests: { limit: 50000, per: minute } sso: true audit_logs: true custom_domains: true priority_support: true