Skip to main content

API

Reference for the Discovery OS Shopify app proxy: search, merchandising routes (mRoute), and recommendations. Call these endpoints from the storefront when you integrate your own UI.

note

Replace {shopDomain} with the store’s Shopify hostname (for example your-store.myshopify.com). Requests are made from the buyer’s browser on the storefront origin so the app proxy can authenticate the session.

Prerequisites: Enable the app embed, validate the session, and send the request header below.

Request header​

Required on every Search, mRoute, and Recommendations request.

Read region from the user’s browser storage (pa-discoveryos-config root fields) and send it as x-shopify-region. If region is EU:

x-shopify-region: EU

The API uses this header to scope the request to that Shopify region.

Session validation​

The app embed exposes **window.paDiscoveryOsApp.validateSession()**. Your client must await this before calling search, mRoute, or recommendations so the session stays valid and lines up with the stored config.

// Example implementation

export async function paRequest(paRequest) {
if (typeof request !== 'function') {
throw new Error('paRequest expects a function as argument');
}

try {
if (window.paDiscoveryOsApp?.validateSession) {
await window.paDiscoveryOsApp.validateSession();
}

return await paRequest();

} catch (error) {
console.error('paRequest failed:', error);
throw error;
}
}

Search API​

Purpose: Run a catalog search and get product hits plus aggregations.

MethodPOST
URLhttps://{shopDomain}/apps/discoveryos/search

Sample payload​

{
"q": "bike", // search term or query
"start": 0,
"size": 5,
"scope": {"brand": ["Bryton"]}, // selected filters,
"sort_fields": [{"price": { "order": "desc", "type": "number"}}], // selected sort
"selected_fields": [ // list of field names that you want to be returned with product response
"title",
"brand",
"link",
"type",
"image_link",
"collections",
"variants.id",
"variants.title",
"variants.price",
"variants.delivery_status",
"variants.badge_handle",
"variants.search_information",
"variants.availableForSale",
"variants.delivery"
],
"aggregations": ["filter_cat", "brand"],
"referralUrl": "your-store.myshopify.com", // current url: window.location.href
"context": "searchPreview",
"customerId": "a7068b20-630c-4dc5-b6a7-2f16d3b68a74",
"sessionId": "4e742af1-691f-480b-9cf1-3becc2aac3a8"
}
note

Use customerId and sessionId from localStorage data.

"aggregations": list of facet field names from localStorage data
"context": searchPreview for search-as-you-type, serp for the search results page, collection for collection search

Sample response​

{
"payload": {
"total_results": 124,
"results": [
{
"refId": "gid://shopify/Product/123",
"name": "Runner Pro",
"url": "/products/runner-pro"
}
],
"aggregations": {
"price_stats": {
"count": 10,
"min": 719,
"max": 1999,
"avg": 1050.5,
"sum": 10505
},
"brand": [
{
"key": "wahoo",
"doc_count": 7
},
{
"key": "elite",
"doc_count": 1
},
{
"key": "garmin",
"doc_count": 1
},
{
"key": "jetblack",
"doc_count": 1
}
]
}
}
}
note

Aggregations: aggregations in the response update your filter component.

Block settings — Select Widget

mRoute API​

Purpose: Load products (and related data) for a merchandising route configured in DiscoveryOS.

MethodPOST
URLhttps://{shopDomain}/apps/discoveryos/mroute

Sample payload​

{
"route": "/collections/collection-handle",
"start": 0,
"size": 20,
"shop": "your-store.myshopify.com",
"scope": {}, // Similar as search API
"sort_fields": [], // Similar as search API
"selected_fields": [ // // Similar as search API
"refId",
"name",
"url",
"images",
"brand",
"prices"
]
}

Sample response​

{
"payload": {
"total_results": 24,
"results": [
{
"refId": "gid://shopify/Product/456",
"name": "Trail Runner",
"url": "/products/trail-runner"
}
]
}
}

Recommendations API​

Purpose: Load the recommendation route and widgets (slots, products, banners metadata) for the current page context.

MethodGET
URLhttps://{shopDomain}/apps/discoveryos/recommendations

Query parameters​

ParameterRequiredDescription
currentUrlYesFull URL of the page the shopper is on. Use the encoded page URL (for example encodeURIComponent(window.location.href) in JavaScript).
expandProductDetailsRecommendedWhen true, product documents in the response include richer fields (attributes, variants, etc.).
refIdOn product pagesShopify product numeric ID for the product being viewed (for example from Liquid product.id).
Include this on product detail pages so recommendations can anchor on the current product.
ifvPLP and collection pages onlyCategory path for niche indexing, for example Mens > Top > Solid Shirt. URL-encode the value. Send ifv only on PLP and collection pages. The recommendations query uses this value and returns related products. Omit it on product pages and other routes.

Example URL (product page)​

Build currentUrl from the shopper’s real page URL (must be URL-encoded). Example pattern:

https://{shopDomain}/apps/discoveryos/recommendations?currentUrl=<encoded-full-page-url>&expandProductDetails=true&refId=<product-id>

On non-product pages, omit refId and still pass currentUrl so routing matches PLP, home, collection, etc.

Example URL (PLP / collection page)​

On PLP and collection pages, omit refId and send ifv with the category path (for example Mens > Top > Solid Shirt). The recommendations API uses that value and returns related products.

https://{shopDomain}/apps/discoveryos/recommendations?currentUrl=<encoded-full-page-url>&expandProductDetails=true&ifv=Mens%20%3E%20Top%20%3E%20Solid%20Shirt

Mens%20%3E%20Top%20%3E%20Solid%20Shirt is the URL-encoded form of Mens > Top > Solid Shirt.

Sample response (shape only)​

The live payload is large. At a high level you receive a recommendations object whose route describes the matched route, the currentProduct (when applicable), and widgets — each widget has slots, and each slot lists products and banners (and campaign metadata used for tracking).

The first widget below is a standard recommendation slot. The second widget’s slot is sponsored (retail media): it includes adSetId, placementId, supplierId, hmac, and the other attribution fields. Those fields are only present when the slot is sponsored.

{
"recommendations": {
"route": {
"id": "7f960983-3740-f011-abf3-02bf4bf6447c",
"name": "PDP",
"currentProduct": {
"refId": "8728216993948",
"name": "Example product",
"url": "https://{shopDomain}/products/example-product",
"isInStock": true,
"brand": { "id": "6170085a-5e4a-433d-a273-dc7924d4a5da", "name": "Example Brand" },
"images": ["https://cdn.shopify.com/..."],
"prices": [{ "price": 17, "code": "AUD" }],
"attributes": []
},
"widgets": [
{
"id": "7b43001c-3740-f011-abf3-02bf4bf6447c",
"name": "PDP",
"widgetTitle": "Recommended to you",
"slots": [
{
"label": "Slot 1",
"tacticId": "46872308-1428-f111-abf3-02bf4bf6447c",
"campaignId": "9d054dab-1328-f111-abf3-02bf4bf6447c",
"products": [
{
"refId": "15109897027606",
"name": "Pink Bear",
"url": "https://{shopDomain}/products/pink-bear",
"isInStock": true,
"images": ["https://cdn.shopify.com/..."],
"prices": [{ "price": 100, "code": "EUR" }],
"attributes": []
}
],
"banners": []
}
]
},
{
"id": "b2c0e539-8a01-f111-abf3-02bf4bf6447c",
"name": "Shopify Banner TEST",
"widgetTitle": "banner-widget",
"slots": [
{
"label": "1",
"tacticId": "9029e8cb-a9ad-f111-abf3-02bf4bf6447c",
"campaignId": "522a229d-a9ad-f111-abf3-02bf4bf6447c",
"recommenderId": "6dfc7c93-a9ad-f111-abf3-02bf4bf6447c",
"adSetId": "bb1f589c-4974-f111-abf3-02bf4bf6447c",
"placementId": "0374cedc-4874-f111-abf3-02bf4bf6447c",
"supplierId": "6ce92bbf-5c81-ef11-abf3-02bf4bf6447c",
"adSetVersion": 1,
"costPerClick": "0.60",
"hmacSalt": "vGWJc434ei47LhV2",
"hmac": "jmKSOqSJlcpIl4DRRQNu1qa-GJb5364hsZD2Ug-sg_-CU9YU49vxdoiMSlPLaQsfY4BeeqnRBsYcGTCTckxgM4e1v4FE6HfOVMCh1TsxIKzvG1fe_1KZ6EqXanD97fee44a3jwY4JIkAoJpGM0XBz43i5ERukX6hxuUMFP5nELbkt6AlWaKnAVhbG8WEdOy2IZI77PIbZB7PA6qsnpyXHwliFNDGZA",
"timeStamp": 639273938909205000,
"products": [
{
"refId": "9104741400732",
"name": "14k Wire Bloom Earrings",
"description": "Sed in metus nec dui consequat vestibulum. In varius pretium nunc, sed bibendum mauris lacinia non. Praesent vel neque ut ligula porttitor vestibulum ac eu erat. Pellentesque quis turpis odio. Etiam auctor laoreet ligula, vel aliquam urna ornare sed. Praesent laoreet diam vitae lectus molestie pulvinar. Nullam blandit Vestibulum euismod Nullam venenatis Aenean a magna eros",
"url": "https://pa-search-test.myshopify.com/products/14k-wire-bloom-earrings",
"isInStock": true,
"brand": {
"id": "db166946-8d37-4b72-8337-077d780580b7",
"name": "Supply Dark"
},
"images": [
"https://cdn.shopify.com/s/files/1/0687/4834/5500/files/18k-rose-gold-wire-bloom-earrings_afcace12-edfb-4c82-aba0-11462409947f.jpg?v=1780916901"
],
"prices": [
{
"price": 449,
"code": "AUD"
}
],
"contents": [],
"attributes": [
{
"name": "variants",
"json": true,
"options": [
{
"value": "{\"id\":\"gid://shopify/ProductVariant/47036108308636\",\"legacyResourceId\":\"47036108308636\",\"title\":\"Default Title\",\"displayName\":\"14k Wire Bloom Earrings - Default Title\",\"price\":\"449.00\",\"position\":1,\"availableForSale\":true,\"taxable\":true,\"inventoryQuantity\":100,\"inventoryPolicy\":\"DENY\",\"selectedOptions\":[{\"name\":\"Title\",\"value\":\"Default Title\"}]}"
}
],
"valueType": 3
},
{
"name": "tags",
"json": false,
"options": [
{
"value": "Rose Gold"
}
],
"valueType": 3
},
{
"name": "status",
"stringValue": "ACTIVE",
"json": false,
"options": [],
"valueType": 1
},
{
"name": "published_at",
"scalarValue": 1780916898,
"json": false,
"options": [],
"valueType": 2
},
{
"name": "created_at",
"scalarValue": 1780916899,
"json": false,
"options": [],
"valueType": 2
},
{
"name": "type",
"stringValue": "Earrings",
"json": false,
"options": [],
"valueType": 1
},
{
"name": "collections",
"json": false,
"options": [
{
"value": "Shop Catalog"
}
],
"valueType": 3
},
{
"name": "collection_handles",
"json": false,
"options": [
{
"value": "all"
}
],
"valueType": 3
}
]
}
],
"banners": [
{
"id": "82dec148-4974-f111-abf3-02bf4bf6447c",
"title": "Great Deal",
"titleColor": "#ffffff",
"subTitle": "ENJOY 50% FLAT SALE TILL JULY 31st",
"subTitleColor": "#fff700",
"description": "Find exactly what you're looking for. Shop with confidence — free returns, fast shipping, and deals you'll love.",
"descriptionColor": "#f9b9b9",
"smallPrintColor": "#ffffff",
"textAlignment": "center",
"backgroundColor": "#8f8f8f",
"ctAs": [
{
"id": "83dec148-4974-f111-abf3-02bf4bf6447c",
"enable": false,
"text": "",
"textColor": "",
"backgroundColor": "",
"redirectUrl": "",
"altText": "",
"position": 0
},
{
"id": "84dec148-4974-f111-abf3-02bf4bf6447c",
"enable": true,
"text": "SEE MORE",
"textColor": "#6a5c5c",
"backgroundColor": "",
"redirectUrl": "https://www.behance.net/gallery/167467037/Shopify-banner-Web-Banner-Design",
"altText": "",
"position": 0
},
{
"id": "85dec148-4974-f111-abf3-02bf4bf6447c",
"enable": false,
"text": "",
"textColor": "",
"backgroundColor": "",
"redirectUrl": "",
"altText": "",
"position": 0
}
],
"images": [
{
"id": "4225815e-b75d-4df1-8be5-3d1836abd9cb",
"imageUrl": "https://rm-assets-prd.shrdsrvcs.p-a.io/6ce92bbf-5c81-ef11-abf3-02bf4bf6447c/original/97954b59-6b0a-4877-78d1-08decd8eae1d.jpeg",
"title": "360_F_320686681_Ur6vdYQgDC9WiijiVfxlRyQffxOgfeFz.jpg",
"isFile": true,
"assetId": "97954b59-6b0a-4877-78d1-08decd8eae1d",
"altText": "",
"alignment": "left",
"bannerType": 4,
"digitalAssetDeviceTypes": 0
}
]
}
]
}
]
}
]
}
}
}

On a sponsored slot, set data-pa-hmac from the slot hmac. These retail media fields are only present when the slot is sponsored.