Blocks API: Get Block Products
curl --request POST \
--url https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products \
--header 'Accept: <accept>' \
--header 'Content-Type: <content-type>' \
--header 'X-Storefront-Access-Token: <x-storefront-access-token>' \
--data '
{
"anchor_id": "<string>",
"anchor_handle": "<string>",
"attributes": [
"<string>"
],
"excludeProductIds": [
"<string>"
],
"filter_group": {},
"pagination": {
"page": 123,
"limit": 123
},
"facets": [
"<string>"
],
"retrieveFacetCount": true,
"includeFacetRanges": true,
"identity": {
"deviceId": "<string>",
"sessionId": "<string>",
"customerId": "<string>",
"companyLocationId": "<string>"
},
"context": {
"geo": {
"country": "<string>",
"province": "<string>",
"city": "<string>"
},
"productsInCart": [
{
"title": "<string>",
"price": 123,
"type": "<string>",
"productId": "<string>",
"variantId": "<string>",
"options": {}
}
],
"productsPurchased": [
{
"title": "<string>",
"price": 123,
"type": "<string>",
"productId": "<string>",
"variantId": "<string>",
"options": {}
}
],
"priorSearches": [
{
"searchQuery": "<string>",
"hadClick": true,
"hasResults": true,
"fromPage": "<string>"
}
],
"marketing": {
"source": "<string>",
"medium": "<string>",
"campaign": "<string>",
"term": "<string>"
},
"customer": {
"signedIn": true,
"returning": true,
"numberOfOrders": 123,
"averageOrderValue": 123,
"daysBetweenOrders": 123,
"daysSinceLastOrder": 123,
"daysSinceOldestOrder": 123,
"totalSpent": 123
},
"market": "<string>",
"shoppingChannel": "<string>",
"custom": {}
},
"responseOptions": {
"mediaPreloads": {
"enabled": true,
"srcsetSizes": [
123
]
}
}
}
'import requests
url = "https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products"
payload = {
"anchor_id": "<string>",
"anchor_handle": "<string>",
"attributes": ["<string>"],
"excludeProductIds": ["<string>"],
"filter_group": {},
"pagination": {
"page": 123,
"limit": 123
},
"facets": ["<string>"],
"retrieveFacetCount": True,
"includeFacetRanges": True,
"identity": {
"deviceId": "<string>",
"sessionId": "<string>",
"customerId": "<string>",
"companyLocationId": "<string>"
},
"context": {
"geo": {
"country": "<string>",
"province": "<string>",
"city": "<string>"
},
"productsInCart": [
{
"title": "<string>",
"price": 123,
"type": "<string>",
"productId": "<string>",
"variantId": "<string>",
"options": {}
}
],
"productsPurchased": [
{
"title": "<string>",
"price": 123,
"type": "<string>",
"productId": "<string>",
"variantId": "<string>",
"options": {}
}
],
"priorSearches": [
{
"searchQuery": "<string>",
"hadClick": True,
"hasResults": True,
"fromPage": "<string>"
}
],
"marketing": {
"source": "<string>",
"medium": "<string>",
"campaign": "<string>",
"term": "<string>"
},
"customer": {
"signedIn": True,
"returning": True,
"numberOfOrders": 123,
"averageOrderValue": 123,
"daysBetweenOrders": 123,
"daysSinceLastOrder": 123,
"daysSinceOldestOrder": 123,
"totalSpent": 123
},
"market": "<string>",
"shoppingChannel": "<string>",
"custom": {}
},
"responseOptions": { "mediaPreloads": {
"enabled": True,
"srcsetSizes": [123]
} }
}
headers = {
"X-Storefront-Access-Token": "<x-storefront-access-token>",
"Content-Type": "<content-type>",
"Accept": "<accept>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Storefront-Access-Token': '<x-storefront-access-token>',
'Content-Type': '<content-type>',
Accept: '<accept>'
},
body: JSON.stringify({
anchor_id: '<string>',
anchor_handle: '<string>',
attributes: ['<string>'],
excludeProductIds: ['<string>'],
filter_group: {},
pagination: {page: 123, limit: 123},
facets: ['<string>'],
retrieveFacetCount: true,
includeFacetRanges: true,
identity: {
deviceId: '<string>',
sessionId: '<string>',
customerId: '<string>',
companyLocationId: '<string>'
},
context: {
geo: {country: '<string>', province: '<string>', city: '<string>'},
productsInCart: [
{
title: '<string>',
price: 123,
type: '<string>',
productId: '<string>',
variantId: '<string>',
options: {}
}
],
productsPurchased: [
{
title: '<string>',
price: 123,
type: '<string>',
productId: '<string>',
variantId: '<string>',
options: {}
}
],
priorSearches: [
{
searchQuery: '<string>',
hadClick: true,
hasResults: true,
fromPage: '<string>'
}
],
marketing: {source: '<string>', medium: '<string>', campaign: '<string>', term: '<string>'},
customer: {
signedIn: true,
returning: true,
numberOfOrders: 123,
averageOrderValue: 123,
daysBetweenOrders: 123,
daysSinceLastOrder: 123,
daysSinceOldestOrder: 123,
totalSpent: 123
},
market: '<string>',
shoppingChannel: '<string>',
custom: {}
},
responseOptions: {mediaPreloads: {enabled: true, srcsetSizes: [123]}}
})
};
fetch('https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'anchor_id' => '<string>',
'anchor_handle' => '<string>',
'attributes' => [
'<string>'
],
'excludeProductIds' => [
'<string>'
],
'filter_group' => [
],
'pagination' => [
'page' => 123,
'limit' => 123
],
'facets' => [
'<string>'
],
'retrieveFacetCount' => true,
'includeFacetRanges' => true,
'identity' => [
'deviceId' => '<string>',
'sessionId' => '<string>',
'customerId' => '<string>',
'companyLocationId' => '<string>'
],
'context' => [
'geo' => [
'country' => '<string>',
'province' => '<string>',
'city' => '<string>'
],
'productsInCart' => [
[
'title' => '<string>',
'price' => 123,
'type' => '<string>',
'productId' => '<string>',
'variantId' => '<string>',
'options' => [
]
]
],
'productsPurchased' => [
[
'title' => '<string>',
'price' => 123,
'type' => '<string>',
'productId' => '<string>',
'variantId' => '<string>',
'options' => [
]
]
],
'priorSearches' => [
[
'searchQuery' => '<string>',
'hadClick' => true,
'hasResults' => true,
'fromPage' => '<string>'
]
],
'marketing' => [
'source' => '<string>',
'medium' => '<string>',
'campaign' => '<string>',
'term' => '<string>'
],
'customer' => [
'signedIn' => true,
'returning' => true,
'numberOfOrders' => 123,
'averageOrderValue' => 123,
'daysBetweenOrders' => 123,
'daysSinceLastOrder' => 123,
'daysSinceOldestOrder' => 123,
'totalSpent' => 123
],
'market' => '<string>',
'shoppingChannel' => '<string>',
'custom' => [
]
],
'responseOptions' => [
'mediaPreloads' => [
'enabled' => true,
'srcsetSizes' => [
123
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Accept: <accept>",
"Content-Type: <content-type>",
"X-Storefront-Access-Token: <x-storefront-access-token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products"
payload := strings.NewReader("{\n \"anchor_id\": \"<string>\",\n \"anchor_handle\": \"<string>\",\n \"attributes\": [\n \"<string>\"\n ],\n \"excludeProductIds\": [\n \"<string>\"\n ],\n \"filter_group\": {},\n \"pagination\": {\n \"page\": 123,\n \"limit\": 123\n },\n \"facets\": [\n \"<string>\"\n ],\n \"retrieveFacetCount\": true,\n \"includeFacetRanges\": true,\n \"identity\": {\n \"deviceId\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"customerId\": \"<string>\",\n \"companyLocationId\": \"<string>\"\n },\n \"context\": {\n \"geo\": {\n \"country\": \"<string>\",\n \"province\": \"<string>\",\n \"city\": \"<string>\"\n },\n \"productsInCart\": [\n {\n \"title\": \"<string>\",\n \"price\": 123,\n \"type\": \"<string>\",\n \"productId\": \"<string>\",\n \"variantId\": \"<string>\",\n \"options\": {}\n }\n ],\n \"productsPurchased\": [\n {\n \"title\": \"<string>\",\n \"price\": 123,\n \"type\": \"<string>\",\n \"productId\": \"<string>\",\n \"variantId\": \"<string>\",\n \"options\": {}\n }\n ],\n \"priorSearches\": [\n {\n \"searchQuery\": \"<string>\",\n \"hadClick\": true,\n \"hasResults\": true,\n \"fromPage\": \"<string>\"\n }\n ],\n \"marketing\": {\n \"source\": \"<string>\",\n \"medium\": \"<string>\",\n \"campaign\": \"<string>\",\n \"term\": \"<string>\"\n },\n \"customer\": {\n \"signedIn\": true,\n \"returning\": true,\n \"numberOfOrders\": 123,\n \"averageOrderValue\": 123,\n \"daysBetweenOrders\": 123,\n \"daysSinceLastOrder\": 123,\n \"daysSinceOldestOrder\": 123,\n \"totalSpent\": 123\n },\n \"market\": \"<string>\",\n \"shoppingChannel\": \"<string>\",\n \"custom\": {}\n },\n \"responseOptions\": {\n \"mediaPreloads\": {\n \"enabled\": true,\n \"srcsetSizes\": [\n 123\n ]\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Storefront-Access-Token", "<x-storefront-access-token>")
req.Header.Add("Content-Type", "<content-type>")
req.Header.Add("Accept", "<accept>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products")
.header("X-Storefront-Access-Token", "<x-storefront-access-token>")
.header("Content-Type", "<content-type>")
.header("Accept", "<accept>")
.body("{\n \"anchor_id\": \"<string>\",\n \"anchor_handle\": \"<string>\",\n \"attributes\": [\n \"<string>\"\n ],\n \"excludeProductIds\": [\n \"<string>\"\n ],\n \"filter_group\": {},\n \"pagination\": {\n \"page\": 123,\n \"limit\": 123\n },\n \"facets\": [\n \"<string>\"\n ],\n \"retrieveFacetCount\": true,\n \"includeFacetRanges\": true,\n \"identity\": {\n \"deviceId\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"customerId\": \"<string>\",\n \"companyLocationId\": \"<string>\"\n },\n \"context\": {\n \"geo\": {\n \"country\": \"<string>\",\n \"province\": \"<string>\",\n \"city\": \"<string>\"\n },\n \"productsInCart\": [\n {\n \"title\": \"<string>\",\n \"price\": 123,\n \"type\": \"<string>\",\n \"productId\": \"<string>\",\n \"variantId\": \"<string>\",\n \"options\": {}\n }\n ],\n \"productsPurchased\": [\n {\n \"title\": \"<string>\",\n \"price\": 123,\n \"type\": \"<string>\",\n \"productId\": \"<string>\",\n \"variantId\": \"<string>\",\n \"options\": {}\n }\n ],\n \"priorSearches\": [\n {\n \"searchQuery\": \"<string>\",\n \"hadClick\": true,\n \"hasResults\": true,\n \"fromPage\": \"<string>\"\n }\n ],\n \"marketing\": {\n \"source\": \"<string>\",\n \"medium\": \"<string>\",\n \"campaign\": \"<string>\",\n \"term\": \"<string>\"\n },\n \"customer\": {\n \"signedIn\": true,\n \"returning\": true,\n \"numberOfOrders\": 123,\n \"averageOrderValue\": 123,\n \"daysBetweenOrders\": 123,\n \"daysSinceLastOrder\": 123,\n \"daysSinceOldestOrder\": 123,\n \"totalSpent\": 123\n },\n \"market\": \"<string>\",\n \"shoppingChannel\": \"<string>\",\n \"custom\": {}\n },\n \"responseOptions\": {\n \"mediaPreloads\": {\n \"enabled\": true,\n \"srcsetSizes\": [\n 123\n ]\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Storefront-Access-Token"] = '<x-storefront-access-token>'
request["Content-Type"] = '<content-type>'
request["Accept"] = '<accept>'
request.body = "{\n \"anchor_id\": \"<string>\",\n \"anchor_handle\": \"<string>\",\n \"attributes\": [\n \"<string>\"\n ],\n \"excludeProductIds\": [\n \"<string>\"\n ],\n \"filter_group\": {},\n \"pagination\": {\n \"page\": 123,\n \"limit\": 123\n },\n \"facets\": [\n \"<string>\"\n ],\n \"retrieveFacetCount\": true,\n \"includeFacetRanges\": true,\n \"identity\": {\n \"deviceId\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"customerId\": \"<string>\",\n \"companyLocationId\": \"<string>\"\n },\n \"context\": {\n \"geo\": {\n \"country\": \"<string>\",\n \"province\": \"<string>\",\n \"city\": \"<string>\"\n },\n \"productsInCart\": [\n {\n \"title\": \"<string>\",\n \"price\": 123,\n \"type\": \"<string>\",\n \"productId\": \"<string>\",\n \"variantId\": \"<string>\",\n \"options\": {}\n }\n ],\n \"productsPurchased\": [\n {\n \"title\": \"<string>\",\n \"price\": 123,\n \"type\": \"<string>\",\n \"productId\": \"<string>\",\n \"variantId\": \"<string>\",\n \"options\": {}\n }\n ],\n \"priorSearches\": [\n {\n \"searchQuery\": \"<string>\",\n \"hadClick\": true,\n \"hasResults\": true,\n \"fromPage\": \"<string>\"\n }\n ],\n \"marketing\": {\n \"source\": \"<string>\",\n \"medium\": \"<string>\",\n \"campaign\": \"<string>\",\n \"term\": \"<string>\"\n },\n \"customer\": {\n \"signedIn\": true,\n \"returning\": true,\n \"numberOfOrders\": 123,\n \"averageOrderValue\": 123,\n \"daysBetweenOrders\": 123,\n \"daysSinceLastOrder\": 123,\n \"daysSinceOldestOrder\": 123,\n \"totalSpent\": 123\n },\n \"market\": \"<string>\",\n \"shoppingChannel\": \"<string>\",\n \"custom\": {}\n },\n \"responseOptions\": {\n \"mediaPreloads\": {\n \"enabled\": true,\n \"srcsetSizes\": [\n 123\n ]\n }\n }\n}"
response = http.request(request)
puts response.read_bodyPOST /storefront/v1/blocks/01HQXYZ123ABC456DEF789/products
{
"anchor_id": "8234567890123",
"pagination": {
"page": 1,
"limit": 12
},
"context": {
"geo": {
"country": "US",
"province": "California"
},
"productsInCart": [
{
"title": "Nike Air Force 1",
"productId": "8234567890123",
"variantId": "45678901234567"
}
],
"shoppingChannel": "web"
},
"identity": {
"sessionId": "abc123",
"deviceId": "device-uuid"
}
}
POST /storefront/v1/blocks/01HQXYZ789GHI012JKL345/products
{
"anchor_id": "summer-collection",
"pagination": {
"page": 1,
"limit": 12
},
"context": {
"geo": {
"country": "US"
},
"shoppingChannel": "web"
},
"identity": {
"sessionId": "abc123"
}
}
POST /storefront/v1/blocks/01HQXYZ789GHI012JKL345/products
{
"anchor_id": "summer-collection",
"pagination": {
"page": 1,
"limit": 20
},
"filter_group": {
"conditional": "AND",
"expressions": [
{
"property": "available",
"operator": "=",
"values": [true]
}
]
},
"context": {
"geo": {
"country": "US"
},
"shoppingChannel": "web"
}
}
POST /storefront/v1/blocks/01HQXYZ456MNO789PQR012/products
{
"pagination": {
"page": 1,
"limit": 8
},
"context": {
"geo": {
"country": "US"
},
"productsInCart": [
{
"title": "Nike Air Force 1",
"productId": "8234567890123",
"variantId": "45678901234567"
},
{
"title": "Classic Tee",
"productId": "8234567890456",
"variantId": "45678901234890"
}
],
"shoppingChannel": "app"
},
"identity": {
"sessionId": "abc123"
}
}
POST /storefront/v1/blocks/01HQXYZ456MNO789PQR012/products
{
"anchor_id": "8234567890123",
"pagination": {
"page": 1,
"limit": 8
},
"excludeProductIds": [
"8234567890456",
"gid://shopify/Product/8234567890789"
],
"context": {
"geo": {
"country": "US"
},
"shoppingChannel": "web"
},
"identity": {
"sessionId": "abc123"
}
}
{
"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": 1644047925,
"handle": "supreme-pouch-44370ss18a32-sm",
"updated_at": 1698280024,
"published_at": 1644047925,
"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": 8,
"page": 1,
"totalPages": 1,
"resultsPerPage": 12,
"block": {
"id": "01HQXYZ123ABC456DEF789",
"title": "Frequently Bought Together",
"anchor_type": "product",
"strategy_type": "interaction",
"strategy_key": "frequently_bought_together"
},
"attributionToken": "01JRVX9N4O5P6Q7R8S9T0U1V2W",
"_meta": {
"affinities": [
{
"property": "vendor",
"operator": "=",
"value": "NIKE",
"weight": 0.85
}
]
},
"_workflow": [
{
"type": "affinity-boosts",
"payload": [
{
"property": "vendor",
"operator": "eq",
"value": "NIKE",
"weight": 0.85
}
]
}
]
}
Blocks
Blocks API: Get Block Products
Blocks API endpoint that returns product recommendations for a specific block using its configured strategy, fallback chain, and merchandising rules.
POST
/
blocks
/
{blockId}
/
products
Blocks API: Get Block Products
curl --request POST \
--url https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products \
--header 'Accept: <accept>' \
--header 'Content-Type: <content-type>' \
--header 'X-Storefront-Access-Token: <x-storefront-access-token>' \
--data '
{
"anchor_id": "<string>",
"anchor_handle": "<string>",
"attributes": [
"<string>"
],
"excludeProductIds": [
"<string>"
],
"filter_group": {},
"pagination": {
"page": 123,
"limit": 123
},
"facets": [
"<string>"
],
"retrieveFacetCount": true,
"includeFacetRanges": true,
"identity": {
"deviceId": "<string>",
"sessionId": "<string>",
"customerId": "<string>",
"companyLocationId": "<string>"
},
"context": {
"geo": {
"country": "<string>",
"province": "<string>",
"city": "<string>"
},
"productsInCart": [
{
"title": "<string>",
"price": 123,
"type": "<string>",
"productId": "<string>",
"variantId": "<string>",
"options": {}
}
],
"productsPurchased": [
{
"title": "<string>",
"price": 123,
"type": "<string>",
"productId": "<string>",
"variantId": "<string>",
"options": {}
}
],
"priorSearches": [
{
"searchQuery": "<string>",
"hadClick": true,
"hasResults": true,
"fromPage": "<string>"
}
],
"marketing": {
"source": "<string>",
"medium": "<string>",
"campaign": "<string>",
"term": "<string>"
},
"customer": {
"signedIn": true,
"returning": true,
"numberOfOrders": 123,
"averageOrderValue": 123,
"daysBetweenOrders": 123,
"daysSinceLastOrder": 123,
"daysSinceOldestOrder": 123,
"totalSpent": 123
},
"market": "<string>",
"shoppingChannel": "<string>",
"custom": {}
},
"responseOptions": {
"mediaPreloads": {
"enabled": true,
"srcsetSizes": [
123
]
}
}
}
'import requests
url = "https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products"
payload = {
"anchor_id": "<string>",
"anchor_handle": "<string>",
"attributes": ["<string>"],
"excludeProductIds": ["<string>"],
"filter_group": {},
"pagination": {
"page": 123,
"limit": 123
},
"facets": ["<string>"],
"retrieveFacetCount": True,
"includeFacetRanges": True,
"identity": {
"deviceId": "<string>",
"sessionId": "<string>",
"customerId": "<string>",
"companyLocationId": "<string>"
},
"context": {
"geo": {
"country": "<string>",
"province": "<string>",
"city": "<string>"
},
"productsInCart": [
{
"title": "<string>",
"price": 123,
"type": "<string>",
"productId": "<string>",
"variantId": "<string>",
"options": {}
}
],
"productsPurchased": [
{
"title": "<string>",
"price": 123,
"type": "<string>",
"productId": "<string>",
"variantId": "<string>",
"options": {}
}
],
"priorSearches": [
{
"searchQuery": "<string>",
"hadClick": True,
"hasResults": True,
"fromPage": "<string>"
}
],
"marketing": {
"source": "<string>",
"medium": "<string>",
"campaign": "<string>",
"term": "<string>"
},
"customer": {
"signedIn": True,
"returning": True,
"numberOfOrders": 123,
"averageOrderValue": 123,
"daysBetweenOrders": 123,
"daysSinceLastOrder": 123,
"daysSinceOldestOrder": 123,
"totalSpent": 123
},
"market": "<string>",
"shoppingChannel": "<string>",
"custom": {}
},
"responseOptions": { "mediaPreloads": {
"enabled": True,
"srcsetSizes": [123]
} }
}
headers = {
"X-Storefront-Access-Token": "<x-storefront-access-token>",
"Content-Type": "<content-type>",
"Accept": "<accept>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Storefront-Access-Token': '<x-storefront-access-token>',
'Content-Type': '<content-type>',
Accept: '<accept>'
},
body: JSON.stringify({
anchor_id: '<string>',
anchor_handle: '<string>',
attributes: ['<string>'],
excludeProductIds: ['<string>'],
filter_group: {},
pagination: {page: 123, limit: 123},
facets: ['<string>'],
retrieveFacetCount: true,
includeFacetRanges: true,
identity: {
deviceId: '<string>',
sessionId: '<string>',
customerId: '<string>',
companyLocationId: '<string>'
},
context: {
geo: {country: '<string>', province: '<string>', city: '<string>'},
productsInCart: [
{
title: '<string>',
price: 123,
type: '<string>',
productId: '<string>',
variantId: '<string>',
options: {}
}
],
productsPurchased: [
{
title: '<string>',
price: 123,
type: '<string>',
productId: '<string>',
variantId: '<string>',
options: {}
}
],
priorSearches: [
{
searchQuery: '<string>',
hadClick: true,
hasResults: true,
fromPage: '<string>'
}
],
marketing: {source: '<string>', medium: '<string>', campaign: '<string>', term: '<string>'},
customer: {
signedIn: true,
returning: true,
numberOfOrders: 123,
averageOrderValue: 123,
daysBetweenOrders: 123,
daysSinceLastOrder: 123,
daysSinceOldestOrder: 123,
totalSpent: 123
},
market: '<string>',
shoppingChannel: '<string>',
custom: {}
},
responseOptions: {mediaPreloads: {enabled: true, srcsetSizes: [123]}}
})
};
fetch('https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'anchor_id' => '<string>',
'anchor_handle' => '<string>',
'attributes' => [
'<string>'
],
'excludeProductIds' => [
'<string>'
],
'filter_group' => [
],
'pagination' => [
'page' => 123,
'limit' => 123
],
'facets' => [
'<string>'
],
'retrieveFacetCount' => true,
'includeFacetRanges' => true,
'identity' => [
'deviceId' => '<string>',
'sessionId' => '<string>',
'customerId' => '<string>',
'companyLocationId' => '<string>'
],
'context' => [
'geo' => [
'country' => '<string>',
'province' => '<string>',
'city' => '<string>'
],
'productsInCart' => [
[
'title' => '<string>',
'price' => 123,
'type' => '<string>',
'productId' => '<string>',
'variantId' => '<string>',
'options' => [
]
]
],
'productsPurchased' => [
[
'title' => '<string>',
'price' => 123,
'type' => '<string>',
'productId' => '<string>',
'variantId' => '<string>',
'options' => [
]
]
],
'priorSearches' => [
[
'searchQuery' => '<string>',
'hadClick' => true,
'hasResults' => true,
'fromPage' => '<string>'
]
],
'marketing' => [
'source' => '<string>',
'medium' => '<string>',
'campaign' => '<string>',
'term' => '<string>'
],
'customer' => [
'signedIn' => true,
'returning' => true,
'numberOfOrders' => 123,
'averageOrderValue' => 123,
'daysBetweenOrders' => 123,
'daysSinceLastOrder' => 123,
'daysSinceOldestOrder' => 123,
'totalSpent' => 123
],
'market' => '<string>',
'shoppingChannel' => '<string>',
'custom' => [
]
],
'responseOptions' => [
'mediaPreloads' => [
'enabled' => true,
'srcsetSizes' => [
123
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Accept: <accept>",
"Content-Type: <content-type>",
"X-Storefront-Access-Token: <x-storefront-access-token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products"
payload := strings.NewReader("{\n \"anchor_id\": \"<string>\",\n \"anchor_handle\": \"<string>\",\n \"attributes\": [\n \"<string>\"\n ],\n \"excludeProductIds\": [\n \"<string>\"\n ],\n \"filter_group\": {},\n \"pagination\": {\n \"page\": 123,\n \"limit\": 123\n },\n \"facets\": [\n \"<string>\"\n ],\n \"retrieveFacetCount\": true,\n \"includeFacetRanges\": true,\n \"identity\": {\n \"deviceId\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"customerId\": \"<string>\",\n \"companyLocationId\": \"<string>\"\n },\n \"context\": {\n \"geo\": {\n \"country\": \"<string>\",\n \"province\": \"<string>\",\n \"city\": \"<string>\"\n },\n \"productsInCart\": [\n {\n \"title\": \"<string>\",\n \"price\": 123,\n \"type\": \"<string>\",\n \"productId\": \"<string>\",\n \"variantId\": \"<string>\",\n \"options\": {}\n }\n ],\n \"productsPurchased\": [\n {\n \"title\": \"<string>\",\n \"price\": 123,\n \"type\": \"<string>\",\n \"productId\": \"<string>\",\n \"variantId\": \"<string>\",\n \"options\": {}\n }\n ],\n \"priorSearches\": [\n {\n \"searchQuery\": \"<string>\",\n \"hadClick\": true,\n \"hasResults\": true,\n \"fromPage\": \"<string>\"\n }\n ],\n \"marketing\": {\n \"source\": \"<string>\",\n \"medium\": \"<string>\",\n \"campaign\": \"<string>\",\n \"term\": \"<string>\"\n },\n \"customer\": {\n \"signedIn\": true,\n \"returning\": true,\n \"numberOfOrders\": 123,\n \"averageOrderValue\": 123,\n \"daysBetweenOrders\": 123,\n \"daysSinceLastOrder\": 123,\n \"daysSinceOldestOrder\": 123,\n \"totalSpent\": 123\n },\n \"market\": \"<string>\",\n \"shoppingChannel\": \"<string>\",\n \"custom\": {}\n },\n \"responseOptions\": {\n \"mediaPreloads\": {\n \"enabled\": true,\n \"srcsetSizes\": [\n 123\n ]\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Storefront-Access-Token", "<x-storefront-access-token>")
req.Header.Add("Content-Type", "<content-type>")
req.Header.Add("Accept", "<accept>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products")
.header("X-Storefront-Access-Token", "<x-storefront-access-token>")
.header("Content-Type", "<content-type>")
.header("Accept", "<accept>")
.body("{\n \"anchor_id\": \"<string>\",\n \"anchor_handle\": \"<string>\",\n \"attributes\": [\n \"<string>\"\n ],\n \"excludeProductIds\": [\n \"<string>\"\n ],\n \"filter_group\": {},\n \"pagination\": {\n \"page\": 123,\n \"limit\": 123\n },\n \"facets\": [\n \"<string>\"\n ],\n \"retrieveFacetCount\": true,\n \"includeFacetRanges\": true,\n \"identity\": {\n \"deviceId\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"customerId\": \"<string>\",\n \"companyLocationId\": \"<string>\"\n },\n \"context\": {\n \"geo\": {\n \"country\": \"<string>\",\n \"province\": \"<string>\",\n \"city\": \"<string>\"\n },\n \"productsInCart\": [\n {\n \"title\": \"<string>\",\n \"price\": 123,\n \"type\": \"<string>\",\n \"productId\": \"<string>\",\n \"variantId\": \"<string>\",\n \"options\": {}\n }\n ],\n \"productsPurchased\": [\n {\n \"title\": \"<string>\",\n \"price\": 123,\n \"type\": \"<string>\",\n \"productId\": \"<string>\",\n \"variantId\": \"<string>\",\n \"options\": {}\n }\n ],\n \"priorSearches\": [\n {\n \"searchQuery\": \"<string>\",\n \"hadClick\": true,\n \"hasResults\": true,\n \"fromPage\": \"<string>\"\n }\n ],\n \"marketing\": {\n \"source\": \"<string>\",\n \"medium\": \"<string>\",\n \"campaign\": \"<string>\",\n \"term\": \"<string>\"\n },\n \"customer\": {\n \"signedIn\": true,\n \"returning\": true,\n \"numberOfOrders\": 123,\n \"averageOrderValue\": 123,\n \"daysBetweenOrders\": 123,\n \"daysSinceLastOrder\": 123,\n \"daysSinceOldestOrder\": 123,\n \"totalSpent\": 123\n },\n \"market\": \"<string>\",\n \"shoppingChannel\": \"<string>\",\n \"custom\": {}\n },\n \"responseOptions\": {\n \"mediaPreloads\": {\n \"enabled\": true,\n \"srcsetSizes\": [\n 123\n ]\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.uselayers.com/api/storefront/v1/blocks/{blockId}/products")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Storefront-Access-Token"] = '<x-storefront-access-token>'
request["Content-Type"] = '<content-type>'
request["Accept"] = '<accept>'
request.body = "{\n \"anchor_id\": \"<string>\",\n \"anchor_handle\": \"<string>\",\n \"attributes\": [\n \"<string>\"\n ],\n \"excludeProductIds\": [\n \"<string>\"\n ],\n \"filter_group\": {},\n \"pagination\": {\n \"page\": 123,\n \"limit\": 123\n },\n \"facets\": [\n \"<string>\"\n ],\n \"retrieveFacetCount\": true,\n \"includeFacetRanges\": true,\n \"identity\": {\n \"deviceId\": \"<string>\",\n \"sessionId\": \"<string>\",\n \"customerId\": \"<string>\",\n \"companyLocationId\": \"<string>\"\n },\n \"context\": {\n \"geo\": {\n \"country\": \"<string>\",\n \"province\": \"<string>\",\n \"city\": \"<string>\"\n },\n \"productsInCart\": [\n {\n \"title\": \"<string>\",\n \"price\": 123,\n \"type\": \"<string>\",\n \"productId\": \"<string>\",\n \"variantId\": \"<string>\",\n \"options\": {}\n }\n ],\n \"productsPurchased\": [\n {\n \"title\": \"<string>\",\n \"price\": 123,\n \"type\": \"<string>\",\n \"productId\": \"<string>\",\n \"variantId\": \"<string>\",\n \"options\": {}\n }\n ],\n \"priorSearches\": [\n {\n \"searchQuery\": \"<string>\",\n \"hadClick\": true,\n \"hasResults\": true,\n \"fromPage\": \"<string>\"\n }\n ],\n \"marketing\": {\n \"source\": \"<string>\",\n \"medium\": \"<string>\",\n \"campaign\": \"<string>\",\n \"term\": \"<string>\"\n },\n \"customer\": {\n \"signedIn\": true,\n \"returning\": true,\n \"numberOfOrders\": 123,\n \"averageOrderValue\": 123,\n \"daysBetweenOrders\": 123,\n \"daysSinceLastOrder\": 123,\n \"daysSinceOldestOrder\": 123,\n \"totalSpent\": 123\n },\n \"market\": \"<string>\",\n \"shoppingChannel\": \"<string>\",\n \"custom\": {}\n },\n \"responseOptions\": {\n \"mediaPreloads\": {\n \"enabled\": true,\n \"srcsetSizes\": [\n 123\n ]\n }\n }\n}"
response = http.request(request)
puts response.read_bodyPOST /storefront/v1/blocks/01HQXYZ123ABC456DEF789/products
{
"anchor_id": "8234567890123",
"pagination": {
"page": 1,
"limit": 12
},
"context": {
"geo": {
"country": "US",
"province": "California"
},
"productsInCart": [
{
"title": "Nike Air Force 1",
"productId": "8234567890123",
"variantId": "45678901234567"
}
],
"shoppingChannel": "web"
},
"identity": {
"sessionId": "abc123",
"deviceId": "device-uuid"
}
}
POST /storefront/v1/blocks/01HQXYZ789GHI012JKL345/products
{
"anchor_id": "summer-collection",
"pagination": {
"page": 1,
"limit": 12
},
"context": {
"geo": {
"country": "US"
},
"shoppingChannel": "web"
},
"identity": {
"sessionId": "abc123"
}
}
POST /storefront/v1/blocks/01HQXYZ789GHI012JKL345/products
{
"anchor_id": "summer-collection",
"pagination": {
"page": 1,
"limit": 20
},
"filter_group": {
"conditional": "AND",
"expressions": [
{
"property": "available",
"operator": "=",
"values": [true]
}
]
},
"context": {
"geo": {
"country": "US"
},
"shoppingChannel": "web"
}
}
POST /storefront/v1/blocks/01HQXYZ456MNO789PQR012/products
{
"pagination": {
"page": 1,
"limit": 8
},
"context": {
"geo": {
"country": "US"
},
"productsInCart": [
{
"title": "Nike Air Force 1",
"productId": "8234567890123",
"variantId": "45678901234567"
},
{
"title": "Classic Tee",
"productId": "8234567890456",
"variantId": "45678901234890"
}
],
"shoppingChannel": "app"
},
"identity": {
"sessionId": "abc123"
}
}
POST /storefront/v1/blocks/01HQXYZ456MNO789PQR012/products
{
"anchor_id": "8234567890123",
"pagination": {
"page": 1,
"limit": 8
},
"excludeProductIds": [
"8234567890456",
"gid://shopify/Product/8234567890789"
],
"context": {
"geo": {
"country": "US"
},
"shoppingChannel": "web"
},
"identity": {
"sessionId": "abc123"
}
}
{
"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": 1644047925,
"handle": "supreme-pouch-44370ss18a32-sm",
"updated_at": 1698280024,
"published_at": 1644047925,
"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": 8,
"page": 1,
"totalPages": 1,
"resultsPerPage": 12,
"block": {
"id": "01HQXYZ123ABC456DEF789",
"title": "Frequently Bought Together",
"anchor_type": "product",
"strategy_type": "interaction",
"strategy_key": "frequently_bought_together"
},
"attributionToken": "01JRVX9N4O5P6Q7R8S9T0U1V2W",
"_meta": {
"affinities": [
{
"property": "vendor",
"operator": "=",
"value": "NIKE",
"weight": 0.85
}
]
},
"_workflow": [
{
"type": "affinity-boosts",
"payload": [
{
"property": "vendor",
"operator": "eq",
"value": "NIKE",
"weight": 0.85
}
]
}
]
}
Authorization
Token-based authentication header in the form of
<YOUR_LAYERS_TOKEN>.Headers
Path parameters
The unique identifier (ULID) of the block you wish to retrieve products for.
Body
The anchor identifier for the block. Required for product and collection anchor types.
- Product anchors: Numeric product ID (e.g.,
"8234567890123") or Shopify GID (e.g.,"gid://shopify/Product/8234567890123"). Both formats are resolved automatically. - Collection anchors: Collection ID (e.g.,
"456789012345") or collection handle (e.g.,"summer-collection"). The system automatically resolves both numeric IDs and string handles. - Cart anchors: Not required (uses
context.productsInCartinstead) - Home, Search, Not Found, Landing, Other anchors: Not required. These surfaces rely on the
contextandidentityparameters (search query, landing source, shopper context) to drive strategy selection. - None anchors: Not required (global blocks)
Deprecated: Use
anchor_id instead. For collection anchors, anchor_id now accepts both collection IDs and handles.Product attributes to include in the response. By default, all attributes are included. Available attributes include:
id, title, handle, body_html, vendor, product_type, tags, images, 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. See the Product Schema for detailed descriptions, including nested field selection for slicing arrays and filtering collections (for example, images[:2].src, variants[sku=ABC].price, metafields[namespace=custom]).A list of product IDs to exclude from the recommendations returned by this block. Use this to deduplicate products across multiple blocks rendered on the same page — for example, to prevent the same product from appearing in both a “Frequently Bought Together” block and a “Customers Also Viewed” block.Each entry can be either a numeric product ID (e.g.,
"8234567890123") or a Shopify GID (e.g., "gid://shopify/Product/8234567890123"). Both formats are accepted and resolved automatically.Excluded products are filtered out before strategy ranking, safeguard checks, and fallback evaluation. If excluding products causes the primary block to fall below its minimum products safeguard, the fallback chain is used and exclusions are applied to fallback blocks as well.Refer to our dedicated Filter Expressions guide to learn more about filter expressions.
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:// Exact facet codes
"facets": ["vendor", "options.Size", "options.Color"]
// Wildcard pattern
"facets": ["options.*"]
// Mixed exact and wildcard
"facets": ["vendor", "options.*", "metafields.product.*"]
If the count of each facet value should be calculated
If you want a min/max range for numeric facets such as price.
User identity information for tracking and personalization. Automatically managed by the Storefront Pixel; required for headless integrations.
Show Properties
Show Properties
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.
Temporary session identifier. Typically corresponds to the Shopify session ID and expires after inactivity or when the browser is closed.
Shopify customer ID for authenticated users. Only present when the user is signed in to their account.
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. See B2B catalogs.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 for implementation guidance.
Show Properties
Show Properties
Geographic location information for regional personalization and merchandising. Automatically determined by the platform for client-side requests based on IP address. For server-side API calls (headless integrations), you should provide this explicitly.
Products currently in the customer’s cart. Used to surface complementary products and influence relevance scoring.
Show Array Item Properties
Show Array Item Properties
Product title.
Product price.
Product type or category.
Product identifier. Accepts a numeric ID (e.g.,
"8234567890123") or a Shopify GID (e.g., "gid://shopify/Product/8234567890123").Product variant identifier.
Product variant options (e.g.,
{"Size": "11", "Color": "Red"}).Products the customer has previously purchased. Informs recommendations and prevents over-promotion of owned items.
Show Array Item Properties
Show Array Item Properties
Product title.
Product price at time of purchase.
Product type or category.
Product identifier. Accepts a numeric ID (e.g.,
"8234567890123") or a Shopify GID (e.g., "gid://shopify/Product/8234567890123").Product variant identifier.
Product variant options (e.g.,
{"Size": "11", "Color": "Red"}).Recent search queries and their outcomes. Helps understand customer intent and refine relevance models.
Show Array Item Properties
Show Array Item Properties
Aggregated customer behavior and purchase patterns for personalization.
Show Properties
Show Properties
Whether the customer is currently authenticated.
Whether this is a returning customer.
Total number of orders placed.
Average order value in store currency.
Average days between orders.
Days since the most recent order.
Days since the first order.
Total amount spent in store currency.
Explicitly set the Shopify Market for this request. 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 the geo.country field (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.Behavior depends on the store’s market application mode:- Strict — Products are filtered to only those available in the resolved market, and market-specific pricing is applied
- Pricing only — The full catalog remains visible, but variant prices are swapped to market-specific values where available
- Off — Market resolution is skipped entirely; base catalog and base pricing are used for all shoppers
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 or Canvas are detected as
"app").Accepted values:"web"— Standard web browser (default)"app"— Mobile app (e.g., Tapcart, Canvas)
Custom contextual data specific to your implementation. Structure is flexible and can contain any key-value pairs relevant to your use case.
Per-request overrides for response behavior. Currently controls image preload hints emitted in the
Example:
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.Show Properties
Show Properties
Controls the
Link: rel=\"preload\" directives generated for product images in this response. See Early hints for background.Show Properties
Show Properties
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.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.{
"responseOptions": {
"mediaPreloads": {
"enabled": true,
"srcsetSizes": [320, 640, 960]
}
}
}
Response
Show Properties
Show Properties
The unique identifier of the product.
The title of the product.
The HTML content describing the product.
The vendor of the product.
The type of the product.
The timestamp when the product was created.
The handle of the product.
The timestamp when the product was updated.
The timestamp when the product was published.
The tags associated with the product.
The parent product id if a child in a Combined Listing.
The role of the product if part of a Combined Listing.
The metafields of the product.
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.
The first available variant (depending on OOS settings) or the variant matched with a filter or search query.
Show Properties
Show Properties
The ID of the variant.
The title of the variant.
The availability of the variant.
The sku of the variant.
The price of the variant.
The compare at price of the variant.
The metafields of the variant.
The position of the variant in the product’s variant list.
Total inventory quantity across all locations. Only included when the store has the Expose Variant Inventory setting enabled.
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.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.The availability of the product.
When the store has the Expose Variant Inventory setting enabled, variant data in block responses (both
first_or_matched_variant and variants) includes the inventory_quantity, inventory_policy, and inventory_levels fields. This behavior is consistent across all storefront API endpoints — search, browse, and blocks. See Variant Schema Fields for details on these fields.The total number of results. When a maximum products safeguard is configured, this value is capped to the maximum. When variant breakouts are enabled, this reflects the count of tiles (both product and variant tiles) rather than just products.
The current page number.
The total number of pages. Calculated from
totalResults and the requested page size. When a maximum products safeguard is configured, this reflects the capped total. When variant breakouts are enabled, the calculation is based on tile count.The number of results per page (matches the
limit parameter from the request).If
retrieveFacetCount is true then an object with keys and values of the specified attributes. When variant breakouts are enabled, facet counts reflect tile counts rather than product counts. Empty values and literal "null" strings are automatically excluded from facet results.If
includeFacetRanges is true then an object with keys of the facet attribute code and value is an object with min/max.A unique request identifier (ULID) for this API call. Use this token to correlate block requests with analytics events via the Beacon API.
Information about the block that generated these recommendations.
Show Properties
Show Properties
The block ID.
The customer-facing title of the block.
The anchor type of the block:
product, collection, cart, home, search, not_found, landing, other, or none.The strategy type used:
interaction, collection_interaction, similar_products, manual, trending, or contextual.The specific strategy key. For product interaction strategies:
frequently_bought_together, customers_also_viewed, customers_also_added_to_cart, viewed_then_bought, customers_also_bought. For collection interaction strategies: browsed_then_bought, browsed_then_viewed, collection_trending. For trending strategies: best_sellers, trending_in_region, live_feed. For contextual strategies: searched_then_viewed, searched_then_purchased, landing_page_picks, free_shipping_picks.Present and set to
true when the block’s strategy data is still being computed or the strategy doesn’t yet have enough signal to return results. This applies to interaction strategies during their initial computation and to trending and contextual strategies that are warming up. In this state, the primary block returns empty results and the fallback chain is used instead. Once the strategy data is ready, this field is no longer included in the response.Show Properties
Show Properties
User affinity signals derived from the session’s contextual information. Only present when you pass the
context and identity parameters and the engine detects meaningful affinity patterns from cart contents and purchase history. The array contains both promotion entries (positive weights for preferred attribute values) and demotion entries (small negative weights for non-preferred values within the same attribute). Entries are grouped by property and sorted by weight in descending order.Show Properties
Show Properties
The product attribute the affinity applies to (e.g.,
"vendor", "product_type", "named_tags.color", "options.Size").The comparison operator.
"eq" for promotion entries that boost a specific value. "not_in" for demotion entries that slightly suppress products that don’t match any detected preference for this attribute.For promotion entries (
"eq"): the specific attribute value that was boosted (e.g., "Nike", "Running Shoes"). For demotion entries ("not_in"): an array of all promoted values for this attribute, so products not matching any of them receive a small negative boost.The boost weight applied. Promotion weights range from
0 to 1.2, where higher values indicate stronger preferences. Demotion weights are small negative values proportional to the strongest promotion in the same attribute group. Option-level attributes (e.g., options.Size) receive lower weights than product-level attributes (e.g., vendor).Array of variant breakout configurations applied to this block. Only present when one or more variant breakouts are active. Multiple breakouts with different option codes can work simultaneously. Each object has the structure
{optionCode: "Stone"}.Show Properties
Show Properties
The product option code that determines which variants are broken out (e.g., “Stone”, “Color”). Each product is broken out by the first matching option code from the array.
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.Show Properties
Show Properties
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.An ordered trace of processing steps the engine performed to produce results. Each entry represents a stage in the pipeline, recorded in the order it was executed.See the Text Search documentation for the full list of possible step types.
Response headers
Every API response includes the following headers for request tracing and performance optimization:| 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 for details. Only included when early hints are enabled (enabled by default). |
Block concepts
For details on how blocks work conceptually (anchor types, strategies, rules, safeguards, and fallback chains), see the platform documentation:Error handling
Error message when the request fails.
404 - Block not found
404 - Block not found
The specified block ID doesn’t exist or is not active.
{
"error": "Block not found"
}
404 - Unable to get products
404 - Unable to get products
The block exists but couldn’t generate recommendations (e.g., missing anchor_id for product anchor).
{
"error": "Unable to get products for block"
}
401 - Unauthorized
401 - Unauthorized
Invalid or missing authentication token.
POST /storefront/v1/blocks/01HQXYZ123ABC456DEF789/products
{
"anchor_id": "8234567890123",
"pagination": {
"page": 1,
"limit": 12
},
"context": {
"geo": {
"country": "US",
"province": "California"
},
"productsInCart": [
{
"title": "Nike Air Force 1",
"productId": "8234567890123",
"variantId": "45678901234567"
}
],
"shoppingChannel": "web"
},
"identity": {
"sessionId": "abc123",
"deviceId": "device-uuid"
}
}
POST /storefront/v1/blocks/01HQXYZ789GHI012JKL345/products
{
"anchor_id": "summer-collection",
"pagination": {
"page": 1,
"limit": 12
},
"context": {
"geo": {
"country": "US"
},
"shoppingChannel": "web"
},
"identity": {
"sessionId": "abc123"
}
}
POST /storefront/v1/blocks/01HQXYZ789GHI012JKL345/products
{
"anchor_id": "summer-collection",
"pagination": {
"page": 1,
"limit": 20
},
"filter_group": {
"conditional": "AND",
"expressions": [
{
"property": "available",
"operator": "=",
"values": [true]
}
]
},
"context": {
"geo": {
"country": "US"
},
"shoppingChannel": "web"
}
}
POST /storefront/v1/blocks/01HQXYZ456MNO789PQR012/products
{
"pagination": {
"page": 1,
"limit": 8
},
"context": {
"geo": {
"country": "US"
},
"productsInCart": [
{
"title": "Nike Air Force 1",
"productId": "8234567890123",
"variantId": "45678901234567"
},
{
"title": "Classic Tee",
"productId": "8234567890456",
"variantId": "45678901234890"
}
],
"shoppingChannel": "app"
},
"identity": {
"sessionId": "abc123"
}
}
POST /storefront/v1/blocks/01HQXYZ456MNO789PQR012/products
{
"anchor_id": "8234567890123",
"pagination": {
"page": 1,
"limit": 8
},
"excludeProductIds": [
"8234567890456",
"gid://shopify/Product/8234567890789"
],
"context": {
"geo": {
"country": "US"
},
"shoppingChannel": "web"
},
"identity": {
"sessionId": "abc123"
}
}
{
"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": 1644047925,
"handle": "supreme-pouch-44370ss18a32-sm",
"updated_at": 1698280024,
"published_at": 1644047925,
"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": 8,
"page": 1,
"totalPages": 1,
"resultsPerPage": 12,
"block": {
"id": "01HQXYZ123ABC456DEF789",
"title": "Frequently Bought Together",
"anchor_type": "product",
"strategy_type": "interaction",
"strategy_key": "frequently_bought_together"
},
"attributionToken": "01JRVX9N4O5P6Q7R8S9T0U1V2W",
"_meta": {
"affinities": [
{
"property": "vendor",
"operator": "=",
"value": "NIKE",
"weight": 0.85
}
]
},
"_workflow": [
{
"type": "affinity-boosts",
"payload": [
{
"property": "vendor",
"operator": "eq",
"value": "NIKE",
"weight": 0.85
}
]
}
]
}
See also
- Blocks Platform Documentation - Learn about block concepts and configuration
Was this page helpful?
⌘I