Skip to content

Add-ons

Purpose

Add-ons are reusable packages of feature values for a product. A package can affect several features, such as seats and storage, and can be attached to multiple subscriptions. Define contributions here; attach packages through Subscriptions. For an individual exception, see overrides or add-ons.

Access and initialization

Access

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

var addons = subscrio.Addons;

Method catalog

Database and connection failures may propagate from any operation. Method-specific errors are listed with each method.

Method Purpose
createAddon Creates an add-on and its contributions.
updateAddon Updates an add-on and selected contributions.
getAddon Gets an add-on or null.
listAddons Lists a product's add-ons.
archiveAddon Stops new attachments.
unarchiveAddon Allows attachments again.
deleteAddon Deletes an unused archived add-on.
Method Purpose
CreateAddonAsync Creates an add-on and its contributions.
UpdateAddonAsync Updates an add-on and selected contributions.
GetAddonAsync Gets an add-on or null.
ListAddonsAsync Lists a product's add-ons.
ArchiveAddonAsync Stops new attachments.
UnarchiveAddonAsync Allows attachments again.
DeleteAddonAsync Deletes an unused archived add-on.

Method details

createAddon

Create an active add-on with a globally unique key. The definition and all contributions are saved together; invalid contributions cancel the operation. Each contributed feature must be associated with the add-on's product.

createAddon(input: CreateAddonDto): Promise<AddonDto>

Parameters

  • input: CreateAddonDto containing the product, label, and feature contributions.

Returns AddonDto: The saved definition, including its complete feature-value map.

Example

// studio must be active, with an associated numeric seats feature.
await subscrio.addons.createAddon({
  key: 'seat-pack',
  productKey: 'studio',
  displayName: 'Extra seats',
  featureValues: { seats: '3' }
});
Errors (3)
  • ValidationError: A key, label, mode, priority, or feature value is invalid.
  • NotFoundError: The product is missing or inactive, or a feature is not associated with it.
  • ConflictError: The add-on key already exists.
Task<AddonDto> CreateAddonAsync(CreateAddonDto input)

Parameters

  • input: CreateAddonDto containing the product, label, and feature contributions.

Returns AddonDto: The saved definition, including its complete feature-value map.

Example

// studio must be active, with an associated numeric seats feature.
await subscrio.Addons.CreateAddonAsync(new CreateAddonDto(
    Key: "seat-pack",
    ProductKey: "studio",
    DisplayName: "Extra seats",
    FeatureValues: new() { ["seats"] = "3" }));
Errors (3)
  • ValidationException: A key, label, mode, priority, or feature value is invalid.
  • NotFoundException: The product is missing or inactive, or a feature is not associated with it.
  • ConflictException: The add-on key already exists.

updateAddon

Update an add-on without changing its key or product. Supplied feature entries add, replace, or remove individual contributions; other entries are retained. Definition and contribution changes commit together. Switching to replacement mode requires every active attachment to have quantity one.

updateAddon(addonKey: string, input: UpdateAddonDto): Promise<AddonDto>

Parameters

Returns AddonDto: The saved definition, including its complete feature-value map.

Example

// seat-pack exists; seats and storage are associated with its product.
await subscrio.addons.updateAddon('seat-pack', {
  featureValues: { seats: '5', storage: null }
});
Errors (3)
  • ValidationError: A supplied property or contribution is invalid.
  • NotFoundError: The add-on or an associated feature is missing.
  • ConflictError: Replacement mode conflicts with an active attachment quantity.
Task<AddonDto> UpdateAddonAsync(string key, UpdateAddonDto input)

Parameters

Returns AddonDto: The saved definition, including its complete feature-value map.

Example

// seat-pack exists; seats and storage are associated with its product.
await subscrio.Addons.UpdateAddonAsync("seat-pack", new UpdateAddonDto(
    FeatureValues: new() { ["seats"] = "5", ["storage"] = null }));
Errors (3)
  • ValidationException: A supplied property or contribution is invalid.
  • NotFoundException: The add-on or an associated feature is missing.
  • ConflictException: Replacement mode conflicts with an active attachment quantity.

getAddon

Retrieve one add-on definition, including archived definitions.

getAddon(addonKey: string): Promise<AddonDto | null>

Parameters

  • addonKey: Add-on key.

Returns AddonDto | null: Definition and complete contributions, or null when the key is missing.

Example

const addon = await subscrio.addons.getAddon('seat-pack');
console.log(addon?.featureValues);
Task<AddonDto?> GetAddonAsync(string key)

Parameters

  • key: Add-on key.

Returns AddonDto?: Definition and complete contributions, or null when the key is missing.

Example

var addon = await subscrio.Addons.GetAddonAsync("seat-pack");
Console.WriteLine(addon?.FeatureValues.Count);

listAddons

List a product's add-ons in ascending key order. Both active and archived definitions are included unless filtered. TypeScript also supports searching by add-on key.

listAddons(productKey: string, filter?: PageFilter): Promise<AddonDto[]>

Parameters

  • productKey: Product whose add-ons to retrieve.
  • filter: Optional PageFilter. Defaults to 50 results at offset zero.

Returns AddonDto[]: Matching definitions and contributions; empty when no results or product exist.

Example

const addons = await subscrio.addons.listAddons('studio', { status: 'active' });
console.log(addons);
Errors (1)
  • ValidationError: Pagination is outside the allowed range.
Task<List<AddonDto>> ListAddonsAsync(string productKey, int limit, int offset, string? status)

Parameters

  • productKey: Product whose add-ons to retrieve.
  • limit: Optional page size, 1 to 500; defaults to 50.
  • offset: Optional nonnegative number of records to skip; defaults to zero.
  • status: Optional status filter; defaults to null, which includes all statuses.

Returns List<AddonDto>: Matching definitions and contributions; empty when no results or product exist.

Example

var addons = await subscrio.Addons.ListAddonsAsync("studio", status: "active");
Console.WriteLine(addons.Count);
Errors (1)
  • ValidationException: Pagination is outside the allowed range.

archiveAddon

Archive the add-on to prevent new attachments. Existing attachments and their contributions remain; archive does not detach subscriptions.

archiveAddon(k: string): Promise<void>

Parameters

  • k: Add-on key.

Returns No returned value.

Example

// seat-pack must exist.
await subscrio.addons.archiveAddon('seat-pack');
Errors (1)
  • NotFoundError: The add-on does not exist.
Task ArchiveAddonAsync(string key)

Parameters

  • key: Add-on key.

Returns No returned value.

Example

// seat-pack must exist.
await subscrio.Addons.ArchiveAddonAsync("seat-pack");
Errors (1)
  • NotFoundException: The add-on does not exist.

unarchiveAddon

Restore the add-on to active status so it can be attached again. Existing definitions and attachments are retained.

unarchiveAddon(k: string): Promise<void>

Parameters

  • k: Add-on key.

Returns No returned value.

Example

// seat-pack must exist.
await subscrio.addons.unarchiveAddon('seat-pack');
Errors (1)
  • NotFoundError: The add-on does not exist.
Task UnarchiveAddonAsync(string key)

Parameters

  • key: Add-on key.

Returns No returned value.

Example

// seat-pack must exist.
await subscrio.Addons.UnarchiveAddonAsync("seat-pack");
Errors (1)
  • NotFoundException: The add-on does not exist.

deleteAddon

Permanently delete an archived add-on and its feature contributions. Any attachment history blocks deletion, including cancelled attachments.

deleteAddon(k: string): Promise<void>

Parameters

  • k: Add-on key.

Returns No returned value.

Example

// seat-pack must exist and be archived with no attachment history.
await subscrio.addons.deleteAddon('seat-pack');
Errors (2)
  • NotFoundError: The add-on does not exist.
  • ConflictError: The add-on is active or has attachment history.
Task DeleteAddonAsync(string key)

Parameters

  • key: Add-on key.

Returns No returned value.

Example

// seat-pack must exist and be archived with no attachment history.
await subscrio.Addons.DeleteAddonAsync("seat-pack");
Errors (2)
  • NotFoundException: The add-on does not exist.
  • ConflictException: The add-on is active or has attachment history.

Data types

For input types, Required means the caller must supply the property. For returned types, it means the property is present; nullability is shown separately.

CreateAddonDto

Properties used to define an add-on.

Field Type Required Default Meaning
key string Yes None Globally unique add-on key; cannot be changed.
productKey string Yes None Owning product; cannot be changed.
displayName string Yes None Nonblank label, at most 255 characters.
description string | undefined No None Optional description.
compositionMode "additive" | "override" | undefined No additive Add contributions to the base value, or replace it. Replacement attachments require quantity one.
priority number | undefined No 0 Lower values win when choosing between replacements. .NET uses a 32-bit integer; TypeScript accepts integers from -2,147,483,647 to 2,147,483,647.
metadata Record<string, unknown> | undefined No None Application-defined metadata.
featureValues Record<string, string> | undefined No None Associated feature keys mapped to contributions, stored as strings and validated for the feature type.
Property Type Required Default Meaning
Key string Yes None Globally unique add-on key; cannot be changed.
ProductKey string Yes None Owning product; cannot be changed.
DisplayName string Yes None Nonblank label, at most 255 characters.
Description string? No null Optional description.
CompositionMode string No additive Add contributions to the base value, or replace it. Replacement attachments require quantity one.
Priority int No 0 Lower values win when choosing between replacements. .NET uses a 32-bit integer; TypeScript accepts integers from -2,147,483,647 to 2,147,483,647.
Metadata Dictionary<string, object?>? No null Application-defined metadata.
FeatureValues Dictionary<string, string>? No null Associated feature keys mapped to contributions, stored as strings and validated for the feature type.

AddonDto

Complete add-on definition. Products and plans include their product's catalog; features include contributing add-ons, and subscriptions include attached definitions.

Field Type Required Default Meaning
key string Yes Not applicable Globally unique add-on key; cannot be changed.
productKey string Yes Not applicable Owning product; cannot be changed.
displayName string Yes Not applicable Nonblank label, at most 255 characters.
description string | undefined No Not applicable Optional description.
compositionMode "additive" | "override" Yes Not applicable Add contributions to the base value, or replace it. Replacement attachments require quantity one.
priority number Yes Not applicable Lower values win when choosing between replacements. .NET uses a 32-bit integer; TypeScript accepts integers from -2,147,483,647 to 2,147,483,647.
metadata Record<string, unknown> | undefined No Not applicable Application-defined metadata.
featureValues Record<string, string> Yes Not applicable Associated feature keys mapped to contributions, stored as strings and validated for the feature type.
status "active" | "archived" Yes Not applicable Catalog status.
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 Globally unique add-on key; cannot be changed.
ProductKey string Yes Not applicable Owning product; cannot be changed.
DisplayName string Yes Not applicable Nonblank label, at most 255 characters.
Description string? Yes Not applicable Optional description.
CompositionMode string Yes Not applicable Add contributions to the base value, or replace it. Replacement attachments require quantity one.
Priority int Yes Not applicable Lower values win when choosing between replacements. .NET uses a 32-bit integer; TypeScript accepts integers from -2,147,483,647 to 2,147,483,647.
Metadata Dictionary<string, object?>? Yes Not applicable Application-defined metadata.
FeatureValues Dictionary<string, string> Yes Not applicable Associated feature keys mapped to contributions, stored as strings and validated for the feature type.
Status string Yes Not applicable Catalog status.
CreatedAt string Yes Not applicable Creation time in UTC.
UpdatedAt string Yes Not applicable Last update time in UTC.

UpdateAddonDto

Editable add-on properties. Feature contributions are patched per key; metadata is replaced as a whole.

Field Type Required Default Meaning
displayName string | undefined No None Nonblank label, at most 255 characters.
description string | undefined No None Optional description.
compositionMode "additive" | "override" | undefined No None Add contributions to the base value, or replace it. Replacement attachments require quantity one.
priority number | undefined No None Lower values win when choosing between replacements. .NET uses a 32-bit integer; TypeScript accepts integers from -2,147,483,647 to 2,147,483,647.
metadata Record<string, unknown> | undefined No None Replaces the saved metadata object. An empty object clears its entries.
featureValues Record<string, string | null> | undefined No None Omit to keep all contributions. Supplied entries add or replace values; null removes a key. An empty map makes no changes. A null map is rejected.
Property Type Required Default Meaning
DisplayName string? No null Nonblank label, at most 255 characters.
Description string? No null Optional description.
CompositionMode string? No null Add contributions to the base value, or replace it. Replacement attachments require quantity one.
Priority int? No null Lower values win when choosing between replacements. .NET uses a 32-bit integer; TypeScript accepts integers from -2,147,483,647 to 2,147,483,647.
Metadata Dictionary<string, object?>? No null Replaces the saved metadata object. An empty object clears its entries.
FeatureValues Dictionary<string, string?>? No null Omit to keep all contributions. Supplied entries add or replace values; null removes a key. An empty map makes no changes. A null map also makes no changes.

PageFilter

TypeScript pagination and filtering options. .NET takes pagination and status as individual method arguments and has no search argument.

Field Type Required Default Meaning
limit number No 50 Integer page size, 1 to 500.
offset number No 0 Nonnegative safe integer; number of rows to skip.
search string No None Case-insensitive key pattern; SQL wildcard characters apply.
status string No None Filter by active or archived status.

No PageFilter DTO is used by this method. See the parameters of ListAddonsAsync.