Entitlements

Define and manage feature access with 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 support

plans:
  - id: pro
    limits:
      projects: 25
      api_requests: { limit: 1000, per: minute }
      sso: false

Entitlement Properties

PropertyTypeRequiredDescription
typeenumYesint, bool, or rate
unitstringNoUnit name for display
descriptionstringNoHuman-readable description

Entitlement Types

Integer (int)

For countable limits:

entitlements:
  projects:
    type: int
    unit: project

  team_members:
    type: int
    unit: seat

# In plans
limits:
  projects: 25
  team_members: 10
  # or
  projects: unlimited

Values:

  • 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 plans
limits:
  sso: true
  audit_logs: false

Values: true or false

Rate (rate)

For time-based limits:

entitlements:
  api_requests:
    type: rate
    unit: request

# In plans
limits:
  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: bool

plans:
  - 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: true

Special Values

Unlimited

Remove the limit entirely:

limits:
  projects: unlimited
  team_members: unlimited

Zero

Explicitly set to zero (different from not defined):

limits:
  extra_storage: 0

Entitlements 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 feature

Grant Syntax

SyntaxMeaning
"+10"Add 10 to existing limit
"-5"Subtract 5 from existing limit
25Set to exactly 25
trueEnable boolean feature
unlimitedRemove limit entirely

Best Practices

1. Use Descriptive Names

# Good
entitlements:
  max_team_members:
    type: int
    unit: member
    description: Maximum team members per workspace

# Avoid
entitlements:
  mtm:
    type: int

2. Document Everything

entitlements:
  api_requests:
    type: rate
    unit: request
    description: API rate limit per minute for REST endpoints

3. 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_case
entitlements:
  team_members:
    type: int
  api_requests:
    type: rate
  audit_logs:
    type: bool

Checking Entitlements in Code

Your backend reads the billing config and checks limits:

// Example: Check if user can create another project
function 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 limit
function 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: 1

entitlements:
  # 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 access

plans:
  - 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

On this page