# Shopify Products Scraper – Prices, Variants, Stock (`ryumoon-data/shopify-store-products-scraper`) Actor

Scrape every product from any Shopify store: prices, compare-at, variants, SKUs, stock, images, tags. Whole store or one collection. Fast JSON feed, no browser. $0.80 per 1,000 products.

- **URL**: https://apify.com/ryumoon-data/shopify-store-products-scraper.md
- **Developed by:** [Ryu Moon](https://apify.com/ryumoon-data) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 products

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Shopify Store Products Scraper: Prices, Variants & Stock

**Get the full product catalogue of any Shopify store in one clean table.** Paste store URLs (or collection URLs) and get every product with price range, sale and compare-at prices, discount %, every variant (size/colour) with SKU and availability, images, tags, vendor, product type, description and created/updated dates. It reads the store's public storefront JSON feed, so there is no browser, no login and usually no proxy. Runs are fast (about 250 products per request) and cheap. Export to JSON, CSV, Excel or Google Sheets, or schedule it to track competitors' prices and stock.

### Use with AI agents (MCP, Claude, ChatGPT, Cursor)

**Purpose:** Get every product from any Shopify store (prices, compare-at and sale prices, variants, SKUs, stock flags, images, tags, descriptions), for the whole store or one collection.

**When to use it**

- Competitor price and catalogue monitoring for a Shopify store, "what does store X sell and at what price", finding products on sale.

**When not to use it**

- Only works on Shopify stores (most stores whose /products.json responds). Not for Amazon, eBay or other platforms.

**Example input**

```json
{
  "startUrls": [
    {
      "url": "https://www.allbirds.com"
    }
  ],
  "maxProductsPerStore": 50,
  "onlyOnSale": true
}
```

**Output fields (one dataset item per row):** `storeName`, `title`, `vendor`, `productType`, `priceMin`, `priceMax`, `compareAtPriceMax`, `currency`, `onSale`, `maxDiscountPercent`, `available`, `variantsCount`, `variants`, `imageUrl`, `url`, `updatedAt`.

**Cost:** $0.005 per run + $0.0008 per product ($0.80 per 1,000). Cap spend with `maxProductsPerStore`.

**Connect it to your agent:** add this remote MCP server (Apify's official MCP server, loaded with just this tool):

```json
{"mcpServers": {"shopify-store-products-scraper": {"url": "https://mcp.apify.com?tools=ryumoon-data/shopify-store-products-scraper"}}}
```

Or call it from any agent with the Apify API: `POST https://api.apify.com/v2/acts/ryumoon-data~shopify-store-products-scraper/run-sync-get-dataset-items` with the input above as the JSON body. Agents without an Apify account can pay per run with [agentic payments](https://docs.apify.com/agents/payments) (x402, MPP or Skyfire).

### What can this Shopify scraper do?

- 🛍️ **Whole store or one collection**: `https://store.com` or `https://store.com/collections/sale`.
- 💲 **Prices and sales**: lowest/highest variant price, compare-at price, on-sale flag and biggest discount %.
- 📦 **Variants and stock**: every variant's SKU, price, options and "available" flag, plus counts of in-stock variants.
- 🏷️ **Catalogue data**: vendor, product type, tags, images, description, created/published/updated dates.
- 🏪 **Store info**: store name and currency (from the store's public meta feed).
- 🧹 **Filters before you pay**: in stock only, on sale only, price range, title keywords, vendor, product type, "updated in the last N days". You are only charged for products that pass.

### Use cases

- **Competitor price monitoring**: schedule daily runs and compare prices and discounts.
- **Dropshipping and product research**: see what a store sells, at what price, and what's new.
- **Stock tracking**: watch when variants sell out or come back.
- **Catalogue migration and feeds**: export a store's products to CSV/JSON.
- **Market research**: compare assortments and pricing across many brands.

### How much does it cost?

Pay-per-event pricing. You pay only for:

| Event | Price | When it is charged |
|---|---|---|
| Actor start | **$0.005** | Once per run (at the default 1 GB memory) |
| Product | **$0.0008** | Each product saved to the dataset, with all its variants and images ($0.80 per 1,000) |

Examples:

- One small store with 120 products: about **$0.10**
- A 2,000-product store: about **$1.61**
- Daily monitor of 10 stores with "updated in the last 1 day" (about 150 changed products): about **$0.13 per day**

Use *Max products per store* or a *maximum cost per run* in Apify Console to cap spend.

### Input

| Field | What it does | Default |
|---|---|---|
| `startUrls` (required) | Store or collection URLs, or plain domains | example: allbirds.com |
| `maxProductsPerStore` | Cost cap per store (0 = all) | `0` |
| `onlyAvailable` / `onlyOnSale` | In stock only / on sale only | `false` |
| `minPrice` / `maxPrice` | Price range in store currency (0 = off) | `0` |
| `titleKeywords`, `vendors`, `productTypes` | Text filters | none |
| `updatedWithinDays` | Only recently changed products (0 = off) | `0` |
| `includeVariants` / `includeImages` / `includeDescription` | Output size | all `true` |
| `maxConcurrency`, `proxyConfiguration` | Advanced | `3`, none |

```json
{ "startUrls": [{ "url": "https://www.allbirds.com/collections/mens" }, { "url": "colourpop.com" }], "onlyOnSale": true, "maxProductsPerStore": 500 }
```

### Output (one row per product)

Real row (variants, images, tags and description shortened):

```json
{
  "storeUrl": "https://colourpop.com",
  "storeName": "ColourPop",
  "currency": "USD",
  "productId": 7664383557714,
  "title": "Colour Me Merry",
  "handle": "colour-me-merry-advent-calendar-2026",
  "url": "https://colourpop.com/products/colour-me-merry-advent-calendar-2026",
  "vendor": "ColourPop",
  "productType": "Advent Calendar 2026",
  "tags": [
    "10.22.26",
    "event:Advent Cal 2026",
    "new-arrival"
  ],
  "priceMin": 77,
  "priceMax": 77,
  "compareAtPriceMax": null,
  "onSale": false,
  "maxDiscountPercent": 0,
  "available": true,
  "variantsCount": 1,
  "variantsAvailable": 1,
  "options": [
    {
      "name": "Title",
      "values": [
        "Default Title"
      ]
    }
  ],
  "imageUrl": "https://cdn.shopify.com/s/files/1/1338/0845/files/Kit-ColourMeMerry-Hero.jpg?v=1792618081",
  "imagesCount": 7,
  "createdAt": "2026-09-24T21:42:26.000Z",
  "publishedAt": "2026-10-22T16:26:51.000Z",
  "updatedAt": "2026-11-02T09:56:22.000Z",
  "images": [
    "https://cdn.shopify.com/s/files/1/1338/0845/files/Kit-ColourMeMerry-Hero.jpg?v=1792618081"
  ],
  "variants": [
    {
      "id": 42754994372690,
      "title": "Default Title",
      "sku": "Kit-ColourMeMerry",
      "price": 77,
      "compareAtPrice": null,
      "available": true,
      "option1": "Default Title",
      "option2": null,
      "option3": null,
      "grams": 544,
      "requiresShipping": true
    }
  ],
  "descriptionText": "It’s the gift that keeps on giving.\n\nTreat your bestie (or yourself) to our first-ever advent calendar packed with 25 new items + fan-faves, worth ove…",
  "collection": "lips",
  "scrapedAt": "2026-11-02T09:56:22.781Z"
}
```

A run summary (store name, currency, products scanned and saved, stores that failed) is saved as `SUMMARY` in the run's key-value store.

### Limits (please read)

- **Shopify stores only.** Other platforms (WooCommerce, Magento, BigCommerce) are reported in `SUMMARY` and not charged.
- **Some stores hide or block the product feed.** Password-protected stores and stores behind strict bot protection can return 403/404. Enabling Apify Proxy (residential) fixes most 403/429s; the proxy traffic is billed by Apify to your account as usual.
- **"Available" is a yes/no flag.** Shopify's public feed doesn't show exact inventory quantities.
- **Prices are in the store's default currency and market.** Local-currency prices for other countries aren't included.
- **Very large stores**: Shopify's public feed pages are capped, so catalogues above about 25,000 products may be incomplete. Scrape collection by collection instead.

### Is it legal?

It reads the public product feed every Shopify storefront serves to visitors' browsers. It collects product data only, no customer or personal data. You are responsible for how you use the data; respect the store's terms and intellectual property (e.g. don't republish their photos and descriptions as your own).

### FAQ

**How do I know if a site is on Shopify?** Add `/products.json` to its address in your browser. If you see product data, it works.

**Can I monitor prices daily?** Yes. Use Apify Schedules, and `updatedWithinDays: 1` to pay only for products that changed.

**Can I use it from my own code or an AI agent?** Yes, through the Apify API, the Apify MCP server, Make, Zapier or n8n.

**Found a bug?** Open an issue on the Issues tab. We reply quickly.

# Actor input Schema

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

Store home pages or domains (e.g. https://www.allbirds.com) to get the whole catalogue, or collection URLs (e.g. https://www.allbirds.com/collections/mens) to get one collection.

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

0 = the whole catalogue. Use this to cap cost on big stores.

## `onlyAvailable` (type: `boolean`):

Keep only products with at least one variant the store marks as available.

## `onlyOnSale` (type: `boolean`):

Keep only products where a variant's price is below its compare-at price.

## `minPrice` (type: `integer`):

0 = no minimum. In the store's currency.

## `maxPrice` (type: `integer`):

0 = no maximum. In the store's currency.

## `titleKeywords` (type: `array`):

Keep only products whose title contains one of these words.

## `vendors` (type: `array`):

Exact vendor names, useful for multi-brand stores.

## `productTypes` (type: `array`):

e.g. 'Shoes', 'Hoodie'.

## `updatedWithinDays` (type: `integer`):

0 = any. Handy for daily price/stock monitoring of changed products only.

## `includeVariants` (type: `boolean`):

Every size/colour with SKU, price, compare-at price and availability.

## `includeImages` (type: `boolean`):

The first image is always included as imageUrl.

## `includeDescription` (type: `boolean`):

Product description as clean text.

## `maxConcurrency` (type: `integer`):

How many stores are scraped at once.

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

Most stores work without a proxy. If a store returns 403 or 429, enable Apify Proxy (residential).

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.allbirds.com"
    }
  ],
  "maxProductsPerStore": 20,
  "onlyAvailable": false,
  "onlyOnSale": false,
  "minPrice": 0,
  "maxPrice": 0,
  "updatedWithinDays": 0,
  "includeVariants": true,
  "includeImages": true,
  "includeDescription": true,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All products stored in the run's default dataset.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.allbirds.com"
        }
    ],
    "maxProductsPerStore": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("ryumoon-data/shopify-store-products-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 = {
    "startUrls": [{ "url": "https://www.allbirds.com" }],
    "maxProductsPerStore": 20,
}

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

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

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

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.allbirds.com"
    }
  ],
  "maxProductsPerStore": 20
}' |
apify call ryumoon-data/shopify-store-products-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ryumoon-data/shopify-store-products-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/dNzwD65ttIhGhmzEH/builds/YGgzutdMyJDUaghpL/openapi.json
