Skip to content

Features

Purpose

A feature defines a capability or limit your products offer: a toggle, a numeric limit, a text setting, or a metered allowance. Define it once, associate it with products, and assign values through plans or subscription overrides. Use Feature Checker to resolve access and Metered Usage to record consumption.

Access and initialization

Access

const features = subscrio.features;
using Subscrio.Core.Application.DTOs;

var features = subscrio.Features;

Method catalog

Database and connection failures may propagate from any operation. The entries below document method-specific errors.

Method Purpose
createFeature Creates a feature.
updateFeature Updates mutable fields.
getFeature Gets one feature or null.
listFeatures Lists matching features.
getFeaturesByProduct Lists a product’s features.
archiveFeature Archives a feature.
unarchiveFeature Restores a feature.
deleteFeature Deletes an unused feature.
Method Purpose
CreateFeatureAsync Creates a feature.
UpdateFeatureAsync Updates mutable fields.
GetFeatureAsync Gets one feature or null.
ListFeaturesAsync Lists matching features.
GetFeaturesByProductAsync Lists a product’s features.
ArchiveFeatureAsync Archives a feature.
UnarchiveFeatureAsync Restores a feature.
DeleteFeatureAsync Deletes an unused feature.

Method details

createFeature

Create an active, global feature with a unique key, value type, default value, and optional metering settings. The feature and its settings are saved together; invalid settings cancel the entire operation.

createFeature(dto: CreateFeatureDto): Promise<FeatureDto>

Parameters

  • dto: CreateFeatureDto containing the feature properties to create. Metered features require all four metering settings; other feature types reject them. A billing_period reset requires usage to be tracked per subscription.

Returns FeatureDto: The persisted feature snapshot, including related add-ons and any metering configuration.

Example

await features.createFeature({
  key: 'max-projects',
  displayName: 'Max Projects',
  valueType: 'numeric',
  defaultValue: '10'
});
Metered feature example
await subscrio.features.createFeature({
  key: 'requests', displayName: 'API requests', valueType: 'metered', defaultValue: '0',
  meteredConfig: { resetPeriod: 'monthly', enforcement: 'hard', aggregation: 'sum', usageScope: 'customer' }
});
await subscrio.features.updateFeature('requests', {
  meteredConfig: { resetPeriod: 'monthly', enforcement: 'soft', aggregation: 'sum', usageScope: 'customer' }
});
const feature = await subscrio.features.getFeature('requests');
console.log(feature?.meteredConfig, feature?.addons);
Errors (2)
  • ValidationError: Invalid input, default value, or metering configuration.
  • ConflictError: The key already exists.
Task<FeatureDto> CreateFeatureAsync(CreateFeatureDto dto)

Parameters

  • dto: CreateFeatureDto containing the feature properties to create. Metered features require all four metering settings; other feature types reject them. A billing_period reset requires usage to be tracked per subscription.

Returns FeatureDto: The persisted feature snapshot, including related add-ons and any metering configuration.

Example

await subscrio.Features.CreateFeatureAsync(new CreateFeatureDto(
    Key: "max-projects",
    DisplayName: "Max Projects",
    ValueType: "numeric",
    DefaultValue: "10"
));
Metered feature example
await subscrio.Features.CreateFeatureAsync(new("requests", "API requests", "metered", "0",
    MeteredConfig: new("monthly", "hard", "sum", "customer")));
await subscrio.Features.UpdateFeatureAsync("requests", new(
    MeteredConfig: new("monthly", "soft", "sum", "customer")));
var feature = await subscrio.Features.GetFeatureAsync("requests");
Console.WriteLine(feature?.MeteredConfig);
Console.WriteLine(feature?.Addons.Count);
Errors (2)
  • ValidationException: Invalid input, default value, or metering configuration.
  • ConflictException: The key already exists.

updateFeature

Change an existing feature without changing its key. Invalid metering settings cancel the entire update.

Once you have recorded usage for a metered feature, you cannot change its feature type, whether usage is tracked per customer or per subscription, how usage is counted, or when usage resets. You can still switch between rejecting usage over the limit (hard) and recording it (soft).

Saving a text feature also updates its product associations: add-on rules and any explicitly configured rules for combining subscriptions become override_wins. This selects one value by priority instead of combining values. See How Feature Values Are Calculated for value priority.

updateFeature(key: string, dto: UpdateFeatureDto): Promise<FeatureDto>

Parameters

  • key: The key identifying the feature, such as max-projects.
  • dto: UpdateFeatureDto containing the feature properties to change. Uses partial updates. Update properties do not accept null.

Returns FeatureDto: The updated feature snapshot.

Example

Uses an existing feature with key max-projects.

await features.updateFeature('max-projects', {
  defaultValue: '25',
  metadata: { tier: 'enterprise' }
});
Errors (2)
  • ValidationError: Invalid input, incompatible value, or restricted metering change.
  • NotFoundError: The feature does not exist.
Task<FeatureDto> UpdateFeatureAsync(string key, UpdateFeatureDto dto)

Parameters

Returns FeatureDto: The updated feature snapshot.

Example

Uses an existing feature with key max-projects.

await subscrio.Features.UpdateFeatureAsync("max-projects", new UpdateFeatureDto(
    DefaultValue: "25",
    Metadata: new Dictionary<string, object?> { ["tier"] = "enterprise" }
));
Errors (2)
  • ValidationException: Invalid input, incompatible value, or restricted metering change.
  • NotFoundException: The feature does not exist.

getFeature

Retrieve a feature definition by its key.

getFeature(key: string): Promise<FeatureDto | null>

Parameters

  • key: The key identifying the feature, such as max-projects.

Returns FeatureDto | null: The feature snapshot, including related add-ons and any metering configuration, or null if the key is missing.

Example

Returns null if max-projects does not exist.

const feature = await features.getFeature('max-projects');
console.log(feature);
Task<FeatureDto?> GetFeatureAsync(string key)

Parameters

  • key: The key identifying the feature, such as max-projects.

Returns FeatureDto?: The feature snapshot, including related add-ons and any metering configuration, or null if the key is missing.

Example

Returns null if max-projects does not exist.

var feature = await subscrio.Features.GetFeatureAsync("max-projects");
Console.WriteLine(feature?.Key);

listFeatures

Browse feature definitions with filtering, sorting, and pagination.

listFeatures(filters?: FeatureFilterDto): Promise<FeatureDto[]>

Parameters

  • filters: FeatureFilterDto options. Optional; when omitted, returns up to 50 records starting at offset 0.

Returns FeatureDto[]: Matching feature snapshots, each including related add-ons; an empty collection when nothing matches.

Example

const toggles = await features.listFeatures({ valueType: 'toggle', limit: 20, offset: 0 });
console.log(toggles);
Errors (1)
  • ValidationError: A filter is invalid.
Task<List<FeatureDto>> ListFeaturesAsync(FeatureFilterDto? filters)

Parameters

  • filters: FeatureFilterDto options. Optional; when omitted, returns up to 50 records starting at offset 0.

Returns List<FeatureDto>: Matching feature snapshots, each including related add-ons; an empty collection when nothing matches.

Example

var toggles = await subscrio.Features.ListFeaturesAsync(new FeatureFilterDto(
    ValueType: "toggle",
    Limit: 20
));
Console.WriteLine(toggles.Count);
Errors (1)
  • ValidationException: A filter is invalid.

getFeaturesByProduct

List the feature definitions associated with a product.

getFeaturesByProduct(productKey: string): Promise<FeatureDto[]>

Parameters

  • productKey: The key of an existing product.

Returns FeatureDto[]: Associated feature snapshots; an empty collection when none are associated.

Example

Requires an existing product with key pro-suite.

const productFeatures = await features.getFeaturesByProduct('pro-suite');
console.log(productFeatures);
Errors (1)
  • NotFoundError: The product does not exist.
Task<List<FeatureDto>> GetFeaturesByProductAsync(string productKey)

Parameters

  • productKey: The key of an existing product.

Returns List<FeatureDto>: Associated feature snapshots; an empty collection when none are associated.

Example

Requires an existing product with key pro-suite.

var productFeatures = await subscrio.Features.GetFeaturesByProductAsync("pro-suite");
Console.WriteLine(productFeatures.Count);
Errors (1)
  • NotFoundException: The product does not exist.

archiveFeature

Mark a feature as archived while retaining its saved definition and relationships. Archiving is required before deletion; use the unarchive method to restore active status.

archiveFeature(key: string): Promise<void>

Parameters

  • key: The key identifying the feature, such as max-projects.

Returns No returned value.

Example

Uses an existing feature with key max-projects.

await features.archiveFeature('max-projects');
Errors (1)
  • NotFoundError: The feature does not exist.
Task ArchiveFeatureAsync(string key)

Parameters

  • key: The key identifying the feature, such as max-projects.

Returns No returned value.

Example

Uses an existing feature with key max-projects.

await subscrio.Features.ArchiveFeatureAsync("max-projects");
Errors (1)
  • NotFoundException: The feature does not exist.

unarchiveFeature

Restore an archived feature to active status.

unarchiveFeature(key: string): Promise<void>

Parameters

  • key: The key identifying the feature, such as max-projects.

Returns No returned value.

Example

Uses an archived feature with key max-projects.

await features.unarchiveFeature('max-projects');
Errors (1)
  • NotFoundError: The feature does not exist.
Task UnarchiveFeatureAsync(string key)

Parameters

  • key: The key identifying the feature, such as max-projects.

Returns No returned value.

Example

Uses an archived feature with key max-projects.

await subscrio.Features.UnarchiveFeatureAsync("max-projects");
Errors (1)
  • NotFoundException: The feature does not exist.

deleteFeature

Permanently delete an archived feature. Remove product associations, plan values, and subscription overrides first; other stored references may also block deletion.

deleteFeature(key: string): Promise<void>

Parameters

  • key: The key identifying the feature, such as max-projects.

Returns No returned value.

Example

Requires max-projects to be archived and free of references.

await features.deleteFeature('max-projects');
Errors (2)
  • NotFoundError: The feature does not exist.
  • DomainError: The feature is active or has references checked by the library.
Task DeleteFeatureAsync(string key)

Parameters

  • key: The key identifying the feature, such as max-projects.

Returns No returned value.

Example

Requires max-projects to be archived and free of references.

await subscrio.Features.DeleteFeatureAsync("max-projects");
Errors (2)
  • NotFoundException: The feature does not exist.
  • DomainException: The feature is active or has references checked by the library.

Data types

For input types, Required means the caller must supply the property. For returned types, it means the property is present in the response; its value may still be null where the type allows it.

CreateFeatureDto

The properties used to define a feature.

Field Type Required Default Meaning
key string Yes None Stable feature identifier. Letters, digits, hyphens and underscores; 1–255 characters.
displayName string Yes None Human-readable label, 1–255 characters.
valueType "toggle" | "numeric" | "text" | "metered" Yes None toggle, numeric, text, or metered.
defaultValue string Yes None Fallback value stored as a string. Toggle: true or false (case-insensitive); numeric: a finite number; metered: a nonnegative safe integer; text: a nonempty string.
description string | undefined No None Optional description, up to 1,000 characters.
groupName string | undefined No None Optional catalog group, up to 255 characters.
meteredConfig MeteredFeatureConfigDto | undefined When metered None Required for a metered feature; rejected for other feature types.
validator Record<string, unknown> | undefined No None Custom validation metadata.
metadata Record<string, unknown> | undefined No None Application-defined metadata.
Property Type Required Default Meaning
Key string Yes None Stable feature identifier. Letters, digits, hyphens and underscores; 1–255 characters.
DisplayName string Yes None Human-readable label, 1–255 characters.
ValueType string Yes None toggle, numeric, text, or metered.
DefaultValue string Yes None Fallback value stored as a string. Toggle: true or false (case-insensitive); numeric: a finite number; metered: a nonnegative safe integer; text: a nonempty string.
Description string? No null Optional description, up to 1,000 characters.
GroupName string? No null Optional catalog group, up to 255 characters.
Validator Dictionary<string, object?>? No null Custom validation metadata.
Metadata Dictionary<string, object?>? No null Application-defined metadata.
MeteredConfig MeteredFeatureConfigDto? When metered null Required for a metered feature; rejected for other feature types.

MeteredFeatureConfigDto

How usage is recorded and limited for a metered feature. All four settings are required when supplying this object.

Field Type Required Default Meaning
resetPeriod "monthly" | "yearly" | "billing_period" | "hourly" | "daily" | "weekly" Yes None hourly, daily, weekly, monthly, yearly, or billing_period. Calendar periods use UTC.
enforcement "hard" | "soft" Yes None hard rejects over-limit usage; soft records usage and reports overage.
aggregation "count" | "sum" Yes None sum adds the quantity; count requires quantity one per event.
usageScope "customer" | "subscription" Yes None customer shares the product usage bucket; subscription keeps a separate bucket per subscription.
Property Type Required Default Meaning
ResetPeriod string Yes None hourly, daily, weekly, monthly, yearly, or billing_period. Calendar periods use UTC.
Enforcement string Yes None hard rejects over-limit usage; soft records usage and reports overage.
Aggregation string Yes None sum adds the quantity; count requires quantity one per event.
UsageScope string Yes None customer shares the product usage bucket; subscription keeps a separate bucket per subscription.

Calendar reset periods use UTC. Billing-period resets require usage to be tracked per subscription. Once usage is recorded, only enforcement can change among these four settings. See Metered Usage for quota checks and reports.

FeatureDto

The complete feature definition returned by create, update, get, and list operations.

Field Type Required Default Meaning
addons AddonDto[] Yes Not applicable Related add-on definitions, including each add-on's complete feature-value map. See AddonDto properties.
meteredConfig MeteredFeatureConfigDto | null | undefined No Not applicable Current metering settings, or absent/null when not configured.
key string Yes Not applicable Stable feature identifier. Letters, digits, hyphens and underscores; 1–255 characters.
displayName string Yes Not applicable Human-readable label, 1–255 characters.
description string | null | undefined No Not applicable Optional description, up to 1,000 characters.
valueType string Yes Not applicable toggle, numeric, text, or metered.
defaultValue string Yes Not applicable Fallback value stored as a string. Toggle: true or false (case-insensitive); numeric: a finite number; metered: a nonnegative safe integer; text: a nonempty string.
groupName string | null | undefined No Not applicable Optional catalog group, up to 255 characters.
status string Yes Not applicable Feature status: active or archived.
validator Record<string, unknown> | null | undefined No Not applicable Custom validation metadata.
metadata Record<string, unknown> | null | undefined No Not applicable Application-defined metadata.
createdAt string Yes Not applicable Creation timestamp in ISO format.
updatedAt string Yes Not applicable Last update timestamp in ISO format.
Property Type Required Default Meaning
Key string Yes Not applicable Stable feature identifier. Letters, digits, hyphens and underscores; 1–255 characters.
DisplayName string Yes Not applicable Human-readable label, 1–255 characters.
Description string? Yes Not applicable Optional description, up to 1,000 characters.
ValueType string Yes Not applicable toggle, numeric, text, or metered.
DefaultValue string Yes Not applicable Fallback value stored as a string. Toggle: true or false (case-insensitive); numeric: a finite number; metered: a nonnegative safe integer; text: a nonempty string.
GroupName string? Yes Not applicable Optional catalog group, up to 255 characters.
Status string Yes Not applicable Feature status: active or archived.
Validator Dictionary<string, object?>? Yes Not applicable Custom validation metadata.
Metadata Dictionary<string, object?>? Yes Not applicable Application-defined metadata.
CreatedAt string Yes Not applicable Creation timestamp in ISO format.
UpdatedAt string Yes Not applicable Last update timestamp in ISO format.
MeteredConfig MeteredFeatureConfigDto? Yes Not applicable Current metering settings, or absent/null when not configured.
Addons List<AddonDto> Yes Not applicable Related add-on definitions, including each add-on's complete feature-value map. See AddonDto properties.

UpdateFeatureDto

The editable properties of a feature. The key cannot be changed. See partial updates.

Field Type Required Default Meaning
displayName string | undefined No None Human-readable label, 1–255 characters.
description string | undefined No None Optional description, up to 1,000 characters.
valueType "toggle" | "numeric" | "text" | "metered" | undefined No None toggle, numeric, text, or metered. Remove credit consumption rules before changing to metered. The existing or supplied default value must be valid for the new type.
defaultValue string | undefined No None Fallback value stored as a string. Toggle: true or false (case-insensitive); numeric: a finite number; metered: a nonnegative safe integer; text: a nonempty string.
groupName string | undefined No None Optional catalog group, up to 255 characters.
meteredConfig MeteredFeatureConfigDto | undefined No None Supply all four settings to update this object. Only metered features accept it.
validator Record<string, unknown> | undefined No None Custom validation metadata. Replaces all saved entries; an empty object clears them.
metadata Record<string, unknown> | undefined No None Application-defined metadata. Replaces all saved entries; an empty object clears them.
Property Type Required Default Meaning
DisplayName string? No null Human-readable label, 1–255 characters.
Description string? No null Optional description, up to 1,000 characters.
ValueType string? No null toggle, numeric, text, or metered. Remove credit consumption rules before changing to metered. The existing or supplied default value must be valid for the new type.
DefaultValue string? No null Fallback value stored as a string. Toggle: true or false (case-insensitive); numeric: a finite number; metered: a nonnegative safe integer; text: a nonempty string.
GroupName string? No null Optional catalog group, up to 255 characters.
Validator Dictionary<string, object?>? No null Custom validation metadata. Replaces all saved entries; an empty object clears them.
Metadata Dictionary<string, object?>? No null Application-defined metadata. Replaces all saved entries; an empty object clears them.
MeteredConfig MeteredFeatureConfigDto? No null Supply all four settings to update this object. Only metered features accept it.

FeatureFilterDto

Filters, pagination, and ordering for the feature catalog.

When supplying a filters object, its TypeScript type requires limit and offset. Omitting the whole argument uses the method defaults.

Field Type Required Default Meaning
limit number Yes 50 Page size, from 1 to 100.
offset number Yes 0 Nonnegative number of records to skip.
status "archived" | "active" | undefined No None Feature status: active or archived.
valueType "toggle" | "numeric" | "text" | "metered" | undefined No None Filter by toggle, numeric, text, or metered.
groupName string | undefined No None Filter by group name.
search string | undefined No None Text search term.
sortBy "displayName" | "createdAt" | undefined No None Sort by displayName or createdAt.
sortOrder "asc" | "desc" | undefined No None Sort direction; the query uses asc when omitted.

All constructor arguments are optional.

Property Type Required Default Meaning
Status string? No null Feature status: active or archived.
ValueType string? No null Filter by toggle, numeric, text, or metered.
GroupName string? No null Filter by group name.
Search string? No null Text search term.
SortBy string? No null Sort by displayName or createdAt.
SortOrder string? No null Sort direction; the query uses asc when omitted.
Limit int No 50 Page size, from 1 to 100.
Offset int No 0 Nonnegative number of records to skip.