Skip to main content

Setting Up Catalog Search

Catalog Search provides fast, relevant product search capabilities for your storefront. This guide walks you through enabling and configuring search for your catalogs using the API.

tip

You can also configure Catalog Search using Commerce Manager. See Catalog Search in Commerce Manager for step-by-step instructions.

Overview

The Catalog Search service provides:

  • Full-text search across product names, descriptions, SKUs, and custom fields
  • Faceted navigation for filtering by categories, attributes, and price ranges
  • Relevance ranking with customizable search profiles
  • Multi-language support with locale-aware search
  • Price filtering with automatic currency and price book support
  • Configurable text processing with stemming, token separators, and symbols (special characters) to index
  • Typo tolerance that forgives spelling mistakes and supports search-as-you-type
  • Synonyms so different words for the same product find each other
  • Stopwords that ignore low-value words like the and a at query time

Prerequisites

Before setting up catalog search, ensure you have:

  • Catalog Search enabled for your store or organization (contact Customer Success to enable this feature)
  • Search enabled for the catalogs you want to be searchable (see Enabling Catalog Search)
  • A published catalog with products, hierarchies, and price books configured
  • API credentials with appropriate permissions

What Happens When Search is Enabled

When you enable search for a catalog:

  1. Automatic indexing: All future catalog releases are automatically indexed when published
  2. Extended publishing: The publish process includes an indexing step that makes products searchable
  3. Search availability: Once indexed, products are searchable via the Search API
note

Existing releases are not automatically indexed. You must publish a new release after enabling search for products to become searchable.

Understanding the Indexing Process

When you publish a catalog release, the following occurs:

  1. The catalog release is processed and stored (shows as 99% complete)
  2. An indexing job is created to make products searchable
  3. Products are transformed and indexed with their:
    • Names and descriptions (per locale)
    • SKUs and other identifiers
    • Category/hierarchy associations
    • Prices from all configured price books
    • Custom indexable fields
  4. The release is marked as PUBLISHED when indexing completes

Configuring Indexable Fields

By default, catalog search indexes standard product fields with default settings. Indexable fields let you extend and fine-tune the search schema:

  • Add custom fields to the index from product extension templates or custom (shopper and admin) attributes
  • Override core field behavior such as stemming, tokenization, and sorting on built-in fields like name, description, and sku
  • Control tokenization at the collection or per-field level using token separators and symbols to index

List Available Searchable Fields

To see what fields are currently searchable:

curl https://useast.api.elasticpath.com/v2/pcm/catalogs/searchable-fields \
-H "Authorization: Bearer $ACCESS_TOKEN"

Add Custom Indexable Fields

To make custom product attributes searchable, create indexable fields:

curl -X POST https://useast.api.elasticpath.com/v2/pcm/catalogs/indexable-fields \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": {
"type": "catalog_search_indexable_fields",
"attributes": {
"fields": [
{
"name": "shopper_attributes.color",
"facetable": true,
"sortable": false
},
{
"name": "extensions.products(clothing).brand",
"facetable": true,
"sortable": true
},
{
"name": "extensions.products(specifications).rating",
"facetable": true,
"sortable": true
}
]
}
}
}'

Field options:

OptionDescription
nameThe field path in your product extensions (must match pattern extensions.products(<template>).<field>) or admin/shopper attributes (must match pattern admin_attributes.<field> or shopper_attributes.<field>)
facetableEnable faceting (aggregated counts) on this field. Default: false
sortableEnable sorting by this field. Default: true for numeric fields, false otherwise
localeLanguage for tokenization (default: en)
stemEnable word stemming on this field. String fields only. Default: false. See Stemming
token_separatorsCharacters that split text into tokens for this field, overriding the collection-level setting. See Customizing Tokenization
symbols_to_indexSpecial characters preserved in tokens for this field, overriding the collection-level setting. See Customizing Tokenization

Override Core Product Fields

Core product fields such as name, description, and sku are always indexed. Use core_field_overrides to change how individual core fields are indexed — for example, to enable stemming on descriptions, split SKUs on hyphens, or make name sortable:

curl -X POST https://useast.api.elasticpath.com/v2/pcm/catalogs/indexable-fields \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": {
"type": "catalog_search_indexable_fields",
"attributes": {
"core_field_overrides": [
{
"name": "description",
"stem": true
},
{
"name": "name",
"stem": true,
"sortable": true
},
{
"name": "sku",
"token_separators": ["-"],
"sortable": true
}
]
}
}
}'

Each override supports stem, sortable, token_separators, and symbols_to_index, but not every setting is available on every core field:

SettingSupported core fields
stemname, description, meta.search.nodes.name
sortablename, sku
token_separatorsAll string fields
symbols_to_indexAll string fields

Stemming

Stemming reduces words to their root form at both index and query time, so a search for running also matches products containing run, runs, or running. This improves search recall for descriptive text fields where shoppers may use different word forms than those found in product data.

For example, with stemming enabled on name, a search for walked matches a product named Walk and Talk Tours — both walked and Walk reduce to the stem walk. Without stemming, an inflected query like walked does not match a product that only contains the base form walk.

Enable stemming per field by setting stem: true on entries in fields (custom fields) or core_field_overrides (core fields):

{
"data": {
"type": "catalog_search_indexable_fields",
"attributes": {
"fields": [
{ "name": "shopper_attributes.material", "stem": true }
],
"core_field_overrides": [
{ "name": "name", "stem": true },
{ "name": "description", "stem": true }
]
}
}
}

Notes:

  • Stemming uses the Snowball stemmer
  • Only valid for string-typed fields
  • Defaults to false

Customizing Tokenization

By default, text is split into tokens on whitespace and newlines, and special characters are stripped during indexing and searching. Two settings let you change this behavior.

Token Separators

token_separators specifies additional characters that split text into separate tokens. This is useful for hyphenated text, part numbers, or other compound formats.

For example, take a product containing the text water-proof. By default, it is tokenized as waterproof, so a search for water proof does not match. With token_separators: ["-"], the text is tokenized as water and proof, so searches for both water-proof and water proof match.

Symbols (Special characters) to Index

symbols_to_index specifies special characters that should be preserved within tokens rather than stripped. This is useful when products contain meaningful symbols.

For example, with default settings the + in S24+ is stripped, so S24+ is indexed as S24 and loses precision. With symbols_to_index: ["+"], S24+ is preserved as a distinct token and matches precisely. Only index special characters if they add value and are actually a differentiating factor e.g. S24+ vs S24.

Each element in token_separators and symbols_to_index must be a single character.

Collection-Level vs Field-Level

Both settings can be applied at two scopes:

  • Collection-level: Set token_separators or symbols_to_index at the top level of the indexable fields attributes to apply across all indexed fields.
  • Field-level: Set the same properties on an individual entry in fields or core_field_overrides to apply only to that field, overriding the collection-level setting. An empty array at the field level defers to the collection-level setting.
{
"data": {
"type": "catalog_search_indexable_fields",
"attributes": {
"token_separators": ["-"],
"symbols_to_index": ["+"],
"core_field_overrides": [
{ "name": "sku", "token_separators": ["/"] }
]
}
}
}

In this example, all fields split tokens on - and preserve +, except sku, which splits on / instead.

caution

After adding or modifying indexable fields, you must reindex your catalog releases for the changes to take effect. See Reindexing.

Setting Up Search Profiles

Search profiles control how search queries are executed. They define which fields to search, their relative importance, and business rules for filtering and boosting results.

Create a Search Profile

curl -X POST https://useast.api.elasticpath.com/v2/pcm/catalogs/search-profiles \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": {
"type": "catalog_search_profile",
"attributes": {
"slug": "default-search",
"description": "Default search profile for storefront",
"fields": [
{ "name": "name", "weight": 10 },
{ "name": "description", "weight": 5 },
{ "name": "sku", "weight": 8 },
{ "name": "meta.search.nodes.name", "weight": 3 }
],
"text_match_type": "max_score"
}
}
}'

Understanding Field Weights

Field weights control the relative importance of each field when ranking search results:

  • Higher weights mean matches in that field contribute more to relevance
  • A product with "laptop" in the name (weight 10) ranks higher than one with "laptop" only in description (weight 5)
  • Weights are relative: 10:5:3 behaves the same as 100:50:30

Text Match Types

The text_match_type determines how scores from multiple fields are combined:

TypeDescriptionBest For
max_score (default)Uses highest score from any matching fieldGeneral product search
max_weightUses score from highest-weighted matching fieldWhen field importance matters more than match quality
sum_scoreSums weighted scores from all matching fieldsRewarding multi-field matches

Typo Tolerance and Partial Word Matching

Search profiles also control how forgiving search is towards imperfect queries — how many spelling mistakes are corrected (typo_tolerance), whether a partially typed last word matches, how compound words like waterproof and water proof match each other, and more. These settings can be tuned per profile and per field, for example to keep SKU matching exact while product names stay forgiving.

See Handling Typos for all available settings with working examples.

Attaching Synonyms

A search profile can reference one or more synonym sets. Synonyms let different words for the same product — couch and sofa, or sneakers and trainers — find each other.

{
"synonym_sets": ["3fa85f64-5717-4562-b3fc-2c963f66afa6"]
}

See Using Synonyms for how to create synonym sets, attach them to profiles, and tune their behavior. To ignore low-value words like the and a, see Using Stopwords.

Adding Filters

Profile filters are automatically applied to all searches using that profile:

{
"filters": [
"status:=live && visibility:=public"
]
}

Multiple filters are combined with OR logic, then ANDed with user filters:

Final Filter = (Profile Filter 1 || Profile Filter 2) && User Filter

Adding Boost Rules

Boost rules promote or demote products based on conditions:

{
"boosts": [
{
"condition": "extensions.products(Details).is_featured:=true",
"weight": 100
},
{
"condition": "extensions.products(Details).on_sale:=true",
"weight": 50
},
{
"condition": "extensions.products(Details).stock_status:=out_of_stock",
"weight": -100
}
]
}
  • Positive weights: Push products to the top
  • Negative weights: Push products to the bottom (bury)

Set a Default Search Profile

Make a profile the default for all searches:

curl -X POST https://useast.api.elasticpath.com/v2/pcm/catalogs/search-profiles/{profile_id}/default \
-H "Authorization: Bearer $ACCESS_TOKEN"

How a search profile is chosen

When a shopper searches your store, Catalog Search resolves one search profile for the request. That profile controls field weights, default filters, sorting, typo tolerance, synonym sets, and related search behavior.

Resolution depends on which search endpoint you call.

For shopper endpoints — POST /pcm/catalog/search and POST /pcm/catalog/multi-search — profiles are chosen in this order:

PrioritySourceBehavior
1Catalog rule search_profile_slugIf the matched catalog rule carries a non-blank slug and that slug resolves to a profile in your tenant, that profile is used. Any search_profile query parameter on the request is ignored.
2search_profile query parameterUsed when the catalog rule has no slug, a blank/whitespace-only slug, or a slug that no longer resolves. A blank or whitespace-only value is treated as omitted. An invalid non-blank slug returns 400 with detail Search profile '{slug}' not found.
3Tenant default profileThe profile marked as default for your store or organization.
4Built-in defaultA system profile used when no named profile applies. The response header EP-Search-Profile is set to the reserved sentinel SYSTEMS_DEFAULT_PROFILE.

Catalog Search reads search_profile_slug from the same shopper-context resolution that selects catalog, release, and price books. You do not pass the rule slug on the search request itself.

note

Invalid or stale rule slugs do not fail the search. If a catalog rule references a profile that was deleted or is out of scope, Catalog Search logs a structured warning and falls through to the query parameter, tenant default, and built-in default — in that order. Catalog rule saves are never blocked because a profile is missing or invalid.

For admin endpoints — POST /pcm/catalogs/{catalog_id}/releases/{release_id}/search and …/multi-search — catalog rule profiles are not applied. You are already targeting an explicit catalog release.

Resolution order:

  1. search_profile query parameter (same blank/invalid rules as shopper search)
  2. Tenant default profile
  3. Built-in default (SYSTEMS_DEFAULT_PROFILE in EP-Search-Profile)

Use admin search to preview a specific release with a chosen profile. Use shopper search to validate segment behavior end to end.

EP-Search-Profile response header

Successful and some error responses include EP-Search-Profile so you can see which profile was applied or attempted:

ResponseHeader value
2xxSlug of the profile actually used. Built-in default → SYSTEMS_DEFAULT_PROFILE.
400 (profile resolution ran)Slug that was attempted — for example an invalid search_profile query value, or the resolved slug when a later validation step failed.
Other errorsHeader omitted when the request fails before profile resolution (for example a malformed search body).

SYSTEMS_DEFAULT_PROFILE is reserved. You cannot create a tenant profile with that slug.

Storefront guidance

  • Preferred pattern for segments: attach search_profile_slug on the catalog rule that already targets the segment (account, customer, channel, or context tag). The storefront sends shopper context headers as today; search picks up the profile automatically after login or context change.
  • Query parameter: use for A/B tests, explicit overrides when no rule slug applies, or tooling — not as the primary way to route B2B or reseller segments.
  • Observability: read EP-Search-Profile on search responses to confirm which profile ran in production or staging.

Segment audiences via catalog rules

Catalog rules already route which catalog and which prices apply to a shopper. You can also attach an optional search_profile_slug on the same rule so search behavior follows the same segmentation — field weights, filters, boosts, and related settings — without hard-coding profile slugs in your storefront.

What you can segment

Catalog rule attributeControls
catalog_idWhich catalog release the shopper searches
pricebook_idsWhich price books apply (price segmentation)
search_profile_slugWhich products appear in search and how they rank

All three are optional on a rule except catalog_id. A common B2B pattern is one rule per reseller account: same catalog, reseller price books, and a search profile whose default filter limits assortment (for example to an approved category or brand list).

Example: reseller assortment

  1. Create a search profile (for example slug reseller-clothing) with a default filter such as meta.search.nodes.name:=Clothing to limit searchable products to a hierarchy branch.
  2. Create or update a catalog rule for the reseller account and set attributes.search_profile_slug to reseller-clothing, alongside any pricebook_ids for that tier.
  3. When the reseller logs in, shopper search uses that profile automatically. Unauthenticated or other shoppers without a matching rule keep the default profile and see the full assortment.

Verify by comparing search result counts and checking EP-Search-Profile on the response.

Hierarchy navigation caveat

Filtering search to one hierarchy node does not hide other nodes in category navigation when products are cross-listed under multiple nodes. Those other nodes may still appear, but they only show products that also match the search profile filter. Total searchable products and facet counts reflect the filtered assortment.

Configure in Commerce Manager

When editing a catalog rule in Commerce Manager, use the search profile picker to attach a slug. The picker is scope-aware:

  • Organization rules — organization-owned profiles
  • Store rules — store-owned and organization-owned profiles

Profile validity is checked at search time, not when the rule is saved. That keeps catalog rule maintenance (including automatic release_id updates on publish) independent of search profile lifecycle.

For a full walkthrough that combines price segmentation with assortment filtering, see Price Segmentation.

Using the Search API

Perform a shopper search:

curl "https://useast.api.elasticpath.com/v2/pcm/catalog/search?q=laptop" \
-H "Authorization: Bearer $ACCESS_TOKEN"

Search with Filters

Filter results by category, price, or custom attributes:

curl "https://useast.api.elasticpath.com/v2/pcm/catalog/search?q=laptop&filter_by=meta.search.nodes.name:=Electronics%20%26%26%20price.float_price:[500..2000]" \
-H "Authorization: Bearer $ACCESS_TOKEN"

Search with Facets

Get aggregated counts for filtering UI:

curl "https://useast.api.elasticpath.com/v2/pcm/catalog/search?q=laptop&facet_by=meta.search.nodes.name,extensions.products(Details).brand" \
-H "Authorization: Bearer $ACCESS_TOKEN"

Execute multiple searches in a single request:

curl -X POST https://useast.api.elasticpath.com/v2/pcm/catalog/multi-search \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"searches": [
{
"q": "laptop",
"filter_by": "meta.search.nodes.name:=Electronics",
"per_page": 10
},
{
"q": "laptop",
"filter_by": "meta.search.nodes.name:=Accessories",
"per_page": 5
}
]
}'

Using a Specific Search Profile

Pass search_profile to select a profile when no valid catalog rule search_profile_slug applies (for example A/B tests or tooling). On shopper search, a valid rule slug takes precedence and this query parameter is ignored — see How a search profile is chosen.

curl "https://useast.api.elasticpath.com/v2/pcm/catalog/search?q=laptop&search_profile=b2b-wholesale" \
-H "Authorization: Bearer $ACCESS_TOKEN"

Check the EP-Search-Profile response header to confirm which profile was applied.

Shopper segments via catalog rules

When different accounts, customers, or channels need different search behavior (assortment filters, ranking, or boosts), attach a search profile on the catalog rule for that segment — the same rule that already selects catalog and price books.

Do this

  1. Create or configure the search profile (filters, field weights, boosts as needed).
  2. Set search_profile_slug on the matching catalog rule (Commerce Manager picker or Catalog Rules API).
  3. Keep the storefront on shopper search with normal context headers — do not hard-code per-segment search_profile query parameters as the primary routing mechanism.

Verify

  1. Search as two shoppers (segmented vs default).
  2. Confirm different result counts and/or ranking when assortment or weights differ.
  3. Confirm response header EP-Search-Profile matches the expected profile slug (or SYSTEMS_DEFAULT_PROFILE for the built-in default).

Learn more

Filter, Facet, and Sort Reference

For comprehensive documentation on filtering, faceting, and sorting search results, see:

Reindexing Catalog Releases

If you modify indexable fields or need to rebuild indexes, you can trigger reindexing:

Reindex All Releases

curl -X POST https://useast.api.elasticpath.com/v2/pcm/catalogs/reindex-releases \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": {
"force_reindex": true
}
}'

Check Index Status

View which indexes are out of sync:

curl "https://useast.api.elasticpath.com/v2/pcm/catalogs/search-indexes?out_of_sync=true" \
-H "Authorization: Bearer $ACCESS_TOKEN"

Best Practices

Search Profile Design

  1. Start with core fields: Always include name, description, and sku
  2. Add category fields: Include meta.search.nodes.name for category-based discovery
  3. Limit field count: Focus on 3-5 key fields to maintain relevance
  4. Test incrementally: Start with small weight differences and adjust based on results

Indexable Fields

  1. Index selectively: Only index fields that users will search or filter by
  2. Enable faceting wisely: Facetable fields increase index size
  3. Consider sorting needs: Enable sorting only for fields you'll sort by

Stemming and Tokenization

  1. Stem descriptive text: Enable stemming on fields like name and description where shoppers use varied word forms; it adds no value for identifiers like SKUs
  2. Split compound identifiers: Use token_separators on fields like sku so part numbers like AB-123 match searches for 123
  3. Preserve meaningful symbols only: Add characters to symbols_to_index only when they carry meaning (for example, + in Galaxy S24+); preserving too many symbols reduces match flexibility
  4. Prefer collection-level settings: Prefer setting token_separators and symbols_to_index at the collection level, and use per-field overrides only for exceptions

Performance

  1. Use specific filters: More specific filters improve query performance
  2. Limit facet values: Use max_facet_values to limit facet result counts
  3. Paginate results: Use page and per_page for large result sets

A/B Testing

Search profiles enable A/B testing without code changes:

  1. Create variant profiles with different field weights or boost rules
  2. Route traffic to different profiles (catalog rules per segment, or the search_profile query parameter when no rule slug applies)
  3. Measure conversion rates and revenue per search
  4. Iterate based on results
Ask External AI