Configure Features
Define capabilities with boolean, metered, and seat feature types in Commet.
Features are reusable building blocks that define the capabilities you sell. Create a feature once and add it to multiple plans with different configurations.
Feature types
| Type | Description | Examples |
|---|---|---|
| Boolean | On/off access to a capability | SSO, Custom Branding, Priority Support |
| Metered | Usage-based with included amounts | API Calls, Storage GB, Emails Sent |
| Seats | Per-user licenses | Editor Seats, Admin Seats, Viewer Seats |
Consumption is defined at the plan level, not the feature level. When you add a feature to a plan, you specify how much is included, whether there's overage, and at what price.
Create features in the dashboard
Go to Features and click Create Feature. Every feature needs a Name (customer-facing) and a Code (internal identifier for the SDK, e.g., api_calls). Feature codes only accept lowercase letters, numbers, and underscores (^[a-z0-9_]+$) and must be unique within your organization.
Metered features also require an Event Code and Unit Name (e.g., "calls", "GB"). Seat features optionally accept a Seat Type (e.g., "Editor", "Admin").
Check feature access
Gate features based on the customer's plan.
const { data } = await commet.features.check({
code: 'custom_branding',
customerId: 'user_123',
})
if (!data.allowed) {
redirect('/upgrade')
}response = commet.features.check(
code='custom_branding',
customer_id='user_123',
)
if not response.data['allowed']:
redirect('/upgrade')result, err := client.Features.Check(ctx, "custom_branding", "user_123")
if err != nil {
return err
}
if !result.Data.Allowed {
// redirect to upgrade
}ApiResponse<CheckResult> result = commet.features().check("custom_branding", "user_123");
if (!result.getData().isAllowed()) {
// redirect to upgrade
}$result = $commet->features->check('custom_branding', 'user_123');
if (!$result->data['allowed']) {
// redirect to upgrade
}curl "https://commet.co/api/features/custom_branding?customerId=user_123&action=canUse" \
-H "x-api-key: $COMMET_API_KEY"Get feature details
Returns usage numbers, limits, and overage info.
const { data } = await commet.features.get({
code: 'api_calls',
customerId: 'user_123',
})
// data.current — usage this period
// data.included — included in plan
// data.remaining — units left
// data.overage — units over the limit
// data.unlimited — true if no capresponse = commet.features.get(
code='api_calls',
customer_id='user_123',
)
# response.data['current'] — usage this period
# response.data['included'] — included in plan
# response.data['remaining'] — units left
# response.data['overage'] — units over the limit
# response.data['unlimited'] — true if no capresult, err := client.Features.Get(ctx, "api_calls", "user_123")
if err != nil {
return err
}
// result.Data.Current — usage this period
// result.Data.Included — included in plan
// result.Data.Remaining — units left
// result.Data.Overage — units over the limit
// result.Data.Unlimited — true if no capApiResponse<Feature> result = commet.features().get("api_calls", "user_123");
// result.getData().getCurrent() — usage this period
// result.getData().getIncluded() — included in plan
// result.getData().getRemaining() — units left
// result.getData().getOverage() — units over the limit
// result.getData().isUnlimited() — true if no cap$result = $commet->features->get('api_calls', 'user_123');
// $result->data['current'] — usage this period
// $result->data['included'] — included in plan
// $result->data['remaining'] — units left
// $result->data['overage'] — units over the limit
// $result->data['unlimited'] — true if no capcurl "https://commet.co/api/features/api_calls?customerId=user_123" \
-H "x-api-key: $COMMET_API_KEY"Pre-flight check
Check if a customer can use a feature and whether they'll be charged extra.
const { data } = await commet.features.canUse({
code: 'team_members',
customerId: 'user_123',
})
if (!data.allowed) {
return { error: 'Upgrade to add more members' }
}
if (data.willBeCharged) {
// Show overage confirmation
}response = commet.features.can_use(
code='team_members',
customer_id='user_123',
)
if not response.data['allowed']:
return {'error': 'Upgrade to add more members'}
if response.data['will_be_charged']:
# Show overage confirmation
passresult, err := client.Features.CanUse(ctx, "team_members", "user_123")
if err != nil {
return err
}
if !result.Data.Allowed {
return errors.New("upgrade to add more members")
}
if result.Data.WillBeCharged {
// Show overage confirmation
}ApiResponse<FeatureAccess> result = commet.features().canUse("team_members", "user_123");
if (!result.getData().isAllowed()) {
return Map.of("error", "Upgrade to add more members");
}
if (result.getData().isWillBeCharged()) {
// Show overage confirmation
}$result = $commet->features->canUse('team_members', 'user_123');
if (!$result->data['allowed']) {
return ['error' => 'Upgrade to add more members'];
}
if ($result->data['willBeCharged']) {
// Show overage confirmation
}curl -X POST https://commet.co/api/usage/check \
-H "x-api-key: $COMMET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customerId": "user_123",
"featureCode": "team_members",
"quantity": 1
}'List all features
const { data } = await commet.features.list('user_123')response = commet.features.list(customer_id='user_123')result, err := client.Features.List(ctx, "user_123")ApiResponse<List<Feature>> result = commet.features().list("user_123");$result = $commet->features->list('user_123');curl "https://commet.co/api/features?customerId=user_123" \
-H "x-api-key: $COMMET_API_KEY"Related
- Track Usage — Send usage events for metered features
- Manage Plans — Add features to pricing plans
- Consumption Models — How features behave in each model
- Seat Management — Manage seat-based licenses
How is this guide?