Subscriptions tools
MCP tools for Subscriptions: subscriptions_cancel, subscriptions_create, subscriptions_discounts_create, subscriptions_events_list, subscriptions_get, subscriptions_list, subscriptions_metrics, subscriptions_migrations_create, subscriptions_migrations_get, subscriptions_migrations_list, subscriptions_pause, subscriptions_preview_change, subscriptions_reactivate, subscriptions_resume, subscriptions_update.
subscriptions_cancel: Cancel a subscriptionsubscriptions_create: Create a subscriptionsubscriptions_discounts_create: Apply a coupon to a subscriptionsubscriptions_events_list: List a subscription's historysubscriptions_get: Get a subscriptionsubscriptions_list: List subscriptionssubscriptions_metrics: Subscription metricssubscriptions_migrations_create: Migrate subscribers to a new pricesubscriptions_migrations_get: Get a price migrationsubscriptions_migrations_list: List price migrationssubscriptions_pause: Pause a subscriptionsubscriptions_preview_change: Preview a subscription changesubscriptions_reactivate: Withdraw a scheduled cancellationsubscriptions_resume: Resume a paused subscriptionsubscriptions_update: Change plan or quantity of a subscription
subscriptions_cancel
Cancel a subscription. Operation subscriptions.cancel · Brand level · permission subscriptions:write · risk tier financial · since M5
Ends a subscription.
mode: at_period_end(default): it stays active until the current period ends (cancelAt), then ends;subscriptions.reactivatewithdraws the cancellation until then. Emitssubscription.cancel_scheduled.mode: now: it ends at once. Withprorate: truethe unused time of the current period goes to the customer's credit balance (at the prices' amounts, discounts taken into account). WithinvoiceNow(default) the metered usage up to now and any pending items are invoiced in a final invoice, which the credit balance reduces. An incomplete subscription's unpaid first invoice is voided. Emitssubscription.canceled.
mode: now with refund: true refunds the unused time of the current period to the customer's card instead:
every paid invoice of the subscription with time left gets a credit note at its original tax rates and a
refund (refunds.create with subscription_prorated; you need the refund permission, and support's refund
limit applies). An invoice paid by bank transfer or from the credit balance can't be refunded that way
(subscription_refund_not_supported: cancel with prorate: true instead).
feedback and comment record why the customer left. The customer's entitlements are recomputed.
The customer is emailed that the subscription is set to end or has ended. reason: replaced says another
subscription of the same customer takes its place (for example an upgrade bought through a new checkout): it is
recorded as cancellation.reason: replaced, the webhook events go out as usual, and the customer gets no
cancellation email, since the new subscription's own emails tell them what runs.
Annotations: readOnlyHint: false · destructiveHint: true · idempotentHint: false · openWorldHint: true
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (sub_…) | yes | – |
expectedVersion | integer | no | (1–9007199254740991) |
mode | one of at_period_end, now | no | at_period_end (default; it can be reactivated until then) or now. (default "at_period_end") |
prorate | boolean | no | now: credit the unused time of the current period to the customer's credit balance. (default false) |
refund | boolean | no | now: refund the unused time of the current period to the customer's card, with a credit note (needs the refund permission). (default false) |
invoiceNow | boolean | no | now: invoice the metered usage and pending items up to now in a final invoice. (default true) |
feedback | one of too_expensive, missing_features, switched_service, unused, customer_service, too_complex, low_quality, other | no | Why the customer is leaving. |
comment | string | no | (1–500 characters) |
by | one of customer, operator, system | no | Who asked: customer or operator (default operator). |
reason | one of cancellation_requested, replaced | no | cancellation_requested (default; the customer is emailed that it ends) or replaced: another subscription of the same customer takes its place (an upgrade bought through a new checkout), so the customer isn't emailed about this one ending. (default "cancellation_requested") |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: A field is malformed or out of range.resource_not_found: No subscription (or customer, price, coupon) with this ID is visible to the request.version_conflict: The subscription changed since you read it (expectedVersion), or at the same time; read it and retry.subscription_status_invalid: The subscription's status doesn't allow this (spec §16.1): seedetails.reason.subscription_refund_not_supported:refund: true, and an invoice with time left wasn't paid by card (bank transfer or credit balance): useprorate: true.refund_limit_exceeded:refund: trueby the support role, above the brand's refund limit: finance cancels it.registration_required: An invoice issued now can't be taxed: the seller isn't registered where the customer is (a new sale).jurisdiction_blocked: The customer's location is blocked for new sales.evidence_conflict: The customer's stored location evidence isn't enough to tax an invoice issued now (§13.3).permission_denied: The credentials can't change this brand's subscriptions (subscriptions:write).
Examples
Cancel at the end of the period
Arguments:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"feedback": "too_expensive",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "active",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
"quantity": 1,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "87000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
"billingCycleAnchor": "2026-10-13T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-11-13T12:00:00.000Z",
"trialStart": null,
"trialEnd": null,
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": true,
"cancelAt": "2026-11-13T12:00:00.000Z",
"canceledAt": null,
"endedAt": null,
"cancellation": {
"reason": "cancellation_requested",
"feedback": "too_expensive",
"comment": null,
"by": "operator"
},
"pause": null,
"discountIds": [],
"pendingUpdate": null,
"latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"incompleteExpiresAt": null,
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 3,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-20T09:00:00.000Z"
}
Cancel now and credit the unused time
Arguments:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"mode": "now",
"prorate": true,
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "canceled",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
"quantity": 1,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "87000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
"billingCycleAnchor": "2026-10-13T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-11-13T12:00:00.000Z",
"trialStart": null,
"trialEnd": null,
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": "2026-10-20T09:00:00.000Z",
"endedAt": "2026-10-20T09:00:00.000Z",
"cancellation": {
"reason": "cancellation_requested",
"feedback": null,
"comment": null,
"by": "operator"
},
"pause": null,
"discountIds": [],
"pendingUpdate": null,
"latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"incompleteExpiresAt": null,
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 3,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-20T09:00:00.000Z"
}
End a subscription another one replaced
The customer upgraded through a new checkout: the old plan ends now, without an email.
Arguments:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"mode": "now",
"reason": "replaced",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "canceled",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
"quantity": 1,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "87000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
"billingCycleAnchor": "2026-10-13T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-11-13T12:00:00.000Z",
"trialStart": null,
"trialEnd": null,
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": "2026-10-20T09:00:00.000Z",
"endedAt": "2026-10-20T09:00:00.000Z",
"cancellation": {
"reason": "replaced",
"feedback": null,
"comment": null,
"by": "operator"
},
"pause": null,
"discountIds": [],
"pendingUpdate": null,
"latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"incompleteExpiresAt": null,
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 3,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-20T09:00:00.000Z"
}
subscriptions_create
Create a subscription. Operation subscriptions.create · Brand level · permission subscriptions:write · risk tier financial · since M5
Starts a subscription of a customer to one or more recurring prices (spec §16.2). The prices must share a currency, and their intervals must be whole multiples of each other (monthly with yearly). A customer has at most one live item per metered price's meter.
- Trial:
trialEnd, elsetrialDays(0 = none), else the prices' shortest trial. The subscription istrialingand nothing is invoiced until the trial ends; free plans have no trial. - Free plans (only zero-amount licensed prices) are
activeat once, with no invoice and no payment method. - First invoice: licensed items for the first period, with the coupon or promotion code applied, taxed now
with the customer's stored location evidence (a new sale: a blocked location is refused). A later
billingCycleAnchorbills a prorated first period (prorationBehavior: nonebills nothing until then). A zero total isn't issued. - Collection:
charge_automaticallycharges the invoice to the customer's saved payment method (paymentMethodId, else their default): the subscription isincompleteuntil the payment succeeds (23 hours at most). Without a saved payment method the answer carriespaymentSetup.url, a hosted checkout in setup mode where the customer saves one; the first invoice is charged right after.send_invoiceemails the invoice with the bank transfer details and isactiveat once.
Emits subscription.created (and invoice.issued/invoice.finalized for the first invoice); the customer's
entitlements are recomputed. Dry-run it to see the first invoice before charging anyone.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
customerId | ID (cus_…) | yes | The customer (cus_…). |
items | array of object | yes | The recurring prices: one currency; intervals that are whole multiples of each other. (1–20 items) |
collectionMethod | one of charge_automatically, send_invoice | no | charge_automatically (the default payment method is charged) or send_invoice (the invoice is emailed with bank transfer details and paid by the due date). (default "charge_automatically") |
daysUntilDue | integer | no | send_invoice: days from an invoice's issue date to its due date (default 14). (0–365) |
trialDays | integer | no | Trial days (0 = no trial). Default: the shortest trial of the prices. (0–730) |
trialEnd | date-time (ISO 8601) | no | When the trial ends (instead of trialDays). |
trialEndBehavior | one of convert, cancel_if_no_payment_method, pause_if_no_payment_method | no | What happens at the trial's end without a payment method: convert (bill anyway), cancel_if_no_payment_method or pause_if_no_payment_method. (default "convert") |
couponId | ID (cpn_…) | no | A coupon to apply (cpn_…). |
promotionCode | string | no | A promotion code as the customer typed it (case doesn't matter). (1–50 characters) |
billingCycleAnchor | date-time (ISO 8601) | no | When the first full period starts (default: now, or the trial's end). A later anchor bills a prorated first period. |
prorationBehavior | one of create_prorations, always_invoice, none | no | With a later billingCycleAnchor: create_prorations and always_invoice charge the partial first period now; none bills nothing until the anchor. (default "create_prorations") |
paymentMethodId | ID (pm_…) | no | A saved payment method of the customer (pm_…); default: the customer's default method. |
setupSuccessUrl | string | no | Without a payment method (charge_automatically): where the setup checkout sends the customer after saving one. (at most 2000 characters) |
usageThreshold | object | no | Invoice metered usage as soon as what it would charge reaches this amount (spec §16.7): limits the credit risk of usage-heavy customers. In the subscription's currency, whole minor units. |
metadata | object | no | Your own key-value pairs (at most 50 keys). On updates the whole set is replaced. |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back. - Plan feature: needs
subscriptions.enabled.
Errors
validation_failed: A field is malformed or out of range.resource_not_found: No subscription (or customer, price, coupon) with this ID is visible to the request.customer_deleted: The customer was deleted.subscription_price_invalid: A price isn't recurring, is archived, is in another currency, or its interval doesn't combine with the others.subscription_meter_conflict: The customer already has a live subscription item for a metered price's meter.subscription_payment_method_invalid:paymentMethodIdisn't a saved, attached payment method of the customer.subscription_anchor_invalid:billingCycleAnchoris before the start or too far ahead.coupon_not_redeemable: The coupon is archived, expired or used up.promotion_code_not_redeemable: The promotion code can't be used for this customer or amount (details.reason).registration_required: An invoice issued now can't be taxed: the seller isn't registered where the customer is (a new sale).jurisdiction_blocked: The customer's location is blocked for new sales.evidence_conflict: The customer's stored location evidence isn't enough to tax an invoice issued now (§13.3).invoice_bank_transfer_missing:send_invoice: the entity has no bank transfer details to put on the first invoice.permission_denied: The credentials can't change this brand's subscriptions (subscriptions:write).entitlement_required: The organization's plan doesn't include subscriptions (subscriptions.enabled).org_suspended: Live mode, while the organization is suspended (§37.5).
Examples
Three seats and metered API calls, charged to the saved card
Arguments:
{
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"items": [
{
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"quantity": 3
},
{
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9"
}
],
"metadata": {
"crm_account": "A-1042"
},
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "incomplete",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
"quantity": 1,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "87000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
"billingCycleAnchor": "2026-10-13T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-11-13T12:00:00.000Z",
"trialStart": null,
"trialEnd": null,
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": null,
"endedAt": null,
"cancellation": null,
"pause": null,
"discountIds": [],
"pendingUpdate": null,
"latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"incompleteExpiresAt": "2026-10-14T11:00:00.000Z",
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 2,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z",
"paymentSetup": null
}
A 14-day trial without a saved card
The trial starts at once; paymentSetup.url lets the customer add a card before it ends.
Arguments:
{
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"items": [
{
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"quantity": 3
}
],
"trialDays": 14,
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "trialing",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
"quantity": 1,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "87000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": null,
"billingCycleAnchor": "2026-10-27T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-10-27T12:00:00.000Z",
"trialStart": "2026-10-13T12:00:00.000Z",
"trialEnd": "2026-10-27T12:00:00.000Z",
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": null,
"endedAt": null,
"cancellation": null,
"pause": null,
"discountIds": [],
"pendingUpdate": null,
"latestInvoiceId": null,
"incompleteExpiresAt": null,
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 1,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z",
"paymentSetup": {
"checkoutSessionId": "cs_01m4tx5nj8emwbyf7y9vcf47zj",
"url": "https://ownrecord.io/c/genno/cs_01m4tx5nj8emwbyf7y9vcf47zj?key=example",
"expiresAt": "2026-10-14T12:00:00.000Z",
"required": false
}
}
subscriptions_discounts_create
Apply a coupon to a subscription. Operation subscriptions.discounts.create · Brand level · permission subscriptions:write · risk tier financial · since M5
Applies a coupon (couponId) or a promotion code the customer gave (promotionCode) to the subscription from
now on: it discounts the subscription's next invoices for the coupon's duration, counted in the subscription's
billing periods. Promotion codes are checked against their restrictions; the redemption counts when the next
invoice is paid (at once for a trial). End a discount with discounts.delete. Emits discount.created and
subscription.updated.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (sub_…) | yes | – |
couponId | ID (cpn_…) | no | – |
promotionCode | string | no | A promotion code as the customer typed it (case doesn't matter). (1–50 characters) |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: A field is malformed or out of range.resource_not_found: No subscription (or customer, price, coupon) with this ID is visible to the request.subscription_status_invalid: The subscription's status doesn't allow this (spec §16.1): seedetails.reason.coupon_not_redeemable: The coupon is archived, expired or used up.promotion_code_not_redeemable: The promotion code can't be used (details.reason).discount_already_applied: The coupon is already applied to this subscription.permission_denied: The credentials can't change this brand's subscriptions (subscriptions:write).
Example
Apply the customer's promotion code
Arguments:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"promotionCode": "LAUNCH50",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "active",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
"quantity": 1,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "87000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
"billingCycleAnchor": "2026-10-13T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-11-13T12:00:00.000Z",
"trialStart": null,
"trialEnd": null,
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": null,
"endedAt": null,
"cancellation": null,
"pause": null,
"discountIds": ["disc_01m4tx5nj8emwbyf7y9vcf47z3"],
"pendingUpdate": null,
"latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"incompleteExpiresAt": null,
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 3,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-20T09:00:00.000Z"
}
subscriptions_events_list
List a subscription's history. Operation subscriptions.events.list · Brand level · permission subscriptions:read · risk tier read · since M5
Lists a subscription's history, newest first: creation, trial, activation, plan and quantity changes,
discounts, scheduled changes, pauses, cancellations, renewals and payment problems. Each entry has what changed
(before, after), how it moved monthly recurring revenue (mrrDelta), who did it and when.
Paginate with limit (1–100, default 10) and starting_after (the next_cursor of the previous page).
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (sub_…) | yes | – |
limit | integer | no | (1–100) |
starting_after | ID (sevt_…) | no | – |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Read-only: changes nothing;
idempotency_keyis ignored.
Errors
resource_not_found: No subscription with this ID is visible to the request.permission_denied: You can't see this brand's subscriptions (subscriptions:read).
Example
The latest changes
Arguments:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"limit": 2,
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}
Result output:
{
"object": "list",
"data": [
{
"id": "sevt_01m4tx5nj8emwbyf7y9vcf47zg",
"object": "subscription_event",
"livemode": false,
"subscriptionId": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"type": "upgraded",
"before": {
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"quantity": 3
}
]
},
"after": {
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y3",
"quantity": 3
}
],
"effective": "now",
"prorationBehavior": "always_invoice",
"invoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn"
},
"mrrDelta": {
"amount": "60000000",
"currency": "EUR"
},
"actor": {
"type": "user",
"id": "usr_01m4tx5nj8emwbyf7y9vcf47zk",
"via": "console"
},
"at": "2026-10-20T09:00:00.000Z"
},
{
"id": "sevt_01m4tx5nj8emwbyf7y9vcf47zh",
"object": "subscription_event",
"livemode": false,
"subscriptionId": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"type": "created",
"before": null,
"after": {
"status": "active"
},
"mrrDelta": {
"amount": "87000000",
"currency": "EUR"
},
"actor": {
"type": "user",
"id": "usr_01m4tx5nj8emwbyf7y9vcf47zk",
"via": "console"
},
"at": "2026-10-13T12:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}
subscriptions_get
Get a subscription. Operation subscriptions.get · Brand level · permission subscriptions:read · risk tier read · since M5
Reads a subscription: its status, items, billing period, trial, cancellation, pause, scheduled change
(pendingUpdate), discounts, latest invoice and its items' monthly recurring amount (mrr).
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (sub_…) | yes | – |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Read-only: changes nothing;
idempotency_keyis ignored.
Errors
resource_not_found: No subscription with this ID is visible to the request.permission_denied: You can't see this brand's subscriptions (subscriptions:read).
Example
An active subscription
Arguments:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}
Result output:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "active",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
"quantity": 1,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "87000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
"billingCycleAnchor": "2026-10-13T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-11-13T12:00:00.000Z",
"trialStart": null,
"trialEnd": null,
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": null,
"endedAt": null,
"cancellation": null,
"pause": null,
"discountIds": [],
"pendingUpdate": null,
"latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"incompleteExpiresAt": null,
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 2,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
}
subscriptions_list
List subscriptions. Operation subscriptions.list · Brand level · permission subscriptions:read · risk tier read · since M5
Lists the brand's subscriptions in the request's mode, newest first. Filter by customerId, status
(trialing, active, past_due, unpaid, paused, canceled, incomplete or incomplete_expired) or
priceId (subscriptions with an item on that price).
Paginate with limit (1–100, default 10) and starting_after (the next_cursor of the previous page).
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
customerId | ID (cus_…) | no | Only this customer's subscriptions. |
status | one of incomplete, incomplete_expired, trialing, active, past_due, unpaid, paused, canceled | no | Only subscriptions in this status. |
priceId | ID (price_…) | no | Only subscriptions with an item on this price. |
limit | integer | no | (1–100) |
starting_after | ID (sub_…) | no | – |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Read-only: changes nothing;
idempotency_keyis ignored.
Errors
validation_failed: A filter or pagination value is malformed.permission_denied: You can't see this brand's subscriptions (subscriptions:read).
Example
A customer's subscriptions
Arguments:
{
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}
Result output:
{
"object": "list",
"data": [
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "active",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
"quantity": 1,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "87000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
"billingCycleAnchor": "2026-10-13T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-11-13T12:00:00.000Z",
"trialStart": null,
"trialEnd": null,
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": null,
"endedAt": null,
"cancellation": null,
"pause": null,
"discountIds": [],
"pendingUpdate": null,
"latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"incompleteExpiresAt": null,
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 2,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}
subscriptions_metrics
Subscription metrics. Operation subscriptions.metrics · Brand level · permission subscriptions:read · risk tier read · since M5
The brand's monthly recurring revenue (MRR) per currency in the request's mode, from the subscriptions' history: MRR at the window's start and end, and what moved it in between: new (subscriptions that started paying), reactivation (resumed or recovered), expansion (upgrades, more seats), contraction (downgrades, fewer seats) and churn (canceled, paused, expired unpaid), with the churn rate (churned MRR / MRR at the start).
MRR counts active and past-due subscriptions' licensed items at their monthly amount (a year is 12 months),
before discounts and tax; trials, paused and ended subscriptions don't count. The window is [from, to),
by default the last 30 days.
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
from | date-time (ISO 8601) | no | The window's start (default: 30 days before to). |
to | date-time (ISO 8601) | no | The window's end (default: now). |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Read-only: changes nothing;
idempotency_keyis ignored.
Errors
validation_failed:fromisn't beforeto.permission_denied: You can't see this brand's subscriptions (subscriptions:read).
Example
The last 30 days
Arguments:
{
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}
Result output:
{
"object": "subscription_metrics",
"livemode": false,
"from": "2026-09-20T09:00:00.000Z",
"to": "2026-10-20T09:00:00.000Z",
"currencies": [
{
"currency": "EUR",
"mrr": {
"amount": "12450000000",
"currency": "EUR"
},
"startMrr": {
"amount": "11800000000",
"currency": "EUR"
},
"newMrr": {
"amount": "870000000",
"currency": "EUR"
},
"reactivationMrr": {
"amount": "0",
"currency": "EUR"
},
"expansionMrr": {
"amount": "240000000",
"currency": "EUR"
},
"contractionMrr": {
"amount": "60000000",
"currency": "EUR"
},
"churnedMrr": {
"amount": "400000000",
"currency": "EUR"
},
"netNewMrr": {
"amount": "650000000",
"currency": "EUR"
},
"churnRatePpm": "33898"
}
],
"truncated": false
}
subscriptions_migrations_create
Migrate subscribers to a new price. Operation subscriptions.migrations.create · Brand level · permission subscriptions:write · risk tier financial · since M5
Moves the subscriptions on one price to another at their renewals, after a notice (spec §16.14). Prices can't change once used, so changing what existing subscribers pay is a migration to a new price that bills alike (the same currency, interval and usage type, and meter for metered prices).
- Every matching subscription (an item on
fromPriceId;filternarrows by status, default trialing, active and past due, and by customer) gets a scheduled change (pendingUpdate) that swaps the item's price at its first renewal on or after the earliest change:noticeDaysfrom now (effective: next_renewal, default) oreffectiveDate(effective: date, itself at leastnoticeDaysaway). Quantities stay. - Each customer is emailed a notice
noticeDays(default 30) before their change. - The renewal applies the change and bills the new price.
subscriptions.migrations.getreports progress: scheduled, notified, applied, pending and skipped.
Subscriptions with another change already scheduled, or set to cancel, are skipped (skippedAtCreation). At
most 1,000 subscriptions per migration. Run it as a dry run first: it returns the counts and the monthly
recurring revenue before and after without changing anything. Each scheduled subscription emits
subscription.updated.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
fromPriceId | ID (price_…) | yes | The price subscribers pay today (price_…). |
toPriceId | ID (price_…) | yes | The price they move to: an active recurring price with the same currency, interval and usage type. |
effective | one of next_renewal, date | no | next_renewal: each subscription changes at its first renewal at least noticeDays away; date: at its first renewal on or after effectiveDate. (default "next_renewal") |
effectiveDate | date-time (ISO 8601) | no | With effective: date: the earliest change (at least noticeDays from now). |
noticeDays | integer | no | Days of notice: the customers are emailed this many days before their change (default 30; at least what your terms promise). (0–365) (default 30) |
filter | object | no | – |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: A field is malformed, oreffectiveDateis missing, misplaced or less thannoticeDaysaway.resource_not_found: No price with this ID exists for the brand in this mode.subscription_migration_invalid: The prices don't bill alike (currency, interval, usage type, meter), are the same, aren't recurring, or the new one is archived (details.reason).subscription_migration_too_large: More than 1,000 subscriptions match: narrow the filter and run several migrations.version_conflict: A matching subscription changed at the same time; retry.permission_denied: The credentials can't change this brand's subscriptions (subscriptions:write).
Example
Move monthly subscribers to the new price at their next renewal after 30 days
Arguments:
{
"fromPriceId": "price_01jacq4m3xf0v8w9zq2y7k5n6p",
"toPriceId": "price_01jacq4m3xf0v8w9zq2y7k5n6q",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "smig_01jacq4m3xf0v8w9zq2y7k5n6h",
"object": "subscription_migration",
"livemode": false,
"brandId": "brd_01jacq4m3xf0v8w9zq2y7k5n6b",
"fromPriceId": "price_01jacq4m3xf0v8w9zq2y7k5n6p",
"toPriceId": "price_01jacq4m3xf0v8w9zq2y7k5n6q",
"currency": "EUR",
"effective": "next_renewal",
"effectiveDate": null,
"noticeDays": 30,
"filter": {
"statuses": ["trialing", "active", "past_due"],
"customerIds": null
},
"status": "scheduled",
"counts": {
"matched": 42,
"scheduled": 40,
"notified": 0,
"applied": 0,
"pending": 40,
"skipped": 2
},
"skippedAtCreation": {
"pending_update": 2,
"cancel_scheduled": 0
},
"revenue": {
"mrrBefore": {
"amount": "400000000",
"currency": "EUR"
},
"mrrAfter": {
"amount": "480000000",
"currency": "EUR"
},
"mrrDelta": {
"amount": "80000000",
"currency": "EUR"
}
},
"firstChangeAt": "2026-11-20T10:00:00.000Z",
"lastChangeAt": "2026-12-19T10:00:00.000Z",
"version": 2,
"createdAt": "2026-10-20T09:00:00.000Z",
"updatedAt": "2026-10-20T09:00:00.000Z"
}
subscriptions_migrations_get
Get a price migration. Operation subscriptions.migrations.get · Brand level · permission subscriptions:read · risk tier read · since M5
Returns a price migration with its progress: how many subscriptions matched and were scheduled, how many
customers were notified, how many changes were applied at a renewal and how many are still pending, and how
many were skipped (at once, or dropped later because the subscription was canceled or changed again).
status is completed once no change is pending.
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (smig_…) | yes | – |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Read-only: changes nothing;
idempotency_keyis ignored.
Errors
resource_not_found: No price migration with this ID exists for the brand in this mode.permission_denied: The credentials can't read this brand's subscriptions.
Example
A migration half applied
Arguments:
{
"id": "smig_01jacq4m3xf0v8w9zq2y7k5n6h",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}
Result output:
{
"id": "smig_01jacq4m3xf0v8w9zq2y7k5n6h",
"object": "subscription_migration",
"livemode": false,
"brandId": "brd_01jacq4m3xf0v8w9zq2y7k5n6b",
"fromPriceId": "price_01jacq4m3xf0v8w9zq2y7k5n6p",
"toPriceId": "price_01jacq4m3xf0v8w9zq2y7k5n6q",
"currency": "EUR",
"effective": "next_renewal",
"effectiveDate": null,
"noticeDays": 30,
"filter": {
"statuses": ["trialing", "active", "past_due"],
"customerIds": null
},
"status": "scheduled",
"counts": {
"matched": 42,
"scheduled": 40,
"notified": 40,
"applied": 25,
"pending": 14,
"skipped": 3
},
"skippedAtCreation": {
"pending_update": 2,
"cancel_scheduled": 0
},
"revenue": {
"mrrBefore": {
"amount": "400000000",
"currency": "EUR"
},
"mrrAfter": {
"amount": "480000000",
"currency": "EUR"
},
"mrrDelta": {
"amount": "80000000",
"currency": "EUR"
}
},
"firstChangeAt": "2026-11-20T10:00:00.000Z",
"lastChangeAt": "2026-12-19T10:00:00.000Z",
"version": 67,
"createdAt": "2026-10-20T09:00:00.000Z",
"updatedAt": "2026-12-05T10:00:00.000Z"
}
subscriptions_migrations_list
List price migrations. Operation subscriptions.migrations.list · Brand level · permission subscriptions:read · risk tier read · since M5
Lists the brand's price migrations in the request's mode, newest first, with their progress. Filter by
fromPriceId.
Paginate with limit (1–100, default 10) and starting_after (the next_cursor of the previous page).
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
fromPriceId | ID (price_…) | no | Only migrations away from this price. |
limit | integer | no | (1–100) |
starting_after | ID (smig_…) | no | – |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Read-only: changes nothing;
idempotency_keyis ignored.
Errors
validation_failed: A filter or pagination value is malformed.permission_denied: The credentials can't read this brand's subscriptions.
Example
A price's migrations
Arguments:
{
"fromPriceId": "price_01jacq4m3xf0v8w9zq2y7k5n6p",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}
Result output:
{
"object": "list",
"data": [
{
"id": "smig_01jacq4m3xf0v8w9zq2y7k5n6h",
"object": "subscription_migration",
"livemode": false,
"brandId": "brd_01jacq4m3xf0v8w9zq2y7k5n6b",
"fromPriceId": "price_01jacq4m3xf0v8w9zq2y7k5n6p",
"toPriceId": "price_01jacq4m3xf0v8w9zq2y7k5n6q",
"currency": "EUR",
"effective": "next_renewal",
"effectiveDate": null,
"noticeDays": 30,
"filter": {
"statuses": ["trialing", "active", "past_due"],
"customerIds": null
},
"status": "scheduled",
"counts": {
"matched": 42,
"scheduled": 40,
"notified": 0,
"applied": 0,
"pending": 40,
"skipped": 2
},
"skippedAtCreation": {
"pending_update": 2,
"cancel_scheduled": 0
},
"revenue": {
"mrrBefore": {
"amount": "400000000",
"currency": "EUR"
},
"mrrAfter": {
"amount": "480000000",
"currency": "EUR"
},
"mrrDelta": {
"amount": "80000000",
"currency": "EUR"
}
},
"firstChangeAt": "2026-11-20T10:00:00.000Z",
"lastChangeAt": "2026-12-19T10:00:00.000Z",
"version": 2,
"createdAt": "2026-10-20T09:00:00.000Z",
"updatedAt": "2026-10-20T09:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}
subscriptions_pause
Pause a subscription. Operation subscriptions.pause · Brand level · permission subscriptions:write · risk tier write · since M5
Pauses an active subscription: collection stops until it resumes, at resumesAt or with
subscriptions.resume. behavior says what happens to the invoices of the periods that pass meanwhile:
void (none are created; the default), keep_as_draft (created, not finalized) or mark_uncollectible
(created and written off). The customer's entitlements stop during the pause (the brand default), and the
subscription stops counting for MRR. Emits subscription.paused.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (sub_…) | yes | – |
expectedVersion | integer | no | (1–9007199254740991) |
behavior | one of keep_as_draft, void, mark_uncollectible | no | What happens to the invoices while paused: keep_as_draft (created, not finalized), void (none) or mark_uncollectible (created and written off). (default "void") |
resumesAt | date-time (ISO 8601) | no | Resume automatically at this time. |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: A field is malformed or out of range.resource_not_found: No subscription (or customer, price, coupon) with this ID is visible to the request.version_conflict: The subscription changed since you read it (expectedVersion), or at the same time; read it and retry.subscription_status_invalid: The subscription's status doesn't allow this (spec §16.1): seedetails.reason.permission_denied: The credentials can't change this brand's subscriptions (subscriptions:write).
Example
Pause for a month
Arguments:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"behavior": "void",
"resumesAt": "2026-11-20T09:00:00.000Z",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "paused",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
"quantity": 1,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "87000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
"billingCycleAnchor": "2026-10-13T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-11-13T12:00:00.000Z",
"trialStart": null,
"trialEnd": null,
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": null,
"endedAt": null,
"cancellation": null,
"pause": {
"behavior": "void",
"resumesAt": "2026-11-20T09:00:00.000Z",
"pausedAt": "2026-10-20T09:00:00.000Z"
},
"discountIds": [],
"pendingUpdate": null,
"latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"incompleteExpiresAt": null,
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 3,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-20T09:00:00.000Z"
}
subscriptions_preview_change
Preview a subscription change. Operation subscriptions.preview_change · Brand level · permission subscriptions:read · risk tier read · since M5
Shows exactly what subscriptions.update would do with the same item changes, proration behaviour, timing and
promotion code, without changing anything: whether it is an upgrade, a downgrade or lateral, when it applies,
and how it is settled (settlement): the invoice issued now (invoice: lines, prorations, discounts, tax at
today's rates, the credit balance applied, the amount due; without a number until it is issued), the pending
items for the next invoice, the credit to the customer's credit balance, or the scheduled change. Also the
subscription as it would be and its monthly recurring amount before and after.
The preview runs the change's own code in a transaction that is rolled back, so it matches the real change as long as nothing changes in between (the time moves on: proration is exact to the second).
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: true
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (sub_…) | yes | – |
items | array of object | no | Item changes: { id, priceId } swaps a price, { id, quantity } changes seats, { priceId, quantity } adds an item, { id, deleted: true } removes one. Items not named stay. (1–40 items) |
prorationBehavior | one of create_prorations, always_invoice, none | no | create_prorations (credit unused time and charge the remaining time on the next invoice; a net credit goes to the customer credit balance), always_invoice (invoice the proration now) or none. |
effective | one of now, period_end | no | now, or at the end of the current period (period_end, stored as pendingUpdate). Default: upgrades and interval changes now with always_invoice, downgrades at the period end. |
paymentBehavior | one of allow_incomplete, pending_if_incomplete | no | For a change invoiced now: allow_incomplete (default; the change applies and a failed payment goes to dunning) or pending_if_incomplete (the old items stay until the invoice is paid). |
couponId | ID (cpn_…) | no | Apply a coupon to the subscription. |
promotionCode | string | no | A promotion code as the customer typed it (case doesn't matter). (1–50 characters) |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Read-only: changes nothing;
idempotency_keyis ignored.
Errors
validation_failed: A field is malformed or out of range.resource_not_found: No subscription (or customer, price, coupon) with this ID is visible to the request.subscription_status_invalid: The subscription's status doesn't allow this (spec §16.1): seedetails.reason.subscription_item_not_found: An itemidisn't one of the subscription's items.subscription_price_invalid: A new price isn't recurring, is archived, is in another currency, or its interval doesn't combine.subscription_meter_conflict: Another live item of the customer already bills this meter.subscription_change_invalid: A change waits for its invoice to be paid, orpending_if_incompletewas asked for asend_invoicesubscription.coupon_not_redeemable: The coupon is archived, expired or used up.promotion_code_not_redeemable: The promotion code can't be used (details.reason).discount_already_applied: The coupon is already applied to this subscription.registration_required: An invoice issued now can't be taxed: the seller isn't registered where the customer is (a new sale).jurisdiction_blocked: The customer's location is blocked for new sales.evidence_conflict: The customer's stored location evidence isn't enough to tax an invoice issued now (§13.3).permission_denied: You can't see this brand's subscriptions (subscriptions:read).
Example
What upgrading to Pro now costs
Arguments:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y3"
}
],
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}
Result output:
{
"object": "subscription_change_preview",
"subscriptionId": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"direction": "upgrade",
"intervalChange": false,
"effective": "now",
"prorationBehavior": "always_invoice",
"settlement": "invoice_now",
"invoice": {
"id": "inv_01m4tx5nj8emwbyf7y9vcf47yk",
"object": "invoice",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"number": null,
"numbering": null,
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47ym",
"subscriptionId": null,
"collectionMethod": "send_invoice",
"kind": "invoice",
"status": "open",
"language": "en",
"issuedAt": "2026-10-20T09:00:00.000Z",
"issueDate": "2026-10-20",
"taxPoint": "2026-10-20T09:00:00.000Z",
"taxPointDate": "2026-10-20",
"daysUntilDue": 14,
"dueDate": "2026-11-03",
"seller": {
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
"legalName": "Acme Digital d.o.o.",
"tradingName": null,
"address": {
"line1": "Ilica 1",
"line2": null,
"city": "Zagreb",
"postalCode": "10000",
"region": null,
"country": "HR"
},
"companyRegistryId": "080000001",
"taxIds": [
{
"type": "eu_vat",
"value": "HR12345678901",
"regimeId": null
}
],
"brand": {
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"name": "Genno",
"primaryColor": "#0E6B5C",
"accentColor": null,
"supportEmail": "help@genno.example",
"supportUrl": null
},
"footerText": null
},
"buyer": {
"type": "b2b",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47ym",
"name": "Alpen Apps GmbH",
"email": "billing@alpen.example",
"address": null,
"country": "AT",
"taxId": {
"type": "eu_vat",
"value": "ATU00000000",
"country": "AT"
}
},
"currency": "EUR",
"lines": [
{
"id": "1",
"description": "Implementation workshop (days)",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47yr",
"priceId": null,
"quantity": 2,
"taxCategoryId": "consulting_remote",
"taxBehavior": "exclusive",
"unitAmount": {
"amount": "600000000",
"currency": "EUR"
},
"net": {
"amount": "1200000000",
"currency": "EUR"
},
"tax": {
"ratePpm": "0",
"amount": {
"amount": "0",
"currency": "EUR"
},
"jurisdictionId": "AT",
"regimeId": "EU_OSS_UNION",
"decision": "reverse_charge",
"rateKind": null,
"rateId": null,
"pendingRegistration": false
},
"gross": {
"amount": "1200000000",
"currency": "EUR"
},
"kind": "invoice_item",
"period": null,
"subscriptionItemId": null,
"invoiceItemId": "ii_01m4tx5nj8emwbyf7y9vcf47ys",
"discount": null,
"meteredQuantity": null
}
],
"totals": {
"net": {
"amount": "1200000000",
"currency": "EUR"
},
"tax": {
"amount": "0",
"currency": "EUR"
},
"gross": {
"amount": "1200000000",
"currency": "EUR"
},
"taxByRate": [
{
"ratePpm": "0",
"jurisdictionId": "AT",
"regimeId": "EU_OSS_UNION",
"decision": "reverse_charge",
"net": {
"amount": "1200000000",
"currency": "EUR"
},
"tax": {
"amount": "0",
"currency": "EUR"
}
}
]
},
"taxCurrencyTotals": null,
"creditApplied": {
"amount": "200000000",
"currency": "EUR"
},
"amountDue": {
"amount": "1000000000",
"currency": "EUR"
},
"notes": [
{
"code": "reverse_charge",
"text": "Prijenos porezne obveze (reverse charge) – čl. 17. st. 1. Zakona o PDV-u"
}
],
"fieldCheck": {
"invoicingRuleIds": [],
"missing": ["buyer_address"],
"unchecked": []
},
"pendingRegistration": false,
"paymentIds": [],
"creditNoteIds": [],
"ledgerTxnIds": ["txn_01m4tx5nj8emwbyf7y9vcf47yn"],
"quoteId": "tq_01m4tx5nj8emwbyf7y9vcf47xr",
"quoteIds": ["tq_01m4tx5nj8emwbyf7y9vcf47xr"],
"pdf": {
"status": "pending",
"fileId": null,
"sha256": null,
"size": null,
"templateVersion": null,
"renderedAt": null,
"url": "/api/v1/invoices/inv_01m4tx5nj8emwbyf7y9vcf47yk/pdf"
},
"finalizedAt": "2026-10-20T09:00:00.000Z",
"paidAt": null,
"payment": null,
"voidedAt": null,
"markedUncollectibleAt": null,
"emailedAt": null,
"sentAt": null,
"draft": null,
"metadata": {
"contract": "ENT-2026-07"
},
"version": 2,
"createdAt": "2026-10-20T08:30:00.000Z",
"updatedAt": "2026-10-20T09:00:00.000Z"
},
"pendingItems": [],
"credit": null,
"subscription": {
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "active",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y3",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "147000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
"billingCycleAnchor": "2026-10-13T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-11-13T12:00:00.000Z",
"trialStart": null,
"trialEnd": null,
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": null,
"endedAt": null,
"cancellation": null,
"pause": null,
"discountIds": [],
"pendingUpdate": null,
"latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"incompleteExpiresAt": null,
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 2,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
},
"mrrBefore": {
"amount": "87000000",
"currency": "EUR"
},
"mrrAfter": {
"amount": "147000000",
"currency": "EUR"
},
"mrrDelta": {
"amount": "60000000",
"currency": "EUR"
}
}
subscriptions_reactivate
Reactivate a subscription. Operation subscriptions.reactivate · Brand level · permission subscriptions:write · risk tier write · since M5
Withdraws a cancellation scheduled for the period end (cancelAtPeriodEnd): the subscription renews as usual.
A subscription already canceled can't be reactivated: create a new one. Emits subscription.updated.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (sub_…) | yes | – |
expectedVersion | integer | no | (1–9007199254740991) |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: A field is malformed or out of range.resource_not_found: No subscription (or customer, price, coupon) with this ID is visible to the request.version_conflict: The subscription changed since you read it (expectedVersion), or at the same time; read it and retry.subscription_status_invalid: The subscription's status doesn't allow this (spec §16.1): seedetails.reason.permission_denied: The credentials can't change this brand's subscriptions (subscriptions:write).
Example
Keep the subscription after all
Arguments:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "active",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
"quantity": 1,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "87000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
"billingCycleAnchor": "2026-10-13T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-11-13T12:00:00.000Z",
"trialStart": null,
"trialEnd": null,
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": null,
"endedAt": null,
"cancellation": null,
"pause": null,
"discountIds": [],
"pendingUpdate": null,
"latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"incompleteExpiresAt": null,
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 4,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-20T09:00:00.000Z"
}
subscriptions_resume
Resume a subscription. Operation subscriptions.resume · Brand level · permission subscriptions:write · risk tier write · since M5
Resumes a paused subscription: it is active again, its current billing period carries on and renewals collect
again. The customer's entitlements come back. Emits subscription.resumed.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (sub_…) | yes | – |
expectedVersion | integer | no | (1–9007199254740991) |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: A field is malformed or out of range.resource_not_found: No subscription (or customer, price, coupon) with this ID is visible to the request.version_conflict: The subscription changed since you read it (expectedVersion), or at the same time; read it and retry.subscription_status_invalid: The subscription's status doesn't allow this (spec §16.1): seedetails.reason.permission_denied: The credentials can't change this brand's subscriptions (subscriptions:write).
Example
Resume now
Arguments:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "active",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
"quantity": 1,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "87000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
"billingCycleAnchor": "2026-10-13T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-11-13T12:00:00.000Z",
"trialStart": null,
"trialEnd": null,
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": null,
"endedAt": null,
"cancellation": null,
"pause": null,
"discountIds": [],
"pendingUpdate": null,
"latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"incompleteExpiresAt": null,
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 4,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-20T09:00:00.000Z"
}
subscriptions_update
Change a subscription. Operation subscriptions.update · Brand level · permission subscriptions:write · risk tier financial · since M5
Changes a subscription's items, quantities, discount, payment method, collection method or metadata.
Items (items[]): { id, priceId } swaps the price of an item, { id, quantity } changes its seats,
{ priceId, quantity } adds an item and { id, deleted: true } removes one; items not named stay. When the change
applies (effective) and how it is billed (prorationBehavior) follow spec §16.5:
- Upgrades (a higher monthly amount) and interval changes default to
nowwithalways_invoice: the unused time of the old items is credited, the remaining time of the new ones charged, and the difference invoiced and charged at once (an interval change starts a new billing period now). If the payment fails, the change stays and the open invoice goes to dunning, unlesspaymentBehavior: pending_if_incompletekeeps the old items until the invoice is paid. - Downgrades and lateral changes default to the end of the period: the change is stored as
pendingUpdateand applied at renewal, with no credit. nowwithcreate_prorations: a net charge waits for the next invoice as pending invoice items; a net credit (fewer seats) goes to the customer's credit balance at once.none: the items change now and nothing is billed.
Trialing subscriptions change at once with nothing to bill. Proration is exact to the second, rounded once per
line; proration lines are taxed at the rates of the change date. Preview a change first with
subscriptions.preview_change (the exact invoice), or dry-run this operation. Emits subscription.updated.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: true
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (sub_…) | yes | – |
expectedVersion | integer | no | The version you read (optimistic concurrency). (1–9007199254740991) |
items | array of object | no | Item changes: { id, priceId } swaps a price, { id, quantity } changes seats, { priceId, quantity } adds an item, { id, deleted: true } removes one. Items not named stay. (1–40 items) |
prorationBehavior | one of create_prorations, always_invoice, none | no | create_prorations (credit unused time and charge the remaining time on the next invoice; a net credit goes to the customer credit balance), always_invoice (invoice the proration now) or none. |
effective | one of now, period_end | no | now, or at the end of the current period (period_end, stored as pendingUpdate). Default: upgrades and interval changes now with always_invoice, downgrades at the period end. |
paymentBehavior | one of allow_incomplete, pending_if_incomplete | no | For a change invoiced now: allow_incomplete (default; the change applies and a failed payment goes to dunning) or pending_if_incomplete (the old items stay until the invoice is paid). |
couponId | ID (cpn_…) | no | Apply a coupon to the subscription. |
promotionCode | string | no | A promotion code as the customer typed it (case doesn't matter). (1–50 characters) |
collectionMethod | one of charge_automatically, send_invoice | no | charge_automatically (the default payment method is charged) or send_invoice (the invoice is emailed with bank transfer details and paid by the due date). |
daysUntilDue | integer or null | no | – |
defaultPaymentMethodId | ID (pm_…) or null | no | The payment method charged for this subscription (null: the customer's default). |
cancelPendingUpdate | boolean | no | Drop a change scheduled for the period end (pendingUpdate). |
usageThreshold | object or null | no | Invoice metered usage as soon as what it would charge reaches this amount (spec §16.7): limits the credit risk of usage-heavy customers. In the subscription's currency, whole minor units. null removes it. |
metadata | object | no | Your own key-value pairs (at most 50 keys). On updates the whole set is replaced. |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
validation_failed: A field is malformed or out of range.resource_not_found: No subscription (or customer, price, coupon) with this ID is visible to the request.version_conflict: The subscription changed since you read it (expectedVersion), or at the same time; read it and retry.subscription_status_invalid: The subscription's status doesn't allow this (spec §16.1): seedetails.reason.subscription_item_not_found: An itemidisn't one of the subscription's items.subscription_price_invalid: A new price isn't recurring, is archived, is in another currency, or its interval doesn't combine.subscription_meter_conflict: Another live item of the customer already bills this meter.subscription_change_invalid: A change waits for its invoice to be paid, orpending_if_incompletewas asked for asend_invoicesubscription.subscription_payment_method_invalid:defaultPaymentMethodIdisn't a saved, attached payment method of the customer.coupon_not_redeemable: The coupon is archived, expired or used up.promotion_code_not_redeemable: The promotion code can't be used (details.reason).discount_already_applied: The coupon is already applied to this subscription.registration_required: An invoice issued now can't be taxed: the seller isn't registered where the customer is (a new sale).jurisdiction_blocked: The customer's location is blocked for new sales.evidence_conflict: The customer's stored location evidence isn't enough to tax an invoice issued now (§13.3).permission_denied: The credentials can't change this brand's subscriptions (subscriptions:write).
Examples
Upgrade to Pro now
The unused Basic time is credited and the Pro time to the period end is invoiced and charged now.
Arguments:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y3"
}
],
"expectedVersion": 2,
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "active",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y3",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "147000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
"billingCycleAnchor": "2026-10-13T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-11-13T12:00:00.000Z",
"trialStart": null,
"trialEnd": null,
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": null,
"endedAt": null,
"cancellation": null,
"pause": null,
"discountIds": [],
"pendingUpdate": null,
"latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"incompleteExpiresAt": null,
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 3,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-20T09:00:00.000Z"
}
Two seats fewer from the next period
Arguments:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"quantity": 1
}
],
"effective": "period_end",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"object": "subscription",
"livemode": false,
"entityId": "ent_01m4tx5nj8emwbyf7y9vcf47zm",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"status": "active",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 3,
"createdAt": "2026-10-13T12:00:00.000Z"
},
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47zb",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y9",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y1",
"quantity": 1,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"currency": "EUR",
"mrr": {
"amount": "87000000",
"currency": "EUR"
},
"collectionMethod": "charge_automatically",
"daysUntilDue": null,
"defaultPaymentMethodId": "pm_01m4tx5nj8emwbyf7y9vcf47zd",
"billingCycleAnchor": "2026-10-13T12:00:00.000Z",
"currentPeriodStart": "2026-10-13T12:00:00.000Z",
"currentPeriodEnd": "2026-11-13T12:00:00.000Z",
"trialStart": null,
"trialEnd": null,
"trialEndBehavior": "convert",
"cancelAtPeriodEnd": false,
"cancelAt": null,
"canceledAt": null,
"endedAt": null,
"cancellation": null,
"pause": null,
"discountIds": [],
"pendingUpdate": {
"kind": "period_end",
"items": [
{
"id": "si_01m4tx5nj8emwbyf7y9vcf47za",
"priceId": "price_01m4tx5nj8emwbyf7y9vcf47y2",
"productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
"quantity": 1,
"createdAt": "2026-10-13T12:00:00.000Z"
}
],
"effectiveAt": "2026-11-13T12:00:00.000Z",
"requestedAt": "2026-10-20T09:00:00.000Z",
"prorationBehavior": "none",
"invoiceId": null,
"expiresAt": null
},
"latestInvoiceId": "inv_01m4tx5nj8emwbyf7y9vcf47zn",
"incompleteExpiresAt": null,
"testClockId": null,
"dunning": null,
"usageThreshold": null,
"entitlementGraceUntil": null,
"metadata": {
"crm_account": "A-1042"
},
"version": 3,
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-20T09:00:00.000Z"
}