New Features
License Management Module
A newclient.license module provides full lifecycle management for software licenses.license.activate({ licenseKey, customerId?, instanceName?, metadata? })Activates a license key and creates a new instance. Returns a LicenseActivateResponse containing the instanceId, activatedAt, expiresOn, and the full LicenseDetails object.license.deactivate({ licenseKey, instanceId })Deactivates a specific license instance. Returns a LicenseDeactivateResponse with message and deactivatedAt.license.validate({ licenseKey, instanceId? })Validates a license key and optionally a specific instance. Returns a LicenseValidateResponse with valid, code, detail, metadata, and the full LicenseDetails.New TypeScript Interfaces
LicenseDetails— Full license object withid,licenseKey,activatedOn,expiresOn,activationUsage,activationLimit,enabled,customer,plan, andsubscription.LicenseCustomer—{ customerId, name?, email? }nested inLicenseDetails.LicensePlan— Expanded withdescription,version,isLatest, andproduct(nestedLicensePlanProduct).LicensePlanProduct—{ id, identifier, name, taxCode?, createdOn?, modifiedOn? }.LicenseActivateResponse,LicenseDeactivateResponse,LicenseValidateResponse— Typed responses for each operation.
SubscriptionData New Fields
Three new fields derived from the subscription’s recurrence string are now included in SubscriptionData (returned within LicenseDetails.subscription and customer subscription summaries):billingType—"SUBSCRIPTION"if the plan has a recurrence,"ONE_TIME"otherwise.recurrenceUnit— Integer unit from the recurrence string (e.g.1from"1 month"), ornull.recurrenceType— Recurrence period in uppercase (e.g."MONTH"), ornull.
New Features
Customer Portal Module
A newclient.portal module lets you create pre-authenticated customer portal sessions server-side and redirect customers directly to their self-serve portal.portal.createSession({ customerId })CreatePortalSessionResponse with:token— Session token authenticating the portal session.email— The customer’s email address.customerPortalUrl— Pre-authenticated URL to redirect the customer to.
New Features
Entitlements Aggregation Engine
When a customer has multiple subscriptions, the API can return duplicatefeatureId entries. The SDK now automatically aggregates them into a single Entitlement object per feature:- Numeric fields (
usageLimit,currentUsage,remaining) are summed across all entries hasAccessistrueif any raw entry grants accesshardLimitistrueif any entry sets it- All raw entries are preserved in the
.items[]array
Entitlement Interface
New type representing an aggregated entitlement with an items: EntitlementDetail[] field containing the raw entries that were aggregated.getRawEntitlement({ customerId, featureId })
Returns the raw API response for a specific feature (CheckEntitlementsResponse with customerId wrapper), without any aggregation:getRawEntitlements({ customerId })
Returns the raw API response for all entitlements, without any aggregation:client.subscription Deprecated Alias
A backward-compatible getter that maps client.subscription to client.subscriptions, so existing code continues to work during migration.Breaking Changes
client.subscription Renamed to client.subscriptions
The subscriptions module now uses the plural form for consistency with other modules (client.customers, client.entitlements, etc.):client.subscription accessor still works as a deprecated alias.getEntitlement() Returns Entitlement | null
Previously returned CheckEntitlementsResponse (the raw API shape with a customerId wrapper). Now returns a single aggregated Entitlement object with an .items[] array, or null if the feature is not found:getRawEntitlement().getAllEntitlements() Removed
Replaced by getEntitlements(), which returns Record<string, Entitlement> — a record keyed by featureId with aggregated values and an .items[] array:getRawEntitlements().FeatureType Changed: "LIMIT" → "CUSTOMIZABLE"
The FeatureType union no longer includes "LIMIT". Update any code that matches on this value:resetAt Removed from Aggregated Entitlement
Since resetAt can differ across subscriptions, it is only available on individual items:Fixed
- Fixed Python-style
try/exceptsyntax in subscription update documentation — replaced with JavaScripttry...catch. - Added missing
try/catcherror handling to subscription cancel documentation example. - Removed invalid JSON comments (
// Server-generated UUID) from documentation response blocks. - Fixed trailing comma in checkout session JSON response example.
- Fixed
"Node SDK Use"typo →"Node SDK User"in create customer documentation. - Fixed
True→true,bool→booleaninhasAccessdocumentation. - Replaced “Pydantic model” references with “TypeScript Interface” or “Object”.
- Replaced “Dictionary” with “Object” in parameter descriptions.
- Fixed Python-style
ACCESS_TOKEN = "..."→const ACCESS_TOKEN = "...";in setup example.