Product catalog APIs overview

Ask about this Page
Copy for AI
View as Markdown

How to work with the APIs for the Product catalog.

This page describes rules that apply across the Product catalog APIs. For what the Product catalog resources are and how they behave, see the Product catalog overview.

APIs in this topic

ResourcePurposeReference
Product TypesDescribe common characteristics, most importantly common custom Attributes, of many concrete Products.Product Types
Attribute GroupsAllow fine-grained access management to a subset of Attributes of a Product.Attribute Groups
ProductsManage your products and product information in your project.Products
Product ProjectionsRetrieve product data projected to the context of your Store, specific to the customer locale and country.Product Projections
Product SelectionsManage individual Store assortments through Product Selections.Product Selections
Product TailoringManage market-specific Product information.Product Tailoring
CategoriesOrganize your Products into various classifications.Categories
ReviewsEvaluate Products and Channels.Reviews

Data model

The Product catalog resources are organized around the Product. Other resources define the structure of a Product, provide views of its data, or adapt it to a Store.

Product structure

Each Product references exactly one Product Type, which defines the custom Attributes of the Product and its Product Variants. You can't change the Product Type of an existing Product. To customize resources other than Products, refer to Types.
An Attribute Group references Attributes by their name as it appears in their Attribute Definition, regardless of the Product Type. As a result, an Attribute Group covers the Attributes with that name in all Product Types.

Product representations

A Product contains both current and staged data simultaneously. A ProductProjection restricts the data to just one of these representations. You can check the hasStagedChanges and published fields on a Product Projection to determine whether a Product has unpublished edits or is currently published. For how publishing changes these fields, see Publishing state.

Store-specific Product data

A Product Selection can contain several Products. You can assign several Product Selections to a Store, and assign a Product Selection to several Stores. You can query the Product Projections of those Products per Store. The following diagram shows the relationship between the Product Selection entity and other entities in the commerce APIs.
Product Selections related to Stores and Products
A Product Tailoring contains Store-specific Product information. It belongs to exactly one Product and one Store.

Working with the APIs

Products

The Master Variant always has id set to 1. You can reassign which variant is the Master Variant by using the Change Master Variant update action.
When updating product data through the HTTP API, you can use the Set Attribute in All Variants update action.

Product Projections

You can project Product data with the Product Projections API and the Products API. On the GraphQL API, the products query blends the capabilities of both REST APIs. The REST query parameters map to GraphQL arguments and fields with similar names, usually without the parameter prefix. For example, the priceCurrency query parameter maps to the currency argument of the price field. For more information, see Query Products.
A Store can define settings such as languages, and Channels for Inventory and pricing. When you project Product data by Store, the Product Projection contains only the localized values, Inventory entries, and Prices that suit the Store. For the query parameter of each projection dimension, see Projection dimensions.

Publishing state

A Product has either one or two projections that you can retrieve, depending on whether the Product is published. Only published Products have a current projection. Newly created Products have only a staged projection. This doesn't change the data that the Product stores: every Product contains both current and staged data from the moment it's created.
When the staged data differs from the current data, the hasStagedChanges flag on ProductCatalogData is set to true.
When you publish a Product, the platform does the following:
  • Copies the staged data to current.
  • Sets the published flag on ProductCatalogData to true.
  • Sets the hasStagedChanges flag on ProductCatalogData to false.
Typical storefront applications retrieve only the current projection of published Products, by querying Product Projections or by searching Products. To restrict access to published Products only, assign the view_published_products:{projectKey} scope instead of view_products:{projectKey}.
Unpublishing a Product only sets the published flag on ProductCatalogData to false. It doesn't change the data stored in the current or staged representations. By default, the Product Projection endpoints no longer return an unpublished Product, and the Product is removed from the Product Search index.

Locale projection

To remove unneeded translations from Product Projections, you can filter LocalizedStrings by locale. The locales to include are determined in the following order:
  1. Locales that you request explicitly.
  2. Locales configured in the Store that you project by.
If a field has no translation for the requested locales, the API checks the Project languages in their configured order and uses the first localized value it finds. This ensures that required fields can't remain empty in the Product Projection.
Locale projection also affects the Line Items of Carts that are bound to a Store.

Price projection by Store

To remove unneeded Embedded Prices from Product Projections, you can filter them by the distribution Channels and countries configured in the Store that you project by.
If the Store has distributionChannels set, the Product Projection includes only the Prices that meet one of the following criteria:
  • The Price has a distribution Channel that is included in the Store's distributionChannels.
  • The Price doesn't have a distribution Channel assigned.
If the Store has countries set, the Product Projection includes only the Prices that meet one of the following criteria:
  • The Price has a country that is included in the Store's countries.
  • The Price doesn't have a country assigned.
This filtering applies to the prices array of the Product Projection.
Price projection by Store applies only when the Product priceMode is Embedded.
Standalone Prices are not computed using the Channels or countries of a Store. To retrieve a Standalone Price in Product Projections, apply projection by price selection.

Inventory projection by Store

To remove unneeded Product Variant Availabilities from Product Projections, you can filter them by the Inventory supply Channels configured in the Store that you project by.
If the Store has supplyChannels set, the availability of the projected Product Variants includes only the following Inventory entries:
  • Inventory entries with a supply Channel that is included in the Store's supplyChannels.
  • Inventory entries without a supply Channel.
Inventory projection also affects the Line Items of Carts that are bound to a Store.

Product Variants in Store

When a Product is part of an active Product Selection of a Store and has an associated Variant Selection, retrieving the Product Projection in that Store returns only the selected Product Variants.

When a Store has two or more active Product Selections that contain the same Product but have different Variant Selections, the representation of the Product in the Store is resolved as follows:

If the Variant Selection of a Product excludes all of its Product Variants, or if the Product is assigned to a Product Selection with mode IndividualExclusion without any Variant Exclusion, the Product is considered absent in the Store.

Categories in Store

When you retrieve a Product Projection in a Store, the ProductProjection categories array includes only the Categories that are available in that Store. The excluded Categories are also removed from categoryOrderHints.

Product Projections API vs. Product Search API

Two primary APIs are available for Product discovery and retrieving Product information: the Product Projection API and the Product Search API. Both read-only APIs are optimized for Customer-facing storefront needs, but they serve different use cases and have distinct characteristics.

The following table compares use cases and features of each API, and it provides performance tips for optimal usage:

FeatureProduct Projections APIProduct Search API
Purpose
  • Retrieves projected representations of Products by their Key or ID or by using Query Predicates.
  • Provides advanced storefront Product discovery at scale, especially across many Stores, Product Selections, and Standalone Prices.
Use case
  • Use in scenarios where tailored and contextualized product data is needed, such as on the Product details page (PDP).
  • Use for full-text and prefix search, filters, and facetted navigation on Product listing pages (PLPs).
Data consistency
Query language
  • Simple filtering by using Query Predicates.
  • Only exact match on standard and Attribute values.
  • Complex filters with expressive search query language, supporting full-text, prefix, and wildcard queries.
  • Calculates facets.
Data returned
  • Product Projections tailored to the requested context.
  • IDs of matching Products and the IDs and SKUs of matching Product Variants.
  • Facets
Publishing state
  • Retrieves published Product data by default, but supports retrieval of staged data by query parameter.
  • Can retrieve tailored as well as original Product data.
  • Indexes the current representation of published Products with their Standalone Prices.
  • Doesn't index tailored Product data.
Product Selections
  • Supports retrieval of only those Products that are assigned to a particular Product Selection.
  • Supports filtering by Stores and Product Selections.
Performance tips
  • Use this API only for a small number of lookups by ID or Key or for simple queries.
  • Cache retrieved Product data.
  • Avoid inefficient query patterns.
For discovering Products based on attribute values and prices on your Product Listing Page, use the Product Search API.
For retrieving product information to be presented on your Product Detail Page, use the Product Projection API or, when using the Modular catalog model, the Variant Projections API.

Product Selections

With the Product Search API you can query if a Product belongs to a specific Product Selection or Store. Currently, Product Variant Selections are not supported. The deprecated Product Projection Search API does not provide Store-specific search requests that are scoped to certain Product Selections.
The guide Integrate external search explains how to integrate an external search service to populate a search index per Store. Alternatively, you can populate one search index per Product Selection. This approach lets you preview upcoming assortments, such as a summer collection, before you publish them.
Treat the sku values as immutable identifiers. Finalize SKUs before assigning Products or Variant Selections to Product Selections to avoid background recalculation of ProductSelectionAssignments when the Product is published.

Product Tailoring

Attributes with savedToLineItem set to false on their AttributeDefinition are excluded from Line Items when a Product with tailoring is added to a Cart.
Tailored data is associated with a Product via the Product's key. Deleting a Product, or changing the Product key, will delete all associated tailored data.
Tailored information is not indexed for the Storefront Search APIs.

Attribute Constraints are validated on Tailoring creation, update, and publishing, but their consistency is not guaranteed with respect to changes on the corresponding Product side.

Tailor product information

For each piece of product information you want to tailor for the Store, add the appropriate Product field with the tailored value to the ProductTailoringData object. For fields that you don't add to this object, the API returns the corresponding original value from the Product's ProductData object when retrieving the ProductProjection in Store.
The following example shows a Product Tailoring for the name and description fields of a Product, but not for its slug. For the slug field, the ProductProjection takes the original value from the ProductData.
Field nameField value on ProductDataField value on ProductTailoringDataField value on ProductProjection in Store
name"en: original name""en: tailored name""en: tailored name"
description"en: original desc""en: tailored desc""en: tailored desc"
slug"en: original_slug""en: original_slug"

Tailor Product Variant information

The API allows you to customize Images and Assets per Store by tailoring existing ProductVariants or Variants. To assign Store-specific Product Variant information, add the tailored Image or Asset to the corresponding ProductVariantTailoring object. For Images and Assets that you don't add to this object, the API returns the corresponding original Images and Assets from the ProductVariant or Variant when retrieving the ProductProjection in Store.
The following example shows a ProductVariantTailoring for the UK Store, but no tailoring for the ES Store. The API retrieves the Images for ProductVariant in UK Store from the Images given in the ProductVariantTailoring UK ignoring the Images in the ProductVariant:
The images for ProductVariant in ES Store are retrieved from the original Images in the ProductVariant because no ProductVariantTailoring is defined for the ES Store.

Stage and publish tailored product information

Similar to the Product's ProductCatalogData, where you can prepare your original product information in the staged version of ProductData, you can prepare the tailored product information in a staged version of the ProductTailoringData, before you publish the ProductTailoring to current.
The published flag on the ProductTailoring indicates the publication status of the tailoring as a whole. When true, you'll find only the fields in the current ProductTailoringData object in the related current ProductProjection in Store. With the unpublish action you can set published to false which leads to all fields falling back to their original values from ProductData regardless of what is stored in the current version of the ProductTailoringData.
The published status of the Product Tailoring is independent of the published status of the Product itself. The published field of the Product on ProductCatalogData determines whether the current Product Projection in Store is retrievable. The following table summarizes how the published statuses affect the availability of Product Projections in Store and their tailored information:
ProductProduct TailoringStaged Product Projection in StoreCurrent Product Projection in Store
unpublishedunpublishedoriginal Product informationnot retrievable
unpublishedpublishedtailored Product informationnot retrievable
publishedunpublishedtailored Product informationoriginal Product information
publishedpublishedtailored Product informationtailored Product information
For the query parameters to retrieve each of these, see Retrieve Product Projection with tailored information.
The hasStagedChanges field is true whenever someone modified tailored information in the staged tailoring information, that are not yet reflected in the current tailoring information. This can give your team some indication to review the staged changes before publishing them, but your reviewer needs to find out which fields have changed. If you are interested in changes on particular fields of the ProductTailoring, we recommend subscribing to Product Tailoring Messages.

Categories

Category tree locking

To keep ancestor lists (paths) and Store assignments consistent, write operations on the Category tree lock the Category nodes they affect. If another operation already holds a required lock, the request fails with an InvalidOperation (400) error.

The lock scope depends on the operation:

  • Whole Category tree: a Change Parent action locks the entire Category tree in the Project for the duration of the request, because it can change the ancestor path of every Category below it. While it is in progress, any other Change Parent action, any Create Category request with a parent, and any Store update action anywhere in the Project fails.
  • Parent Category: a Create Category request with a parent locks that parent Category. The request fails if another Create Category request under the same parent, a Store update action on that parent or one of its existing children, or a Change Parent action is in progress. Creating a Category without a parent doesn't take this lock. Requests targeting different parents don't conflict with each other.
  • Category and its parent: the Set Stores, Add Store, and Remove Store actions lock the Category itself and its parent Category. Concurrent Store updates to the same Category, to sibling Categories, or to a Category and one of its direct children can conflict.
  • Category and its descendants: the Set Stores with Descendants, Add Store with Descendants, and Remove Store with Descendants actions don't change any Store when the API receives the request. The API only records the request and responds with 202 Accepted. A background process then updates the target Category and every descendant Category, which is eventually consistent. While the background process runs, it locks the target Category and its subtree, so Store updates, Change Parent actions, and Create Category requests with a parent for Categories in that subtree fail and should be retried. These actions are only available on the general endpoint and are rejected on the Store-specific endpoint.
To reduce conflicts, serialize requests that create or update Categories under the same parent. If a request fails because of a lock conflict, retry it after a short delay. For general retry recommendations, see Retry policies. For Category imports, see CategoryImport.

Manage workflow and governance

To enforce custom validation, automated data enrichment, or content filtering before changes are saved, you can use API Extensions on Products. For example, an API Extension can validate that SKUs follow internal conventions, enrich Attributes with data from an external PIM system, or redact unapproved content on create and update requests before persisting data.
Product modeling elements (such as Product Types, Attributes, and Categories) span multiple Projects including development, staging, and production. Set keys on all entities to ensure that you can replicate the data across different environments. After establishing the foundational structure, consider using an infrastructure-as-code tool to manage Product Types, Attributes, Categories, and more. For example, you can use Terraform with the commercetools Terraform provider.

Limits

In the Classic ProductCatalogModel, a Product can have up to 100 Product Variants. In the Modular ProductCatalogModel, a Product can have up to 10 000 Variants, which are managed as standalone entities through the Variants API. These limits can be increased per project after we review the performance impact. Contact the commercetools support team and provide the region, project key, and use case.
A maximum number of 1 000 ProductTypes can be created per Project. This is a soft limit that can be increased per Project after a performance impact review. See Limit increase guidance.
A maximum number of 100 Attribute Groups can be created per Project.
The maximum number of SKUs per Product Selection matches the Product Variants limit per Product. This is a soft limit that can be increased per Project after a performance impact review. See Limit increase guidance.
A maximum number of 100 000 000 Product Tailoring across all Products and Stores can be created per Project. This is a soft limit that can be increased per Project after a performance impact review. See Limit increase guidance.
A maximum number of 10 000 Categories can be created per Project. This is a soft limit that can be increased per Project after a performance impact review. See Limit increase guidance.