Storefront search APIs overview

Ask about this Page
Copy for AI
View as Markdown

How to work with the APIs for storefront search.

This page describes rules that apply across the Storefront Search APIs. For what Product Search is and how it behaves, see the Storefront search overview.

APIs in this topic

ResourcePurposeReference
Product SearchCreate storefront discovery experiences where customers can browse and search across your Products.Product Search

Working with the APIs

Activate the Product Search API

The Product Search API is not active for the Project by default. Before first use, you have to activate it by one of the following options:

Once activated for your Project, your Products get indexed, and the Search Products endpoint will become fully functional soon after.

Automatic deactivation

The Product Search API is automatically deactivated for a Project if there have been no calls to the Search Products endpoint for 30 consecutive days. Once deactivated, the Product Search API rejects all search requests with an ObjectNotFound error.

You can reactivate the Product Search API as described above.

Data integration

The Product Search API is designed to be ID-first to provide high performance. This means that the query result contains only Product IDs (together with matching Product Variant IDs when requested), but not the entire resource. This design prefers lower response times over completeness of data, which can be achieved through the additional methods described in Data integration.

Compare product retrieval methods

You can use the following methods for retrieving product data, each suited to different use cases.

Product Search is optimized for product discovery based on indexed product information. It allows full-text and non-exact searches using prefixes and wildcards, and provides faceting to support multi-facet navigation on product listing pages. Be aware of the indexing delay: the product information might not always reflect the latest state.
Query Product Projections queries the product database directly to check Products against the provided predicates. Typical storefront queries can take significantly longer compared to a Product Search request. Use this method only when real-time data accuracy is more critical than query performance. Since this method returns either the current or the staged representation of a Product, the response is smaller than querying the full Product resource.
Do not use this method to retrieve current product stock levels. The availability of a ProductVariant in a Product Projection is eventually consistent and may not reflect immediate stock. Instead, use the Inventory API.
Query VariantProjections returns lightweight, read-only representations of individual Product Variants with embedded Product data. Use this method for storefront pages that need Variant-level data under the Modular ProductCatalogModel. For more information, see Variant Projections.
Query Products returns entire Products with both current and staged representations. Use this method only for product data management in backoffice applications.

Product indexing

Indexing is a process carried out by the API to build the search index for your product information, which is optimized for read access with low response times. If you retrieve product information using the Products API or Product Projections API before indexing is complete, the product data in the search index might be different. The search index is automatically updated whenever Products are changed.
FunctionalityProduct Search
Indexed projection of the Productscurrent
Support for Variant-level Attributesvariants.attributes.<attribute-name> expression, up to 50 Attributes per Product Variant
Support for Product-level Attributes BETAattributes.<attribute-name> expression, up to 50 Attributes per Product Variant
Support for Standalone Pricesfor sorting, filtering, and faceting, up to 10 000 Standalone Prices per Product
Support for validity periods of Pricesvariants.prices.* keyword fields
Support for Storesstores keyword field, up to 15 000 Stores per Product
Support for Product SelectionsproductSelections keyword field, up to 15 000 Product Selections per Product
Support for Product Tailoringwith GraphQL
The Product Search API uses a dedicated search index to provide fast and relevant search results. To prevent your storefront from exposing staged product data, only the current representation of Products is indexed for Product Search by design. Product Search indexes Attributes and Prices of published Products based on specific limits to ensure optimal performance.

Attributes

Product Search indexes both Product Attributes BETA and Variant Attributes for which the AttributeDefinition's isSearchable field is set as true. Only Attributes that are present in the Product or Product Variant are indexed. If a Product Type defines an Attribute but the corresponding Product Variant does not have a value for this Attribute, then this Attribute is not indexed.

Large number of Attributes

For performance reasons, the number of indexed Attributes per Product Variant is limited to 50. The limit applies to both Product Attributes and Variant Attributes separately. For example, if a Product Variant has 42 Variant Attributes and the respective Product has additional 15 Product Attributes, then all 57 Attributes are indexed.
If the number of searchable Attributes present in a Product Variant exceeds this limit, the indexer applies the following strategy to make 50 Attributes available for Product Search.

Indexing strategy

For each Product Variant, the indexer:

  • Counts the number of Attributes used on the Product Variant in the order they are defined on the corresponding Product Type.
  • Skips any Attribute that is not present on the Product Variant.
  • Skips any Attribute that is present but not marked as searchable.
  • Indexes any Attribute that is present and marked as searchable.
  • Continues until the limit of 50 Attributes is reached.

Example

Consider an example Product Type that has 100 Attributes (attr_1, ..., attr_100) defined and all of them are marked as searchable.
  • Given a Product Variant that has all Attributes of this Product Type in use, Product Search would index the first 50 Attributes (from attr_1 to attr_50). The remaining Attributes (attr_51 to attr_100) would not be indexed due to the limit.
  • Let's say there is another Product Variant that uses 60 Attributes from the example Product Type (attr_21 to attr_80). Product Search would skip the first 20 Attributes since they are not present on the Product Variant, and would start from attr_21 this time. The indexer would then finish with attr_70 because the limit has been reached leaving out attr_71 to attr_80.

Product Attributes BETA

The indexing strategy is applied separately for Product Attributes on Products when they exceed the limit of 50. Overall, Product Search can index up to (50 + 50) Attributes per Product Variant.

Prices

The Product's priceMode determines which Prices are indexed in the variants.prices field.
For the Embedded ProductPriceMode, the API indexes Embedded Prices; for Standalone, the API indexes the Standalone Prices associated with the Product Variant. The Modular ProductCatalogModel supports only Standalone Prices.
The API uses the variants.prices field for sorting, filtering, and faceting on Products, but its content is not retrievable through the Product Search API. Standalone Prices cannot be retrieved through the Product Search API. To retrieve Price data, use the GraphQL API or the Product Projection API for Embedded Prices. In Projects with the ProductCatalogModel set to Modular, use the Variant Projections API.
To ensure good performance of the API, the number of Standalone Prices indexed per Product is limited to 10 000 in Classic Projects. In Projects with the ProductCatalogModel set to Modular, indexed Variants and indexed Standalone Prices of a Product share this same 10 000 limit. The indexer prioritizes Variants, indexing as many Variants of the Product as possible first, then uses any remaining capacity within the limit to index Standalone Prices. For Products with Standalone Prices that exceed the available limit, the system indexes a selection of the Prices as explained in the Large number of Standalone Prices section.
Only one valid price for each price scope (currency, country, customerGroup, and distributionChannel) is actually indexed. Like other attributes, this process operates on an eventually consistent basis, meaning that invalid prices might still be present in the index immediately after an update. When trying later, the price will be updated.

In case of multiple prices for the same scope, the one with the narrower (valid) time range is always selected over the price without time ranges.

Large number of Standalone Prices

In Classic Projects, the search index can hold up to 10 000 Standalone Prices per Product. In Modular Projects, this same limit is shared with indexed Variants, as described in Prices; The indexer fills this shared limit with Variants first, then indexes Standalone Prices using whatever capacity remains. For example, a Product has 9500 Variants and 1200 Standalone Prices. Since Variants are indexed first, they consume 9500 of the 10,000 limit, leaving only 500 slots for Standalone Prices. As a result, only 500 of the 1200 Standalone Prices can be indexed.

If a Product has more Standalone Prices than the remaining capacity allows, the API applies a sorting algorithm when indexing Product Prices to ensure a fair distribution of indexed Prices across all Product Variants.

For each Product in the Project:

  1. Calculate the per-Variant Price limit. To do this, divide the available Standalone Prices capacity (10 000 in Classic Projects, or the remaining capacity after Variants are indexed in Modular Projects) by the number of Variants on the Product. This gives the maximum number of Standalone Prices indexed per Variant.
  2. fetch Prices for all Variants.
  3. for each Variant:
  • sort Prices by

    • currency (alphabetically by the value.currencyCode)
    • country (alphabetically, missing field is sorted as first)
    • channel (alphabetically by key, missing field is sorted as first)
    • Customer Group (alphabetically by key, missing field is sorted as first)
  • truncate Prices that are beyond the Variant limit.

Examples

  • Example 1: A Product has 4 Variants and 1000 Standalone Prices. Each Variant is allowed a maximum of 250 (1000 / 4) indexed Standalone Prices. If a Variant has 300 Standalone Prices, they are sorted by currency, then country, then channel, then Customer Group. Only the first 250 (in that sorted order) are indexed; the remaining 50 are discarded.
  • Example 2: A Product has 10,500 Variants, which exceeds the available Standalone Prices capacity of 10,000. Since Variants are indexed first, no capacity remains for Standalone Prices, so the per-Variant Price limit is 0. As a result, none of the Product's Standalone Prices are indexed.

Prices with validity dates

The Price with the most exact data and price scope is indexed for a Product Variant. This means that a Price with a valid time range is given priority over a Price without a validity period. Prices that are not valid at the time of indexing are not considered for indexing. Product Search does not automatically update the search index when a Price reaches its validity date or becomes invalid.

If your use case requires prices with validity dates, please contact our commercetools support team. We will help you configure your Project to ensure proper handling of price updates based on validity dates.

Stores

The search index can hold up to 15 000 Stores per Product. If a Product belongs to more than 15 000 Stores, the API will return non-deterministic results for expressions on the stores keyword field.

Product Selections

The search index can hold up to 15 000 Product Selections per Product. If a Product belongs to more than 15 000 Product Selections, the API will return non-deterministic results for expressions on the productSelections keyword field.

Localized content

To support exact, fullText, prefix, fuzzy, and wildcard expressions, the Product Search API analyzes the localized product data specific to the supported languages.

Language settings

When Products are indexed, the Product Search API selects the best-fitting language-specific analyzer according to the Project settings. If no languages are set on the Project, the analyzers for the following languages are used by default: en, en-GB, en-CA, en-US, en-AU, de, de-DE, es, se, fi, da, fr, and fr-FR.
Any language that is specified on the Product field, but not defined in the Project settings, will make that localized Product field not searchable.
Example: A Project has language settings defined for en and de, and a Product has localized name fields, one for name.ro and one for name.de. Since the Romanian language is not part of the Project language settings, the name.ro field is not searchable, only the name.de field is in this case.

Supported languages

subtaglanguage
arArabic
caCatalan
csCzech
daDanish
deGerman
elGreek
enEnglish
esSpanish
euBasque
faPersian
fiFinnish
frFrench
hiHindi
huHungarian
hyArmenian
idIndonesian
itItalian
koKorean
lvLatvian
nlDutch
noNorwegian
plPolish
ptPortuguese
roRomanian
ruRussian
skSlovak
svSwedish
thThai
trTurkish
zhChinese

Index updates

Our search infrastructure uses an event-driven indexing process to ensure product and price information remains current. The indexing method depends on the type of operation on the product catalog:

Incremental indexing

The following changes will cause an incremental indexing:

  • A creation, update, or deletion of a Product, a Product Variant or a Price (Embedded or Standalone).
  • An activation or deactivation of a Product Discount leading to changes on Prices.
  • An addition of Products or Product Variants to a Product Selection (same for removal).

On average, an incremental index update is performed within a few minutes. Depending on the amount of Products to be updated, for example in a batched process, the actual delay—until all the Products are up-to-date—can be higher.

Incremental indexing is paused while a full reindexing is in progress.

Full reindexing

The following changes will require a full reindexing:

  • A creation, update, or deletion of a Product Type.
  • A creation, update, or deletion of a Store.
  • A deletion of a Product Selection.

On average, a full reindex is performed within 15 minutes. The actual delay—until the product data is up-to-date—can be higher and depends on the following factors:

  • The number of Products in the catalog.
  • The number and size of the Product Variants of the Products.
  • The number of Standalone Prices used in the Project.
  • The number of Product Selections and Stores used in the Project.

Query expressions

FunctionalityProduct Search
Full-text searchfullText expression
Fuzzy searchfuzzy expression
Exact matchexact expression
Range of valuesrange expression
If field existsexists expression
Prefix matchprefix expression
Wildcard matchwildcard expression
Boosting particular searchable fieldsboosting
Specify query expressions per searchable fieldby field name
Operators to define compound expressionsand, or, not, filter operators

Query result

By default, the Product Search API returns only the IDs of the matching Products. You can use the returned Product IDs to retrieve the full projection of a Product (Get Product Projection by ID).
Where the Variant data comes from depends on the ProductCatalogModel of the Project, Classic or Modular. For details, see Data integration.
FunctionalityProduct Search
IDs of the matching Productsby default
Full representations of the matching Productswith GraphQL
Price selectionwith GraphQL
Scoped Price searchwith filter by price

Filtering

FunctionalityProduct Search
Non-facet-driven filter (for example by Category, Attribute values, full-text search) that both results and every facet's base set inherit.query in ProductSearchRequest
Narrow the set of returned products after facets are calculated.postFilter in ProductSearchRequest
Narrow the calculated facet results.filter in facet expressions

Faceting

FunctionalityProduct Search
Count all occurrences of distinct values.distinct facets
Count Products that have values within a specified range.ranges facets
Count the number of Products or Product Variants.count facets
Calculate statistics for facet values.stats facets
Allow for handling missing values when calculating facets.missing values
Filter facet results.filter facet
Specify scope of facets.scope of facets
Assign a custom name to a facet result.name in facet expression

Sorting

FunctionalityProduct Search
Sort order (ascending or descending)asc and desc sort order
Sort mode to specify which value to sort on when a Product contains multiple values for the fieldmin, max, avg, sum sort mode
Specify exactly which resources should be considered for sorting.sort filter
Sort by a localized field, such as namelanguage property on the sort object
Sort by CategoryOrderHintsstructured sort object

Pagination

FunctionalityProduct Search
Maximum results per page (limit)100
Maximum total results reachable through paginationfirst 10 000 results
Error when the offset exceeds the maximumInvalidInput error

Limits

Product Search supports searching through Products across the following resources:

ResourceLimit per Product
Stores15 000
Product Selections15 000
Standalone Prices10 000

These limits are soft:

  • If you exceed the limits for Stores or Product Selections, the API returns non-deterministic results.
  • If you exceed the limit for Standalone Prices, the API applies a sorting algorithm during Product indexing to offer a balanced selection of Prices across Variants.
For performance reasons, the API imposes some limitations. Follow our performance tips to minimize the response times for the Product Search API.