| name | stigg-subscriptions |
| description | Use when operating subscriptions in Stigg โ provision a customer onto a plan, preview a subscription's pricing, update an active subscription (plan, add-ons, period, quantities, coupons, spend limits), cancel, run free trials and convert them to paid, support multiple subscriptions per customer (workspaces / projects), or migrate an existing subscription to the latest published plan version. Triggers include "provisionSubscription", "preview a subscription", "upgrade", "downgrade", "cancel subscription", "schedule cancellation", "trial expired", "migrate subscription to latest version". |
Stigg Subscriptions โ Lifecycle Operations
This skill covers day-to-day subscription operations: provision, preview, update, cancel, trials, multi-subscription products, and plan-version migration (moving an existing sub from plan v1 to plan v2 after a publish).
Before You Start
Per the umbrella stigg skill: search first. Provisioning options, billing-cycle behavior, and trial-conversion semantics evolve. Open the relevant SDK / REST page (Mintlify Stigg docs MCP) before authoring.
The Operation Map
| Op | Purpose | Reference |
|---|
| Provision | Create a subscription for a customer on a plan (+ add-ons, trial, billing details) | references/provisioning.md |
| Preview | Calculate pricing for a hypothetical subscription before provisioning | inline below |
| Update | Change an active subscription's plan / add-ons / period / quantities / spend / coupons / trial | references/updates.md |
| Cancel | End a subscription immediately, at end-of-period, or on a specific date | inline below |
| Trials | Start a trial, convert to paid, handle expiry | references/trials.md |
| Multiple active subscriptions | One customer, many subscriptions, scoped by resourceId | inline below |
| Plan-version migration | Move an existing sub from plan v1 to plan v2 (after a publish) | references/plan-version-migration.md |
Provision a Subscription
Minimal backend call
const sub = await stigg.provisionSubscription({
customerId: 'customer-123',
planId: 'plan-pro',
billingCountryCode: 'US',
});
The provisioning surface includes (see references/provisioning.md for the full list):
- Resource ID โ required when the product allows multiple active subscriptions.
- Billing period โ monthly / annual / etc., for paid plans.
- Plan configuration โ unit quantities for in-advance commitment charges and variable entitlements; price overrides.
- Add-ons โ list of add-ons (and quantities) compatible with the plan.
- Subscription start date โ
Immediately (default) / EndOfCurrentBillingPeriod (if an active paid sub already exists) / SpecificDate (past = back-dated, no immediate charge; future = activates on date).
- Free trial โ applicable to paid / custom plans.
- Spend management โ
minimumSpend, maximumSpend.
- Discounts โ applied coupons (catalog-wide or ad-hoc subscription-specific).
- Payment method โ
automaticallyUsePaymentMethodOnFile / generate-an-invoice / no-payment-via-Stigg.
- Billing cycle anchor โ
UNCHANGED (default) / NOW.
- Proration โ
ProrateNow / ProrateOnNextInvoice / NoProration.
Generous-entitlement rule: when a customer's effective entitlements come from multiple sources โ active subscription, add-ons, trial, promotional entitlements, additional product subscriptions โ Stigg picks the most generous value across all of them. The "trial vs paid" case is just one instance of this rule; it applies whenever sources overlap.
Preview a Subscription
Before provisioning, preview the immediate and recurring invoices:
const preview = await stigg.previewSubscription({
customerId: 'customer-123',
planId: 'plan-pro',
billingPeriod: 'MONTHLY',
addons: [{ addonId: 'addon-seats', quantity: 10 }],
couponId: 'SAVE20',
subscriptionId: 'sub-789',
});
Node SDK / GraphQL returns immediateInvoice and recurringInvoice with each amount as a { amount, currency } Money object (lowercase subtotal). Direct REST callers see a flatter DTO with scalar amounts and the field name subTotal (capital T). Amounts are in full dollars / units of the currency, not cents โ 49 means $49.00 (Stripe convention is the opposite, this catches Stripe-savvy devs). See references/provisioning.md for the full shape and previewSubscription use cases.
Update a Subscription
Critical: updateSubscription (the GraphQL mutation) does not support changing the plan. To change a subscription's plan, call provisionSubscription again โ Stigg routes it through the right mechanism (in-place update or replace, depending on plan-type transition; see the migration matrix below).
await stigg.updateSubscription({
subscriptionId: 'sub-123',
addons: [{ addonId: 'addon-seats', quantity: 10 }],
billingPeriod: 'ANNUAL',
});
await stigg.provisionSubscription({
customerId: 'customer-123',
planId: 'plan-pro',
});
What updateSubscription directly supports (per the GraphQL mutation surface):
- Billing period (paid plans, e.g.
MONTHLY โ ANNUAL).
- Add-ons (replaces existing โ pass the new full list).
- Billable features (in-advance commitment quantities, per-unit quantities).
- Price overrides.
Other update flows surfaced by the Stigg app UI (trial extension / shortening, spend-limit changes, coupon application, billing-cycle anchor reset, proration on the change) flow through separate SDK methods or provisionSubscription re-calls โ search the docs for the specific operation.
Scheduled updates replace, don't queue: a new update overrides any pending scheduled update and applies immediately (documented for the Stigg app UI; SDK behavior generally matches โ confirm in your SDK's docs).
Detailed flow + patterns: references/updates.md.
Cancel a Subscription
Via @stigg/node-server-sdk (which translates to the cancelSubscription GraphQL mutation):
await stigg.cancelSubscription({
subscriptionId: 'sub-789',
subscriptionCancellationTime: 'END_OF_BILLING_PERIOD',
});
Field-name note: Node SDK uses subscriptionId. Python / Go / Ruby / Java / .NET SDKs and the raw GraphQL mutation use subscriptionRefId. Direct REST takes the ID in the URL path.
subscriptionCancellationTime:
| Value | Behavior |
|---|
IMMEDIATE | Cancel immediately. |
END_OF_BILLING_PERIOD | Cancel at the end of the current billing period. Default for most products. Not applicable to custom-priced plans or trial subscriptions. |
SPECIFIC_DATE | Cancel on the date specified by endDate. Not applicable for trial periods. |
subscriptionCancellationAction:
| Value | Behavior |
|---|
DEFAULT | Product's default cancellation behavior (revoke access or downgrade to free, per product policy). |
REVOKE_ENTITLEMENTS | Immediately revoke all entitlements upon cancellation. |
States after cancel: CANCELED (already ended) or CANCELLATION_SCHEDULED (pending).
Direct REST users (calling https://api.stigg.io/api/v1 via curl): the unprefixed REST field names are cancellationTime, cancellationAction, endDate, prorate. Same enum values.
Trials
Trials apply to paid and custom plans. The plan defines the default trial; provisioning can override it.
- Provision with trial โ pass trial config at provision time.
- Convert trial โ paid โ provision a paid subscription on top; Stigg starts the paid plan at the trial end.
- Trial expired without conversion โ fires the
trial.expired event; trigger win-back from your app.
- One trial per customer per product in self-served flows (admin overrides exist).
- Customers who already paid are not eligible for another self-serve free trial.
Detailed mechanics + examples (in-app upgrade, trial with add-ons): references/trials.md.
Multiple Active Subscriptions Per Customer
For multi-tenant products (workspaces / projects / apps), a single customer holds many subscriptions, scoped by resourceId:
const sub = await stigg.provisionSubscription({
customerId: 'customer-123',
resourceId: 'workspace-abc',
planId: 'plan-team',
});
Once enabled (it's a product-level setting, fixed at product creation):
- Pass
resourceId on every relevant call โ provision, update, entitlement check, usage report, paywall widget.
- The customer can have separate plans on each workspace, all paid with the same payment method.
- Trial vs paid: at most one active trial and one active non-trial subscription per
(customer, resource) pair.
- Combine with single-instance products (set the other product to "single active subscription") to model "account + sub-accounts" / "platform + app instances" โ e.g., Webflow's account + per-site model.
Once a product has any subscriptions, you cannot toggle multi-active on/off. Decide at product creation.
Plan-Version Migration (Catalog v1 โ v2)
When a plan is republished, existing subscriptions stay on the old version unless migrated. Routine, ongoing operation.
Catalog-side publish flow (drafts, version policy, what triggers grandfathering) lives in stigg-pricing-modeling/references/plans.md. This section is the subscription-side migration mechanics.
Two migration mechanisms, picked automatically by Stigg based on the plan-type transition:
| Path | Mechanism | Why |
|---|
| Free โ Paid | Provision new subscription | Paid plans need billable metric values. |
| Free โ Custom | Provision new subscription | Custom plans need values for variable entitlements. |
| Paid โ Free | Migrate to latest version | In-place. |
| Paid โ Custom | Migrate to latest version | In-place; the existing external-billing-system subscription is not canceled โ only Stigg-side metadata is removed. |
| Custom โ Paid | Provision new subscription | Paid plans need billable metric values. |
| Custom โ Free | Migrate to latest version | In-place. |
Triggering migration:
- UI: open the subscription,
โฎ โ Migrate to latest โ pick Immediately or At end of current period.
- Programmatic: the migrate-subscription mutation / SDK method. Allows gradual rollout.
If migration is immediate and the customer's current price differs from the latest published price, Stigg auto-charges or credits the prorated amount.
Detailed migration reference: references/plan-version-migration.md.
When NOT to Use This Skill
- Modeling features / plans / add-ons โ
stigg-pricing-modeling.
- Runtime entitlement checks / usage reporting โ
stigg-entitlements.
- Strategic advice on pricing models โ
stigg-pricing-expert.
Common Mistakes
| Mistake | Fix |
|---|
Forgetting resourceId on multi-active products | Every call (provision / update / entitlement / usage / widget) needs it. |
| Treating scheduled updates as a queue | A new update replaces scheduled ones. If you need a queue, model it in your app. |
| Cancelling immediately when the product policy says end-of-period | Use the product's default; opt-in to immediate only when you mean it. |
| Trying to cancel a custom-priced plan at end of period | Not supported by the cancellation modal. Use a specific date or coordinate with billing. |
| Self-serve trial for a customer who's already paid | Not eligible. Admin override needed. Surface the right CTA in your app. |
Skipping previewSubscription before charging | Customers expect to see what they'll pay. Preview first, then provision. |
Not setting billingCycleAnchor: NOW on a major upgrade | The customer's bill cycle drifts. Reset explicitly when the change should start a fresh period. |