Skip to main content
When making requests to the Search, Browse, Blocks, or Similar Products API, you can use the attributes parameter to specify which product fields to include in the response. This lets you optimize response payload size by requesting only the data you need.
Only attributes marked as visible on storefront can be requested in the attributes parameter or used in filters. Attributes marked as not visible, such as internal computed fields, will be rejected if included in API requests. See Visible in API responses for more details.

Core product attributes

The following attributes are available for all products and can be requested in the attributes[] parameter:

Special attributes

Example API request

Example response with selected attributes

By default, if no attributes parameter is provided, all available attributes are included in the response. Specifying attributes helps reduce response payload size and improve performance.

Selecting nested fields

In addition to top-level attributes, the attributes parameter accepts dot-notation paths that let you trim nested objects, slice arrays, and filter collections to just the entries you need. This keeps responses small for storefront tiles and product detail views without making a separate request per shape. Selectors are scoped to the response shape. They do not change which products are returned. Use filters to control the product set; use field selection to control the payload per product.
Field selection is a no-op for plain dotted paths (for example, variants.price) — backward compatible with existing integrations. Modifiers ([], [n], [start:end], [key=value]) opt you into the trimming behavior described below.

Selector forms

Multiple selectors that target the same collection are merged. For example, variants[].id plus variants[].price returns variants trimmed to {id, price}.

Slicing and indexing

  • [start:end] returns the half-open slice, using zero-based positions.
  • [n] returns the single entry at that position, still wrapped in the array.
  • [:n] and [n:] are shorthand for “first n” and “from n onward”.
  • Negative indexes are not supported.
Slices and indexes for variants use the storefront-visible position order. Hidden variants (for example, B2B-only variants when the request is not B2B) are excluded before the slice is applied.

Equality filters

[field=value] keeps only the entries whose field equals value. Values can be unquoted, single-quoted, or double-quoted. Quote them when the value contains spaces or punctuation. Numeric values compare numerically, so price=110 matches a stored 110.00. Pass a comma-separated list to match any of several values: variants[sku=ABC,DEF] keeps variants whose sku equals ABC or DEF. Commas inside a quoted value are treated as part of the value, so variants[sku="A,B"] matches the single SKU A,B. Empty members and trailing commas (for example, variants[sku=ABC,]) are rejected as parse errors. Repeating the same filter across multiple selectors unions the value sets in request order. For example, requesting both metafields[namespace=custom] and metafields[namespace=greyson] returns metafields from both namespaces. Different filter keys on the same collection, or mixing a filter with a positional modifier, still conflict.
  • For arrays like variants and images, filtering trims the array in place. The parent product is still returned even if no entries match.
  • For map-shaped fields like product metafields ({namespace: {key: value}}) and variant inventory_levels ({location_id: quantity}), filtering trims the map while preserving its shape.
  • Filtering on a field that doesn’t exist on the entries (or on a hidden internal column) is a no-op rather than an error, so the response shape stays consistent.
Equality is the only supported operator. Comparison operators (>, <, >=, <=, !=), boolean combinators (AND/OR, &&/||), and IN lists are rejected at validation time.

Trimming metafields

Product metafields is a {namespace: {key: value}} map, and it accepts two selector spellings:
  • Namespace set — metafields[namespace=custom,greyson] returns only the listed namespaces. Use this when you want one or more whole namespaces in a single selector.
  • Dotted path — metafields.custom returns the whole custom namespace, and metafields.custom.color returns just the color key inside it. Use dotted form when you want individual keys.
A whole-namespace selector subsumes a key selector for the same namespace, so requesting both metafields.custom and metafields.custom.color returns all of custom. Namespaces and keys must consist of letters, digits, _, -, or .. The bracket-then-dot spelling metafields[namespace=custom].color is rejected with a 400. Use the dotted form to reach into a namespace. Products missing a requested namespace or key drop the entry rather than emit null, and a product with no metafields at all returns metafields: {}.

Trimming variant metafields

Variant metafields is a list of {namespace, key, value, …} records rather than a map. You can trim it on both variants[] and first_or_matched_variant with these selectors: Keep these rules in mind:
  • Selectors on each root are independent. A variants[].metafields.* selector never trims first_or_matched_variant, and the reverse is also true. Request both when you need both trimmed.
  • The trimmed value stays a list with the original record shape. A variant with no matching records returns metafields: [].
  • Namespaces and keys must consist of letters, digits, _, -, or .. Hyphenated and digit-leading keys such as shopify.color-pattern are supported.
  • The variants[] form requires the [] modifier. A plain dotted path such as variants.metafields.custom.color is a no-op and returns the full list, matching the behavior of other plain dotted paths.
  • You can combine metafield selectors with other variant leaf selectors, such as variants[].id.
These selectors return a 400 with the field_projection error shape:
  • Chains deeper than <namespace>.<key>.
  • Any filter other than [namespace=…], such as [key=…]. Keys repeat across namespaces, so a key alone does not identify a record.
  • Positional modifiers such as [0] or [:2] on metafields, and modifiers on the namespace or key segment.
  • A dotted path after [namespace=…], such as variants[].metafields[namespace=custom].color. Use variants[].metafields.custom.color instead.
The same selectors work in browse, search, and blocks responses.

first_or_matched_variant and field selection

Trimming or filtering variants does not affect first_or_matched_variant. The matched variant is still derived from the full variant set, so a request like variants[sku=NOPE] combined with first_or_matched_variant returns an empty variants array alongside the regular matched variant.

Validation and errors

Each collection may carry only one array modifier across all selectors in a single request. Mixing two modifiers on the same collection (for example, variants[:2] and variants[sku=ABC] in the same request) returns a 400 with a structured body:
The same error shape is returned for malformed paths, unsupported operators, negative indexes, and selectors the projection layer cannot execute. Examples include a positional modifier on metafields and a dotted chain after metafields[namespace=…]. The response points you at the equivalent dotted form that the projection layer can honor. Rejecting these up front avoids silently returning the untrimmed payload. A bracket modifier on a sub-path segment of a map column (for example, selling_plans.groups[name=Subscribe].plans or metafields.custom[key=color]) is a special case. It does not return a 400. The predicate is dropped and the request is served as the equivalent dotted form (for example, selling_plans.groups.plans), which returns the full set of entries rather than a filtered subset. Use the dotted form directly when you want that behavior, and filter the extra entries client-side if you need to narrow the result.

Examples

Return product tiles with the first two images, only the matched variant’s price, and metafields from the custom namespace:
Return a single metafield key using the dotted form:
Return one metafield from each variant and a different metafield from the matched variant:
Each variant keeps only its custom.bucket_listing record, and the matched variant keeps only its other.bucket_listing record. Return inventory at a single location for every variant:
Field selection respects API visibility. Attributes hidden from storefront responses are rejected the same way they would be in a plain attributes request. Selectors can never re-expose a hidden field.

See also