Use these endpoints to configure product filters for storefront listings. Reads require read_products; creating, updating, reordering, or deleting a filter requires write_products.
Built-in filters cover price, availability, sale status, vendor, brand, categories, and tags. You can change their labels, enabled state, and order; their filter behavior is fixed. To add a filter, list eligible attribute or metafield sources first. Each source lists its compatible filter and display types and a recommended configuration. An app can use only metafield definitions it can read, and product and variant metafields have distinct filter keys. Configuration endpoints return base-language labels. Product filter translations read and write only label for an enabled non-default locale and additionally require read_translations or write_translations. Labels accept up to 100 characters; an empty string removes a translation. Storefront CTX uses translated headings and source choice labels; a heading without a translation shows its base-language label. Filter keys and choice values remain unchanged. Built-in yes/no, availability, and sale-state phrases use Storefront Messages, including per-language overrides.
For an update, send that definition’s current revision. For a reorder, fetch the unfiltered list, then send its top-level revision and every definition ID, including disabled ones. A stale revision returns 409 FILTER_REVISION_STALE. Reordering changes each definition’s revision, so fetch the list again before updating one. Product Filter configuration changes do not currently emit webhooks.
Endpoints#
Product filter contract
Get product filter limits and supported presentation choices.
max_per_store includes built-in and disabled filters. The query_max_* and facet_values_* limits govern storefront selections. Use the sources endpoint to see which presentation choices a specific attribute or metafield definition supports.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
401UNAUTHORIZEDAuthorization header missing, malformed, or token invalid/expired.
-
402SUBSCRIPTION_REQUIREDThe store does not have an active or trialing subscription.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the required scope for this call.
-
429RATE_LIMITEDThe token's request allowance is exhausted. Retry after the Retry-After header.
List product filter sources
List attributes and metafield definitions available as filter sources.
Each source includes compatible filter types, display choices, and a recommended configuration. Sources already used by a filter are omitted. A metafield definition must be readable by the token, visible on the storefront, and enabled for filtering. metafield_owner_type distinguishes product and variant definitions.
Query parameters
| Name | Type | Description |
|---|---|---|
source_type
required
|
string |
Source family to list: attribute or metafield. |
search
|
string |
Match a source by its name, namespace, key, or slug. |
limit
|
integer |
Number of sources, from 1 to source_list_max. Omission uses source_list_default; an oversized limit is rejected. |
offset
|
integer |
Number of matching sources to skip. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
401UNAUTHORIZEDAuthorization header missing, malformed, or token invalid/expired.
-
402SUBSCRIPTION_REQUIREDThe store does not have an active or trialing subscription.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the required scope for this call.
-
429RATE_LIMITEDThe token's request allowance is exhausted. Retry after the Retry-After header.
-
400FILTER_SOURCE_TYPE_INVALIDsource_type must be attribute or metafield.
-
400INVALID_INPUTLimit, offset, or search is outside the Product Filter contract.
List product filters
Search, filter, and sort the store's storefront product filters.
Search matches label or filter_key. store_total counts every definition, including disabled ones, even when search or filters narrow the response. The top-level revision covers the complete list; use it when reordering. Each definition has its own revision for updates. source_available reflects whether its source remains eligible and readable by the token. Sorting this response does not change storefront order.
Query parameters
| Name | Type | Description |
|---|---|---|
search
|
string |
Match label or filter_key. |
source_type
|
string |
Filter by system, attribute, or metafield. |
enabled
|
boolean |
Filter by enabled state. |
sort_by
|
string |
One of the contract's sort_columns. |
sort_direction
|
string |
asc or desc. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
401UNAUTHORIZEDAuthorization header missing, malformed, or token invalid/expired.
-
402SUBSCRIPTION_REQUIREDThe store does not have an active or trialing subscription.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the required scope for this call.
-
429RATE_LIMITEDThe token's request allowance is exhausted. Retry after the Retry-After header.
-
400FILTER_SOURCE_TYPE_INVALIDsource_type is not system, attribute, or metafield.
-
400INVALID_INPUTSearch, enabled value, sort column, or sort direction is invalid.
Create a product filter
Create a storefront filter from an attribute or metafield definition.
Choose a filter type and display type supported by the source. The service derives filter_key: for example, the Material attribute yields attribute:material, while a product metafield with namespace specs and key material yields metafield:product:specs.material. enabled defaults to true. allow_multiple defaults to true for multi_enum and color, and false for other filter types; range filters cannot allow multiple values.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
source_type
required
|
string |
Filter source: attribute or metafield. |
source_id
required
|
string |
Attribute id or Metafield Definition id returned by List product filter sources. |
label
required
|
string |
Shopper-facing label in the store's default language. |
filter_type
required
|
string |
Filter behavior supported by the selected source. |
display_type
required
|
string |
Storefront control supported by the selected source and filter type. |
enabled
|
boolean |
Whether the filter is enabled immediately. Defaults to true when omitted. |
allow_multiple
|
boolean |
Whether shoppers may select more than one choice. Use the source recommendation; ranges require false. |
sort_order
|
integer |
Initial storefront position from zero through sort_order_max. Omit to append after the current filters. |
Errors
-
401UNAUTHORIZEDAuthorization header missing, malformed, or token invalid/expired.
-
402SUBSCRIPTION_REQUIREDThe store does not have an active or trialing subscription.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the required scope for this call.
-
429RATE_LIMITEDThe token's request allowance is exhausted. Retry after the Retry-After header.
-
400STORE_API_INVALID_REQUEST_BODYThe body is malformed, contains trailing JSON, or contains an unknown field.
-
409FILTER_SYSTEM_MANAGEDThe request tries to create a built-in filter or change its fixed behavior.
-
400FILTER_LABEL_INVALIDLabel contains control characters.
-
400FILTER_LABEL_REQUIREDLabel is empty after trimming.
-
400FILTER_LABEL_TOO_LONGLabel exceeds label_max_length.
-
400FILTER_SORT_ORDER_INVALIDsort_order is outside zero through sort_order_max.
-
400FILTER_SOURCE_TYPE_INVALIDsource_type is not supported.
-
400FILTER_SOURCE_ID_REQUIREDA non-system filter requires a source id.
-
400FILTER_TYPE_INVALIDfilter_type is not supported.
-
400FILTER_DISPLAY_TYPE_INVALIDdisplay_type is not supported.
-
400FILTER_TYPE_DISPLAY_INVALIDThe display type is not compatible with the filter type.
-
400FILTER_SOURCE_DISPLAY_INVALIDThe filter type or display type is not supported by the selected source.
-
400FILTER_SOURCE_NOT_FOUNDThe selected source does not exist in this store or the token cannot read it.
-
400FILTER_METAFIELD_NOT_FILTERABLEThe Metafield Definition is not storefront-visible and filterable.
-
409FILTER_DEFINITION_DUPLICATEA filter already exists for this source.
-
409FILTER_LIMIT_REACHEDThe store has reached its Product Filter limit.
Reorder product filters
Replace the complete storefront filter order atomically.
Read the unfiltered list, then send its top-level revision and every definition id once, including disabled filters. A changed revision returns FILTER_REVISION_STALE; an incomplete or duplicate set returns FILTER_ORDER_INVALID. The operation is atomic. Reordering also changes each definition revision, so read the list again before a later update.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
revision
required
|
integer |
Complete-list revision from an unfiltered List product filters response. |
definition_ids
required
|
array<string> |
Every current definition id in the desired order. Replace these example IDs with the full unfiltered list from your store. |
Errors
-
401UNAUTHORIZEDAuthorization header missing, malformed, or token invalid/expired.
-
402SUBSCRIPTION_REQUIREDThe store does not have an active or trialing subscription.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the required scope for this call.
-
429RATE_LIMITEDThe token's request allowance is exhausted. Retry after the Retry-After header.
-
400STORE_API_INVALID_REQUEST_BODYThe body is malformed, contains trailing JSON, or contains an unknown field.
-
400FILTER_REVISION_REQUIREDThe update or reorder request has no usable revision.
-
409FILTER_REVISION_STALEThe definition or list changed since the supplied revision.
-
400FILTER_ORDER_INVALIDThe ID set is incomplete, contains duplicates, or includes an ID that does not exist in this store.
-
400INVALID_INPUTAn ID in the request is malformed.
Update a product filter
Update a filter's label, state, supported presentation, selection behavior, or position.
Send the current definition revision. This is a merge update: omitted fields stay unchanged. A stale revision is rejected without saving. You can disable a filter even if its source is no longer eligible or readable. Built-in filter type, display, and selection behavior are fixed; their labels, enabled state, and order can change. Changing a base-language label marks its translations outdated without deleting them.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
string |
Product filter definition id. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
revision
required
|
integer |
The definition revision from the latest list or mutation response. Re-read after reordering. |
label
|
string |
New base-language label; the source name does not change. |
filter_type
|
string |
Filter behavior supported by the definition's source. |
display_type
|
string |
Storefront control supported by the source and resulting filter type. |
enabled
|
boolean |
Whether the filter appears on storefront listings. |
allow_multiple
|
boolean |
Whether shoppers may select more than one value. |
sort_order
|
integer |
Storefront position, from zero through the contract's sort_order_max. Prefer the atomic reorder endpoint for list reordering. |
Errors
-
401UNAUTHORIZEDAuthorization header missing, malformed, or token invalid/expired.
-
402SUBSCRIPTION_REQUIREDThe store does not have an active or trialing subscription.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the required scope for this call.
-
429RATE_LIMITEDThe token's request allowance is exhausted. Retry after the Retry-After header.
-
400STORE_API_INVALID_REQUEST_BODYThe body is malformed, contains trailing JSON, or contains an unknown field.
-
400FILTER_REVISION_REQUIREDThe update or reorder request has no usable revision.
-
409FILTER_REVISION_STALEThe definition or list changed since the supplied revision.
-
409FILTER_SYSTEM_MANAGEDThe request tries to create a built-in filter or change its fixed behavior.
-
400FILTER_LABEL_INVALIDLabel contains control characters.
-
400FILTER_LABEL_REQUIREDLabel is empty after trimming.
-
400FILTER_LABEL_TOO_LONGLabel exceeds label_max_length.
-
400FILTER_SORT_ORDER_INVALIDsort_order is outside zero through sort_order_max.
-
400FILTER_TYPE_INVALIDfilter_type is not supported.
-
400FILTER_DISPLAY_TYPE_INVALIDdisplay_type is not supported.
-
400FILTER_TYPE_DISPLAY_INVALIDThe display type is not compatible with the filter type.
-
400FILTER_SOURCE_DISPLAY_INVALIDThe filter type or display type is not supported by the selected source.
-
400FILTER_SOURCE_NOT_FOUNDThe selected source does not exist in this store or the token cannot read it.
-
400FILTER_METAFIELD_NOT_FILTERABLEThe Metafield Definition is not storefront-visible and filterable.
-
404FILTER_DEFINITION_NOT_FOUNDThe filter does not exist in this store.
-
400INVALID_INPUTAn ID in the request is malformed.
Delete a product filter
Delete an attribute or metafield-backed filter.
Deleting a custom filter removes its label translations but leaves the source attribute or metafield definition and products intact. Built-in filters cannot be deleted; disable one with the update endpoint.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
string |
Product filter definition id. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
401UNAUTHORIZEDAuthorization header missing, malformed, or token invalid/expired.
-
402SUBSCRIPTION_REQUIREDThe store does not have an active or trialing subscription.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the required scope for this call.
-
429RATE_LIMITEDThe token's request allowance is exhausted. Retry after the Retry-After header.
-
404FILTER_DEFINITION_NOT_FOUNDThe filter does not exist in this store.
-
400FILTER_SYSTEM_UNDELETABLEBuilt-in filters cannot be deleted.
-
400INVALID_INPUTAn ID in the request is malformed.