Skip to main content
Features represent the capabilities you bundle with your products — things like “SSO enabled”, “Premium support”, or “100GB storage”. When customers subscribe to a plan, they automatically receive entitlements that grant access to these features.

How It Works

  1. Create features for your product (via Platform UI)
  2. Link features to prices within a plan
  3. Customers subscribe and entitlements are provisioned automatically
  4. Check entitlements via API to gate access in your application

Feature Types

Boolean

Simple on/off access. Either the customer has it or they don’t.Examples: SSO enabled, Premium support, API access

Static

Fixed capability with configuration values that define limits or quotas.Examples: 25 team seats, 100GB storage, 1000 API calls/month

Metered

Usage-based access enforced against real consumption data. The customer’s quota decrements as they use your product.Examples: 1M tokens/month, 100 API calls/day, 50GB storage

Creating Features

You can create features via the Platform UI or the API.
1

Navigate to your product

Go to Products and select the product you want to add features to.
2

Open the Features tab

Click the Features tab to view and manage features for this product.
3

Create a new feature

Click New Feature and fill in the details:
  • Name: Display name shown in the UI (e.g., “AI Tokens”)
  • Key: Unique identifier used in API calls, lowercase with hyphens (e.g., ai-tokens)
  • Type: Boolean, Static, or Metered
4

Save the feature

Click Save to create the feature. It’s now available to link to prices.
Use descriptive, consistent keys for your features. They’ll appear in API responses and your application code.

Linking Features to Prices

Once you have features, link them to prices within your plans. This determines what entitlements customers receive when they subscribe.
1

Navigate to a plan

Go to Products > Plans and select the plan you want to configure.
2

Edit a price

Select a price within the plan to edit its configuration.
3

Select a feature

Choose a feature from the dropdown to associate with this price.
4

Configure entitlement template

For Static features, define the configuration values that will be granted:
{
  "maxUsers": 25,
  "storageGB": 100
}
For Metered features, define the usage limit:
{
  "limit": 1000000
}
This grants the customer 1,000,000 units of usage per billing period, tracked against the billable metric linked to this price.
To add features to a plan without charging for them, create a fee with a price of 0. This lets you attach a feature for entitlement purposes while not billing the customer.

Automatic Entitlement Provisioning

When a customer subscribes to a plan, entitlements are automatically provisioned based on the features linked to that plan’s prices. When the subscription is terminated, they are canceled. No manual intervention required.

Checking Entitlements via API

Use the API to check if a customer has access to specific features. This is how you gate functionality in your application.
API Reference: See the List Entitlements API endpoint for complete request and response schemas.

List Customer Entitlements

async function checkEntitlements(customerId) {
  const url = new URL('https://api.paygentic.io/v1/entitlements');
  url.searchParams.set('customerId', customerId);
  // Optional filters:
  // url.searchParams.set('featureKey', 'sso-access');
  // url.searchParams.set('productId', 'prod_abc123');

  const response = await fetch(url, {
    headers: { 'Authorization': 'Bearer sk_test_YOUR_API_KEY' }
  });
  return response.json();
}

// Example: Check if customer has SSO access
const entitlements = await checkEntitlements('cus_abc123');
const hasSso = entitlements.data.some(
  e => e.featureKey === 'sso-access' && e.hasAccess
);

Response Format

{
  "object": "list",
  "data": [
    {
      "hasAccess": true,
      "featureKey": "sso-access",
      "featureType": "boolean",
      "config": null,
      "entitlementId": "ent_abc123",
      "productId": "prod_xyz789",
      "activeFrom": "2024-01-01T00:00:00Z",
      "activeTo": null,
      "status": "active"
    },
    {
      "hasAccess": true,
      "featureKey": "storage-quota",
      "featureType": "static",
      "config": {
        "limitGB": 500
      },
      "entitlementId": "ent_def456",
      "productId": "prod_xyz789",
      "activeFrom": "2024-01-01T00:00:00Z",
      "activeTo": null,
      "status": "active"
    }
  ],
  "pagination": {
    "limit": 20,
    "offset": 0,
    "total": 2
  }
}

Key Response Fields

FieldDescription
hasAccessWhether the customer currently has access to this feature
featureKeyThe unique identifier for the feature
featureTypeboolean, static, or metered
configFor static features, the configuration values (limits, quotas, etc.)
statusCurrent status: active, expired, or canceled
The list endpoint (GET /v1/entitlements) returns hasAccess but does not include balance or usage data. To get real-time balance and usage for a metered entitlement, use GET /v1/entitlements/{entitlementId}.

Metered Features

Metered features enforce usage-based quotas against real consumption data. Instead of a static config value, the system tracks how much the customer has actually used and compares it against their granted limit.

How metered entitlements work

  1. You configure a feature with type: metered and link it to a price with a billable metric
  2. The entitlement template defines the usage limit (e.g., { "limit": 1000000 })
  3. As the customer sends meter events, their usage accumulates
  4. Your application checks the entitlement balance before allowing each operation
The grant engine reads aggregated meter data in real time, so hasAccess always reflects current consumption.

Checking a metered entitlement balance

Use GET /v1/entitlements/{entitlementId} to get a real-time snapshot of a customer’s usage and remaining quota. For metered entitlements, the response includes live balance and usage data in addition to the base entitlement fields.
curl -X GET "https://api.paygentic.io/v1/entitlements/ent_abc123" \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"

Balance response

{
  "object": "entitlement",
  "id": "ent_abc123",
  "customerId": "cus_xyz789",
  "featureId": "feat_789",
  "featureKey": "ai-tokens",
  "featureType": "metered",
  "subscriptionId": "sub_abc",
  "status": "active",
  "activeFrom": "2026-01-01T00:00:00Z",
  "activeTo": null,
  "hasAccess": true,
  "metadata": {},
  "balance": 450000,
  "usageInPeriod": 550000,
  "overage": 0,
  "currentPeriodStart": "2026-02-01T00:00:00Z",
  "currentPeriodEnd": "2026-03-01T00:00:00Z"
}
FieldDescription
idThe entitlement ID
featureKeyThe unique identifier for the feature
featureTypeAlways "metered" for metered features
statusEntitlement status: active, expired, or canceled
hasAccesstrue if the customer still has quota, or if the entitlement is configured as a soft limit
balanceUnits remaining in the current period
usageInPeriodUnits consumed so far this period
overageUnits consumed beyond the granted limit (if soft limit)
currentPeriodStart / currentPeriodEndThe active billing or entitlement period

Hard limits vs soft limits

By default, hasAccess becomes false once balance reaches zero. You can configure an entitlement as a soft limit, which allows usage to continue beyond the granted quota (generating overage) while still returning hasAccess: true. Use soft limits when you want to track overages for post-period billing or alerting, without hard-blocking the customer at the quota boundary.

Required setup

For a metered feature to work, your price must be linked to a billable metric that has eventType, valueProperty, and aggregation configured. The grant engine uses these fields to query the meter data and calculate current usage. See Meter Events for how to instrument your application to send usage data.

Use Cases

Feature Gating

Check hasAccess before enabling premium features in your application:
const entitlements = await checkEntitlements(customerId);
const ssoEntitlement = entitlements.data.find(e => e.featureKey === 'sso-access');

if (ssoEntitlement?.hasAccess) {
  // Enable SSO login option
  showSsoButton();
} else {
  // Show upgrade prompt
  showUpgradePrompt('SSO is available on Professional plans and above');
}

Enforcing Static Limits

Read config values for static features to enforce limits:
const entitlements = await checkEntitlements(customerId);
const storageEntitlement = entitlements.data.find(e => e.featureKey === 'storage-quota');

if (storageEntitlement?.hasAccess) {
  const limitGB = storageEntitlement.config.limitGB;
  const currentUsageGB = await getCurrentStorageUsage(customerId);

  if (currentUsageGB >= limitGB) {
    throw new Error(`Storage limit of ${limitGB}GB reached`);
  }
}

Enforcing Metered Quotas

Check the balance endpoint before allowing consumption:
async function canProcessRequest(customerId, entitlementId) {
  const response = await fetch(
    `https://api.paygentic.io/v1/entitlements/${entitlementId}`,
    { headers: { 'Authorization': `Bearer ${API_KEY}` } }
  );
  const { hasAccess, balance } = await response.json();
  return { allowed: hasAccess, remaining: balance };
}

// Before processing an AI inference request
const { allowed, remaining } = await canProcessRequest(customerId, entitlementId);
if (!allowed) {
  return res.status(429).json({ error: 'Token quota exceeded' });
}

// Process the request, then send a meter event
await processInference(request);
await sendMeterEvent({ type: 'ai.inference', subject: customerId, data: { tokens: 1500 } });

Next Steps