Catalog V1 to V3 Conversion Guide

This guide aims to assist developers in migrating from the Stores Catalog V1 API to the V3 API. It outlines key changes in the product object structure and provides detailed conversion tables for various components.

This guide does not provide an automatic migration path. Rather, it serves as a reference for understanding structural and naming differences between the two versions. Use this guide when rebuilding or updating your implementation to align with the new V3 API.

Important:

To ensure that new and existing sites can install your app, your app must support both Catalog V3 and Catalog V1. You must confirm compatibility in your app's dashboard for Wix users to install your app.

New apps that don't support both versions won't be listed in the app market. Existing apps that don't support both versions won't work on new sites.

Major Changes

  1. Product to Variant Field Relocation: Several fields have moved from the product level to the variant level, including actual price and compare at price. This change allows for more granular control per variant.
  2. Universal Variants: Every product now has at least one variant. Products without options are treated as 'single variant products'.
  3. Variant Management: The manageVariants field has been removed. All products now have variants:
    1. Products without options are considered single variant products
    2. Products with at least one option (equivalent to managedVariants: true in V1) may have multiple variants
  4. Pricing Model Changes:
    • Variant-Level Pricing: Pricing is now exclusively managed at the variant level. The priceData and convertedPriceData objects have been removed. Instead, the price fields themselves will reflect the converted currency values. Note that read-only Price Ranges like actualPriceRange and compareAtPriceRange are still available at the product level to reflect the minimum and maximum prices across all variants.
    • New Discount Model: The discount object (including percentage or amount types) is no longer supported. Instead, discounts are represented by the relationship between two price fields:
      • actualPrice: (Required) The final selling price (what the customer pays).
      • compareAtPrice: (Optional) The original price (displayed as strikethrough).
    • How to Convert:
      • If product has a discount: Map V1 price → V3 compareAtPrice, and V1 discountedPrice → V3 actualPrice.
      • If product has NO discount: Map V1 price → V3 actualPrice and leave compareAtPrice empty.
  5. Options and Modifiers: In V3 options will always create variants, equivalent to V1 manageVariants=true. Modifiers behave like V1 options with manageVariants=false. A major improvement in V3 is the ability to mix options and modifiers on the same product.
  6. Custom Text Fields: These have been moved to the modifiers field. Map V1 customTextFields &arr; V3 modifiers with type FREE_TEXT.

Some fields previously accessible via the Catalog V1 Product object are now available through other Catalog V3 APIs. On the other hand, some fields that required separate API calls in V1 are now directly available in the Products V3 API.

Conversion Tables

*Fields marked with an asterisk signify little to no change in semantics or access.

Product Object Conversion

Product V1Product V3Notes
id*idThe $hasSome operator for filtering by product.id is not supported in V3.
name*name
slug*slug
visible*visible
productTypeproductTypeEnum values in V3 are in UPPER_CASE
descriptiondescription (recommended) OR plainDescription (if integration with RICOS isn't possible)
skuvariantsInfo.variants[i].skuFor single variant product only. Each variant in V3 can have its own SKU
weightvariantsInfo.variants[i].physicalProperties.weightFor single variant product only. Each variant in V3 can have its own weight
weightRange.minValuephysicalProperties.shippingWeightRange.minValue
weightRange.maxValuephysicalProperties.shippingWeightRange.maxValue
stock.trackInventoryAvailable via Inventory Items APIEach variant in V3 can have its own inventory. Search Inventory Items and filter by productId and/or variantId.
stock.quantityAvailable via Inventory Items APIEach variant in V3 can have its own inventory. Search Inventory Items and filter by productId and/or variantId.
stock.inventoryStatusinventory.availabilityStatus
priceData.currencycurrencyNow a requested field
priceData.pricevariantsInfo.variants[i].price.compareAtPrice.amountSee Pricing Model Changes in Major Changes section above
priceData.discountedPricevariantsInfo.variants[i].price.actualPrice.amountSee Pricing Model Changes in Major Changes section above
priceData.formatted.pricevariantsInfo.variants[i].price.compareAtPrice.formattedAmountSee Pricing Model Changes in Major Changes section above
priceData.formatted.discountedPricevariantsInfo.variants[i].price.actualPrice.formattedAmountSee Pricing Model Changes in Major Changes section above
priceData.formatted.pricePerUnitvariantsInfo.variants[i].physicalProperties.pricePerUnit.descriptionSee Pricing Model Changes in Major Changes section above
priceData.pricePerUnitvariantsInfo.variants[i].physicalProperties.pricePerUnit.valueSee Pricing Model Changes in Major Changes section above
convertedPriceData.currencycurrencyNow a requested field
convertedPriceData.pricevariantsInfo.variants[i].price.compareAtPrice.amountFor single variant product only. Each variant in V3 can have its own compare at price
convertedPriceData.discountedPricevariantsInfo.variants[i].price.actualPrice.amountFor single variant product only. Each variant in V3 can have its own actual price
convertedPriceData.formatted.pricevariantsInfo.variants[i].price.compareAtPrice.formattedAmountFor single variant product only.
convertedPriceData.formatted.discountedPricevariantsInfo.variants[i].price.atualPrice.formattedAmountFor single variant product only.
convertedPriceData.formatted.pricePerUnitvariantsInfo.variants[i].physicalProperties.pricePerUnit.descriptionFor single variant product only.
convertedPriceData.pricePerUnitvariantsInfo.variants[i].physicalProperties.pricePerUnit.valueFor single variant product only.
priceRange.minValuecompareAtPriceRange.minValue.amount
priceRange.maxValuecompareAtPriceRange.maxValue.amount
costAndProfitData.itemCostvariantsInfo.variants[i].revenueDetails.cost.amountFor single variant product only.
costAndProfitData.formattedItemCostvariantsInfo.variants[i].revenueDetails.cost.formattedAmountFor single variant product only.
costAndProfitData.profitvariantsInfo.variants[i].revenueDetails.profit.amountFor single variant product only.
costAndProfitData.formattedProfitvariantsInfo.variants[i].revenueDetails.profit.formattedAmountFor single variant product only.
costAndProfitData.profitMarginvariantsInfo.variants[i].revenueDetails.profitMarginFor single variant product only.
costRange.minValuecostRange.minValue.amount
costRange.maxValuecostRange.maxValue.amount
pricePerUnitData.baseQuantityphysicalProperties.pricePerUnit.quantity
pricePerUnitData.baseMeasurementUnitphysicalProperties.pricePerUnit.measurementUnit
pricePerUnitData.totalQuantityvariantsInfo.variants[i].physicalProperties.pricePerUnit.settings.quantityV3 moves unit settings to the variant level for greater flexibility. Base settings remain on the product.
pricePerUnitData.totalMeasurementUnitvariantsInfo.variants[i].physicalProperties.pricePerUnit.settings.measurementUnitV3 moves unit settings to the variant level for greater flexibility. Base settings remain on the product.
additionalInfoSections[i].descriptioninfoSections[i].description (recommended) OR infoSections[i].plainDescription (if integration with RICOS isn't possible)Learn more in the Info Section API
additionalInfoSections[i].titleinfoSections[i].titleLearn more in the Info Section API
-infoSections[i].uniqueNameNew in V3. Required unique identifier set by the developer. Learn more in the Info Section API
media.mainMediamedia.mainSee media conversion table
media.items[i]media.itemsInfo.items[i]See media conversion table
customTextFields[i].titlemodifiers[i].freeTextSettings.titleManage these fields with the Customizations API
customTextFields[i].maxLengthmodifiers[i].freeTextSettings.maxCharCountManage these fields with the Customizations API
customTextFields[i].mandatorymodifiers[i].mandatoryManage these fields with the Customizations API
manageVariants-See point (3) in Major Changes section above
productOptionsoptionsSee Options and Modifiers in Major Changes section above
productOptions[i].optionType and manageVariants = trueoptions[i].optionRenderTypeWritable in V3. drop_down becomes TEXT_CHOICES; color becomes SWATCH_CHOICES.
productOptions[i].optionType and manageVariants = falsemodifiers[i].modifierRenderTypeWritable in V3. drop_down becomes TEXT_CHOICES; color becomes SWATCH_CHOICES.
productOptions[i].name and manageVariants = trueoptions[i].name
productOptions[i].name and manageVariants = falsemodifiers[i].name
productOptions[i].choices[i].value and manageVariants = trueoptions[i].choicesSettings.choices[i]
productOptions[i].choices[i].value and manageVariants = falsemodifiers[i].choicesSettings.choices
productOptions[i].choices[i].description and manageVariants = trueoptions[i].choicesSettings.choices[i].name
productOptions[i].choices[i].description and manageVariants = falsemodifiers[i].choicesSettings.choices[i].name
productOptions[i].choices[i].media and manageVariants = trueoptions[i].choicesSettings.choices[i].linkedMedia[i]See media conversion table
productOptions[i].choices[i].media and manageVariants = falsemodifiers[i].choicesSettings.choices[i].linkedMedia[i]See media conversion table
productOptions[i].choices[i].inStockoptions[i].choicesSettings.choices[i].inStock
productOptions[i].choices[i].visibleoptions[i].choicesSettings.choices[i].visible
productPageUrl.baseurl.urlMust be a full URL
productPageUrl.pathurl.relativePath
numericIdWas used for cursor paging - V3 Query & Search APIs support cursor paging out of the box
inventoryItemIdAvailable via Inventory Items APIMoved to inventory service but it's no longer saved on Product V3. Search Inventory Items and filter by productId and/or variantId.
discount.typevariantsInfo.variants[i].price.actualPrice.amountDiscounts now saved on each variant
discount.valuevariantsInfo.variants[i].price.actualPrice.amountDiscounts now saved on each variant
collectionIds[i]directCategories[i].id
variants[i].idvariantsInfo.variants[i].id
variants[i].choices[key]variantsInfo.variants[i].choices[i].optionChoiceNames.optionName
variants[i].choices[value]variantsInfo.variants[i].choices[i].optionChoiceNames.choiceName
-variantsInfo.variants[i].choices[i].optionChoiceNames.renderTypeNew in V3. Required. Must match the optionRenderType defined in product.options.
variants[i].variant.priceData-See point (5) in Major Changes section above
variants[i].variant.convertedPriceData.pricevariantsInfo.variants[i].price.compareAtPriceRange.amount
variants[i].variant.convertedPriceData.discountedPricevariantsInfo.variants[i].price.actualPrice.amount
variants[i].variant.convertedPriceData.formatted.pricevariantsInfo.variants[i].price.compareAtPriceRange.formattedAmount
variants[i].variant.convertedPriceData.formatted.discountedPricevariantsInfo.variants[i].price.actualPrice.formattedAmount
variants[i].variant.convertedPriceData.formatted.pricePerUnitvariantsInfo.variants[i].physicalProperties.pricePerUnit.description
variants[i].variant.convertedPriceData.pricePerUnitvariantsInfo.variants[i].physicalProperties.pricePerUnit.value
variants[i].variant.costAndProfitData.itemCostvariantsInfo.variants[i].revenueDetails.cost.amount
variants[i].variant.costAndProfitData.formattedItemCostvariantsInfo.variants[i].revenueDetails.cost.formattedAmount
variants[i].variant.costAndProfitData.profitvariantsInfo.variants[i].revenueDetails.profit.amount
variants[i].variant.costAndProfitData.formattedProfitvariantsInfo.variants[i].revenueDetails.profit.formattedAmount
variants[i].variant.costAndProfitData.profitMarginvariantsInfo.variants[i].revenueDetails.profitMargin
variants[i].variant.weightvariantsInfo.variants[i].physicalProperties.weight
variants[i].variant.skuvariantsInfo.variants[i].sku
variants[i].variant.visiblevariantsInfo.variants[i].visible
variants[i].stock.trackQuantityAvailable via Inventory Items API
variants[i].stock.quantityAvailable via Inventory Items API
variants[i].stock.inStockvariantsInfo.variants[i].inventoryStatus.inStock
lastUpdatedupdatedDate
createdDatecreatedDate
seoData*seoData
ribbonribbon.nameManage these fields with the Ribbons API
brandbrand.nameManage these fields with the Brands API
taxGroupIdtaxGroupId
digitalFile.idvariantsInfo.variants[i].digitalProperties.digitalFile.idEach variant in V3 can have its own digital file
digitalFile.fileNamevariantsInfo.variants[i].digitalProperties.digitalFile.fileNameEach variant in V3 can have its own digital file
digitalFile.fileTypevariantsInfo.variants[i].digitalProperties.digitalFile.fileTypeEach variant in V3 can have its own digital file

*Fields marked with an asterisk signify little to no change in semantics or access.

Media Conversion Table

New in V3: product media can be set directly as part of the Products API via the product.media field.

Media V1Media V3
thumbnail.url-
thumbnail.width-
thumbnail.height-
thumbnail.format-
thumbnail.altText-
mediaType-
title and mediaType = IMAGEimage.fileName
title and mediaType = VIDEOvideo.filename
id and mediaType = IMAGEimage.id
id and mediaType = VIDEOvideo.id
image.url*image.url
image.width*image.width
image.height*image.height
image.format-
image.altText*image.altText
video.files[i].urlvideo.resolutions[i].url
video.files[i].widthvideo.resolutions[i].width
video.files[i].heightvideo.resolutions[i].height
video.files[i].formatvideo.resolutions[i].format
video.files[i].altText-
video.stillFrameMediaId-

Inventory Conversion Table

In V3, you can manage inventory using the dedicated Inventory Items API. Alternatively, you can set inventory alongside product variants for easier assignment using Create Product With Inventory or Bulk Update Products With Inventory.

Inventory V2Inventory Items V3Notes
id*id
productId*productId
trackQuantitytrackQuantityNow per-variant and read-only. Derived from inStock or quantity.
variants[i].variantIdvariantId
variants[i].inStocktrackingMethod.inStock
variants[i].quantitytrackingMethod.quantity
variants[i].availableForPreorderAvailabilityStatus = PREORDER
lastUpdatedupdatedDate
numericId-Was used for cursor paging - V3 Query & Search APIs support cursor paging out of the box
preorderInfo.enabledpreorderInfo.enabledNow per-variant
preorderInfo.messagepreorderInfo.messageNow per-variant
preorderInfo.limitpreorderInfo.limitNow per-variant

Subscriptions Conversion Table

In V1 Subscriptions has its own APIs, where in V3 we don't have a dedicated API. Subscriptions exists directly in Product entity.

SubscriptionOption V1Product V3
idsubscriptionDetails.subscriptions[i].id
titlesubscriptionDetails.subscriptions[i].title
descriptionsubscriptionDetails.subscriptions[i].description
subscriptionSettings.frequencysubscriptionDetails.subscriptions[i].frequency
subscriptionSettings.intervalsubscriptionDetails.subscriptions[i].interval
subscriptionSettings.autoRenewalsubscriptionDetails.subscriptions[i].autoRenewal
subscriptionSettings.billingCyclessubscriptionDetails.subscriptions[i].billingCycles
discount.typesubscriptionDetails.subscriptions[i].discount.type
discount.valuesubscriptionDetails.subscriptions[i].discount.amountOff OR subscriptionDetails.subscriptions[i].discount.percentOff
SubscriptionOptionInProduct V1Product V3
idsubscriptionDetails.subscriptions[i].id
hiddensubscriptionDetails.subscriptions[i].visible
titlesubscriptionDetails.subscriptions[i].title
descriptionsubscriptionDetails.subscriptions[i].description
subscriptionSettings.frequencysubscriptionDetails.subscriptions[i].frequency
subscriptionSettings.intervalsubscriptionDetails.subscriptions[i].interval
subscriptionSettings.autoRenewalsubscriptionDetails.subscriptions[i].autoRenewal
subscriptionSettings.billingCyclessubscriptionDetails.subscriptions[i].billingCycles
discount.typesubscriptionDetails.subscriptions[i].discount.type
discount.valuesubscriptionDetails.subscriptions[i].discount.amountOff OR subscriptionDetails.subscriptions[i].discount.percentOff

Webhook Conversion Table

The following table shows Catalog V1 webhooks and their equivalents in Catalog V3 that are triggered at the same time:

Catalog V1Catalog V3
Product CreatedProduct Created
Product ChangedProduct Updated
Product DeletedProduct Deleted
Variants ChangedProduct Updated variantsInfo will be included in modifiedFields
Collection CreatedCategory Created
Collection ChangedCategory Updated
Collection DeletedCategory Deleted

We've updated the structure of the webhook/event payload. The product ID is now provided both at the top level as entityId and as product.id within the payload itself. The table below describes where to find the product ID or product entity in the new webhook payloads:

Catalog V1 WebhooksCatalog V3 Webhooks
productId, collectionId, variants.variantIdAll webhook payloads - entityId
Product Changed - changedFieldsmodifiedFields
Product/Collection Created entity datacreatedEvent.entityAsJson

For more detailed information on specific field changes and how to access data in the new API structure, please refer to our API documentation.

Did this help?