> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uselayers.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Image Search: Execute Search

> Image Search API endpoint to run visual searches across your product catalog using uploaded image IDs or base64-encoded image payloads.

## Authorization

**X-Storefront-Access-Token** `string` *required*

Token-based authentication header in the form of `<YOUR_LAYERS_TOKEN>`.

## Headers

**Content-Type** `string` *required* (default: application/json)

**Accept** `string` *required* (default: application/json)

## Body

**image\_data** `string` *required*

Base64 Encoded PNG or JPEG Image Data. Required if `image_id` is not provided.

**image\_id** `string` *required*

UUID identifier returned from the [Image Upload API](https://docs.uselayers.com/api-reference/upload-image.md). Required if `image_data` is not provided. Use `image_id` for better performance and support for larger images.

**attributes** `string[]`

Product attributes to include in the response. By default, all attributes are included except `media`. Available attributes include: `id`, `title`, `handle`, `body_html`, `vendor`, `product_type`, `tags`, `images`, `media`, `available`, `created_at`, `updated_at`, `published_at`, `price_range`, `options`, `original_options`, `metafields`, `named_tags`, `calculated`, `category`, `featured_media`, `is_gift_card`, `has_variants_that_require_components`, `combined_listing_parent_product_id`, `combined_listing_role`, `first_or_matched_variant`, and `variants`. The `media` attribute is not returned by default; include `media` in `attributes` to get the product media list. See the [Product Schema](https://docs.uselayers.com/developers/product-schema/api-attributes.md) for detailed descriptions, including [nested field selection](https://docs.uselayers.com/developers/product-schema/api-attributes.md#selecting-nested-fields) for slicing arrays and filtering collections (for example, `images[:2].src`, `variants[sku=ABC].price`, `metafields[namespace=custom]`).

**filter\_group** `object`

Storefront endpoints accept nested `AND`/`OR` filter groups up to two levels deep. Each nested group must contain at least one expression; empty nested groups are rejected. Metafield filter properties may include hyphens in their namespace or key, for example `metafields.my-app.fit-type`.

Refer to the dedicated [Filter Expressions](https://docs.uselayers.com/engine/filtering.md) guide to learn more about filter expressions.

**pagination** `Pagination Object`

**pagination**

**page** `int`

The current page of results to fetch.

**limit** `int`

The max results to fetch per page.

**facets** `string[]`

Facets to be included. Accepts both exact facet codes (e.g., `"vendor"`, `"options.Size"`) and wildcard patterns (e.g., `"options.*"`, `"metafields.product.*"`).

Wildcard patterns expand to all matching attribute codes. For example, `"options.*"` expands to all option facets like `"options.Size"` and `"options.Color"`. Wildcards must match at least one attribute code to be valid.

**Examples:**

```json theme={null}
// Exact facet codes
"facets": ["vendor", "options.Size", "options.Color"]

// Wildcard pattern
"facets": ["options.*"]

// Mixed exact and wildcard
"facets": ["vendor", "options.*", "metafields.product.*"]
```

**retrieveFacetCount** `boolean`

If the count of each facet value should be calculated.

**includeFacetRanges** `boolean`

If you want a min/max range for numeric facets such as price.

**enrichFacetMetaobjects** `boolean`

When `true`, any facet backed by a `metaobject_reference` or `list.metaobject_reference` metafield is returned with a companion `facetDisplay` object. Each entry maps a facet value (the metaobject handle) to the referenced metaobject's `display_name` and `fields`. When the metaobject defines a color or image field, the entry also carries a resolved `swatch` object.

Use this when your storefront filter UI needs human-readable labels or nested field data (for example, a color name or swatch hex) instead of the raw handle. When `false` or omitted, only the handles are returned in `facets`.

Values are looked up from the local metaobject cache. Handles with no matching cached metaobject are omitted from `facetDisplay` and remain as plain values in `facets`. See [Metaobjects and reference metafields](https://docs.uselayers.com/developers/product-schema/metafields/metaobjects-and-references.md) for the normalized shape of each entry.

**sort\_order\_code** `string`

Code of the sort order to apply. Use `"relevance"` for the default relevance-based ranking, or any custom sort order code configured in your store. Retrieve available sort order codes from the [Sort Orders API](https://docs.uselayers.com/api-reference/sort-orders.md).

**defaultSelectedOptions** `array`

Specify which product variants should be selected by default in the `first_or_matched_variant` field.

**Properties**

**optionCode** `string` *required*

The product option code to match (e.g., `"birthstone"`, `"color"`). Option codes are automatically normalized (e.g., `"Birth Stone"` becomes `"birth_stone"`).

**value** `string` *required*

The option value to match (e.g., `"February"`, `"Blue"`).

**Behavior:**

* Uses **OR logic** - selects the first variant matching ANY of the specified option values
* Falls back to the first variant by position if no match is found
* **Automatically skipped** when any option or variant filters are applied (filters take precedence)
* Only affects the `first_or_matched_variant` field in the response

**discountEntitlements** `array`

Apply discounts to products, variants, or collections. When provided, price-based sorting and filtering will use discounted prices. See the [Discount Entitlements](https://docs.uselayers.com/shopify-integration/discount-entitlements.md) guide for detailed usage.

Fixed amounts use your shop's base currency. Layers skips them on market pricing rows in a different native currency, without converting the discount. Percentage discounts still apply to those localized prices. A variant that falls back to its base price can still receive a fixed-amount discount.

**Discount Entitlement Object**

**entitled** `object` *required*

Defines which products qualify for the discount.

**entitled**

**all** `boolean`

When `true`, applies discount to all products. When `false`, uses products, variants, or collections arrays.

**products** `string[]`

Array of product IDs or handles that qualify for the discount. Maximum 250 entries.

**variants** `string[] | number[]`

Array of variant IDs that qualify for the discount. Maximum 250 entries.

**collections** `string[]`

Array of collection handles that qualify for the discount. Maximum 250 entries.

**conditions** `object`

Optional filter group that qualifies products for the discount based on their attributes (for example, `tags` or `vendor`). Uses the same shape as the top-level `filter_group` parameter. Matches are additive with `products`, `variants`, and `collections` on the same entitlement.

**discount** `object` *required*

Defines the discount to apply.

**discount**

**type** `string` *required*

The discount type: `PERCENTAGE` or `FIXED_AMOUNT`.

**value** `number` *required*

The discount value. For `PERCENTAGE`, this must be a number between 0 and 100 (e.g., 10 for 10% off). For `FIXED_AMOUNT`, this is the amount in your shop's base currency, not the shopper's market currency.

**identity** `object`

User identity information for tracking and personalization. Automatically managed by the Storefront Pixel; required for headless integrations.

**Properties**

**deviceId** `string`

Persistent browser identifier that remains constant across sessions. Used to recognize returning visitors for long-term personalization. Automatically generated and managed by the Storefront Pixel.

**sessionId** `string`

Temporary session identifier. Layers-generated sessions expire after 30 minutes without activity. The Storefront Pixel refreshes the rolling window at page load and on every route change, including pages without tracked events. When a legacy Shopify or fallback cookie is available, Layers prefers it and does not control its lifetime. Without consent, the pixel uses a sessionStorage or in-memory fallback and does not write an analytics cookie.

**customerId** `string`

Shopify customer ID for authenticated users. Only present when the customer is signed in to their account.

**companyLocationId** `string`

Shopify B2B company location GID (e.g. `gid://shopify/CompanyLocation/123456789`) for the authenticated buyer. Layers resolves the catalog assigned to the company location and uses it to scope results: only products in the catalog are returned, prices come from the catalog's price list, and excluded collections return 404. Omit for retail (DTC) traffic.

When you pass `companyLocationId`, you must also pass the buyer's `customerId`. Layers verifies with Shopify that the customer belongs to the company that owns the location before resolving the catalog; unauthorized or unauthenticated requests return a `403`. See [B2B catalogs](https://docs.uselayers.com/shopify-integration/b2b-catalogs.md).

**context** `object`

Contextual information about the customer's session, behavior, and environment. Automatically collected by the Storefront Pixel; must be manually provided for headless integrations. See [Contextual Information](https://docs.uselayers.com/engine/contextual-information.md) for implementation guidance.

**Properties**

**geo** `object`

Geographic location information for regional personalization and merchandising. Layers determines it from the IP address for client-side requests. For server-side API calls (headless integrations), provide `geo` explicitly.

**Properties**

**country** `string`

Country code or name (e.g., "US", "Canada").

**province** `string`

State or province name (e.g., "California", "Ontario").

**city** `string`

City name (e.g., "Los Angeles", "Toronto").

**productsInCart** `array`

Products currently in the customer's cart. Used to surface complementary products and influence relevance scoring.

**Array Item Properties**

**title** `string`

Product title. Each entry needs at least a `productId`, `variantId`, or non-empty `title`. Layers drops entries with none of these.

**price** `number`

Unit price in the request currency's major units (e.g. `29.00` for \$29), not cents. Accepts a JSON number or a numeric string such as `"29.00"`.

**type** `string`

Product type or category.

**productId** `string`

Product identifier. Accepts a numeric ID (e.g., `"8234567890123"`) or a Shopify GID (e.g., `"gid://shopify/Product/8234567890123"`).

**variantId** `string`

Product variant identifier.

**options** `object`

Product variant options (e.g., `{"Size": "11", "Color": "Red"}`).

**quantity** `integer`

Number of units of this line in the cart. Layers rounds fractional values down to a whole number. Missing values, non-numeric values, and values below `1` count as `1`. Layers uses it to calculate the cart subtotal for [Free Shipping Picks](https://docs.uselayers.com/platform/blocks/strategies.md#free-shipping-picks).

**freeShippingThreshold** `number`

The cart subtotal at which the shopper qualifies for free shipping, in the request currency's major units (e.g. `75.00` for \$75), not cents. Layers ignores values that aren't a number greater than `0`. Required for [Free Shipping Picks](https://docs.uselayers.com/platform/blocks/strategies.md#free-shipping-picks) blocks.

> [!WARNING]
>
> Shopify's `/cart.js` and Liquid money values such as `cart.total_price` and `item.price` are in cents. Divide them by 100 before sending `productsInCart[].price` or `freeShippingThreshold`.

**productsViewed** `array`

Products the shopper has viewed during the current session. Layers uses these as short-lived personalization signals, with recent views weighted more heavily. Only the 20 most recent views are used. The Storefront Pixel populates this automatically; send it manually only for headless integrations. See [Recently viewed products](https://docs.uselayers.com/engine/contextual-information/data-structure.md#recently-viewed-products).

**Array Item Properties**

**id** `string`

Product identifier. Accepts a numeric ID or a Shopify GID. Also accepted as `productId`.

**at** `integer`

Timestamp of the view in Unix milliseconds. Views without `at` still count but skip recency weighting.

**title** `string`

Product title.

**type** `string`

Product type or category.

**variantId** `string`

Variant identifier, if the shopper viewed a specific variant.

**options** `object`

Product variant options (e.g., `{"Size": "11", "Color": "Red"}`).

**productsPurchased** `array`

Products the customer has previously purchased. Informs recommendations and prevents over-promotion of owned items.

**Array Item Properties**

**title** `string`

Product title. Each entry needs at least a `productId`, `variantId`, or non-empty `title`. Layers drops entries with none of these.

**price** `number`

Unit price in the request currency's major units (e.g. `29.00` for \$29), not cents, at time of purchase. Accepts a JSON number or a numeric string such as `"29.00"`.

**type** `string`

Product type or category.

**productId** `string`

Product identifier. Accepts a numeric ID (e.g., `"8234567890123"`) or a Shopify GID (e.g., `"gid://shopify/Product/8234567890123"`).

**variantId** `string`

Product variant identifier.

**options** `object`

Product variant options (e.g., `{"Size": "11", "Color": "Red"}`).

**priorSearches** `array`

Recent search queries and their outcomes. Helps understand customer intent and refine relevance models.

**Array Item Properties**

**searchQuery** `string` *required*

The search query text.

**hadClick** `boolean` (default: false)

Whether the customer clicked on any results from this search.

**hasResults** `boolean` (default: false)

Whether the search returned any results.

**fromPage** `string`

The page the search was started from (e.g., the referring page URL or page type). Layers accepts this field but doesn't currently use it for ranking or rules.

**marketing** `object`

UTM parameters and marketing campaign information for attribution tracking.

**Properties**

**source** `string`

Marketing source (e.g., "google", "facebook").

**medium** `string`

Marketing medium (e.g., "cpc", "email", "social").

**campaign** `string`

Campaign name.

**term** `string`

Search term or keyword.

**content** `string`

Ad or link variant, such as the value of `utm_content`.

**clickIds** `object`

Click identifiers from the landing URL, keyed by parameter name (e.g., `fbclid`, `gclid`). Layers derives the originating network from them as `marketing.clickSource` and discards the raw tokens. See [Context data structure](https://docs.uselayers.com/engine/contextual-information/data-structure.md#click-identifiers-and-derived-click-source).

**referrer** `string`

Host or URL of the site that linked the shopper to the storefront (e.g., "google.com"). Layers normalizes it to a lowercase host without `www.`.

**landingPath** `string`

Storefront path the shopper first landed on this visit (e.g., "/collections/sale"). Layers removes the query string and keeps up to 512 characters.

**channel** `string`

Arrival channel. Layers derives it from UTMs, click identifiers, and the referring site, and keeps a value you send only when it can't derive one. See [Arrival channel](https://docs.uselayers.com/engine/contextual-information/data-structure.md#arrival-channel).

**experiments** `object`

A/B test assignments for the shopper, keyed by experiment ID with the assigned group ID as the value (e.g., `{"exp_123": "group_b"}`). Used by the **Experiment Group** contextual condition. The Layers app embed fills this from Intelligems automatically; values your storefront sends for the same experiment take precedence. Entries whose value isn't a string are dropped.

**customer** `object`

Aggregated customer behavior and purchase patterns for personalization.

**Properties**

**signedIn** `boolean`

Whether the customer is currently authenticated.

**returning** `boolean`

Whether this is a returning customer.

**numberOfOrders** `integer`

Total number of orders placed.

**averageOrderValue** `number`

Average order value in store currency.

**daysBetweenOrders** `integer`

Average days between orders.

**daysSinceLastOrder** `integer`

Days since the most recent order.

**daysSinceOldestOrder** `integer`

Days since the first order.

**totalSpent** `number`

Total amount spent in store currency.

**tags** `array`

Shopify customer tags on the shopper's profile (e.g., `["vip", "wholesale"]`). Collected by the Storefront Pixel for signed-in customers; `null` for guests.

**segments** `array`

Shopify customer segment IDs the shopper belongs to. Server-resolved: Layers populates this from the signed-in `identity.customerId` on every request and ignores any value you send. `null` for guests and customers with no segment memberships. Available as `context.customer.segments` in [contextual conditions](https://docs.uselayers.com/platform/merchandising/contextual-conditions.md).

**market** `string`

Explicitly set the Shopify Market for this request. Must be provided inside `context`; it is not a top-level request body parameter. Used for market-specific product availability filtering and contextual pricing. Accepts a two-letter country code (e.g., `"US"`, `"CA"`), a numeric Shopify Market ID (e.g., `"12345"`), or a Shopify Market GID (e.g., `"gid://shopify/Market/12345"`).

When not provided, the market is automatically resolved from `context.geo.country` (or the shopper's detected country for client-side requests). If no matching market is found, the store's primary market is used as the fallback.

When you send a two-letter country code that belongs to the resolved market, Layers also prices for that country, ahead of the shopper's detected location. See [Market resolution](https://docs.uselayers.com/engine/contextual-information/data-structure.md#market).

**Behavior depends on the store's market application mode** (set under **Settings > Search & Discovery > Search Behavior**, in the **Markets** card):

* **Restrict to market catalog** — Products are filtered to only those available in the resolved market, and market-specific pricing is applied
* **Adjust pricing only** — The full catalog remains visible, but variant prices are swapped to market-specific values where available
* **Ignore markets** (default) — Market resolution is skipped entirely; base catalog and base pricing are used for all shoppers

**session** `object`

Session-level signals about the current visit.

**Properties**

**returning** `boolean`

Whether the current session belongs to a returning visitor. Layers derives this from the storefront's session cookie when not provided.

**locale** `string`

Storefront locale code (e.g., `"en"`, `"fr"`, `"pt-br"`). Case-insensitive; Layers normalizes to lowercase. When the locale is published in Shopify and served by the resolved market, Layers returns translated display text (titles, descriptions, option values, filter labels) while IDs, prices, and filter values stay in the source language. Regional locales fall back to their base language (`pt-br` uses `pt`). The store's primary locale returns source text. See [Translations](https://docs.uselayers.com/shopify-integration/translations.md).

**currency** `string`

ISO 4217 currency code (e.g., `"USD"`, `"EUR"`). Case-insensitive; Layers normalizes to uppercase. When Layers can resolve a currency from the shopper's market or pricing context, the server-resolved value takes precedence.

**b2bCompany** `string`

Shopify B2B company location identifier. When `identity.companyLocationId` is provided, Layers resolves the company location server-side and the server value takes precedence.

**deviceType** `string`

Shopper device category: `"mobile"`, `"desktop"`, `"tablet"`, or `"bot"`. Used by **Device Type** contextual conditions. When omitted, Layers detects it from the request's `User-Agent`; an explicit value takes precedence. For server-side integrations, send the shopper's device type rather than relying on your server's user agent. Tablets are separate from mobile phones. See [Device type](https://docs.uselayers.com/engine/contextual-information/data-structure.md#device-type).

**shoppingChannel** `string` (default: web)

The shopping channel the customer is browsing from. Used for channel-specific merchandising, sorting, and analytics segmentation. Automatically detected from request headers when not provided (e.g., mobile app requests via Tapcart, Fuego, or Mobiloud Canvas are detected as `"app"`).

**Accepted values:**

* `"web"` — Standard web browser (default)
* `"app"` — Mobile app (e.g., Tapcart, Fuego, Mobiloud Canvas)

**custom** `object`

Custom contextual data specific to your implementation. Structure is flexible and can contain any key-value pairs relevant to your use case.

**responseOptions** `object`

Per-request overrides for response behavior. Currently controls image preload hints emitted in the `Link` response header. You can disable preloads or narrow the srcset to the breakpoints your storefront uses. You cannot enable preloads when the store has them disabled.

**Properties**

**mediaPreloads** `object`

Controls the `Link: rel=\"preload\"` directives generated for product images in this response. See [Early hints](https://docs.uselayers.com/sdk/performance.md#early-hints-link-header-preloading) for background.

**Properties**

**enabled** `boolean` (default: true)

Set to `false` to skip the `Link` header for this request. Useful for server-rendered pages that do not benefit from preload hints, or when you want to reduce response header size. Cannot enable preloads if they are disabled at the store level.

**srcsetSizes** `int[]`

Custom responsive image widths (in pixels) to emit in `imagesrcset`. Each value must be an integer between `1` and `10000`. Overrides the store-level srcset configuration for this request only. When omitted, the store configuration or platform defaults are used.

**sizes** `string`

Media query string emitted as the `imagesizes` attribute in the preload `Link` header (for example `(max-width: 600px) 100vw, 50vw`). Tells the browser which srcset width to pick per viewport. Overrides the store-level sizes value for this request only. When omitted or empty, the store configuration is used. Each comma-separated entry may carry a media condition, including the last entry. See the [accepted format](https://docs.uselayers.com/sdk/performance.md#customization) for details. The API rejects invalid values with a validation error.

**Example:**

```json theme={null}
{
  "responseOptions": {
    "mediaPreloads": {
      "enabled": true,
      "srcsetSizes": [320, 640, 960],
      "sizes": "(max-width: 600px) 100vw, 50vw"
    }
  }
}
```

## Response

**results** `Array of Objects`

**Properties**

**id** `number`

The unique identifier of the product.

**title** `string`

The title of the product.

**body\_html** `string`

The HTML content describing the product.

**vendor** `string`

The vendor of the product.

**product\_type** `string`

The type of the product.

**created\_at** `number`

The timestamp when the product was created.

**handle** `string`

The handle of the product.

**updated\_at** `number`

The timestamp when the product was updated.

**published\_at** `number`

The timestamp when the product was published.

**tags** `Array of strings`

The tags associated with the product.

**combined\_listing\_parent\_product\_id** `number`

The parent product id if a child in a Combined Listing.

**combined\_listing\_role** `string`

The role of the product if part of a Combined Listing.

**images** `Array of Objects`

The images of the product.

**Properties**

**alt** `string`

The alt text of the image.

**src** `string`

The src of the image.

**width** `number`

The width of the image.

**height** `number`

The height of the image.

**variant\_ids** `Array`

The variant IDs associated with the image.

**media** `Array of Objects`

Ready images, Shopify-hosted videos, external videos, and 3D models in Shopify order. Not returned by default; include `media` in `attributes` to get it. The existing `images` field is unchanged. See [Product media](https://docs.uselayers.com/developers/product-schema.md#product-media) for the fields for each type and the image fallback before a product's next sync.

**metafields** `Object`

The metafields of the product.

**calculated** `Object`

The computed attributes of the product. Only includes attributes with non-null, non-empty values. Attributes that evaluate to null or an empty string are omitted.

**category** `Object`

The Shopify Product Taxonomy Category of the product.

**Properties**

**name** `string`

The name of the category leaf.

**full\_name** `string`

The full name of the category.

**id** `string`

The ID of the category.

**is\_leaf** `boolean`

Is the category a leaf category.

**is\_root** `boolean`

Is the category a root category.

**first\_or\_matched\_variant** `Object`

The first available variant (depending on OOS settings) or the variant matched with a filter or search query.

**Properties**

**id** `number`

The ID of the variant.

**title** `string`

The title of the variant.

**available** `boolean`

The availability of the variant.

**sku** `number`

The sku of the variant.

**price** `string`

The price of the variant.

**compare\_at\_price** `string`

The compare at price of the variant.

**metafields** `Object`

The metafields of the variant.

**selected\_options** `Array of Objects`

The selected options of the variant.

**Properties**

**name** `string`

The name of the option.

**value** `string`

The value of the option.

**option\_value** `object`

The linked metafield of the option.

**position** `number`

The position of the variant in the product's variant list.

**inventory\_quantity** `number`

Total inventory quantity across the locations in the store's [inventory location scope](https://docs.uselayers.com/shopify-integration/catalog-sync.md#inventory-location-scope), which is all locations by default. Only included when the store has the **Expose Variant Inventory** setting enabled.

**inventory\_policy** `string`

Inventory policy for the variant: `DENY` (stop selling when out of stock) or `CONTINUE` (allow overselling). Only included when the store has the **Expose Variant Inventory** setting enabled.

**inventory\_levels** `object`

Object mapping location IDs to available inventory quantities (e.g., `{"1001": 5, "1002": 10}`). Returns empty object `{}` when no inventory data exists. Only included when the store has the **Expose Variant Inventory** setting enabled.

**featured\_media** `Object`

The featured media of the product.

**Properties**

**mediaContentType** `string`

The type of media.

**alt** `string`

The alt text of the image.

**src** `string`

The src of the image.

**width** `number`

The width of the image.

**height** `number`

The height of the image.

**featured\_media** `Object`

The featured media of the product.

**Properties**

**mediaContentType** `string`

The type of media.

**alt** `string`

The alt text of the image.

**src** `string`

The src of the image.

**width** `number`

The width of the image.

**height** `number`

The height of the image.

**available** `boolean`

The availability of the product.

**price\_range** `Object`

The price range of the product.

**Properties**

**from** `number`

The starting price of the product.

**to** `number`

The ending price of the product.

**totalResults** `number`

The total number of results.

**page** `number`

The current page number.

**totalPages** `number`

The total number of pages.

**facetRanges** `object`

If `includeFacetRanges` is `true` then an object with keys of the facet attribute code and value is an object with min/max.

**facets** `object`

If `retrieveFacetCount` is `true` then an object with keys and values of the specified attributes. Empty values and literal `"null"` strings are automatically excluded from facet results.

**facetDisplay** `object`

Only returned when `enrichFacetMetaobjects` is `true` and at least one requested facet is backed by a `metaobject_reference` or `list.metaobject_reference` metafield. Keys are facet attribute codes and values map each facet value (the referenced metaobject's handle) to the metaobject's `display_name` and `fields`. Handles with no matching cached metaobject are omitted here and remain as plain values in `facets`. See [Metaobjects and reference metafields](https://docs.uselayers.com/developers/product-schema/metafields/metaobjects-and-references.md) for the normalized field shape.

**attributionToken** `string`

A unique request identifier (ULID) for this API call. Use this token to correlate requests with analytics events via the [Beacon API](https://docs.uselayers.com/tracking-api/send-events.md).

**\_meta** `object`

Metadata about the search request.

**Properties**

**mediaPreloads** `object`

Echoes the image preload configuration used to build the `Link` response header for this request. Only present when image preloads are emitted. See [Early hints](https://docs.uselayers.com/sdk/performance.md#early-hints-link-header-preloading).

**Properties**

**srcsetSizes** `int[]`

The responsive image widths (in pixels) used in the `imagesrcset` of the `Link` header. Reflects the request override when provided, otherwise the store-level configuration or platform defaults.

**search\_lane** `string`

Only present when Layers is temporarily serving keyword-only results platform-wide. The only value is `"prefix_only"`. Image search depends entirely on semantic matching, so in this mode the endpoint returns a well-formed empty response (`results: []`, `totalResults: 0`) instead of an error. Check this field to show a fallback experience rather than treating the empty result as "no matches."

**\_workflow** `array of objects`

An ordered trace of processing steps the engine performed. See the [Text Search](https://docs.uselayers.com/api-reference/search.md) documentation for the full list of possible step types.

### Response headers

| Header | Description |
| - | - |
| `x-request-id` | A unique identifier (ULID) for the request. This matches the `attributionToken` in the response body. |
| `x-layers-build` | The Layers build version that served the request. |
| `X-Layers-Results-Cache` | Indicates whether the response was served from the results cache. Returns `HIT` or `MISS`. |
| `Link` | Contains `rel="preload"` directives for product images (up to 6 items). See [Early hints](https://docs.uselayers.com/sdk/performance.md#early-hints-link-header-preloading) for details. Only included when early hints are enabled (enabled by default). |

## Error responses

### 422 Unprocessable Entity

A 422 error is returned when the `image_id` refers to an image that failed to process. This can occur when:

* The uploaded image is corrupted or invalid
* The image format is unsupported
* The image file cannot be read or decoded

**Error response structure:**

```json theme={null}
{
    "error": "Image processing failed",
    "message": "Image is corrupted or invalid"
}
```

The `message` field provides specific details about why the image processing failed.

## Usage examples

### Using image ID (recommended)

First, upload an image to get an `image_id`:

```bash theme={null}
curl -X POST "https://app.uselayers.com/api/storefront/v1/images/upload" \
  -H "X-Storefront-Access-Token: YOUR_TOKEN" \
  -F "image=@/path/to/your/image.jpg"
```

Then use the returned `image_id` for searching:

```json theme={null}
{
    "image_id": "550e8400-e29b-41d4-a716-446655440000",
    "pagination": {
        "page": 1,
        "limit": 20
    },
    "context": {
        "geo": {
            "country": "US"
        },
        "shoppingChannel": "web"
    },
    "identity": {
        "sessionId": "abc123",
        "deviceId": "device-uuid"
    }
}
```

### Using base64 image data (legacy)

```json theme={null}
{
    "image_data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD...",
    "pagination": {
        "page": 1,
        "limit": 20
    },
    "context": {
        "shoppingChannel": "web"
    }
}
```

```json Response theme={null}
{
    "results": [
        {
            "id": 7003338965178,
            "title": "SUPREME SEALLINE SEE POUCH SMALL",
            "body_html": "The Supreme Sealline See Pouch Small is a versatile and waterproof storage solution that seamlessly marries utility and style. With its clear window for easy visibility and the iconic Supreme branding, it's a sought-after accessory for those who appreciate keeping their essentials dry while making a fashion statement, whether at the beach or in the city..",
            "vendor": "SUPREME",
            "product_type": "Accessories",
            "created_at": "2022-02-05T01:22:05.000000Z",
            "handle": "supreme-pouch-44370ss18a32-sm",
            "updated_at": "2023-10-25T20:47:04.000000Z",
            "published_at": "2022-02-05T01:22:05.000000Z",
            "tags": [
                "consignment",
            ],
            "images": [
                {
                    "alt": "SUPREME POUCH",
                    "src": "https://cdn.shopify.com/s/files/1/0588/3677/9194/products/ss18_supreme_tnf_pouch_blk_2-l_5fb1316e-22f7-4702-9953-57f3fbdda5be.jpg?v=1644047927",
                    "width": 800,
                    "height": 534,
                    "variant_ids": []
                }
            ],
            "metafields": {
                "product": {
                    "alias": "SEALLINE SEE POUCH SMALL",
                    "colorway": "BLACK",
                    "styleCode": "SS18A30 BLACK",
                    "yearOfRelease": 2018,
                    "searchColor": [
                        "black"
                    ]
                }
            },
            "available": true,
            "price_range": {
                "from": 30,
                "to": 30
            }
        }
    ],
    "totalResults": 1000,
    "page": 1,
    "totalPages": 20,
    "facets": {
        "vendor": {
            "ADIDAS": 30,
            "JORDAN": 336,
            "NEW BALANCE": 15,
            "NIKE": 384,
            "REEBOK": 4,
            "SUPREME": 624,
            "VANS": 32
        }
    },
    "attributionToken": "2y10smI2dB7XZXXFJsLUELltgueq8NRdcRD3U8djkLqxQmaVMvg1lSCf2"
}
```
