# Shopify Store Scraper — Products, Collections & App Detection (`extractmaster01/shopify-store-scraper`) Actor

Extract products, variants, prices, and collections from any Shopify store. Detect 50+ installed apps across 11 categories: email marketing, subscriptions, loyalty, live chat, reviews & more. No browser or proxy needed.

- **URL**: https://apify.com/extractmaster01/shopify-store-scraper.md
- **Developed by:** [extractmaster01](https://apify.com/extractmaster01) (community)
- **Categories:** E-commerce, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 product scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

![Shopify Store Scraper](https://raw.githubusercontent.com/masterofextraction01/actor-readme-images/refs/heads/main/shopify-banner.png)

## Shopify Store Scraper — Products, Collections & App Detection 🛒

> **Extract products, variants, prices, collections, and detect 50+ installed apps from any Shopify store.**

Fast, reliable, and proxy-free. Built for e-commerce intelligence, competitor tracking, and B2B lead generation.

---

### ✨ What makes this different?

- **App Detection (50+ apps, 11 categories)** — Detects which Shopify apps are installed by analyzing the store's homepage and product pages. Covers Klaviyo, Recharge, Gorgias, Yotpo, Okendo, Loox, Postscript, Stamped, Attentive, and many more. Perfect for SaaS sales teams targeting stores by their tech stack.
- **Full variant data** — Every product includes the complete variant array with per-variant price, compareAtPrice, discountPercent, SKU, barcode, weight, and availability. Competitors return only a count.
- **Competitor-aligned schema** — Field names match the Apify Shopify scraper ecosystem (`priceMin`, `priceMax`, `featuredImage`, `onSale`, `available`, `fullyOutOfStock`, `requiresShipping`, `weightAndUnit`).
- **Multi-store parallelism** — Scrape dozens of stores in a single run with configurable concurrency.
- **No browser, no proxy required** — Lightning fast, no headless browser, no anti-bot friction.
- **Named datasets** — App detection results go to a dedicated `apps` dataset, keeping the default dataset exclusively for products and collections (uniform schema → clean CSV/Excel exports).

---

### 💰 Pricing

Pay-per-event — you only pay for what you successfully extract.

| Event | Price |
|---|---|
| Product scraped | **$2.00 / 1K** (`$0.002 / product`) |
| Collection scraped | **$1.00 / 1K** (`$0.001 / collection`) |

*Example: 3 stores × 500 products each = 1,500 products = **$3.00 total**. No subscriptions, no hidden fees.*

---

### 🎯 Use Cases

- **Competitor price monitoring** — Track prices, discounts, and stock availability across multiple stores daily.
- **B2B SaaS lead generation** — Find all Shopify stores using Klaviyo, Recharge, or any other app and pitch your product.
- **Market research** — Analyze product catalogs, pricing tiers, discount patterns, and inventory at scale.
- **Dropshipping research** — Evaluate catalog depth, vendor diversity, and product availability before entering a niche.
- **Tech stack intelligence** — Build lists of stores segmented by their installed app stack.

---

### ⚙️ Input Parameters

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | Array | required | Shopify store URLs, product URLs (`/products/{handle}`), or collection URLs (`/collections/{handle}`). Standard Apify URL list format: `[{ "url": "https://..." }]`. |
| `scrapeProducts` | Boolean | `true` | Extract products with variants, prices, images, and options. |
| `sortBy` | String | `best_selling` | Product sort order: `best_selling` (default), `price_asc`, `price_desc`, `newest`, `title`. |
| `scrapeCollections` | Boolean | `false` | Extract store collections with title, description, and product count. |
| `mapProductCollections` | Boolean | `false` | Add a `collections` array to each product. Requires extra requests (slower). |
| `detectApps` | Boolean | `false` | Detect 50+ installed Shopify apps across 11 categories. Results in dedicated `apps` dataset. |
| `maxProductsPerStore` | Integer | `0` | Max matched products per store (0 = unlimited). |
| `maxItems` | Integer | `1000` | Global item limit across all stores and types. |
| `query` | String | `""` | Optional keyword filter. Case-insensitive. Matches title, tags, vendor, productType, and description. |
| `maxRecommendationsPerProduct` | Integer | `0` | Max product recommendations to fetch per scraped product (0-10). |
| `storeConcurrency` | Integer | `3` | Stores processed in parallel (max 10). |
| `proxyConfiguration` | Object | `{ useApifyProxy: false }` | Optional proxy config. Most stores respond to `/products.json` without a proxy. Enable Residential proxies only if a store returns HTTP 403 — this typically affects large brands (Gymshark, Allbirds, MVMT) that block datacenter IP ranges. Residential proxies consume Apify proxy credits. |

#### Example Input

```json
{
  "startUrls": [
    { "url": "https://allbirds.com" },
    { "url": "https://gymshark.com/products/t-shirt" },
    { "url": "https://gymshark.com/collections/mens-shorts" }
  ],
  "query": "wool",
  "scrapeProducts": true,
  "scrapeCollections": false,
  "detectApps": true,
  "sortBy": "best_selling",
  "maxProductsPerStore": 0,
  "maxItems": 1000,
  "storeConcurrency": 3,
  "maxRecommendationsPerProduct": 5
}
````

***

### 📊 Output

Results are split across three datasets, each with a uniform schema:

- **Default dataset** — products only (`scrapeProducts: true`)
- **`collections` dataset** — collections only (`scrapeCollections: true`)
- **`apps` dataset** — app detection results, one record per store (`detectApps: true`)

Separating products and collections into their own datasets means each dataset has a consistent schema — no mixed types that truncate fields when exported as CSV or viewed in the Apify table UI.

> **Accessing datasets:** All three datasets are accessible directly from the run's **Output tab** via the dataset selector dropdown: **Products**, **Collections**, and **App Detection**.

#### Product

```json
{
  "type": "product",
  "storeUrl": "https://allbirds.com",
  "store": "allbirds.com",
  "productId": 7123456789,
  "url": "https://allbirds.com/products/mens-wool-runners",
  "title": "Men's Wool Runners",
  "handle": "mens-wool-runners",
  "description": "Crafted from ZQ-certified merino wool, breathable and naturally odor resistant.",
  "vendor": "Allbirds",
  "productType": "Shoes",
  "tags": ["wool", "running", "men"],
  "priceMin": 98.00,
  "priceMax": 98.00,
  "compareAtPrice": null,
  "discountPercent": null,
  "onSale": false,
  "available": true,
  "fullyOutOfStock": false,
  "currency": "USD",
  "variantCount": 12,
  "availableVariantCount": 10,
  "options": [{ "name": "Size", "values": ["8", "9", "10", "11"] }],
  "variants": [
    {
      "id": 39876543,
      "title": "Natural Grey / 10",
      "price": 98.00,
      "compareAtPrice": null,
      "discountPercent": null,
      "sku": "M-WR-GRY-10",
      "barcode": null,
      "available": true,
      "option1": "Natural Grey",
      "option2": "10",
      "option3": null,
      "weight": 0.28,
      "weightUnit": "kg"
    }
  ],
  "requiresShipping": true,
  "weightAndUnit": "0.28 kg",
  "imageCount": 5,
  "featuredImage": "https://cdn.shopify.com/s/files/...",
  "imageAltTexts": ["Men's Wool Runners in Natural Grey", "Side view"],
  "images": ["https://cdn.shopify.com/s/files/..."],
  "recommendedProductIds": [7123456790, 7123456791],
  "collections": [],
  "createdAt": "2024-03-01T00:00:00-05:00",
  "updatedAt": "2026-05-15T12:00:00-05:00",
  "publishedAt": "2024-03-01T00:00:00-05:00",
  "scrapedAt": "2026-06-14T10:00:00.000Z"
}
```

#### App Detection (in `apps` dataset)

```json
{
  "domain": "allbirds.com",
  "storeUrl": "https://allbirds.com",
  "reviews": ["yotpo"],
  "email_marketing": ["klaviyo"],
  "popups": null,
  "subscriptions": ["recharge"],
  "loyalty": null,
  "live_chat": ["gorgias"],
  "search": ["algolia"],
  "page_builder": null,
  "currency_converter": null,
  "upsell": ["reconvert"],
  "analytics": ["hotjar"],
  "all": ["yotpo", "klaviyo", "recharge", "gorgias", "algolia", "reconvert", "hotjar"],
  "count": 7,
  "scrapedAt": "2026-06-14T10:00:00.000Z"
}
```

#### Collection (when `scrapeCollections: true`)

```json
{
  "type": "collection",
  "storeUrl": "https://allbirds.com",
  "store": "allbirds.com",
  "collectionId": 254789012,
  "collectionUrl": "https://allbirds.com/collections/mens",
  "title": "Men's",
  "handle": "mens",
  "description": "",
  "productsCount": 98,
  "publishedAt": "2019-10-01T00:00:00-05:00",
  "updatedAt": "2026-05-15T12:00:00-05:00",
  "scrapedAt": "2026-06-14T10:00:00.000Z"
}
```

***

### 🔍 Detected Apps — Categories

When `detectApps: true`, the scraper checks for 50+ apps across 11 categories:

| Category | Examples |
|---|---|
| Reviews | Judge.me, Yotpo, Loox, Stamped, Okendo, Junip, Reviews.io, Trustpilot, Shopify Product Reviews |
| Email Marketing | Klaviyo, Omnisend, Mailchimp, Drip, Attentive, Postscript, Braze, Iterable, Bloomreach Engagement |
| Popups | Privy, Justuno, OptiMonk |
| Subscriptions | Recharge, Bold Subscriptions, Appstle |
| Loyalty | Smile.io, LoyaltyLion, Yotpo Loyalty |
| Live Chat | Gorgias, Zendesk, Tidio, Intercom, Drift |
| Search | Algolia, Searchanise, Klevu |
| Page Builder | Shogun, PageFly, GemPages, Zipify Pages |
| Currency Converter | Currency Converter Plus, Weglot, LangShop |
| Upsell | ReConvert, Rebuy, Bold Upsell, In Cart Upsell |
| Analytics | Hotjar, Google Tag Manager, Google Analytics, Facebook Pixel, TikTok Pixel, Pinterest Tag, Snapchat Pixel |

***

### ❓ FAQ

**Q: Do I need proxies?**
A: Most stores respond to `/products.json` without one. Enable Residential proxies only if a store returns HTTP 403 — this typically affects large brands (Gymshark, Allbirds, MVMT) that block datacenter IP ranges. Residential proxies consume Apify proxy credits.

**Q: Does it work on any Shopify store?**
A: Yes, on any standard Shopify store. Stores with heavily restricted or customized storefronts may return fewer results.

**Q: How does app detection work?**
A: The scraper analyzes each store and cross-references against our signature database of 50+ apps. False negatives are possible for stores with heavily customized themes or apps configured to load lazily.

**Q: Can I scrape multiple stores in one run?**
A: Yes — add as many URLs as you need to `startUrls`. Use `storeConcurrency` (default 3, max 10) to control how many are processed in parallel.

**Q: Can I schedule daily runs?**
A: Yes — use Apify's built-in scheduler. Combine with webhooks or Google Sheets integration for automated monitoring.

**Q: Does keyword search use Shopify's native search engine?**
A: No, it filters the full product list client-side. The actor fetches all products from the store (respecting `maxProductsPerStore`) and filters by the `query` matching the title, vendor, tags, product type, or description. This means for very large stores, all products are fetched before filtering, which is still fast and doesn't incur extra proxy costs.

**Q: Can I scrape specific products or collections?**
A: Yes! Simply pass the product URL (e.g. `https://store.com/products/item`) or collection URL (e.g. `https://store.com/collections/sale`) in the `startUrls` array. The scraper will handle them correctly. A product URL results in 1 product record. A collection URL results in N product records (all products in that collection). A store URL results in a full catalog crawl.

**Q: How do I find Shopify stores in a niche?**
A: Tools like BuiltWith, Koala Inspector, or the Apify Shopify Store Finder let you search for Shopify stores by niche or category. Then paste the URLs here and run.

# Actor input Schema

## `startUrls` (type: `array`):

List of Shopify store URLs to scrape. Supports store root URLs, collection URLs, or product URLs. Custom domains and myshopify.com are both supported.

## `scrapeProducts` (type: `boolean`):

Extract all products with variants, prices, images, description, and options.

## `sortBy` (type: `string`):

Order in which products are returned. 'best\_selling' is recommended for dropshipping research.

## `scrapeCollections` (type: `boolean`):

Extract all product collections with title, description, and product count.

## `mapProductCollections` (type: `boolean`):

Add a 'collections' array to each product showing which collections it belongs to. Requires additional requests (slower).

## `detectApps` (type: `boolean`):

Detect 50+ Shopify apps installed on the store, organized into 11 categories: reviews, email marketing, popups, subscriptions, loyalty, live chat, search, page builder, currency converter, upsell, and analytics. Results saved to a dedicated 'apps' dataset.

## `maxProductsPerStore` (type: `integer`):

Maximum products per store. 0 = unlimited.

## `maxItems` (type: `integer`):

Global limit across all stores and item types.

## `storeConcurrency` (type: `integer`):

How many stores to process in parallel. Higher values speed up multi-store runs but use more memory and proxy bandwidth.

## `query` (type: `string`):

Optional keyword to filter products. Case-insensitive. Matches product title, vendor, product type, tags, and description. Leave empty to return all products.

## `maxRecommendationsPerProduct` (type: `integer`):

Number of recommended product IDs to fetch per product (0 = disabled, max 10). Adds extra requests.

## `proxyConfiguration` (type: `object`):

Most Shopify stores respond to /products.json without a proxy. Enable Residential proxies only if a store returns HTTP 403 — this typically affects large brands (Gymshark, Allbirds, MVMT) that block datacenter IP ranges. Residential proxies consume Apify proxy credits.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://allbirds.com"
    }
  ],
  "scrapeProducts": true,
  "sortBy": "best_selling",
  "scrapeCollections": false,
  "mapProductCollections": false,
  "detectApps": false,
  "maxProductsPerStore": 0,
  "maxItems": 1000,
  "storeConcurrency": 3,
  "query": "",
  "maxRecommendationsPerProduct": 0,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `products` (type: `string`):

Default dataset containing scraped products. Uniform schema — exports cleanly to CSV and Excel.

## `collections` (type: `string`):

Named dataset containing scraped collections (title, handle, description, product count). Only populated when scrapeCollections is true.

## `apps` (type: `string`):

Detected Shopify apps per store across 11 categories (reviews, email marketing, subscriptions, loyalty, live chat, search, page builder, currency converter, upsell, analytics). Only populated when detectApps is true.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("extractmaster01/shopify-store-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("extractmaster01/shopify-store-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call extractmaster01/shopify-store-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=extractmaster01/shopify-store-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Shopify Store Scraper — Products, Collections & App Detection",
        "description": "Extract products, variants, prices, and collections from any Shopify store. Detect 50+ installed apps across 11 categories: email marketing, subscriptions, loyalty, live chat, reviews & more. No browser or proxy needed.",
        "version": "0.1",
        "x-build-id": "NfEE1VsD66Cgf68e8"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/extractmaster01~shopify-store-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-extractmaster01-shopify-store-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/extractmaster01~shopify-store-scraper/runs": {
            "post": {
                "operationId": "runs-sync-extractmaster01-shopify-store-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/extractmaster01~shopify-store-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-extractmaster01-shopify-store-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "startUrls"
                ],
                "properties": {
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "List of Shopify store URLs to scrape. Supports store root URLs, collection URLs, or product URLs. Custom domains and myshopify.com are both supported.",
                        "default": [
                            {
                                "url": "https://allbirds.com"
                            }
                        ],
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "scrapeProducts": {
                        "title": "Scrape Products",
                        "type": "boolean",
                        "description": "Extract all products with variants, prices, images, description, and options.",
                        "default": true
                    },
                    "sortBy": {
                        "title": "Sort Products By",
                        "enum": [
                            "best_selling",
                            "price_asc",
                            "price_desc",
                            "newest",
                            "title"
                        ],
                        "type": "string",
                        "description": "Order in which products are returned. 'best_selling' is recommended for dropshipping research.",
                        "default": "best_selling"
                    },
                    "scrapeCollections": {
                        "title": "Scrape Collections",
                        "type": "boolean",
                        "description": "Extract all product collections with title, description, and product count.",
                        "default": false
                    },
                    "mapProductCollections": {
                        "title": "Map Products to Collections",
                        "type": "boolean",
                        "description": "Add a 'collections' array to each product showing which collections it belongs to. Requires additional requests (slower).",
                        "default": false
                    },
                    "detectApps": {
                        "title": "Detect Installed Apps",
                        "type": "boolean",
                        "description": "Detect 50+ Shopify apps installed on the store, organized into 11 categories: reviews, email marketing, popups, subscriptions, loyalty, live chat, search, page builder, currency converter, upsell, and analytics. Results saved to a dedicated 'apps' dataset.",
                        "default": false
                    },
                    "maxProductsPerStore": {
                        "title": "Max Products per Store",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum products per store. 0 = unlimited.",
                        "default": 0
                    },
                    "maxItems": {
                        "title": "Max Total Items",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Global limit across all stores and item types.",
                        "default": 1000
                    },
                    "storeConcurrency": {
                        "title": "Store Concurrency",
                        "minimum": 1,
                        "maximum": 10,
                        "type": "integer",
                        "description": "How many stores to process in parallel. Higher values speed up multi-store runs but use more memory and proxy bandwidth.",
                        "default": 3
                    },
                    "query": {
                        "title": "Keyword Filter",
                        "type": "string",
                        "description": "Optional keyword to filter products. Case-insensitive. Matches product title, vendor, product type, tags, and description. Leave empty to return all products.",
                        "default": ""
                    },
                    "maxRecommendationsPerProduct": {
                        "title": "Max Recommendations per Product",
                        "minimum": 0,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Number of recommended product IDs to fetch per product (0 = disabled, max 10). Adds extra requests.",
                        "default": 0
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Most Shopify stores respond to /products.json without a proxy. Enable Residential proxies only if a store returns HTTP 403 — this typically affects large brands (Gymshark, Allbirds, MVMT) that block datacenter IP ranges. Residential proxies consume Apify proxy credits.",
                        "default": {
                            "useApifyProxy": false
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
