Entitlements

Check what features a customer has access to based on their subscription plan.

How Entitlements Work

Each plan in StackBE has an entitlements object that defines feature access. When you check entitlements for a customer, StackBE returns the entitlements from their active plan.

json
// Example plan entitlements
{
  "api_calls": 10000,        // Numeric limit
  "premium_support": true,   // Boolean feature flag
  "export_formats": ["csv", "json", "xlsx"],  // Array of options
  "team_members": 5          // Numeric limit
}

Check Entitlements

Get all entitlements for a customer. This is useful for rendering UI based on their plan.

Using the SDK

typescript
import { StackBE } from '@stackbe/sdk';

const stackbe = new StackBE({
  apiKey: process.env.STACKBE_API_KEY!,
  appId: process.env.STACKBE_APP_ID!,
});

// Get full entitlements
const entitlements = await stackbe.entitlements.get(customerId);

console.log(entitlements);
// {
//   planId: 'plan_pro',
//   planName: 'Pro Plan',
//   status: 'active',
//   entitlements: {
//     api_calls: 10000,
//     premium_support: true,
//     export_formats: ['csv', 'json', 'xlsx'],
//     team_members: 5
//   },
//   currentPeriodEnd: '2025-02-15T00:00:00Z'
// }

Via API

bash
curl "https://api.stackbe.io/v1/entitlements?customerId=cust_abc123" \
  -H "Authorization: Bearer sk_live_your_api_key"

Check Specific Feature

Check if a customer has access to a specific feature. Returns the feature value and whether they have access.

typescript
// Check a boolean feature
const { hasAccess } = await stackbe.entitlements.check(customerId, 'premium_support');

if (!hasAccess) {
  return { error: 'Premium support requires a Pro plan' };
}

// Check a numeric limit
const { hasAccess, value } = await stackbe.entitlements.check(customerId, 'api_calls');
console.log(`Customer can make ${value} API calls`);

// Check array entitlement
const { hasAccess, value } = await stackbe.entitlements.check(customerId, 'export_formats');
const canExportXlsx = value?.includes('xlsx');

Via API

bash
curl "https://api.stackbe.io/v1/entitlements/check/premium_support?customerId=cust_abc123" \
  -H "Authorization: Bearer sk_live_your_api_key"

# Response:
# { "hasAccess": true, "value": true, "planName": "Pro Plan" }

Express Middleware

The SDK provides middleware for Express to automatically check entitlements on routes.

typescript
import express from 'express';
import { StackBE } from '@stackbe/sdk';

const app = express();
const stackbe = new StackBE({
  apiKey: process.env.STACKBE_API_KEY!,
  appId: process.env.STACKBE_APP_ID!,
});

// Middleware to require a feature
const requireFeature = (feature: string) => {
  return async (req, res, next) => {
    const customerId = req.user.stackbeCustomerId;
    const { hasAccess } = await stackbe.entitlements.check(customerId, feature);

    if (!hasAccess) {
      return res.status(403).json({
        error: 'Feature not available on your plan',
        feature,
        upgradeUrl: '/pricing',
      });
    }

    next();
  };
};

// Protect routes
app.post('/api/export/xlsx', requireFeature('xlsx_export'), async (req, res) => {
  // Only Pro+ customers can access this
});

app.get('/api/analytics', requireFeature('advanced_analytics'), async (req, res) => {
  // Only customers with advanced_analytics entitlement
});

UI Patterns

Use entitlements to show/hide features and display upgrade prompts.

typescript
// React component example
function FeatureGate({ feature, children, fallback }) {
  const { entitlements } = useEntitlements();

  if (!entitlements?.[feature]) {
    return fallback || <UpgradePrompt feature={feature} />;
  }

  return children;
}

// Usage
<FeatureGate feature="premium_support">
  <PremiumSupportChat />
</FeatureGate>

// With custom fallback
<FeatureGate
  feature="team_members"
  fallback={<p>Upgrade to invite team members</p>}
>
  <TeamMembersList />
</FeatureGate>

Organization Entitlements

When a customer is in an organization context (B2B), entitlements are checked against the organization's subscription, not the individual's.

typescript
// If customer has an org session token, entitlements come from org subscription
const entitlements = await stackbe.entitlements.get(customerId, {
  organizationId: orgId,  // Optional: explicit org context
});

// The SDK handles this automatically if using org-scoped session tokens

See Organizations for more on B2B features.

Best Practices

  • Cache entitlements — Entitlements don't change frequently. Cache them for a few minutes to reduce API calls.
  • Use descriptive feature names — Name entitlements clearly: can_export_xlsx is better than feature_3.
  • Check server-side — Always verify entitlements on the server. Client-side checks are for UI only.
  • Handle missing entitlements gracefully — If an entitlement key doesn't exist, treat it as false or 0.

Next Steps