Products
Purpose
Products group your plans and associated features. Define features first, associate them with a product, then assign plan-specific values. Product results also include the add-on catalog and feature-resolution settings.
Access and initialization
Access
Method catalog
Database and connection failures may propagate from any operation. Method-specific errors are listed with each method.
| Method | Purpose |
|---|---|
createProduct | Creates an active product. |
updateProduct | Updates product details. |
getProduct | Gets a product or null. |
listProducts | Lists matching products. |
associateFeature | Associates a feature and configures resolution. |
dissociateFeature | Removes a feature association. |
archiveProduct | Archives a product. |
unarchiveProduct | Restores a product. |
deleteProduct | Permanently deletes an unused product. |
| Method | Purpose |
|---|---|
CreateProductAsync | Creates an active product. |
UpdateProductAsync | Updates product details. |
GetProductAsync | Gets a product or null. |
ListProductsAsync | Lists matching products. |
AssociateFeatureAsync | Associates a feature and configures resolution. |
DissociateFeatureAsync | Removes a feature association. |
ArchiveProductAsync | Archives a product. |
UnarchiveProductAsync | Restores a product. |
DeleteProductAsync | Permanently deletes an unused product. |
Method details
createProduct
Create an active product with a globally unique, immutable key.
Parameters
dto: CreateProductDto with the product key and label.
Returns ProductDto: Product details, associated features, and the add-on catalog.
Example
await subscrio.products.createProduct({
key: 'pro-suite',
displayName: 'Pro Suite',
description: 'Advanced subscription plans'
});
Errors (2)
ValidationError: The key or product properties are invalid.ConflictError: The product key is already in use.
Parameters
dto: CreateProductDto with the product key and label.
Returns ProductDto: Product details, associated features, and the add-on catalog.
Example
await subscrio.Products.CreateProductAsync(new CreateProductDto(
Key: "pro-suite",
DisplayName: "Pro Suite",
Description: "Advanced subscription plans"));
Errors (2)
ValidationException: The key or product properties are invalid.ConflictException: The product key is already in use.
updateProduct
Update the label, description, or metadata without changing the product key.
Parameters
key: Product to update.dto: UpdateProductDto. Uses partial updates.
Returns ProductDto: Product details, associated features, and the add-on catalog.
Example
// pro-suite exists.
await subscrio.products.updateProduct('pro-suite', {
displayName: 'Pro Suite Plus',
metadata: { tier: 'pro' }
});
Errors (2)
ValidationError: The supplied properties are invalid.NotFoundError: The product does not exist.
Parameters
key: Product to update.dto: UpdateProductDto. Uses partial updates.
Returns ProductDto: Product details, associated features, and the add-on catalog.
Example
// pro-suite exists.
await subscrio.Products.UpdateProductAsync("pro-suite", new UpdateProductDto(
DisplayName: "Pro Suite Plus",
Metadata: new() { ["tier"] = "pro" }));
Errors (2)
ValidationException: The supplied properties are invalid.NotFoundException: The product does not exist.
getProduct
Retrieve a product by its key, including archived products.
Parameters
key: Product key.
Returns ProductDto | null: Product with related catalog snapshots, or null when absent.
Example
Parameters
key: Product key.
Returns ProductDto?: Product with related catalog snapshots, or null when absent.
Example
listProducts
List products with filtering and pagination. TypeScript orders by creation time, newest first, regardless of supplied sort options. .NET defaults to label order and honors its sort options.
Parameters
filters: Optional ProductFilterDto. Omitting it uses 50 records at offset zero.
Returns ProductDto[]: Matching product snapshots, or an empty collection.
Example
const products = await subscrio.products.listProducts({
status: 'active', limit: 20, offset: 0, sortOrder: 'asc'
});
console.log(products);
Errors (1)
ValidationError: A filter or pagination value is invalid.
Parameters
filters: Optional ProductFilterDto. Omitting it uses 50 records at offset zero.
Returns List<ProductDto>: Matching product snapshots, or an empty collection.
Example
var products = await subscrio.Products.ListProductsAsync(
new ProductFilterDto(Status: "active", Limit: 20));
Console.WriteLine(products.Count);
Errors (1)
ValidationException: A filter or pagination value is invalid.
associateFeature
Associate a global feature with a product and optionally set how its values are resolved. Calling again updates the association's settings. Omitting the entire resolution argument preserves existing rules. Supplying options without a subscription rule resets that rule to the default subscription selection. See How Feature Values Are Calculated for how the rules affect results.
Parameters
productKey: Product key.featureKey: Global feature key.resolution: Optional FeatureResolutionOptions. Defaults depend on the feature type.
Returns No returned value.
Example
// pro-suite and the numeric seats feature already exist.
await subscrio.products.associateFeature('pro-suite', 'seats', {
addonRule: 'additive',
subscriptionRule: 'most_generous'
});
Errors (2)
NotFoundError: The product or feature does not exist.ValidationError: A resolution rule is invalid or incompatible with a text feature.
Parameters
productKey: Product key.featureKey: Global feature key.resolution: Optional FeatureResolutionOptions. Defaults depend on the feature type.
Returns No returned value.
Example
// pro-suite and the numeric seats feature already exist.
await subscrio.Products.AssociateFeatureAsync("pro-suite", "seats",
new FeatureResolutionOptions(
AddonRule: "additive", SubscriptionRule: "most_generous"));
Errors (2)
NotFoundException: The product or feature does not exist.ValidationException: A resolution rule is invalid or incompatible with a text feature.
dissociateFeature
Remove the product-feature association. This does not delete the global feature, plan values, or subscription overrides. If both records exist, removing an absent association makes no changes.
Parameters
productKey: Product key.featureKey: Feature key.
Returns No returned value.
Example
Errors (1)
NotFoundError: The product or feature does not exist.
Parameters
productKey: Product key.featureKey: Feature key.
Returns No returned value.
Example
Errors (1)
NotFoundException: The product or feature does not exist.
archiveProduct
Mark the product as archived, retaining its plans and feature associations. This does not archive its plans or subscriptions.
Parameters
key: Product key.
Returns ProductDto: Product details, associated features, and the add-on catalog.
Example
Errors (1)
NotFoundError: The product does not exist.
Parameters
key: Product key.
Returns ProductDto: Product details, associated features, and the add-on catalog.
Example
Errors (1)
NotFoundException: The product does not exist.
unarchiveProduct
Restore the product to active status without changing its plans or feature associations.
Parameters
key: Product key.
Returns ProductDto: Product details, associated features, and the add-on catalog.
Example
Errors (1)
NotFoundError: The product does not exist.
Parameters
key: Product key.
Returns ProductDto: Product details, associated features, and the add-on catalog.
Example
Errors (1)
NotFoundException: The product does not exist.
deleteProduct
Permanently delete an archived product. All plans, including archived plans, must be removed first. Other stored references can also prevent deletion.
Parameters
key: Product key.
Returns No returned value.
Example
// pro-suite exists and is archived with no plans or other references.
await subscrio.products.deleteProduct('pro-suite');
Errors (2)
NotFoundError: The product does not exist.DomainError: The product is active, has plans, or has other references that block deletion.
Parameters
key: Product key.
Returns No returned value.
Example
// pro-suite exists and is archived with no plans or other references.
await subscrio.Products.DeleteProductAsync("pro-suite");
Errors (2)
NotFoundException: The product does not exist.DomainException: The product is active, has plans, or has other references that block deletion.
Data types
Required refers to caller-supplied input fields, or guaranteed presence for returned fields. Nullability is shown in Type.
CreateProductDto
Properties for a new product.
| Field | Type | Required | Default | Meaning |
|---|---|---|---|---|
key | string | Yes | None | Immutable key, 1 to 255 lowercase letters, digits, and hyphens. |
displayName | string | Yes | None | Human-readable label, 1 to 255 characters. |
description | string | undefined | No | None | Optional description, up to 1,000 characters. |
metadata | Record<string, unknown> | undefined | No | None | Application-defined metadata. |
| Property | Type | Required | Default | Meaning |
|---|---|---|---|---|
Key | string | Yes | None | Immutable key, 1 to 255 lowercase letters, digits, and hyphens. |
DisplayName | string | Yes | None | Human-readable label, 1 to 255 characters. |
Description | string? | No | null | Optional description, up to 1,000 characters. |
Metadata | Dictionary<string, object?>? | No | null | Application-defined metadata. |
ProductDto
Product details and related catalog snapshots.
| Field | Type | Required | Default | Meaning |
|---|---|---|---|---|
addons | AddonDto[] | Yes | Not applicable | Related add-on definitions. |
features | { featureKey: string; resolution: FeatureResolutionOptions; }[] | Yes | Not applicable | Associated feature keys and resolution options. See ProductFeatureDto for each entry. |
key | string | Yes | Not applicable | Stable identifier. |
displayName | string | Yes | Not applicable | Human-readable label, 1 to 255 characters. |
description | string | null | undefined | No | Not applicable | Optional description, up to 1,000 characters. |
status | string | Yes | Not applicable | Current record status. |
metadata | Record<string, unknown> | null | undefined | No | Not applicable | Application-defined metadata. |
createdAt | string | Yes | Not applicable | Creation time in UTC. |
updatedAt | string | Yes | Not applicable | Last update time in UTC. |
| Property | Type | Required | Default | Meaning |
|---|---|---|---|---|
Key | string | Yes | Not applicable | Stable identifier. |
DisplayName | string | Yes | Not applicable | Human-readable label, 1 to 255 characters. |
Description | string? | Yes | Not applicable | Optional description, up to 1,000 characters. |
Status | string | Yes | Not applicable | Current record status. |
Metadata | Dictionary<string, object?>? | Yes | Not applicable | Application-defined metadata. |
CreatedAt | string | Yes | Not applicable | Creation time in UTC. |
UpdatedAt | string | Yes | Not applicable | Last update time in UTC. |
Addons | List<AddonDto> | Yes | Not applicable | Related add-on definitions. |
Features | List<ProductFeatureDto> | Yes | Not applicable | Associated feature keys and resolution options. See ProductFeatureDto for each entry. |
UpdateProductDto
Editable product properties. Uses partial updates.
| Field | Type | Required | Default | Meaning |
|---|---|---|---|---|
displayName | string | undefined | No | None | Human-readable label, 1 to 255 characters. |
description | string | undefined | No | None | Replacement description, at most 1,000 characters. Null is rejected. |
metadata | Record<string, unknown> | undefined | No | None | Replaces the saved metadata; an empty object clears its entries. |
| Property | Type | Required | Default | Meaning |
|---|---|---|---|---|
DisplayName | string? | No | null | Human-readable label, 1 to 255 characters. |
Description | string? | No | null | Replacement description, at most 1,000 characters. Null retains the saved value. |
Metadata | Dictionary<string, object?>? | No | null | Replaces the saved metadata; an empty object clears its entries. |
ProductFilterDto
Filtering and pagination for products. In TypeScript, a supplied filter object requires limit, offset, and sortOrder; the whole argument can be omitted.
| Field | Type | Required | Default | Meaning |
|---|---|---|---|---|
sortOrder | "asc" | "desc" | Yes | asc | Accepted but currently ignored by the query. |
limit | number | Yes | 50 | Maximum page size, 1 to 100. |
offset | number | Yes | 0 | Nonnegative number of rows to skip. |
sortBy | "displayName" | "createdAt" | undefined | No | None | Accepted values: displayName or createdAt. Currently ignored; results are newest first. |
status | "active" | "archived" | undefined | No | None | Filter by active or archived status. |
search | string | undefined | No | None | Matches product key or label without case sensitivity. When supplied with status, the search predicate takes precedence in the current TypeScript query. |
| Property | Type | Required | Default | Meaning |
|---|---|---|---|---|
Status | string? | No | null | Filter by active or archived status. |
Search | string? | No | null | Matches product key or label; case sensitivity follows the database collation. Combines with status. |
Limit | int | No | 50 | Maximum page size, 1 to 100. |
Offset | int | No | 0 | Nonnegative number of rows to skip. |
SortBy | string? | No | null | displayName or createdAt. Without this value, sorts by displayName. |
SortOrder | string | No | asc | asc or desc; applied when SortBy is supplied. |
FeatureResolutionOptions
Rules on the product-feature relationship. Text features allow only override_wins as an explicit rule.
| Field | Type | Required | Default | Meaning |
|---|---|---|---|---|
addonRule | FeatureValueRule | undefined | No | None | Combines add-ons: additive, most_generous, or override_wins. A new association defaults to additive for numeric/metered, most_generous for toggle, and override_wins for text. Omission preserves an existing add-on rule. |
subscriptionRule | FeatureValueRule | null | undefined | No | None | Combines eligible subscriptions: additive, most_generous, or override_wins. Null or omission inside supplied options restores default subscription selection. |
| Property | Type | Required | Default | Meaning |
|---|---|---|---|---|
AddonRule | string? | No | null | Combines add-ons: additive, most_generous, or override_wins. A new association defaults to additive for numeric/metered, most_generous for toggle, and override_wins for text. Omission preserves an existing add-on rule. |
SubscriptionRule | string? | No | null | Combines eligible subscriptions: additive, most_generous, or override_wins. Null or omission inside supplied options restores default subscription selection. |
ProductFeatureDto
An associated feature and its resolution settings. TypeScript uses this anonymous entry shape inside ProductDto.features.
| Field | Type | Required | Default | Meaning |
|---|---|---|---|---|
featureKey | string | Yes | Not applicable | Associated global feature key. |
resolution | FeatureResolutionOptions | Yes | Not applicable | Rules currently stored for this association. |
| Property | Type | Required | Default | Meaning |
|---|---|---|---|---|
FeatureKey | string | Yes | Not applicable | Associated global feature key. |
Resolution | FeatureResolutionOptions | Yes | Not applicable | Rules currently stored for this association. |
Related guides
- Features: define the global feature catalog.
- Plans: assign plan-specific feature values.
- How Feature Values Are Calculated: understand value selection.
- Add-ons: define reusable contributions for this product.