# Shopify Products Scraper (`automly/shopify-products-scraper`) Actor

Scrape public Shopify store catalogs into flat product records — title, price range, variants, images, availability, and timestamps — from any store's public products.json and collection endpoints. Built for price monitoring, catalog research, and AI/LLM pipelines.

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

## Pricing

from $1.55 / 1,000 results

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 web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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 Products Scraper — Prices, Variants, Images & Stock 🛍️

**Scrape any public Shopify store's full product catalog** — titles, prices, variants, SKUs, images, availability, tags, and timestamps — as clean, flat **JSON or CSV**. No API key, no login, no Shopify app. Point it at one or more store URLs and get a structured product dataset ready for **price monitoring, competitor analysis, catalog research, and AI/LLM pipelines**.

### What does Shopify Products Scraper do?

Give it any Shopify store URL (or a specific collection) and it returns every product as one clean row. It reads the store's **public** storefront data directly — so you get complete, accurate fields without scraping rendered HTML or fighting a browser.

- Scrape **all products** from a Shopify store
- Scrape a specific **collection** (e.g. `mens-shoes`)
- Get **full variants** — price, compare-at price, SKU, options, per-variant stock
- Get **all product images**
- **Filter** by price range and in-stock availability, server-side
- Scrape **many stores** in one run
- Export to **JSON, CSV, Excel, or XML**

### How to scrape Shopify products without the API

Shopify's official API needs a custom app, OAuth, and store permission you don't have for stores you don't own. This actor skips all of that — it reads each store's **public** `products.json` and collection endpoints, the same data the storefront serves to anyone. **No API key, no login, no access token.**

If a store has disabled its public JSON, the actor automatically **falls back to the XML product sitemap** and per-product JSON — so it keeps working on stores where simpler scrapers return nothing.

### What data can you extract from a Shopify store?

Each product record includes:

| Field | Description |
|-------|-------------|
| `title`, `handle`, `productUrl` | Product name, slug, and canonical URL |
| `productId` | Shopify numeric product id |
| `vendor`, `productType`, `tags` | Brand, type, and tags |
| `priceMin` / `priceMax` | Lowest / highest variant price (real decimals — **not** ×100) |
| `compareAtPriceMin` | Original price when the product is on sale |
| `currency` | Store currency code (e.g. `USD`) |
| `available` | `true` when at least one variant is in stock |
| `variantCount`, `variants` | Per-variant id, title, SKU, price, compare-at, options, stock |
| `imageUrls` | All product image URLs |
| `createdAt`, `updatedAt`, `scrapedAt` | Product create/update + scrape timestamps |

### Shopify scraping use cases

- **Price monitoring** — track competitor prices and discounts across stores
- **Competitor analysis** — compare catalogs, variants, vendors, and tags
- **Catalog research & enrichment** — build product datasets for your own apps
- **Inventory tracking** — watch stock status and new product launches
- **Market research** — see how brands structure products, pricing, and metadata
- **AI / LLM pipelines** — feed clean product data into search, RAG, or agents

### How to scrape a Shopify store

1. Click **Try for free**.
2. Add one or more **Store URLs** (a bare domain like `allbirds.com`, the home page, or any product/collection URL — only the store origin is used).
3. (Optional) Add **collection** handles/URLs to scrape just those.
4. Set **Max products per store**, and optional **price** / **in-stock** filters.
5. Click **Start**. Download the results as JSON, CSV, or Excel, or pull them via the API.

#### Example input

```json
{
  "storeUrls": ["https://www.allbirds.com", "https://www.kith.com"],
  "collections": [],
  "maxProductsPerStore": 500,
  "includeVariants": true,
  "includeImages": true,
  "onlyAvailable": true,
  "minPrice": 20,
  "useApifyProxy": true
}
```

### Input parameters

| Field | Type | Description |
|-------|------|-------------|
| `storeUrls` | array (required) | Shopify store URLs. Bare domain, home page, or any product/collection URL. |
| `collections` | array | Optional collection handles or URLs. Scrapes only these, on every store. |
| `maxProductsPerStore` | integer | Max products per store, after filtering. Default `1000`. |
| `includeVariants` | boolean | Include the full variant list. Default `true`. |
| `includeImages` | boolean | Include image URLs. Default `true`. |
| `onlyAvailable` | boolean | Skip products with no in-stock variant. Default `false`. |
| `minPrice` / `maxPrice` | integer | Keep products whose lowest price is within this range. |
| `useApifyProxy` | boolean | Route through Apify Proxy. Default `true`. |
| `proxyGroups` | array | Specific proxy groups (e.g. `RESIDENTIAL`). |

### Output example

```json
{
  "storeUrl": "https://www.allbirds.com",
  "productId": 123456789,
  "title": "Wool Runner",
  "handle": "wool-runner",
  "productUrl": "https://www.allbirds.com/products/wool-runner",
  "vendor": "Allbirds",
  "productType": "Shoes",
  "tags": ["wool", "mens"],
  "priceMin": 98.0,
  "priceMax": 102.5,
  "compareAtPriceMin": 110.0,
  "currency": "USD",
  "available": true,
  "variantCount": 2,
  "variants": [
    { "variantId": 2, "title": "9 / Grey", "sku": "WR-9-GRY", "price": 102.5, "compareAtPrice": 110.0, "available": true, "options": ["9", "Grey"] }
  ],
  "imageUrls": ["https://cdn.shopify.com/a.jpg"],
  "createdAt": "2025-01-01T10:00:00-08:00",
  "updatedAt": "2026-06-01T10:00:00-07:00",
  "scrapedAt": "2026-06-20T12:00:00Z"
}
```

### Why this Shopify scraper

- **Clean prices** — real decimal values (`98.00`), not raw integers multiplied by 100 that you have to divide yourself.
- **Robust** — automatic XML sitemap fallback when a store disables `products.json`, so it works where lighter scrapers fail.
- **Built-in filters** — price range and in-stock filtering happen server-side, so your dataset only contains the products you asked for.
- **Multi-store** — scrape a whole list of competitors in a single run.
- **No API key, no login** — just URLs in, structured data out.

### How much does it cost to scrape Shopify?

The actor reads Shopify's bulk `products.json` (up to 250 products per request), so it's fast and cheap — most of the cost is a small amount of Apify platform compute. Start with the free trial to measure the exact cost for your volume, then scale up.

### How do I know if a website is built on Shopify?

Visit `https://thestore.com/admin`. If you land on a **Shopify login page**, the store runs on Shopify and this actor can scrape it. You can also append `/products.json` to the store URL — if it returns product JSON, you're good.

### FAQ

**Do I need a Shopify API key or app?**
No. The actor reads each store's public storefront data — no API key, no OAuth, no app install.

**Can I scrape a single collection instead of the whole store?**
Yes. Add the collection handle (`mens-shoes`) or full collection URL to `collections`.

**Why are the prices "clean" and not multiplied by 100?**
We return real decimal prices (`19.99`). Some scrapers return Shopify's raw integer cents (`1999`) and leave you to divide — this one doesn't.

**What if a store disabled its `products.json`?**
The actor automatically falls back to the store's XML product sitemap and per-product JSON. If every public endpoint is blocked, it returns nothing for that store.

**Can I scrape many stores at once?**
Yes — pass a list of store URLs and they're all scraped in one run.

**What export formats are supported?**
JSON, CSV, Excel, and XML — from the Storage tab or the Apify API.

**Can I monitor prices on a schedule?**
Yes. Schedule the actor in the Apify Console to re-run on an interval and diff the results.

### Related actors

Pair this with other e-commerce and web scrapers in the Apify Store to combine Shopify catalog data with marketplaces, reviews, and competitor sources.

# Actor input Schema

## `storeUrls` (type: `array`):

Public Shopify store URLs to scrape (one per line). Accepts a bare domain (allbirds.com), the store home page, or any product/collection URL — only the store origin is used. Each store's public products.json (and collection endpoints, if set) is read.

## `collections` (type: `array`):

Optional. Collection handles or collection URLs to scrape instead of the whole catalog (for example: mens-shoes, or https://www.allbirds.com/collections/mens-shoes). When set, only products in these collections are fetched, applied to every store. Leave empty to scrape all products.

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

Maximum number of products to collect from each store (after filtering). Use a small number for quick tests and a larger one for a full catalog export.

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

When enabled, each product record includes the full list of variants (price, compare-at price, SKU, options, availability). Disable for a lighter record with only the aggregate price range.

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

When enabled, each product record includes the list of product image URLs. Disable to omit image URLs.

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

When enabled, products with no purchasable (in-stock) variant are skipped.

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

Optional. Only keep products whose lowest variant price is at least this value (in the store's currency). Leave empty for no lower bound.

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

Optional. Only keep products whose lowest variant price is at most this value (in the store's currency). Leave empty for no upper bound.

## `useApifyProxy` (type: `boolean`):

Route requests through Apify Proxy. Recommended — it reduces the chance of being rate-limited by a store. Disable to connect directly.

## `proxyGroups` (type: `array`):

Optional. Specific Apify Proxy groups to use (for example: RESIDENTIAL). Leave empty to use the default datacenter proxy. Only applies when 'Use Apify Proxy' is enabled.

## Actor input object example

```json
{
  "storeUrls": [
    "https://www.allbirds.com"
  ],
  "maxProductsPerStore": 1000,
  "includeVariants": true,
  "includeImages": true,
  "onlyAvailable": false,
  "useApifyProxy": true
}
```

# Actor output Schema

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

All product records produced by this run.

## `overview` (type: `string`):

Dataset presented using the overview view.

# 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 = {
    "storeUrls": [
        "https://www.allbirds.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("automly/shopify-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 = { "storeUrls": ["https://www.allbirds.com"] }

# Run the Actor and wait for it to finish
run = client.actor("automly/shopify-products-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 '{
  "storeUrls": [
    "https://www.allbirds.com"
  ]
}' |
apify call automly/shopify-products-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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