Skip to main content
You can attach addons when the subscription is created. After that, attach and remove them through the subscription modification API with type: "addon" and addon_bulk_params. One request can carry any mix of attaches and removals. They apply as a single transaction and settle as one netted charge or credit, which you can preview before applying.

Before you start

An attachment is validated before anything is written:
  • The addon must be published.
  • The subscription must be active or draft. Trialing subscriptions cannot take addons.
  • The addon needs at least one charge compatible with the subscription: same currency, and a billing period that equals or divides evenly into the subscription’s (daily and weekly charges must match it exactly). An addon with no compatible charge, including an entitlement-only addon, is rejected. See compatibility rules.
  • One-time charges qualify whatever their billing period, and each bills on the invoice whose period contains its start date. On an existing subscription, a one-time charge attached with none to start mid-period is never invoiced, because that period’s advance invoice has already gone out; attach it with change_at: "end_of_period" to bill it on the renewal invoice. With create_prorations, attaching or removing an addon that carries a one-time charge fails with line item billing_period must equal or strictly divide the subscription billing_period.
  • Metered features must not conflict: if the plan, an addon already on the subscription, or another addon in the same request entitles the same feature, their usage_reset_period values have to agree, or the request fails with Feature <feature_id> is already measured over <period>, but this addon measures it over <period>. The exception is an addon removed in the same request: when it ends on or before the new addon starts, their reset periods may differ, so you can swap them in one request.
  • A future-dated change cannot cut into a running entitlement grant window. That covers attaching an addon that grants a metered feature with a grant window already running on the subscription, and removing an addon whose grant window is running. Apply such changes immediately or at the period end; a date in between fails with Apply this change immediately, or schedule it for the period end.
When a request changes several addons, every entry is checked, and one failing entry rejects the whole request.

At subscription creation

Pass addons in the addons array. Each entry takes the same fields as a post-creation attach.
  • start_date defaults to the subscription start date.
  • No separate proration settlement is created at creation. The addon’s in-advance charges land on the subscription’s first invoice, and its in-arrear charges on the period-end invoice.
  • An addon start_date after the subscription start is charged only for the time it covers. A short first period from a calendar billing cycle is prorated only when the subscription is created with proration_behavior: "create_prorations".
  • The new subscription must start active or draft. If it starts trialing, or incomplete because of its payment_behavior, the request fails with Addon can only be added to active or draft subscriptions.
  • A single request accepts at most 20 addon entries.

Attach addons to an existing subscription

Call the modification API with type: "addon" and one entry per addon in addon_bulk_params.adds:
Run the same body against /modify/preview first to see the resulting line items, invoice, or credit without writing anything. In a preview, new associations and line items carry the ID (preview-created), and the invoice or wallet credit carries (preview-invoice) or (preview-wallet-credit) with status: "preview". Previews quote the addon’s list prices and default quantities; override_line_items are applied only on execute. The execute response reports everything the change touched, with one addon_associations entry per attach:
invoices[].status is the payment status of the settlement invoice, such as PENDING or SUCCEEDED. A credit to the wallet appears instead as action: "wallet_credit" with status: "issued".
Store the addon_associations[].id values from the response. Removing an addon later requires its association ID, not the addon ID. GET /v1/subscriptions/{id}/addons/associations also lists active associations, but only those that overlap the current billing period; an addon scheduled to start after the period end appears there once its period begins.

Addon attach fields

Each entry in adds takes: To gate a change behind a payment, add a checkout object at the top level of the modification request, next to type and addon_bulk_params; it is not a field of an attach entry. See payment-gated addon changes.

Addon quantity

There is no quantity field on the attach itself. To sell more than one unit:
  • Override the charge quantity: pass override_line_items with the fixed charge’s price_id and the quantity.
  • Attach the addon again: list the same addon_id more than once in adds, or attach it again in a later request. Each attachment is an independent association with its own line items and entitlements, so two attachments of a seat addon are two seats.
Without an override, a fixed charge’s quantity defaults to its min_quantity, or 1.

Remove addons from a subscription

Send one entry per association in addon_bulk_params.removes:

Addon removal fields

Each entry in removes takes: Removal behavior to know:
  • The default, removing at period end, produces zero credit: the customer keeps the addon until the date they already paid for.
  • A onetime addon cannot be removed at all: attaching it already set its end date, so a removal fails with This addon is already marked for removal.
  • An addon that carries a one-time charge can be removed only without create_prorations; with it, the removal fails with line item billing_period must equal or strictly divide the subscription billing_period.
  • The association’s addon_status flips to cancelled as soon as the removal is accepted, even when the end date is in the future. Billing and entitlements continue until the end_date, but the association no longer appears in GET /v1/subscriptions/{id}/addons/associations, which lists active associations only.
  • A second removal of the same association fails with This addon is already marked for removal.

Attach and remove addons in one request

Combine adds and removes to change several addons at once, for example to move a customer from one support tier to another:
  • A request holds between 1 and 20 entries across adds and removes.
  • The same addon may appear more than once in adds. An association may appear only once in removes; a repeat fails with Each addon association can be removed at most once per request.
  • Each entry keeps its own timing and proration setting, with one exception: two attaches that start within the current period and grant the same feature through entitlement grants must use the same start date, or the request fails with Send them as separate changes, or give both the same date.
  • Everything runs in a single transaction: removals first, then attaches. If any entry fails, nothing is applied.
  • An addon removed here no longer blocks a replacement that measures the same metered feature over a different reset period, as long as the removal takes effect no later than the attach. See Before you start.
  • All charges and credits from the request are netted into one settlement document, described below.
  • The response lists every association the request touched: attaches with change_action: "created", and removals with change_action: "ended", addon_status: "cancelled", and their end_date.

Proration and settlement

With proration_behavior: "create_prorations", a mid-cycle change is priced for the remainder of the period:
  • Fixed charges billed in advance are prorated on attach, and credited for unused time on removal, capped at what was invoiced for the period containing the removal date, or at list price when nothing has been invoiced for it yet.
  • Fixed charges billed in arrear raise no upfront charge; the next invoice bills the prorated amount.
  • Usage charges are never prorated; usage is billed at period end as usual.
  • A charge on a different cadence from the subscription is prorated against its own period, not the subscription’s.
The charges and credits of every entry in the request are then netted into a single document: An entry with proration_behavior: "none", or with no proration_behavior, adds nothing to that document. Its in-advance charges are first billed on the renewal invoice, for the next period, so the rest of the current period goes unbilled. Its in-arrear charges are billed at period end for the time the addon was active.

Entitlements and credit grants on attach

  • The addon’s entitlements join the subscription’s from the association start and leave at its end. With create_prorations, a mid-cycle attach prorates entitlement grant quotas for the time left in the window, and the first credit grant for the time left in the period; with none, both are granted in full. Quota already granted is never taken back.
  • The override_entitlements array on subscription creation rejects addon entitlements.
  • The addon’s credit grants are cloned to the subscription and credit the prepaid wallet. Recurring grants repeat each period while the association is active. Removing the addon cancels future grant applications without clawing back credits already granted. Grants are tracked per addon, not per attachment, so removing one attachment of a duplicated addon stops future grants for all of its attachments.

Payment-gated addon changes

Pass a checkout object at the top level of the modification request to hold the change until the customer pays, using the same checkout session flow as subscription creation:
  • Checkout requires an active subscription; a request against a draft subscription is rejected.
  • override_line_items and line_item_commitments cannot be combined with checkout; the request is rejected.
  • Only entries with create_prorations put an amount on the checkout. When the netted amount is not a charge, including when no entry uses create_prorations, no session opens and the change applies immediately without payment. The request must still pass the checks above.
  • While payment is pending, each attached association’s addon_status is pending: no line items, no entitlements, no credit grants. Removals in the same request wait too; the addons they end stay active until the customer pays.
  • Completion applies the whole change, removals included. Expiry or cancellation of the session archives the pending associations, and the removals never happen.
  • While the session is open, an addon it is set to remove cannot be removed by another request (Complete or cancel the pending checkout for this subscription first), and neither can a pending association (Complete or cancel the pending checkout for this addon first).
  • One open checkout session is allowed per subscription.
See Checkout sessions for the session object, redirect URLs, and expiry cleanup.

Plan changes and cancellation

  • A swap-in-place plan change (/change/v2) keeps addon associations by default. Its entity_policies.addons object sets a default_behaviour of carry or drop, with per-association overrides. Dropped addons end at the change, and are credited for unused time only when the change uses proration_behavior: "create_prorations" or billing_period_behaviour: "anchor_at_effect".
  • The legacy plan change (/change/execute) cancels the subscription and creates a new one; addons are not carried over.
  • Cancelling a subscription cancels its addon associations, ends their line items, and stops future credit grant applications. Scheduled cancellations do this when they take effect.

Webhooks

An addon change fires one subscription.updated once it is applied, however many addons the request touched. A payment-gated change fires it when its checkout completes. There are no addon.* events. Payment-gated flows also emit the checkout.session.* events.

Via dashboard

In the dashboard, subscriptions are called contracts and addons are add-ons.

While creating a contract

On the Charges & add-ons step of a new contract, the Add-ons card collects the addons to attach:
  1. Pick an addon under Add-on. A dialog opens listing the addon’s charges in the contract’s currency and billing period, including one-time charges.
  2. Optionally, use a charge’s ⋯ menu to change how it bills on this contract: Override price sets a new billing model and price, and Add commitment (usage charges only) sets a commitment. Reset to add-on price undoes both.
  3. Click Add add-on. The addon joins the card’s table, which lists each charge’s price and marks a changed one (changed).
  4. To attach more, pick them under Add another. Until the contract is created, each addon’s ⋯ menu offers Edit, which reopens its dialog, and Remove add-on.
The Add add-on dialog for Advanced analytics on a new contract, with the usage charge's menu showing Override price and Add commitment

On an existing contract

The Add-ons section on the contract page lists each attached addon with its status, start date, and end date.
  • Attach: click Add add-on and choose the Add-on. Its charges appear below, with the same Override price and Add commitment options as on a new contract. Click Add add-on; the addon starts now, as a recurring addon with no proration.
  • Remove: open the addon’s ⋯ menu and select Remove add-on. It comes off the contract at the end of the current billing period; charges already billed are unaffected.
The Add add-on dialog on a contract page with Advanced analytics chosen and its fixed charge repriced
The dashboard attaches or removes one addon at a time. To set a charge quantity, a one-time cadence, a custom start or end date, or proration, or to change several addons in one request, use the API described above.

Legacy addon requests

Two older ways to change addons still work, and both run through the same batch logic:
  • addon_params on the modification API changes one addon per request: "action": "add" with the attach fields under add, or "action": "remove" with the removal fields under remove. It is applied as a batch of one entry. It cannot be sent together with addon_bulk_params, and a removal sent this way cannot carry checkout.
  • POST /v1/subscriptions/addon and DELETE /v1/subscriptions/addon are deprecated. POST takes the attach fields plus subscription_id and an optional inline checkout; DELETE takes the removal fields and finds the subscription from the association.
Use addon_bulk_params for new integrations: a single attach or removal is a request with one entry. Unlike the deprecated endpoints, the modification API also offers previews and reports every change in one response.