# Shopify Scraper — Any Store's Full Product Catalog (`glitchbound/shopify-scraper`) Actor

Export the complete catalog of any Shopify store: every product and variant with price, compare-at price, live discount, SKU, stock status, images, tags, vendor and description. Filter by keyword, vendor, type, price range, in-stock or on-sale. Official Shopify endpoint, no key.

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

## Pricing

from $1.40 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Scraper — Any Store's Full Product Catalog

Export the complete catalog of **any Shopify store** — every product, every variant, with live prices and stock.

Uses the `/products.json` endpoint Shopify publishes on every storefront. No key, no login, no headless browser, nothing rendered by JavaScript.

### One row per variant

A shirt in 4 sizes is **4 sellable SKUs** — 4 prices, 4 stock states. That's what you get by default, because "is the medium in stock at $39?" is the question people are actually asking.

Set `oneRowPerProduct: true` to collapse to one row per product with `priceMin` / `priceMax` instead.

### What you get

| Field | Example |
|---|---|
| `title`, `variantTitle`, `sku` | `Men's Cruiser`, `10`, `A12856M080` |
| `price`, `compareAtPrice` | `105.00`, `140.00` |
| **`onSale`, `discountPercent`** | `true`, `25.0` |
| `inStock` | `true` |
| `vendor`, `productType`, `tags` | `Allbirds`, `Shoes`, `[…]` |
| `option1/2/3`, `options` | `Blue`, `10` · `["Color","Size"]` |
| `url`, `image`, `variantImage`, `imageCount` | |
| `description` | plain text, HTML stripped |
| `publishedAt`, `createdAt`, `updatedAt` | |
| `productId`, `variantId`, `grams` | |

`discountPercent` is computed for you — price monitoring shouldn't require arithmetic on your end.

### Filters that actually save you money

Everything below filters **before** billing, and the row cap counts rows *kept*, not scanned — so a narrow filter never comes back empty just because the first 250 products didn't match.

```json
{
  "storeUrls": ["allbirds.com", "gymshark.com"],
  "onSaleOnly": true,
  "inStockOnly": true,
  "minPrice": 20,
  "maxPrice": 150,
  "keywords": ["shoe", "runner"],
  "maxProductsPerStore": 500
}
```

- `keywords` — match on title, type, vendor or tags
- `vendors`, `productTypes` — exact match
- `inStockOnly`, `onSaleOnly`
- `minPrice` / `maxPrice`

### Collections

Set `includeCollections: true` to also get the store's collections with product counts — a fast map of how a competitor organises their catalog.

### Who this is for

- **Competitor & price monitoring** — schedule it daily, diff the prices, catch every discount the day it launches
- **Dropshippers & resellers** — pull a supplier's full catalog with SKUs and stock in one run
- **Market research** — how many SKUs, what price bands, what's sold out
- **Affiliate & deal sites** — `onSaleOnly: true` is a ready-made deals feed
- **AI / dataset builders** — clean structured product data, no HTML parsing

### Pricing

Pay per result. One row = one variant (or one product, or one collection). Stores that fail come back as `error` rows and are **not** charged, and neither is anything removed by your filters.

### Notes

- If a store isn't on Shopify, or has password-protected its storefront, you get a clear `error` row saying exactly that — not a raw HTTP code.
- Shopify caps this endpoint at 250 products per page; the Actor pages automatically up to 10,000 products per store.
- Prices are in the store's own currency. Shopify does not expose the currency code on this endpoint, so check the store if you're mixing regions.
- Set a **max charge per run** in the run options for a hard spend ceiling — the Actor honors it and stops cleanly.

# Actor input Schema

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

Store domains, one per line — e.g. "allbirds.com" or "https://gymshark.com". Any URL from the store works; only the domain is used.

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

Cap on rows returned per store. Counts rows kept after filtering, so filters never make a run come back empty.

## `oneRowPerProduct` (type: `boolean`):

By default you get one row per variant (each size/colour, with its own price and stock). Turn this on to collapse to one row per product with a price range instead.

## `keywords` (type: `array`):

Only keep products whose title, type, vendor or tags contain one of these words.

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

Only keep products from these vendors (exact match, case-insensitive).

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

Only keep these product types, e.g. "Shoes", "T-Shirts" (exact match, case-insensitive).

## `inStockOnly` (type: `boolean`):

Drop sold-out variants.

## `onSaleOnly` (type: `boolean`):

Only variants currently discounted below their compare-at price.

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

Only products at or above this price, in the store's own currency.

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

Only products at or below this price, in the store's own currency.

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

Include the product description as plain text.

## `includeCollections` (type: `boolean`):

Also return the store's collections with product counts — a quick map of how the catalog is organised.

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

Proxy settings. Shopify blocks datacenter IP ranges outright on this endpoint, so residential proxy is the default and is required for most stores — changing it will cause HTTP 429 errors.

## Actor input object example

```json
{
  "storeUrls": [
    "allbirds.com"
  ],
  "maxProductsPerStore": 1000,
  "oneRowPerProduct": false,
  "inStockOnly": false,
  "onSaleOnly": false,
  "includeDescription": true,
  "includeCollections": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Shopify product variants with price, discount and stock status.

# 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": [
        "allbirds.com"
    ]
};

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

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

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/0caTHTWBSlA0SOF6f/builds/P1aWkd8GdbWyFeTau/openapi.json
