Subscription
Private Subscription API endpoints
- GET/subscriptions
- POST/subscriptions
- GET/subscriptions/{subscription_id}
- PATCH/subscriptions/{subscription_id}
- POST/subscriptions/{subscription_id}/cancel
- DELETE/subscriptions/{subscription_id}/undo_cancellation
- POST/subscriptions/{subscription_id}/pause
- POST/subscriptions/{subscription_id}/resume
- POST/subscriptions/{subscription_id}/skip
- POST/subscriptions/{subscription_id}/reactivate
- POST/subscriptions/{subscription_id}/switch_plan
- POST/subscriptions/{subscription_id}/change_plans
- PATCH/subscriptions/{subscription_id}/address
- PATCH/subscriptions/{subscription_id}/payment_method
- PATCH/subscriptions/{subscription_id}/preferences
- POST/subscriptions/{subscription_id}/items
- GET/subscriptions/{subscription_id}/items/{item_id}
- PATCH/subscriptions/{subscription_id}/items/{item_id}
- DELETE/subscriptions/{subscription_id}/items/{item_id}
- PATCH/subscriptions/{subscription_id}/items/{item_id}/preferences
- PATCH/subscriptions/{subscription_id}/items/{item_id}/bundle
- POST/subscriptions/{subscription_id}/items/{item_id}/change_plan
- POST/subscriptions/{subscription_id}/items/{item_id}/change_variant
- POST/subscriptions/{subscription_id}/items/{item_id}/discounts
- DELETE/subscriptions/{subscription_id}/items/{item_id}/discounts/{discount_id}
- POST/subscriptions/{subscription_id}/discounts
- DELETE/subscriptions/{subscription_id}/discounts/{discount_id}
An API endpoint to get list of subscriptions
Query parameters
pageoptionalintegerPage number
per_pageoptionalintegerItems per page
statusesoptionalstring[]Filter by subscription statuses
created_at[gte]optionalstringFilter to include only records with a created_at on or after the given date.
created_at[lte]optionalstringFilter to include only records with a created_at on or before the given date.
start_created_atoptionalstringDeprecatedDeprecated alias of created_at[gte]. When both arrive, created_at[gte] wins.
end_created_atoptionalstringDeprecatedDeprecated alias of created_at[lte]. When both arrive, created_at[lte] wins.
customer_idoptionalintegerFilter by customer ID
product_idoptionalintegerDeprecatedDeprecated, use plan_ids or bundle_ids instead. Filter by product ID. Accepts a parent product ID or a plan (child product) ID; a parent is expanded to itself plus all of its plans. Matches subscriptions whose primary product or any line item is in the resulting set.
plan_idsoptionalinteger[]Filter by exact plan IDs. Matches subscriptions whose primary product or any line item is one of the given plans. Cannot be combined with bundle_ids.
bundle_idsoptionalinteger[]Filter by bundle IDs. Matches subscriptions whose primary product or any line item belongs to one of the bundles' products. Cannot be combined with plan_ids.
activeoptionalintegerFilter by the subscription active flag (0 or 1).
Possible values: 0, 1.
pausedoptionalintegerFilter by the subscription paused flag (0 or 1). Skipping until a date (skipping_until) does not set this flag.
Possible values: 0, 1.
expand[]optionalstring[]List of relations to expand in the response. Each expandable field on the response schema names its key, e.g. expand[]=customer. Nested keys use dot notation, e.g. items.product or subscriptions.items. Fields marked as always present are returned without being requested. An expanded list is null, not [], when there are no records. Unknown keys are ignored unless the endpoint says otherwise.
Returnsobject
Subscriptions list response
Error responses
422objectA query parameter failed validation: page below 1, per_page outside 1 to 100, a customer_id, product_id, plan_ids[] or bundle_ids[] value that does not belong to the shop, plan_ids sent together with bundle_ids, an unknown statuses[] value, a non-boolean active or paused, a date not in 2022-02-24T04:00:00 format, or a non-array expand[].
Create a subscription directly, without a checkout. No invoice is issued at creation: an auto-collecting subscription is billed by the renewals engine once starts_at is due, while one with auto_collecting: false waits for manually issued invoices.
Query parameters
expand[]optionalstring[]List of relations to expand in the response. Each expandable field on the response schema names its key, e.g. expand[]=customer. Nested keys use dot notation, e.g. items.product or subscriptions.items. Fields marked as always present are returned without being requested. An expanded list is null, not [], when there are no records. Unknown keys are ignored unless the endpoint says otherwise.
Request body
Create a subscription
auto_collectingoptionalbooleanWhether renewals are collected automatically. When true the subscription is charged by the renewals engine when the next payment date is due; when false it is never charged automatically and waits for manually issued invoices.
The renewals engine skips non-auto-collecting subscriptions entirely, so starts_at is recorded but nothing is billed on that date. It takes effect only once auto_collecting is switched back to true.
Defaults to true.
customer_idRequiredintegerThe customer the subscription belongs to.
currency_codeRequiredstringSubscription currency. Must be enabled for the shop and, when a payment method is given, one of that payment method's currencies โ the shop currencies attached to its gateway.
payment_method_idRequiredintegerThe customer's payment method, charged on every renewal. Must belong to the customer and support currency_code (see the payment method's currencies); an expired card is rejected. The subscription's test mode is derived from the payment method's gateway: a payment method on a test gateway creates a test subscription.
shipping_address_idoptionalinteger | nullThe customer's shipping address id. Required when any product on the subscription is physical; prohibited when every product is digital and none of them collects a shipping address. The products counted are those in items[] plus the gift products of the coupon in discounts, if any. A pickup point id is accepted instead of a street address only when a physical product is present, and then shipping_method_id must be a local pickup method.
billing_address_idoptionalinteger | nullThe customer's billing address id. Defaults to shipping_address_id when omitted.
shipping_method_idoptionalinteger | nullShipping method id. Must be published in the shop and available for shipping_address_id and the subscription's products: a shipping option or local delivery method serving the address's country, region and zip, or a local pickup method serving the pickup point. A FlavorCloud method is accepted only for an address outside the shop's country. Rejected when sent without shipping_address_id. Required when any product on the subscription is physical; prohibited when every product is digital, even one that collects a shipping address. The gift products of the coupon in discounts count like items[] products.
shipping_carrier_idoptionalinteger | nullShipping carrier id. Required for (and only allowed with) dynamic shipping methods.
shipping_carrier_serviceoptionalstring | nullShipping carrier service code. Required for (and only allowed with) dynamic shipping methods.
giftoptionalobject | nullMarks the subscription as a gift. With a future starts_at the subscription is created in the gift_waiting_to_start status and activates on that date.
starts_atoptionalstring | nullThe day the first charge should land, as a Y-m-d date in the shop's timezone. It is stored at the shop's renewal time, exactly like next_payment_date on the update endpoint, and doubles as the gift start date. Must be today or later, where "today" is evaluated against the server's UTC clock โ not the shop's timezone.
Omit the field (or send null) to bill the subscription as soon as the renewals engine next runs. That is not the same as passing today's date: today resolves to today at the shop's renewal time, which may still be hours away.
Only meaningful for auto-collecting subscriptions โ see auto_collecting. A future date does not put the subscription in a distinct status.
Format: date.
charges_limitoptionalinteger | nullNumber of successful charges after which the subscription expires. Defaults to the subscription product's setting when omitted; pass null for unlimited.
discountsoptionalobject[]Subscription-level discounts. At most one entry per type is allowed: a coupon, a gift_card and a custom discount may be combined. The coupon becomes the subscription discount (and its gift products, if any, are added as coupon items); the gift card is redeemed to the customer and its balance is consumed by upcoming invoices; a discount becomes a single subscription-scoped discount, visible via expand=discounts, applied once per invoice across all items โ including items added after creation. Items may still carry their own per-item discounts via items[].discounts. At billing time discounts stack in a fixed order โ per-item discounts first, then the subscription discount, then the coupon (each computed on the already-discounted total), then the gift card against the remainder โ and can never exceed the invoice total.
metadataoptionalobject[] | nullList of metadata and their values
itemsRequiredobject[]Subscription items. The item type follows the key that names its product: plan_id items are subscription lines (all of them must share one billing cycle), variant_id items are one_time add-ons. At least one plan_id item is required. More than one plan_id item needs the multiple subscription products feature of the shop's plan, and a membership plan (a digital plan) takes no variant_id items.
ReturnsSubscription
Subscription object response
Error responses
400objectThe coupon in discounts was redeemable when the request was validated but reached its redemption limit, expired or was deactivated before the subscription was written (coupon_not_redeemable) - typically because a concurrent request took the last redemption. Redemptions are serialised per coupon, so exactly one of the competing requests succeeds. The same holds for the gift card in discounts when a concurrent request redeemed it first (gift_card_already_redeemed, "The gift voucher was already redeemed."). Nothing is created.
422objectValidation failed. customer_id is not a customer of the shop; currency_code is not a currency the shop sells in; payment_method_id does not belong to the customer ("The selected payment method does not belong to the customer."), is an expired card ("The selected payment method card has expired.") or cannot be charged in currency_code ("The payment method id field cannot be charged in EUR; it can be charged in USD."). items names no plan ("The items must contain at least one subscription plan."), plans on different billing cycles ("All subscription plans must share the same billing cycle."), a one-time item on a membership plan ("One-time items are not allowed on membership subscriptions.") or more than one plan while the shop's plan lacks the multiple subscription products feature ("Multiple subscription products are not available on your current plan."); an item sends neither or both of plan_id and variant_id, a product that is not available, a duration on a plan, a bundle that is missing for a configurable bundle, sent for another product or does not fit it, or preferences that do not answer the plan's survey. A shipping address or method is missing while a product is physical ("The shipping method id is required when the subscription contains a physical product.") or sent while no product needs it ("The shipping address id is prohibited for digital products."), the address is not the customer's, a pickup point comes without a local pickup method, the method does not serve the address, or the carrier fields are missing for a dynamic-rate method or sent for another one. gift is sent without recipient_email; starts_at is before today. discounts repeats a type ("Only one coupon discount is allowed per subscription."), names a coupon that is not redeemable or a gift card that is not valid ("The gift card is not valid.") or has expired ("The gift card has already expired."), or holds a discount entry without duration or without exactly one of percent_off and amount_off; items[].discounts holds more than one entry or a type other than discount.
429objectAnother rate-limited request from the same IP address is still running. The endpoint handles one such request at a time.
A detailed description of the subscription.
Path parameters
subscription_idRequiredintegerSubscription ID
Format: integer.
Query parameters
expand[]optionalstring[]List of relations to expand in the response. Each expandable field on the response schema names its key, e.g. expand[]=customer. Nested keys use dot notation, e.g. items.product or subscriptions.items. Fields marked as always present are returned without being requested. An expanded list is null, not [], when there are no records. Unknown keys are ignored unless the endpoint says otherwise.
ReturnsSubscription
Subscription object response
Error responses
400objectThe subscription exists but belongs to another shop.
404objectNo subscription exists with this ID.
422objectThe expand[] parameter is not an array.
Partially update an active subscription. Only the keys present in the body are applied, every other field is left untouched. metadata replaces all subscription-level metadata; item metadata is updated through PATCH /subscriptions/{subscription_id}/items/{item_id}. product_id is deprecated: change plans with POST /subscriptions/{subscription_id}/change_plans.
Path parameters
subscription_idRequiredintegerSubscription ID
Query parameters
expand[]optionalstring[]List of relations to expand in the response. Each expandable field on the response schema names its key, e.g. expand[]=customer. Nested keys use dot notation, e.g. items.product or subscriptions.items. Fields marked as always present are returned without being requested. An expanded list is null, not [], when there are no records. Unknown keys are ignored unless the endpoint says otherwise.
Request body
Update a subscription
product_idoptionalintegerDeprecatedDeprecated: use POST /subscriptions/{subscription_id}/change_plans with one pick for the subscription's only subscription item. Moves that item to the given subscription plan of this shop in the same transaction as the other keys. Rejected with 422 for subscriptions with multiple subscription items, for a plan on the other membership kind and for a configurable bundle other than the current one, whose contents must be picked through POST /subscriptions/{subscription_id}/items/{item_id}/change_plan.
quantityoptionalintegerSubscription-level quantity. Rejected for subscriptions with multiple subscription items; update the quantity per item via PATCH /subscriptions/{subscription_id}/items/{item_id}.
next_payment_dateoptionalstringNext payment date in Y-m-d format. Must be after yesterday.
Format: date.
gift_recipient_emailoptionalstring | nullEmail of the gift recipient. Send null to clear it.
Format: email.
gift_messageoptionalstring | nullGift message. Send null to clear it.
auto_collectingoptionalbooleanWhether payments are collected automatically.
successful_shipment_numberoptionalintegerNumber of successful shipments.
tagsoptionalobjectTag changes to apply to the subscription.
metadataoptionalMetadataUpdateSubscription-level metadata only. Item metadata is not affected.
ReturnsSubscription
Subscription object response
Error responses
400objectThe subscription is not active (bad_request). The write re-checks the product_id pick under the lock and refuses it when a subscription item added by a concurrent write since validation would stay on another billing cycle (plan_change_items_left_behind, Item 2 must also be moved to a plan with the same billing cycle.).
404objectNo subscription with this ID exists in the shop.
422objectValidation failed, for example product_id is not a subscription plan of this shop on the subscription's membership kind (The selected plan is not available for this item.) or is a configurable bundle other than the current one (The selected plan needs new bundle contents. Pick it with its contents using POST subscriptions/{subscription}/items/{item}/change_plan.), product_id or quantity is sent for a subscription with multiple subscription items (This subscription has multiple subscription items. Change the plans per item using POST subscriptions/{subscription}/change_plans.), next_payment_date is not a Y-m-d date after yesterday, a tags.delete ID is not a tag of this shop, or a metadata entry is invalid.
Cancels a subscription for a given reason.
Path parameters
subscription_idRequiredintegerThe ID of the subscription to cancel
Request body
Cancellation Reasons Body
reason_idoptionalinteger | nullThe ID of the cancellation reason (available if cancellation reasons are enabled)
extra_feedbackoptionalstring | nullAdditional feedback from the customer
involuntary_churnoptionalboolean | nullInvoluntary churn occurs when a subscription ends due to issues like payment failures. Pass false to clear the past due status and prevent involuntary churn event. Pass true to keep the subscription in its current past due state, which may lead to involuntary churn.
typeoptionalstring | nullCancellation type. Defaults to 'immediate'. For committed subscriptions 'end_of_commitment' sets cancellation after commitment fulfillment. 'end_of_period' schedules cancellation at the end of the current billing period.
Possible values: immediate, end_of_period, end_of_commitment.
ReturnsSubscription
Subscription object response
Error responses
400objectThe subscription is not active, for example because it is already cancelled.
404objectNo subscription with this ID exists in the shop.
422objecttype is not immediate, end_of_period or end_of_commitment; the subscription is already set to cancel at the end of the period (The subscription is already set to cancel at end of period.) or at the end of its commitment (The subscription is already set to cancel at the end of commitment.); type is end_of_commitment but the subscription has no commitment term; reason_id does not belong to the shop, or the shop has cancellation reasons turned off (A cancellation reason cannot be submitted because cancellation reasons are disabled for this shop.); extra_feedback is longer than 255 characters; or involuntary_churn is not a boolean.
429objectAnother rate-limited request from the same IP address is still running. The endpoint handles one such request at a time.
Undo the cancellation of a subscription.
Path parameters
subscription_idRequiredintegerThe ID of the subscription
ReturnsSubscription
Subscription object response
Error responses
400objectThe subscription belongs to another shop, is not active, or is not set to cancel at the end of the period or at the end of its commitment.
404objectNo subscription exists with this ID.
Pauses an active subscription until it is resumed with POST /subscriptions/{subscription_id}/resume. The shop's and the product's pause settings do not apply here.
Path parameters
subscription_idRequiredintegerSubscription ID
ReturnsSubscription
Subscription object response
Error responses
400objectThe subscription is not active, is already paused, is past due, is set to cancel at the end of the period, or is skipping renewals.
404objectNo subscription with this ID exists in the shop.
429objectAnother rate-limited request from the same IP address is still running. The endpoint handles one such request at a time.
Resumes a paused or skipping subscription: the pause and the skip are cleared and next_payment_date becomes the next payment date, stored at the shop's renewal time.
Path parameters
subscription_idRequiredintegerSubscription ID
Request body
next_payment_dateRequiredstringThe next payment date, as a Y-m-d date of today or later.
Format: date.
ReturnsSubscription
Subscription object response
Error responses
400objectThe subscription is not active, or it is neither paused nor skipping renewals.
404objectNo subscription with this ID exists in the shop.
422objectnext_payment_date is missing, not a Y-m-d date, or before today.
429objectAnother rate-limited request from the same IP address is still running. The endpoint handles one such request at a time.
Skips renewals until skip_until, which becomes the next payment date, stored at the shop's renewal time. Any date after today is accepted; the shop's skipping settings do not apply here. End a skip early with POST /subscriptions/{subscription_id}/resume.
Path parameters
subscription_idRequiredintegerSubscription ID
Request body
skip_untilRequiredstringThe date renewals are skipped until, as a Y-m-d date after today.
Format: date.
ReturnsSubscription
Subscription object response
Error responses
400objectThe subscription is not active, is paused, is past due, or is already skipping renewals.
404objectNo subscription with this ID exists in the shop.
422objectskip_until is missing, not a Y-m-d date, or not after today.
429objectAnother rate-limited request from the same IP address is still running. The endpoint handles one such request at a time.
Makes a cancelled or expired subscription active again with renewal_date as its next payment date, stored at the shop's renewal time. The cancellation, pause and skip are cleared and charges_limit resets to unlimited. The shop's reactivation settings do not apply here.
Path parameters
subscription_idRequiredintegerSubscription ID
Request body
renewal_dateRequiredstringThe next payment date, as a Y-m-d date of today or later.
Format: date.
ReturnsSubscription
Subscription object response
Error responses
400objectThe subscription is neither cancelled nor expired.
404objectNo subscription with this ID exists in the shop.
422objectrenewal_date is missing, not a Y-m-d date, or before today.
429objectAnother rate-limited request from the same IP address is still running. The endpoint handles one such request at a time.
Switch the subscription to another plan by starting over
Closes the subscription and opens a new one, keeping the customer, addresses, payment method, dates, discounts and tags. The new subscription starts on plan_id, or on the subscription's current plan when no plan is named. It holds exactly one subscription item on that plan, seeded from the subscription's representative item (the lowest-id subscription item): its quantity and item discounts carry over, its bundle contents only when the new plan has the same bundle and its survey answers only when it has the same survey; every other subscription item is not copied, one-time items are copied as they are. The old subscription is marked switched. To change plans in place, with every item and the billing cycle kept together, use POST subscriptions/{subscription_id}/change_plans.
Path parameters
subscription_idRequiredintegerThe ID of the subscription to switch
Request body (optional)
plan_idoptionalintegerThe plan the new subscription starts on; any subscription plan of the shop. Defaults to the subscription's current plan.
ReturnsSubscription
The new subscription
Error responses
400objectThe subscription is not active.
404objectNo subscription with this ID exists in the shop.
422objectplan_id is not an integer or not a subscription plan of the shop.
429objectAnother rate-limited request from the same IP address is still running. The endpoint handles one such request at a time.
Moves the named subscription items to other plans in one write: a plan change, a product change or a billing cycle change. The picks are laid over the current items and every subscription item must end on one billing cycle (plan hash); an item that is not named is never written, so a cycle change names every subscription item. A pick may be any subscription plan of the shop, unpublished or archived included, on the subscription's membership kind; one-time items are never picks. A pick's bundle is accepted only when the target plan is a configurable bundle, required when that bundle is not the item's current bundle, and replaces the contents when sent; on the same bundle the contents are kept without it, while any other bundle, or none, drops them. A pick equal to the current plan is a no-op without bundle and a contents change with it. Survey answers reset unless the target plan's active survey is the one they answer, and the subscription's product_id follows its lowest-id subscription item. Nothing else is written: the renewal date, the commitment, discounts and upcoming orders stay as they are and the change takes effect at the next renewal. One subscription item moves on its own with POST subscriptions/{subscription_id}/items/{item_id}/change_plan.
Path parameters
subscription_idRequiredintegerSubscription ID
Query parameters
expand[]optionalstring[]List of relations to expand in the response. Each expandable field on the response schema names its key, e.g. expand[]=customer. Nested keys use dot notation, e.g. items.product or subscriptions.items. Fields marked as always present are returned without being requested. An expanded list is null, not [], when there are no records. Unknown keys are ignored unless the endpoint says otherwise.
Request body
itemsRequiredobject[]The picks, one per subscription item to move.
ReturnsSubscription
The subscription with its items on their new plans
Error responses
400objectThe subscription is not active (subscription_not_active). The write re-checks the picks under the lock and refuses one that another write made invalid while the change waited for the subscription: a named item was removed (plan_change_item_not_found, "Item 2 is not a subscription item of this subscription."), or an unnamed item is on another billing cycle (plan_change_items_left_behind, "Item 2 must also be moved to a plan with the same billing cycle.").
404objectNo subscription with this ID exists in the shop.
422objectitems is missing, empty or not a list; an id is not an item of this subscription ("The item does not belong to this subscription."), is a one-time item ("The item is not a subscription item.") or is named twice ("The item is picked more than once."); a plan_id is not a subscription plan of the shop on the subscription's membership kind ("The selected plan is not available for this item."); the picks name plans on different cycles ("All picked plans must share one billing cycle." on items.N.plan_id) or leave an unnamed item on another cycle ("Item 2 must also be moved to a plan with the same billing cycle." on items); bundle is sent for a plan that is not a configurable bundle ("The bundle field is not accepted for this plan."), missing while the target's bundle is not the item's current bundle ("The bundle field is required for this plan."), or its items or preferences do not fit the target's bundle; or expand is not an array.
429objectAnother rate-limited request from the same IP address is still running. The endpoint handles one such request at a time.
Changes the shipping address, the shipping method and, for a dynamic-rate method, the carrier and service of an active subscription. Only the keys sent are written; null clears one. Which keys are required or accepted follows the subscription's plan (product_id).
Path parameters
subscription_idRequiredintegerSubscription ID
Request body
shipping_address_idoptionalinteger | nullOne of the customer's addresses or pickup points. Required when shipping_method_id is sent and the plan collects a shipping address; rejected when it does not. A pickup point needs a physical plan and a local pickup shipping_method_id in the same request.
shipping_method_idoptionalinteger | nullA published shipping method of the shop that serves shipping_address_id, which must be sent with it. Required when shipping_address_id is sent and the plan is physical and not a gift card; rejected for a digital or gift-card plan.
shipping_carrier_idoptionalinteger | nullA carrier of the dynamic-rate shipping_method_id sent. Required with a dynamic-rate method and rejected otherwise.
shipping_carrier_serviceoptionalstring | nullA service code offered by shipping_carrier_id. Required with a dynamic-rate method and rejected otherwise.
update_orders_addressoptionalinteger1 also copies the subscription's shipping address, method, carrier and service to its future_shipment and awaiting_delivery orders. Rejected with a dynamic-rate shipping_method_id.
Possible values: 0, 1.
ReturnsSubscription
Subscription object response
Error responses
400objectThe subscription is not active.
404objectNo subscription with this ID exists in the shop.
422objectA key has the wrong type; shipping_address_id is missing while a shipping_method_id is sent for a plan that collects a shipping address ("A shipping address is required when a shipping method is set on a product that collects shipping addresses."), sent for a plan that does not ("A shipping address cannot be set because the subscription's product does not collect shipping addresses."), not the customer's, or a pickup point without a local pickup method or on a digital plan; shipping_method_id is missing while a shipping_address_id is sent for a physical plan ("A shipping method is required when a shipping address is set on a product that requires shipping."), sent for a digital or gift-card plan ("A shipping method cannot be set because the subscription's product does not require shipping."), not a published method of the shop, or sent without a shipping_address_id it serves ("Incorrect value for shipping method id"); the carrier fields are missing for a dynamic-rate method, sent without one, or not offered by it; or update_orders_address is not 0 or 1, or is 1 with a dynamic-rate method ("Updating order address is not supported for dynamic shipping methods.").
Sets the payment method renewals are charged to, together with the subscription's currency and, optionally, its billing address. Only active subscriptions can be updated.
Path parameters
subscription_idRequiredintegerSubscription ID
Request body
payment_method_idRequiredintegerOne of the customer's payment methods, on a gateway in the subscription's mode (a test gateway for a test subscription, a live one otherwise). An expired card is rejected.
currency_codeRequiredstringThe subscription's currency from now on; must be a known currency code.
billing_address_idoptionalintegerOne of the customer's addresses. Left unchanged when omitted.
ReturnsSubscription
Subscription object response
Error responses
400objectThe subscription is not active.
404objectNo subscription with this ID exists in the shop.
422objectpayment_method_id is missing, not an integer, not one of the customer's payment methods on a gateway in the subscription's mode ("The selected payment method id is invalid."), or a card that has expired ("The selected payment method card has expired."); currency_code is missing or not a known currency; or billing_address_id is not one of the customer's addresses.
Replaces the survey answers of an active subscription with a single subscription item; null or an empty list clears them where the survey accepts no answers. For a subscription with several subscription items use PATCH /subscriptions/{subscription_id}/items/{item_id}/preferences.
Path parameters
subscription_idRequiredintegerSubscription ID
Request body
preferencesRequiredobject[] | nullAnswers to the active survey of the subscription's plan.
update_ordersoptionalinteger1 also writes the answers to the subscription's future_shipment and awaiting_delivery orders. Accepted only when the survey is shown after checkout and the subscription's shipping method is not dynamic-rate.
Possible values: 0, 1.
ReturnsSubscription
Subscription object response
Error responses
400objectThe subscription is not active (bad_request), has more than one subscription item (subscription_preferences_not_editable), or a chosen answer is out of stock (out_of_stock).
404objectNo subscription with this ID exists in the shop.
422objectpreferences is missing or the answers do not match the plan's active survey ("The preferences are invalid"); a preference has no question_id or answers; or update_orders is not 0 or 1, or is 1 while the subscription uses dynamic shipping ("The update orders is not allowed when the subscription uses dynamic shipping.") or the survey is not shown after checkout ("The update orders is prohibited when the survey appearance type is not after checkout.").
Add an item to a subscription. A subscription item adds another concurrent subscription line, named by its plan_id (the plan must share the subscription's billing cycle); a one_time item adds a one-time add-on product, named by its variant_id. The item is billed on the next renewal, not immediately.
Path parameters
subscription_idRequiredintegerSubscription ID
Query parameters
expand[]optionalstring[]List of relations to expand in the response. Each expandable field on the response schema names its key, e.g. expand[]=customer. Nested keys use dot notation, e.g. items.product or subscriptions.items. Fields marked as always present are returned without being requested. An expanded list is null, not [], when there are no records. Unknown keys are ignored unless the endpoint says otherwise.
Request body
Create a subscription item
ReturnsSubscriptionItem
Subscription item object response
Error responses
400objectThe subscription is not active, or type is one_time and the subscription is a membership (its product is digital) (bad_request); or type is subscription and the shop's plan lacks the multiple subscription products feature (feature_not_available, The multiple subscription products feature is not available on your current plan.).
404objectNo subscription with this ID exists in the shop.
422objecttype is missing or not one_time or subscription; the key matching the type is missing (The plan_id field is required for subscription items., The variant_id field is required for one_time items.) or the other kind's key is sent (The plan_id field is only allowed for subscription items; a one_time item takes variant_id., The variant_id field is only allowed for one_time items; a subscription item takes plan_id.); plan_id is not a published, unarchived subscription plan of the shop or does not share the subscription's billing cycle (The selected product must share this subscription's billing cycle.); variant_id is not a published, unarchived, non-gift-card one-time product of the shop without variants and not a configurable bundle (The selected product is not a valid one-time product for this shop.); duration is not 1 or is sent for a subscription item (The duration field is not allowed for subscription items.); quantity is missing or below 1; bundle is missing while the plan is a configurable bundle, sent while it is not, or its preferences or items do not fit the bundle; or metadata holds an unknown metafield or an invalid value.
Show a single subscription item.
Path parameters
subscription_idRequiredintegerSubscription ID
item_idRequiredintegerSubscription item ID
Query parameters
expand[]optionalstring[]List of relations to expand in the response. Each expandable field on the response schema names its key, e.g. expand[]=customer. Nested keys use dot notation, e.g. items.product or subscriptions.items. Fields marked as always present are returned without being requested. An expanded list is null, not [], when there are no records. Unknown keys are ignored unless the endpoint says otherwise.
ReturnsSubscriptionItem
Subscription item object response
Error responses
400objectThe subscription item does not belong to this subscription.
404objectNo subscription with this ID exists in the shop, or no subscription item exists with this ID.
422objectThe expand[] parameter is not an array.
Update a subscription item's quantity, duration and/or metadata. duration is only valid for one-time items. The product is not changed here: move a subscription item to another plan with POST /subscriptions/{subscription_id}/items/{item_id}/change_plan (or several at once with POST /subscriptions/{subscription_id}/change_plans) and a one_time item to another variant with POST /subscriptions/{subscription_id}/items/{item_id}/change_variant. metadata replaces all metadata of the item.
Path parameters
subscription_idRequiredintegerSubscription ID
item_idRequiredintegerSubscription item ID
Query parameters
expand[]optionalstring[]List of relations to expand in the response. Each expandable field on the response schema names its key, e.g. expand[]=customer. Nested keys use dot notation, e.g. items.product or subscriptions.items. Fields marked as always present are returned without being requested. An expanded list is null, not [], when there are no records. Unknown keys are ignored unless the endpoint says otherwise.
Request body
Update a subscription item
quantityoptionalintegerItem quantity.
durationoptionalinteger | nullAdd-on duration. Only valid for one-time items; prohibited for subscription items.
Possible values: 1.
metadataoptionalMetadataUpdateMetadata of this item only.
ReturnsSubscriptionItem
Subscription item object response
Error responses
400objectThe subscription is not active, or the subscription item does not belong to this subscription.
404objectNo subscription with this ID exists in the shop, or no subscription item exists with this ID.
422objectquantity is not an integer of at least 1; duration is not 1, or is sent for a subscription item (The duration field is not allowed for subscription items.); a metadata entry is invalid (unknown metadata ID, missing values, or a value that does not fit the field); or expand[] is not an array.
Remove a subscription item. The last remaining subscription item cannot be removed. The request responds with 400 (error code last_subscription_item); cancel the subscription instead. The subscription's product_id is re-synced to the plan of its lowest-id remaining subscription item.
Only one rate-limited request per IP address runs at a time; an overlapping request responds with 429 (error code too_many_requests) instead of queueing.
Path parameters
subscription_idRequiredintegerSubscription ID
item_idRequiredintegerSubscription item ID
Query parameters
expand[]optionalstring[]List of relations to expand in the response. Each expandable field on the response schema names its key, e.g. expand[]=customer. Nested keys use dot notation, e.g. items.product or subscriptions.items. Fields marked as always present are returned without being requested. An expanded list is null, not [], when there are no records. Unknown keys are ignored unless the endpoint says otherwise.
ReturnsSubscription
Subscription object response
Error responses
400objectThe subscription is not active or the subscription item does not belong to this subscription (bad_request), or the item is the last remaining subscription item (last_subscription_item, Cannot remove the last subscription item. Please cancel the subscription instead.).
404objectNo subscription with this ID exists in the shop, or no subscription item exists with this ID.
422objectexpand is not an array.
429objectAnother rate-limited request from the same IP address is still running. The endpoint handles one such request at a time.
Update a subscription item's preferences
Update the survey preferences (answers) for a single subscription item.
Path parameters
subscription_idRequiredintegerSubscription ID
item_idRequiredintegerSubscription item ID
Query parameters
expand[]optionalstring[]List of relations to expand in the response. Each expandable field on the response schema names its key, e.g. expand[]=customer. Nested keys use dot notation, e.g. items.product or subscriptions.items. Fields marked as always present are returned without being requested. An expanded list is null, not [], when there are no records. Unknown keys are ignored unless the endpoint says otherwise.
Request body
Update a subscription item's survey preferences
preferencesRequiredobject[] | nullupdate_ordersoptionalbooleanUpdate order preferences in the awaiting_delivery and future_shipment status. Allowed when the survey appearance type is after checkout.
ReturnsSubscriptionItem
Subscription item object response
Error responses
400objectThe subscription is not active or the item is a one-time item (bad_request), or the chosen answers are out of stock (out_of_stock).
404objectNo subscription with this ID exists in the shop, no subscription item exists with this ID, or the item does not belong to this subscription.
422objectpreferences is missing, or the answers do not match the product's active survey (The preferences are invalid); a preference has no question_id or answers; or update_orders is true while the subscription uses dynamic shipping (The update orders is not allowed when the subscription uses dynamic shipping.) or while the survey is not shown after checkout and the shop does not sync order preferences (The update orders is prohibited when the survey appearance type is not after checkout.).
Deprecated. Do not use it in new integrations.
Deprecated: use POST /subscriptions/{subscription_id}/items/{item_id}/change_plan with plan_id (the target plan, or the current one to change only the contents) and bundle, and PATCH /subscriptions/{subscription_id}/items/{item_id} for the quantity. Update the configurable-bundle configuration (preferences, items, quantity and optionally the product) of a single subscription item. The item's product must be a configurable bundle. Works for subscriptions with any number of subscription items. The request runs as that pick plus the quantity change in one transaction.
Path parameters
subscription_idRequiredintegerSubscription ID
item_idRequiredintegerSubscription item ID
Query parameters
expand[]optionalstring[]List of relations to expand in the response. Each expandable field on the response schema names its key, e.g. expand[]=customer. Nested keys use dot notation, e.g. items.product or subscriptions.items. Fields marked as always present are returned without being requested. An expanded list is null, not [], when there are no records. Unknown keys are ignored unless the endpoint says otherwise.
Request body
Update a single subscription item's configurable bundle. The item's product must be a configurable bundle.
bundleRequiredSubscriptionBundleBodyBundle payload (preferences + items) for this subscription item.
quantityoptionalintegerItem quantity. When omitted the current quantity is kept.
product_idoptionalintegerOptional target plan for this item: a published configurable bundle of the shop, on the subscription's billing cycle unless the item is its only subscription item. When omitted the item keeps its current product.
ReturnsSubscriptionItem
Subscription item object response
Error responses
400objectThe subscription is not active, or the item is a one-time item (bad_request).
404objectNo subscription with this ID exists in the shop, no subscription item exists with this ID, or the item does not belong to this subscription.
422objectbundle is missing or lacks the preferences and items keys; the target product is not a configurable bundle (The selected product must have a configurable bundle.); bundle.preferences do not match the bundle (The bundle.preferences is invalid.); bundle.items hold a product the bundle does not allow (The bundle.items contains the invalid product.); product_id is not a subscription plan of the shop (The selected plan is not available for this item.), is on another billing cycle while the subscription has other subscription items (The selected plan is on another billing cycle. Move every subscription item at once with POST subscriptions/{subscription}/change_plans.), or is not published and unarchived, the scope this deprecated route keeps; or quantity is below 1.
Change the plan of a subscription item
Moves one subscription item to another plan: a pick of POST subscriptions/{subscription_id}/change_plans on its own route, with that route's targets (any subscription plan of the shop on the subscription's membership kind, the item's current plan included), bundle rules and effects. The plan must share the subscription's billing cycle unless the item is its only subscription item, which may change the cycle alone (one-time items do not count); with other subscription items, move them all at once with change_plans. One-time items change their variant with change_variant.
Path parameters
subscription_idRequiredintegerSubscription ID
item_idRequiredintegerSubscription item ID
Query parameters
expand[]optionalstring[]List of relations to expand in the response. Each expandable field on the response schema names its key, e.g. expand[]=customer. Nested keys use dot notation, e.g. items.product or subscriptions.items. Fields marked as always present are returned without being requested. An expanded list is null, not [], when there are no records. Unknown keys are ignored unless the endpoint says otherwise.
Request body
plan_idRequiredintegerThe plan the item moves to.
bundleoptionalSubscriptionBundleBody | nullThe contents for a configurable bundle plan: items (product_id, quantity) and preferences (metafield_id, values). null is the same as leaving bundle out.
ReturnsSubscriptionItem
The subscription item on its new plan
Error responses
400objectThe subscription is not active (subscription_not_active), or the item is a one-time item (item_not_subscription). The write re-checks the pick under the lock and refuses one that another write made invalid while the change waited for the subscription: the item was removed (plan_change_item_not_found), or another subscription item is on another billing cycle (plan_change_items_left_behind).
404objectNo subscription with this ID exists in the shop, or no subscription item with this ID belongs to the subscription.
422objectplan_id is missing, not an integer, or not a subscription plan of the shop the item may move to ("The selected plan is not available for this item."), or is on another billing cycle while the subscription has other subscription items ("The selected plan is on another billing cycle. Move every subscription item at once with POST subscriptions/{subscription}/change_plans."); bundle is sent for a plan without a configurable bundle ("The bundle field is not accepted for this plan."), missing while the plan's bundle is not the item's current bundle ("The bundle field is required for this plan."), lacks preferences or items, or holds preferences or items the bundle does not allow; or expand is not an array.
429objectAnother rate-limited request from the same IP address is still running. The endpoint handles one such request at a time.
Change the variant of a one-time item
Moves a one-time item of the subscription to another one-time variant of the shop. The change takes effect at the next renewal; quantity and duration stay as they are (change them with PATCH subscriptions/{subscription_id}/items/{item_id}). Sending the item's current variant is a no-op. Subscription items change their plan with POST subscriptions/{subscription_id}/items/{item_id}/change_plan or POST subscriptions/{subscription_id}/change_plans.
Path parameters
subscription_idRequiredintegerSubscription ID
item_idRequiredintegerSubscription item ID
Query parameters
expand[]optionalstring[]List of relations to expand in the response. Each expandable field on the response schema names its key, e.g. expand[]=customer. Nested keys use dot notation, e.g. items.product or subscriptions.items. Fields marked as always present are returned without being requested. An expanded list is null, not [], when there are no records. Unknown keys are ignored unless the endpoint says otherwise.
Request body
variant_idRequiredintegerThe one-time variant the item moves to.
ReturnsSubscriptionItem
Subscription item object response
Error responses
400objectThe subscription is not active (subscription_not_active), or the item is a subscription item (item_not_one_time).
404objectNo subscription with this ID exists in the shop, or no subscription item with this ID belongs to the subscription.
422objectvariant_id is missing, not an integer, or not a one-time variant of the shop that is published, not archived, not a gift card, a leaf and not a configurable bundle; or expand is not an array.
429objectAnother rate-limited request from the same IP address is still running. The endpoint handles one such request at a time.
Apply a discount to a subscription item
Applies a custom discount to one item of an active subscription. An item carries one at a time: remove it first to change it. An item gifted by a coupon keeps the coupon's discount next to the custom one, and both apply at renewal.
Path parameters
subscription_idRequiredintegerSubscription ID
item_idRequiredintegerSubscription item ID
Request body
The custom discount to apply to the subscription item
typeRequiredstringThe kind of discount. Only discount, a custom discount, is accepted on an item.
Possible values: discount.
percent_offoptionalnumberPercentage taken off the item. Exactly one of percent_off or amount_off must be provided.
amount_offoptionalintegerFixed amount taken off the item, in the minor units of the shop's base currency, converted to the subscription's currency at billing time. An amount above the item's price makes it free, never negative. Exactly one of percent_off or amount_off must be provided.
durationRequiredstringonce applies the discount to the next renewal that bills the item and then discards it; forever re-applies it on every renewal.
Possible values: once, forever.
ReturnsSubscriptionItem
Subscription item object response, with its discounts
Error responses
400objectThe item belongs to another subscription (bad_request), the subscription is not active (subscription_not_active), or the item already carries a custom discount (discount_already_applied).
404objectNo subscription with this ID exists in the shop, or no subscription item with this ID exists.
422objectThe payload is not a valid custom discount, for example:
The type field must be "discount", coupon and gift card discounts can only be applied to the subscription.The duration field is required for discounts of type "discount".The percent off field is required for discounts of type "discount" when amount_off is not provided.The percent off field cannot be combined with amount_off, a discount of type "discount" takes either an amount off or a percent off.
Remove a subscription item discount
Removes a discount of a subscription item: its custom one, or the discount a coupon put on the item it gifted. Without its coupon's discount a gift is billed at full price and is no longer removed when the coupon ends, so remove the item instead to drop the gift. The coupon is not credited back. Invoices that were already discounted are left untouched.
Path parameters
subscription_idRequiredintegerSubscription ID
item_idRequiredintegerSubscription item ID
discount_idRequiredintegerID of the discount to remove, as listed in the item's discounts
ReturnsSubscriptionItem
Subscription item object response, with its discounts
Error responses
400objectThe item belongs to another subscription, or the discount does not belong to the item.
404objectNo subscription, subscription item or discount with this ID exists.
Applies a subscription-level discount to an active subscription. Two kinds are supported and one of each may be applied at the same time: a coupon discount, which redeems a coupon and takes its duration from the coupon itself, and a custom discount, whose amount and duration you set directly. Applying a second discount of the same kind is rejected โ remove the existing one first. The discount is applied to upcoming invoices, not to invoices that already exist.
Path parameters
subscription_idRequiredintegerSubscription ID
Request body
The discount to apply to the subscription
typeoptionalstringThe kind of discount to apply. Defaults to coupon when omitted, so a body carrying only coupon_id keeps working.
Possible values: coupon, discount.
Defaults to "coupon".
coupon_idoptionalintegerID of the coupon to redeem. Required for the coupon type and prohibited for discount. The coupon must belong to the shop and still be redeemable; how long the discount lasts is taken from the coupon's own duration.
percent_offoptionalnumberPercentage taken off the invoice total. Only valid for the discount type; exactly one of percent_off or amount_off must be provided.
amount_offoptionalintegerFixed amount taken off the invoice total, in the minor units of the shop's base currency โ the same convention coupons use. It is converted to the subscription's currency at billing time, so a subscription billed in another currency is discounted by the converted equivalent. Only valid for the discount type; exactly one of percent_off or amount_off must be provided.
durationoptionalstringHow long the custom discount lasts. once applies it to the next invoice only and is then discarded; forever re-applies it on every renewal. Required for the discount type and prohibited for coupon.
Possible values: once, forever.
ReturnsSubscription
Subscription object response, with discounts expanded
Error responses
400objectThe subscription is not active (subscription_not_active), it already carries a discount of the requested type (discount_already_applied) โ remove the existing one first, the message names the type that is already applied โ or the coupon's last redemption was taken by a request that committed while this one was being validated (coupon_not_redeemable).
404objectNo subscription with this ID exists in the shop.
422objectThe payload does not match the requested discount type. Every message
names both the offending field and the type in play, so the response
alone is enough to correct the request. amount_off is validated the
same way as percent_off, with the counterpart field named in its
place, and it is capped at 99999999. A coupon that does not belong to
the shop fails with The selected coupon id is invalid., one that can
no longer be redeemed with The selected coupon can no longer be redeemed., and an unsupported type with The selected type is invalid. โ whatever discounts the subscription already carries, a
payload that does not validate is answered here, not with a 400.
The coupon_id field is required for discounts of type "coupon".The coupon_id field is only allowed for discounts of type "coupon", the requested discount type is "discount".The duration field is required for discounts of type "discount".The duration field is only allowed for discounts of type "discount", the requested discount type is "coupon".The percent_off field is required for discounts of type "discount" when amount_off is not provided.The percent_off field cannot be combined with amount_off, a discount of type "discount" takes either an amount off or a percent off.The code field is not accepted here. Apply a coupon by its coupon_id.
Removes a subscription-level discount โ either the coupon-backed one or the custom one. A coupon that was redeemed to create the discount is not credited back. Invoices that were already discounted are left untouched; upcoming invoices are billed without the discount.
Path parameters
subscription_idRequiredintegerSubscription ID
discount_idRequiredintegerID of the discount to remove, as returned by expand[]=discounts
ReturnsSubscription
Subscription object response, with discounts expanded
Error responses
400objectThe discount does not belong to this subscription.
404objectNo subscription with this ID exists in the shop, or no discount with this ID exists.