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:
AttributeDescription
idUnique product identifier (always included)
titleProduct title
handleURL-friendly product handle
body_htmlProduct description HTML
vendorProduct vendor/brand
product_typeProduct type classification
tagsArray of product tags
imagesArray of product images
availableProduct availability status
created_atProduct creation timestamp
updated_atProduct last update timestamp
published_atProduct publication timestamp
price_rangeProduct price range object
optionsAvailable product options (filtered by availability)
original_optionsAll product options (unfiltered)
options_v2Enhanced options array with swatch and linked metafield data
metafieldsProduct metafields object
named_tagsParsed key:value tags object
calculatedComputed attributes object
categoryShopify Product Taxonomy category
featured_mediaFeatured product media
is_gift_cardGift card indicator
has_variants_that_require_componentsBundle product indicator
published_on_webWhether the product is published to the Online Store sales channel
published_on_appWhether the product is published to your storefront app sales channel
available_market_idsShopify Market IDs the product is available in (requires markets sync)
combined_listing_parent_product_idParent product ID for combined listings
combined_listing_roleRole in combined listing (PARENT/CHILD)

Special attributes

AttributeDescription
first_or_matched_variantReturns the first available variant or the variant matching applied filters. Must be explicitly requested.
variantsReturns an array of all product variants ordered by position. Each variant has the same fields as first_or_matched_variant. Must be explicitly requested.

Example API request

{
  "attributes": [
    "id",
    "title",
    "handle",
    "images",
    "price_range",
    "vendor",
    "first_or_matched_variant"
  ],
  "sort_order_code": "best-selling"
}

Example response with selected attributes

{
  "results": [
    {
      "id": 7003338965178,
      "title": "Premium Cotton T-Shirt",
      "handle": "premium-cotton-t-shirt",
      "images": [
        {
          "alt": "Premium Cotton T-Shirt - Front",
          "src": "https://cdn.shopify.com/s/files/product-front.jpg",
          "width": 800,
          "height": 800,
          "variant_ids": []
        }
      ],
      "price_range": {
        "from": 29.99,
        "to": 34.99,
        "compare_at_price": 39.99
      },
      "vendor": "Brand Name",
      "first_or_matched_variant": {
        "id": 41234567890123,
        "title": "Small / Blue",
        "price": "29.99",
        "sku": "TSHIRT-BLU-S",
        "compare_at_price": "39.99",
        "available": true,
        "position": 1,
        "selected_options": [
          {"name": "Size", "value": "Small"},
          {"name": "Color", "value": "Blue"}
        ]
      }
    }
  ],
  "totalResults": 150,
  "page": 1,
  "totalPages": 15
}
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

SelectorWhat it does
titleIncludes the top-level field.
seo.titleIncludes a single nested field on an object.
images[:2].srcSlices the first two images and keeps only the src field on each.
images[0]Returns just the first image.
variants[]Includes the full array (equivalent to variants for the variants list).
variants[].idTrims every variant object to the listed leaf fields. Combine multiple leaf selectors to keep more than one field.
variants[sku=ABC123]Keeps only variants whose sku equals ABC123.
metafields[namespace=custom]Keeps only product metafields under the custom namespace.
variants[].inventory[location_id=123]Keeps inventory entries for the given location on every variant.
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.
  • 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.

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:
{
  "error": "field_projection",
  "message": "Conflicting modifiers on `variants`. A collection may use only one array modifier (slice, index, `[]`, or filter) across all selectors.",
  "path": "variants[sku=ABC]"
}
The same error shape is returned for malformed paths, unsupported operators, and negative indexes.

Examples

Return product tiles with the first two images, only the matched variant’s price, and metafields from the custom namespace:
{
  "attributes": [
    "id",
    "title",
    "handle",
    "images[:2].src",
    "price_range",
    "variants[sku=TSHIRT-BLU-S].price",
    "metafields[namespace=custom]"
  ]
}
Return inventory at a single location for every variant:
{
  "attributes": [
    "id",
    "variants[].id",
    "variants[].inventory[location_id=123]"
  ]
}
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