# Shopify Store Scraper – Products, Prices & Variants (`ninhothedev/shopify-store-scraper`) Actor

Scrape any Shopify store's catalog: products, prices, compare-at prices, variants, SKUs, availability, images and tags. For price monitoring, competitor and dropshipping research.

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

## Pricing

from $0.50 / 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/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 Scraper – Products, Prices & Variants

**Shopify Store Scraper** extracts the full product catalog from any Shopify store: **product titles, prices (min/max), compare-at (sale) prices, variants, SKUs, availability, images, vendor, product type, tags, options (size, color...), descriptions and publish/update dates**. Paste one or many store domains such as `allbirds.com` or `gymshark.com`, optionally limit the run to one collection, and export the products to JSON, CSV, Excel or Google Sheets. It reads each store's public `products.json` feed, so you don't need an API key, a Shopify login or proxies, and you pay only per product.

It's built for e-commerce teams, dropshippers, brands monitoring competitors, pricing analysts, marketplaces and agencies that need clean Shopify product data at scale.

### What data can you extract?

Each product becomes one dataset row:

| Field | Example | Description |
|---|---|---|
| `store` | `allbirds.com` | Store domain |
| `id` | `7340901859408` | Shopify product ID |
| `title` | `Women's Allbirds Flip Flop - Dusty Pink` | Product name |
| `handle` | `womens-allbirds-flip-flop-dusty-pink` | URL handle (slug) |
| `url` | `https://allbirds.com/products/womens-allbirds-flip-flop-dusty-pink` | Product page URL |
| `vendor` | `Allbirds` | Brand / vendor |
| `product_type` | `Shoes` | Shopify product type |
| `tags` | `["allbirds::gender => womens", ...]` | Product tags |
| `price_min` / `price_max` | `25.0` / `25.0` | Lowest and highest variant price |
| `available` | `true` | `true` if at least one variant can be bought |
| `variants` | `[{"id": "42146889039952", "title": "5", "price": "25.00", "sku": "A12513W050", "available": false, "compare_at_price": "50.00"}]` | Every variant with price, SKU, availability and compare-at price |
| `images` | `["https://cdn.shopify.com/s/files/..."]` | All product image URLs |
| `options` | `[{"name": "Size", "values": ["5", "6", "7"]}]` | Option names and values (size, color, material...) |
| `description` | `Sun on your feet. Comfort underneath...` | Description as plain text (HTML removed, max 5,000 characters) |
| `created_at` / `updated_at` / `published_at` | `2026-03-27T14:03:50-07:00` | Product timestamps from Shopify |
| `scraped_at` | `2026-10-15T18:04:55+00:00` | UTC time of the scrape |

### How to use Shopify Store Scraper

1. Add one or more Shopify stores under **Store URLs**. Bare domains (`allbirds.com`), full URLs (`https://www.gymshark.com`) and product or collection page URLs all work, because only the domain is used.
2. Optionally enter a **Collection handle** (for example `mens` from `/collections/mens`) to scrape just that collection, and set **Max products per store**.
3. Click **Start** and download the products as JSON, CSV or Excel, or connect the dataset to Google Sheets, Make, Zapier or n8n. Use **Schedules** for daily or weekly price monitoring.

Example input:

```json
{
  "storeUrls": ["allbirds.com", "https://www.gymshark.com"],
  "collectionHandle": "",
  "maxItemsPerStore": 1000
}
```

The actor pages through the catalog 250 products at a time until the store runs out of products or your limit is reached. If one store fails (not a Shopify store, or `products.json` is blocked), it's skipped and logged, and the other stores still deliver results.

### Output example

Real output from a local test run with the default input (`allbirds.com`). Variants, images and tags are shortened:

```json
{
  "store": "allbirds.com",
  "id": "7340901859408",
  "title": "Women's Allbirds Flip Flop - Dusty Pink",
  "handle": "womens-allbirds-flip-flop-dusty-pink",
  "url": "https://allbirds.com/products/womens-allbirds-flip-flop-dusty-pink",
  "vendor": "Allbirds",
  "product_type": "Shoes",
  "tags": ["allbirds::edition => limited", "allbirds::gender => womens", "allbirds::hue => pink"],
  "created_at": "2026-03-27T14:03:50-07:00",
  "updated_at": "2026-10-15T11:04:55-07:00",
  "published_at": "2026-09-25T16:58:13-07:00",
  "price_min": 25.0,
  "price_max": 25.0,
  "available": true,
  "variants": [
    {
      "id": "42146889039952",
      "title": "5",
      "price": "25.00",
      "sku": "A12513W050",
      "available": false,
      "compare_at_price": "50.00"
    }
  ],
  "images": [
    "https://cdn.shopify.com/s/files/1/1104/4168/files/A12513_26Q2_Allbirds-Flip-Flop-Dusty-Pink_PDP_LEFT.png?v=1774646345"
  ],
  "options": [{ "name": "Size", "values": ["5", "6", "7", "8", "9", "10", "11"] }],
  "description": "Sun on your feet. Comfort underneath. Light, easy, and made for warm weather, these flip flops bring everyday comfort to sunny days, beach walks, and everything in between. Just slip them on and go.",
  "scraped_at": "2026-10-15T18:04:55.891868+00:00"
}
```

### Pricing

This actor uses **pay-per-event** pricing. You pay per product, and variants and images are included at no extra cost:

- **$0.0005 per product** (= **$0.50 per 1,000 products**)
- **$0.00005 per actor start**

Examples:

| Scenario | Products | Cost |
|---|---:|---:|
| One store, default limit | 250 | ≈ $0.13 |
| Full catalog of a mid-size store | 2,000 | ≈ $1.00 |
| 20 competitor stores × 500 products | 10,000 | ≈ $5.00 |
| 10 stores × 500 products, scraped weekly (4 runs/month) | 20,000 | ≈ $10.00 |

There are no proxy or third-party API costs. To cap spend, use **Max products per store**, a **Collection handle**, or Apify's *maximum cost per run*.

### Use cases

- **Competitor price monitoring**: scrape rival stores daily and track `price_min`, `compare_at_price` and availability to spot discounts and stock-outs.
- **Dropshipping and product research**: find bestselling product types, vendors and price points in any niche.
- **Assortment and catalog analysis**: compare product counts, product types, options and launch dates (`published_at`) across brands.
- **Product feeds and catalog migration**: export a store's products, variants, SKUs and images for marketplaces, PIM systems or a store migration.
- **Brand protection and MAP compliance**: check how retailers price and describe your products.
- **Lead generation for agencies and apps**: qualify Shopify merchants by catalog size, vendors and categories.

### Integrations and API

You can run the Shopify scraper from the Apify API, the Apify CLI, or integrations like **Make**, **Zapier**, **n8n**, **Google Sheets**, **Slack**, **Airbyte** and **webhooks**. A typical setup is a daily schedule that writes products to Google Sheets or a database, plus a webhook or Make/Zapier filter that alerts you when a competitor's price changes.

Python example with the official `apify-client`:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("ninhothedev/shopify-store-scraper").call(
    run_input={"storeUrls": ["allbirds.com", "gymshark.com"], "maxItemsPerStore": 500}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["store"], item["title"], item["price_min"], item["available"], len(item["variants"]))
```

### FAQ

**Is it legal to scrape Shopify stores?**
The actor reads only public product data that each Shopify store publishes through its `products.json` endpoint, the same data shown on its product pages. It does not access customer data, orders or admin areas. You're responsible for complying with each store's terms and the laws that apply to you.

**Which stores work?**
Any store running on Shopify that exposes `products.json`, which most stores do. Non-Shopify sites, and stores that block the endpoint, are skipped and reported in the log.

**How many products can I get?**
Up to 10,000 products per store per run (set with **Max products per store**). There's no limit on the number of stores.

**Which currency are prices in?**
The store's default currency, as published in `products.json`. The output has no separate currency field, so check the store if it sells in several currencies.

**Does it return inventory quantities or sales numbers?**
No. Shopify doesn't publish those. You get availability per variant (`available: true/false`), not exact stock levels.

**Do I need proxies?**
No. The actor uses plain HTTPS requests with no proxy costs.

**Can I scrape a single collection?**
Yes. Enter the collection handle (the part after `/collections/` in the URL), and the actor scrapes only that collection in every store you listed.

**Something doesn't work?**
Open an issue on the actor's **Issues** tab with your run ID and the store URL. We usually respond within a day.

### Related actors

- [Amazon Product Scraper](https://apify.com/ninhothedev/amazon-product-scraper): compare Shopify prices with Amazon search results and prices.
- [Trustpilot Reviews Scraper](https://apify.com/ninhothedev/trustpilot-scraper): customer reviews and ratings of e-commerce brands.
- [Website Contact & Email Extractor](https://apify.com/ninhothedev/website-contact-extractor): emails, phone numbers and social profiles of Shopify merchants.
- [JSON-LD Extractor](https://apify.com/ninhothedev/json-ld-extractor): Schema.org product structured data from any web shop.
- [Google Reviews Scraper](https://apify.com/ninhothedev/google-reviews-scraper): Google Maps reviews of retailers and brands.

# Actor input Schema

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

Shopify stores to scrape, one per line. Bare domains (allbirds.com), full URLs (https://www.gymshark.com) and product or collection page URLs all work, because only the domain is used. Stores that aren't on Shopify are skipped and logged.

## `collectionHandle` (type: `string`):

Scrape only one collection in every store: enter the part after /collections/ in the URL, e.g. 'mens' for https://store.com/collections/mens. Leave empty to scrape the whole catalog.

## `maxItemsPerStore` (type: `integer`):

Maximum number of products saved per store (1–10,000). Each product includes all its variants and images. Lower it to cap cost.

## Actor input object example

```json
{
  "storeUrls": [
    "allbirds.com"
  ],
  "maxItemsPerStore": 250
}
```

# Actor output Schema

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

No description

# 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"
    ],
    "maxItemsPerStore": 250
};

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

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ninhothedev/shopify-store-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/DBkLH9sfObU9aaZbW/builds/BuzkMFZHXgldXnbtD/openapi.json
