Features Guide

Defining Features

Learn how to define and use features in BillAI to control access to your app's functionality.

What are Features?

Features are the building blocks of your pricing plans. Each feature represents a capability or resource that users can access based on their subscription plan.

When you create a plan in BillAI, you define which features are included and optionally set limits for usage-based features.

Feature Types

Boolean Features

Simple on/off access control. Either a user has access to the feature, or they don't.

Premium exports
AI-powered features
Advanced settings

Usage-based Features

Features with a numeric limit. Track usage and automatically deny access when limits are exceeded.

API calls per month
Storage quota
AI tokens/credits

Defining Features in Plans

When creating a plan in the dashboard, you can add features using the Features Editor. Here's how to define each type:

Boolean Features

Add a feature with a boolean value of true.

Example Plan Features (JSON)
{
  "premium_export": true,
  "ai_summaries": true,
  "advanced_settings": true
}

Usage-based Features

Add a feature with a numeric value representing the limit.

Example Plan Features (JSON)
{
  "api_calls": 1000,      // 1000 API calls per month
  "storage_mb": 500,       // 500 MB storage
  "ai_tokens": 10000       // 10,000 AI tokens
}

Combined Example

Most plans will have a mix of both types:

Pro Plan Features
{
  // Boolean features
  "premium_export": true,
  "ai_summaries": true,
  "priority_support": true,
  
  // Usage-based features  
  "api_calls": 10000,
  "storage_mb": 2048,
  "ai_tokens": 50000
}

Checking Features in Code

Boolean Features

const result = await access.check(userId, 'premium_export');

if (!result.granted) {
  // Feature not available - show upgrade prompt
  return { 
    error: 'upgrade_required',
    upgradeUrl: result.upgradeUrl 
  };
}

// Proceed with the feature
return performExport();

Usage-based Features

// Check and increment usage in one call
const result = await access.check(userId, 'api_calls', {
  increment: 1,  // Count this API call
});

if (!result.granted) {
  // Limit exceeded
  return {
    error: 'limit_exceeded',
    message: `API limit reached (${result.usage}/${result.limit})`,
    upgradeUrl: result.upgradeUrl,
  };
}

// Proceed with the API call
return processRequest();

Check Without Incrementing

To check remaining usage without counting, omit the increment option:

// Just check, don't increment
const result = await access.check(userId, 'api_calls');

const remaining = (result.limit || 0) - (result.usage || 0);
console.log(`Remaining API calls: ${remaining}`);

Feature Naming Best Practices

Use snake_case

Feature names should be lowercase with underscores: premium_export, api_calls

Be descriptive

Choose names that clearly describe the feature: ai_text_generation instead of just ai

Include unit for usage features

Add the unit to make limits clear: storage_mb, bandwidth_gb

Feature names are case-sensitive

api_calls and API_Calls are different features. Stick to one convention.

Plan Design Tips

Start with a Free plan

Create a Free plan with limited features. This lets users try your app before committing. Set usage limits low enough to demonstrate value but encourage upgrades.

Gate premium capabilities, not core functionality

Let users accomplish basic tasks for free. Reserve premium features for power users who will see the value in paying.

Use meaningful limits

Set usage limits that match real usage patterns. Too low frustrates users, too high and there's no incentive to upgrade.

Provide clear upgrade paths

When access is denied, show users exactly what they get by upgrading. Use the upgradeUrl from the check result.

Example Plan Structure

Here's a typical three-tier pricing structure:

Free

$0/month

{
  "basic_export": true,
  "api_calls": 100,
  "storage_mb": 50
}

Pro

Popular

$19/month

{
  "basic_export": true,
  "premium_export": true,
  "ai_summaries": true,
  "api_calls": 5000,
  "storage_mb": 1024
}

Enterprise

$99/month

{
  "basic_export": true,
  "premium_export": true,
  "ai_summaries": true,
  "priority_support": true,
  "api_calls": 100000,
  "storage_mb": 10240
}