Product
Private Product API endpoints
- GET/products
- GET/products/{product_id}
- GET/variants/{variant_id}
- PUT/variants/{variant_id}
- GET/plans/{plan_id}
- PUT/plans/{plan_id}
- POST/products/subscription
- PUT/products/subscription/{product_id}
- POST/products/subscription/{product_id}/publish
- POST/products/subscription/{product_id}/unpublish
- POST/products/subscription/{product_id}/archive
- POST/products/subscription/{product_id}/metadata
- POST/products/one_time
- PUT/products/one_time/{product_id}
- POST/products/one_time/{product_id}/publish
- POST/products/one_time/{product_id}/unpublish
- POST/products/one_time/{product_id}/archive
- POST/products/one_time/{product_id}/metadata
- POST/variants
- POST/variants/{variant_id}/archive
- POST/variants/batch
- POST/plans
- POST/plans/{plan_id}/archive
An API endpoint to get list of products. The private API can access both published and unpublished products. Archived products and products that belong to a bundle are never returned, so bundle_id and bundle are always null here. Child records (variants and plans) are excluded as well; fetch those with expand[]. Results are ordered by id descending unless sort is supplied.
Query parameters
pageoptionalintegerPage number for pagination
Defaults to 1.
per_pageoptionalintegerItems per page
Defaults to 10.
typeoptionalstringFilter by product type
Possible values: one_time, subscription.
ids[]optionalinteger[]Filter by product IDs. Values must be unique.
tags[]optionalstring[]Filter by tags. Values must be unique.
slugs[]optionalstring[]Filter by product slugs. Values must be unique.
publishedoptionalbooleanFilter by published status
digitaloptionalbooleanFilter by digital products
gift_cardoptionalbooleanFilter by gift card products
expand[]optionalstring[]Relations to expand. Accepted values: variants (one-time products), plans and pricings (subscription products), and bundle. Dot notation expands nested relations of those, for example variants.bundle_plan or plans.parent. images, tags, options and metadata are always included and need not be requested. Unknown values are ignored.
sort[field]optionalstringField to sort by. Required whenever any sort[...] key is present, so sending sort[direction] on its own returns 422. Send sort as an object (sort[field]=name), never as a scalar. When sort is omitted the list is ordered by id descending.
Possible values: id, name.
sort[direction]optionalstringSort direction; defaults to asc.
Possible values: asc, desc.
Defaults to "asc".
Returnsobject
Products list response
A detailed description of the product. The private API can access both published and unpublished products.
Path parameters
product_idRequiredintegerProduct ID
Query parameters
expand[]optionalstring[]Relations to expand. Accepted values: variants (one-time products), plans and pricings (subscription products), and bundle. Dot notation expands nested relations of those, for example variants.bundle_plan or plans.parent. images, tags, options and metadata are always included and need not be requested. Unknown values are ignored.
ReturnsOneTimeProduct | SubscriptionProduct
Product object response
Error responses
403objectThe product belongs to another shop, or is archived.
404objectNo product exists with this ID, or the ID belongs to a variant or plan rather than a parent product.
Get a specific variant by ID. This endpoint is only for one-time product variants. Accepted expand values are parent, product and bundle_plan; without them those fields are null. options, attributes, metadata, stock_count and price_schema are always included and need no expand. Unrecognised expand values are ignored.
Path parameters
variant_idRequiredintegerVariant ID
Query parameters
expand[]optionalstring[]List of relations to expand in the response.
ReturnsVariant
Variant object response
Path parameters
variant_idRequiredintegerVariant ID
Request body
nameoptionalstring | nullRequired when the parent product is a gift card and the variant has no name yet.
priceoptionalintegerdescriptionoptionalstring | nullinventory_item_idoptionalinteger | nullProhibited for gift card products.
optionsoptionalobject | nullProhibited for gift card products. A product cannot have more than 3 distinct option types in total, counting option types already used by its variants.
ReturnsVariant
Variant object response
Get a specific plan by ID. This endpoint is only for subscription product plans that are not part of a bundle; use GET /bundles/{bundle_id}/plans/{plan_id} for those. Archived plans are not returned. Expandable relations: parent, product and bundle_plan. Shippings, survey, stock_count, metadata and price_schema are always included.
Path parameters
plan_idRequiredintegerPlan ID
Query parameters
expand[]optionalstring[]List of relations to expand in the response.
ReturnsPlan
Plan object response
Path parameters
plan_idRequiredintegerPlan ID
Request body
nameoptionalstring | nullpriceoptionalintegerPrice in cents. Cannot be changed if the plan has active subscriptions.
cut_off_daysoptionalinteger | nullRequired when the plan's shipment schedule is anchored (entries with unit_day), and prohibited when it is not. If shipment_schedule is sent in the same request, that value decides; otherwise the stored schedule does.
cut_off_timeoptionalstring | nullFormat HH:mm. Defaults to "23:59" when cut_off_days is sent without it. Rejected for digital products, for non-anchored shipment schedules, and when the shop's subscription plan does not include the cut-off-time feature.
charge_immediatelyoptionalintegerProhibited for digital products. Must be 1 when the plan is ad-hoc (no rebilling_day, rebilling_day_of_month or rebilling_day_of_week stored). Required whenever ship_immediately is sent.
Possible values: 0, 1.
ship_immediatelyoptionalintegerRequired whenever charge_immediately is sent. Cannot be 1 while charge_immediately is 0, and cannot be set to 0 while the plan has buffer_days; send buffer_days as null in the same request to clear it.
Possible values: 0, 1.
buffer_daysoptionalinteger | nullOnly settable when the plan has exactly one shipment schedule entry, counted from shipment_schedule if sent in the same request, otherwise from the plan's stored schedule.
trial_priceoptionalinteger | nullProhibited when the parent product has a pre-order end date, and prohibited for anchored plans (plans with a stored rebilling_day* value).
trial_length_daysoptionalinteger | nullProhibited when the parent product has a pre-order end date, and prohibited for anchored plans (plans with a stored rebilling_day* value).
trial_single_orderoptionalintegerProhibited for digital products. Setting it to 1 also requires an ad-hoc plan with a trial length (sent or already stored) and no pre-order end date.
Possible values: 0, 1.
commitment_billing_countoptionalinteger | nullOnly available when the shop's subscription plan includes commitment billing.
charges_limitoptionalinteger | nullshipment_scheduleoptionalobject[]Prohibited for digital products. All entries must use the same format, and each entry must supply exactly one of the two pairs: buffered (add_unit + add_count) or anchored (unit_day + unit_offset). The buffered pair is prohibited while the plan's schedule is anchored.
survey_idoptionalinteger | nullID of a survey belonging to the authenticated shop.
ReturnsPlan
Plan object response
Request body
nameRequiredstringslugRequiredstringLetters, digits, dashes and underscores only. Must be unique among the shop's products; a duplicate slug is rejected with 422.
digitaloptionalintegerPossible values: 0, 1.
descriptionoptionalstring | nulldelivery_infooptionalstring | nullgifting_enabledoptionalinteger | nullNot available for digital products: when digital is 1 the only accepted value is 0. Defaults to 0 when omitted.
Possible values: 0, 1.
pre_order_end_atoptionalstring | nullDate in Y-m-d form; must be today or later. Must be omitted when digital is 1; pre-order is not available for digital products.
Format: date.
setup_feeoptionalinteger | nullpause_enabledoptionalintegerDisabling pause (0) requires the optional-pause feature on the shop's plan. Shops without it may only send 1. Defaults to 1 when omitted.
Possible values: 0, 1.
collect_shipping_addressoptionalinteger | nullOnly digital products (digital: 1) may send 0. For physical products the only accepted value is 1. Defaults to 1 for physical products and 0 for digital ones when omitted.
Possible values: 0, 1.
tax_product_codeoptionalstring | nullUS-based shops only. Sending a non-empty value from a shop in any other country is rejected with 422.
inventory_item_idoptionalinteger | nullMust reference a non-archived inventory item belonging to the shop.
funnel_idoptionalinteger | nullMust reference a non-deleted funnel belonging to the shop.
tagsoptionalobjectimagesoptionalobject | nullReturnsSubscriptionProduct
Subscription product created
Path parameters
product_idRequiredintegerProduct ID
Request body
nameoptionalstringslugoptionalstringLetters, digits, dashes and underscores only. Must be unique among the shop's other products; a duplicate slug is rejected with 422.
descriptionoptionalstring | nulldelivery_infooptionalstring | nullgifting_enabledoptionalintegerMust be omitted for digital products; sending any value, including 0, on a digital product is rejected with 422.
Possible values: 0, 1.
pre_order_end_atoptionalstring | nullDate in Y-m-d form; must be today or later. Must be omitted for digital products. Rejected with 422 when any active plan of this product has a trial; remove the trial first, or send null to clear the pre-order date.
Format: date.
setup_feeoptionalinteger | nullpause_enabledoptionalintegerDisabling pause (0) requires the optional-pause feature on the shop's plan. Shops without it may only send 1.
Possible values: 0, 1.
collect_shipping_addressoptionalintegerOnly accepted as 0 when the product is digital. For a physical product the only accepted value is 1.
Possible values: 0, 1.
tax_product_codeoptionalstring | nullUS-based shops only. Sending a non-empty value from a shop in any other country is rejected with 422.
inventory_item_idoptionalinteger | nullMust reference a non-archived inventory item belonging to the shop.
funnel_idoptionalinteger | nullMust reference a non-deleted funnel belonging to the shop.
change_product_collection_idoptionalinteger | nullID of the product collection used for cross-product plan switching. Must be a non-archived collection of the shop whose type is 'subscription' or unset.
tagsoptionalobjectimagesoptionalobjectReturnsSubscriptionProduct
Subscription product updated
Fails with 400 when the product is archived or part of a bundle, when name or slug is missing, when it has no active plans, or when a physical product has a plan without shipping options.
Path parameters
product_idRequiredintegerProduct ID
ReturnsSubscriptionProduct
Subscription product published
Fails with 400 when the product is archived or part of a bundle.
Path parameters
product_idRequiredintegerProduct ID
ReturnsSubscriptionProduct
Subscription product unpublished
Fails with 400 when the product is already archived, is part of a bundle, or still has active subscriptions.
Path parameters
product_idRequiredintegerProduct ID
ReturnsSubscriptionProduct
Subscription product archived
Attaches and detaches metadata on the product. The product must not be archived and must not belong to a bundle; either case returns 400 (entity_archived, product_in_bundle). Values attached to or detached from a parent product are also applied to all of its active variants.
Path parameters
product_idRequiredintegerProduct ID
Request body
Metadata sync request body
metadataRequiredobjectReturnsSubscriptionProduct
Subscription product metadata synced
Request body
nameRequiredstringslugRequiredstringLetters, digits, dashes and underscores only. Must be unique among the shop's products.
gift_cardoptionalintegerPossible values: 0, 1.
digitaloptionalintegerMust be omitted when gift_card is 1; gift cards are always digital. Sending both fields returns a validation error.
Possible values: 0, 1.
descriptionoptionalstring | nulldelivery_infooptionalstring | nullMust be omitted when digital or gift_card is 1; delivery info is not available for digital products.
gift_card_expirationoptionalinteger | nullGift card expiration in months. Only allowed when gift_card is 1; sending it for a non-gift-card product returns a validation error.
gifting_enabledoptionalintegerMust be omitted when digital or gift_card is 1; gifting is not available for digital products. Null is not accepted. Defaults to 0.
Possible values: 0, 1.
collect_shipping_addressoptionalinteger | nullOnly digital products (digital or gift_card = 1) may send 0. For physical products the only accepted value is 1. Defaults to 1 for physical products and 0 for digital ones.
Possible values: 0, 1.
funnel_idoptionalinteger | nulltax_product_codeoptionalstring | nullOnly available for US-based shops. Shops in any other country must omit this field entirely.
tagsoptionalobjectimagesoptionalobject | nullReturnsOneTimeProduct
One-time product created
Returns 400 when the product is already archived (entity_archived) or belongs to a bundle (product_in_bundle). The id must refer to a one-time product owned by the authenticated shop.
Path parameters
product_idRequiredintegerProduct ID
Request body
nameoptionalstringslugoptionalstringLetters, digits, dashes and underscores only. Must be unique among the shop's products (this product excluded).
descriptionoptionalstring | nulldelivery_infooptionalstring | nullMust be omitted when the stored product is digital (digital = true in the response).
gift_card_expirationoptionalinteger | nullGift card expiration in months. Only allowed when the stored product is a gift card (gift_card = true in the response).
gifting_enabledoptionalintegerMust be omitted when the stored product is digital (digital = true in the response).
Possible values: 0, 1.
collect_shipping_addressoptionalinteger0 is accepted only when the stored product is digital (digital = true in the response). For physical products the only accepted value is 1.
Possible values: 0, 1.
positionoptionalintegerfunnel_idoptionalinteger | nulltax_product_codeoptionalstring | nullOnly available for US-based shops. Shops in any other country must omit this field entirely.
tagsoptionalobjectimagesoptionalobjectReturnsOneTimeProduct
One-time product updated
Preconditions, each returning 400: the product must have a name and a slug (missing_required_fields), it must have at least one non-archived variant (no_active_children), it must not be archived (entity_archived) and it must not belong to a bundle (product_in_bundle). Gift card products also require the gift_cards feature on the shop.
Path parameters
product_idRequiredintegerProduct ID
ReturnsOneTimeProduct
One-time product published
Returns 400 when the product is already archived (entity_archived) or belongs to a bundle (product_in_bundle). The id must refer to a one-time product owned by the authenticated shop.
Path parameters
product_idRequiredintegerProduct ID
ReturnsOneTimeProduct
One-time product unpublished
Returns 400 when the product is already archived (entity_archived, so archive is not idempotent) or belongs to a bundle (product_in_bundle). The id must refer to a one-time product owned by the authenticated shop.
Path parameters
product_idRequiredintegerProduct ID
ReturnsOneTimeProduct
One-time product archived
Attaches and detaches metadata on the product. The product must not be archived and must not belong to a bundle; either case returns 400 (entity_archived, product_in_bundle). Values attached to or detached from a parent product are also applied to all of its active variants.
Path parameters
product_idRequiredintegerProduct ID
Request body
Metadata sync request body
metadataRequiredobjectReturnsOneTimeProduct
One-time product metadata synced
Creates a variant on a one-time product. The parent product must not be archived. A product is limited to 125 variants. Only one variant without options is allowed per product, so once a product has any variant, further variants must supply options.create (gift card products are exempt).
Request body
product_idRequiredintegerParent one-time product ID
nameoptionalstring | nullRequired when product is a gift card or when no options are provided.
priceRequiredintegerPrice in cents
descriptionoptionalstring | nullinventory_item_idoptionalinteger | nullProhibited for gift card products.
optionsoptionalobject | nullProhibited for gift card products. A product cannot have more than 3 distinct option types in total, counting option types already used by its variants.
ReturnsVariant
Variant object response
Archives a one-time product variant. Fails if the variant is already archived, or if it is the parent product's last non-archived variant, because a product must keep at least one active variant.
Path parameters
variant_idRequiredintegerVariant ID
ReturnsVariant
Variant object response
Creates, updates and archives variants of a one-time product in one call. Not available for gift card products, and the product must not be archived. The maxItems: 100 cap applies per list; in addition, the product's variant count after the batch (existing + created - archived) must not exceed 125.
Request body
product_idRequiredintegergenerate_inventoryoptionalbooleanDefaults to false.
inventory_group_idoptionalinteger | nullMust be a non-deleted inventory item group belonging to your shop.
inventory_stock_countoptionalintegerDefaults to 0.
createoptionalobject[]Every entry must use the same set of option names, and that set must match the option names already used by the product's existing variants (case-insensitive). A product cannot have more than 3 distinct option types in total. An entry with no options.create must supply name.
updateoptionalobject[]Within each entry, options.create[].name must already be an option type on the product, since new option types cannot be introduced here, and options.update[].id must be an option that belongs to the product.
archiveoptionalobject[]Returnsobject
Batch operation result
Request body
product_idRequiredintegerParent subscription product ID
frequency_unitRequiredstringPossible values: day, week, month.
frequency_countRequiredintegerMinimum 1, but minimum 2 when rebilling_day is set together with frequency_unit=day.
nameoptionalstring | nullpriceoptionalintegerPrice in cents
anchor_dateoptionalstring | nullAccepts a date (Y-m-d) or the string "today", which resolves to the current date. Only allowed for non-digital products whose shipment_schedule uses the anchored format (entries with unit_day). Required when a rebilling_day* field is set and frequency_unit=day.
Format: date.
rebilling_dayoptionalintegerOnly the value 1 is accepted. Allowed for non-digital products with frequency_unit=day only. Mutually exclusive with rebilling_day_of_week and rebilling_day_of_month. Do not send null; omit the field instead.
Possible values: 1.
rebilling_day_of_monthoptionalintegerMutually exclusive with the other two rebilling_day* fields. Requires a non-digital product and frequency_unit=month, and must agree with anchor_date when one is supplied. Do not send null; omit the field instead.
rebilling_day_of_weekoptionalintegerMutually exclusive with the other two rebilling_day* fields. Requires a non-digital product and frequency_unit=week, and must agree with anchor_date when one is supplied. Do not send null; omit the field instead.
cut_off_daysoptionalinteger | nullOnly allowed when shipment_schedule uses the anchored format (entries with unit_day). Required when a rebilling_day* field is set.
cut_off_timeoptionalstring | nullFormat HH:mm. Defaults to "23:59" when cut_off_days is sent without it. Rejected for digital products, for non-anchored shipment schedules, and when the shop's subscription plan does not include the cut-off-time feature.
charge_immediatelyoptionalintegerProhibited for digital products. Must be 1 for ad-hoc plans (plans with no rebilling_day, rebilling_day_of_month or rebilling_day_of_week). Required whenever ship_immediately is sent. Defaults to 1 when omitted.
Possible values: 0, 1.
ship_immediatelyoptionalintegerRequired whenever charge_immediately is sent, and cannot be 1 while charge_immediately is 0. Defaults to 0 when omitted.
Possible values: 0, 1.
buffer_daysoptionalinteger | nulltrial_priceoptionalinteger | nullProhibited when the parent product has a pre-order end date, and prohibited for anchored plans (plans that set any rebilling_day* field).
trial_length_daysoptionalinteger | nullProhibited when the parent product has a pre-order end date, and prohibited for anchored plans (plans that set any rebilling_day* field).
trial_single_orderoptionalintegerProhibited for digital products. Setting it to 1 also requires an ad-hoc plan with trial_length_days set and no pre-order end date on the parent product.
Possible values: 0, 1.
commitment_billing_countoptionalinteger | nullOnly available when the shop's subscription plan includes commitment billing; otherwise the request is rejected.
charges_limitoptionalinteger | nullshipment_scheduleoptionalobject[]Required when the parent product is not digital, and prohibited when it is digital. All entries must use the same format: either every entry is buffered (add_unit + add_count) or every entry is anchored (unit_day + unit_offset). Mixing formats is rejected.
survey_idoptionalinteger | nullID of a survey belonging to the authenticated shop.
ReturnsPlan
Plan object response
Archive a subscription product plan. The plan must belong to a subscription product that is not part of a bundle (use POST /bundles/{bundle_id}/plans/{plan_id}/archive for those), must not already be archived, must not be the parent product's last active plan, and must have no active subscriptions attached.
Path parameters
plan_idRequiredintegerPlan ID
ReturnsPlan
Plan object response