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.featureAccess.get({
code: 'custom_branding',
customerId: 'user_123',
})
if (!data.allowed) {
redirect('/upgrade')
}response = commet.feature_access.get(
'custom_branding',
customer_id='user_123',
)
if not response.data.allowed:
redirect('/upgrade')result, err := client.FeatureAccess.Get(ctx, "custom_branding", &commet.GetFeatureAccessParams{
CustomerID: "user_123",
})
if err != nil {
return err
}
if !result.Data.Allowed {
// redirect to upgrade
}ApiResponse<FeatureLookup> result = commet.featureAccess()
.get("custom_branding", GetFeatureAccessParams.builder("user_123").build());
if (!result.getData().allowed()) {
// redirect to upgrade
}$result = $commet->featureAccess->get('custom_branding', 'user_123');
if (!$result->data->allowed) {
// redirect to upgrade
}curl "https://commet.co/api/v1/feature-access/custom_branding?customerId=user_123" \
-H "x-api-key: $COMMET_API_KEY"Get feature details
Returns usage numbers, limits, and overage info.
const { data } = await commet.featureAccess.get({
code: 'api_calls',
customerId: 'user_123',
})
// data.current — usage this period
// data.included — included in plan
// data.remaining — units left
// data.overageQuantity — units over the limit
// data.unlimited — true if no capresponse = commet.feature_access.get(
'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_quantity — units over the limit
# response.data.unlimited — true if no capresult, err := client.FeatureAccess.Get(ctx, "api_calls", &commet.GetFeatureAccessParams{
CustomerID: "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.OverageQuantity — units over the limit
// result.Data.Unlimited — true if no capApiResponse<FeatureLookup> result = commet.featureAccess()
.get("api_calls", GetFeatureAccessParams.builder("user_123").build());
// result.getData().current() — usage this period
// result.getData().included() — included in plan
// result.getData().remaining() — units left
// result.getData().overageQuantity() — units over the limit
// result.getData().unlimited() — true if no cap$result = $commet->featureAccess->get('api_calls', 'user_123');
// $result->data->current — usage this period
// $result->data->included — included in plan
// $result->data->remaining — units left
// $result->data->overageQuantity — units over the limit
// $result->data->unlimited — true if no capcurl "https://commet.co/api/v1/feature-access/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.featureAccess.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.feature_access.can_use(
'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.FeatureAccess.CanUse(ctx, "team_members", &commet.CanUseFeatureParams{
CustomerID: "user_123",
})
if err != nil {
return err
}
if !result.Data.Allowed {
return errors.New("upgrade to add more members")
}
if result.Data.WillBeCharged != nil && *result.Data.WillBeCharged {
// Show overage confirmation
}ApiResponse<FeatureLookup> result = commet.featureAccess()
.canUse("team_members", CanUseFeatureParams.builder("user_123").build());
if (!result.getData().allowed()) {
return Map.of("error", "Upgrade to add more members");
}
if (Boolean.TRUE.equals(result.getData().willBeCharged())) {
// Show overage confirmation
}$result = $commet->featureAccess->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 a customer's features
const { data } = await commet.featureAccess.list({ customerId: 'user_123' })response = commet.feature_access.list(customer_id='user_123')result, err := client.FeatureAccess.List(ctx, &commet.ListFeatureAccessParams{
CustomerID: "user_123",
})ApiResponse<List<FeatureAccess>> result = commet.featureAccess()
.list(ListFeatureAccessParams.builder("user_123").build());$result = $commet->featureAccess->list('user_123');curl "https://commet.co/api/v1/feature-access?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?