# Shopify Product Scraper (`rebra_api/shopify-product-scraper`) Actor

Scrape every product from any Shopify store — title, price, variants, SKUs, images, tags and dates — straight from the public product feed. One row per product or per variant. No login, no browser. Perfect for price research, dropshipping and catalogue imports.

- **URL**: https://apify.com/rebra_api/shopify-product-scraper.md
- **Developed by:** [Arber Lutolli](https://apify.com/rebra_api) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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 Product Scraper

Scrape **every product from any Shopify store** — no login, no browser automation, no manual work.

Give it store addresses like `allbirds.com`; get back a clean row for every product: title, price range, variants, SKUs, images, tags, vendor, product type and dates. Export to CSV, Excel, JSON or pull it via the API.

Perfect for dropshippers, competitor and price research, catalogue imports, market analysis and feeding product data into your own app.

### What it does

For each Shopify domain you provide, the Actor:

1. Reads the store's **public product feed** (`products.json`) — the fixed address every Shopify store exposes, no login required.
2. Pages through the **entire catalogue** (or up to your limit).
3. Returns a clean, structured row for **every product** — or, if you prefer, **one row per variant** (SKU-level), so each size/colour has its own price and stock status.

Headless (Hydrogen/Oxygen) stores are handled automatically via their `*.myshopify.com` domain. It uses plain HTTPS requests through Apify Proxy — **no headless browser** — so runs are fast and cheap.

### Input

| Field | Meaning |
|---|---|
| **Shopify store domains or URLs** | One per line, e.g. `allbirds.com`. |
| **One row per variant (SKU-level)** | Off = one row per product. On = one row per variant (size/colour/SKU). |
| **Include product description text** | Adds a plain-text description to each row. On by default. |
| **Max products per store** | Cap per store. `0` = all products. |
| **Stores processed at once** | Concurrency. 5 is a safe default. |
| **Proxy** | Apify Proxy. **Residential** gives the best hit rate. |

### Output (one row per product)

```json
{
  "recordType": "product",
  "domain": "allbirds.com",
  "productTitle": "Men's Wool Runners",
  "handle": "mens-wool-runners",
  "productUrl": "https://allbirds.com/products/mens-wool-runners",
  "vendor": "Allbirds",
  "productType": "Shoes",
  "tags": ["wool", "everyday"],
  "priceMin": 98.0,
  "priceMax": 110.0,
  "price": 98.0,
  "variantCount": 24,
  "available": true,
  "optionNames": ["Size", "Color"],
  "imageCount": 6,
  "image": "https://cdn.shopify.com/...",
  "descriptionText": "Our iconic everyday shoe...",
  "createdAt": "2020-02-01T00:00:00-05:00",
  "updatedAt": "2026-10-18T09:12:00-04:00",
  "publishedAt": "2020-02-03T00:00:00-05:00"
}
```

In **variant mode** each row instead carries `variantId`, `variantTitle`, `sku`, `price`, `compareAtPrice`, `available`, `option1/2/3`, `weightGrams` and `barcode`.

### Good to know

- **Shopify only.** Non-Shopify domains return a short `error` row (and aren't charged). Need WooCommerce or contact/lead data too? See the **Shopify & WooCommerce Store Leads** Actor.
- **Pricing** is pay-per-result: you're charged per product (or per variant row) returned.
- `products.json` doesn't expose currency, so `currency` is `null` — prices are in the store's own currency.

### Use cases

- Competitor and **price monitoring** across stores.
- **Dropshipping / catalogue import** into your own store or app.
- Market and assortment research (what sells, at what price, in what categories).
- Feed product data into a spreadsheet, database or pricing tool.

### FAQ

**Can I export products from a Shopify store I don't own?**
Yes. Every Shopify store exposes a public `products.json` feed, so you don't need admin access, a password or an app — just the store's web address.

**How is this different from Shopify's built-in export?**
Shopify's built-in export only works for *your own* store, one store at a time, and large exports get emailed to you. This scrapes **any** store, **many at once**, and delivers CSV / Excel / JSON or a live API feed.

**What fields do I get for each product?**
Title, handle, URL, vendor, product type, tags, price range, variant count, SKUs, availability, images and dates — or switch to **one row per variant** for full SKU-level detail.

**Does it work on every Shopify store?**
Most of them. Headless (Hydrogen / Oxygen) stores are handled automatically via their `*.myshopify.com` domain. A small share sit behind Cloudflare challenges and may not return data.

**Can I track competitor prices over time?**
Yes — schedule the Actor to re-run and record price and stock changes across your list of stores.

# Actor input Schema

## `domains` (type: `array`):

One per line, e.g. allbirds.com. Full URLs are fine — only the domain is used.

## `oneRowPerVariant` (type: `boolean`):

Off = one row per product (default). On = one row per variant, so each size/colour/SKU is its own row with its own price and availability.

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

Adds a plain-text (HTML-stripped) product description to each row.

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

Limit how many products to pull from each store. 0 = all of them.

## `concurrency` (type: `integer`):

Higher is faster but heavier. 5 is a safe default for product scraping (many pages per store).

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

Routes requests through Apify Proxy so the store feed doesn't rate-limit you. RESIDENTIAL gives the best hit rate. Proxy usage is billed to whoever runs the Actor.

## Actor input object example

```json
{
  "domains": [
    "allbirds.com",
    "ridgewallet.com"
  ],
  "oneRowPerVariant": false,
  "includeDescription": true,
  "maxProductsPerStore": 0,
  "concurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

One row per product (or per variant): price, variants, images, tags and dates.

# 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 = {
    "domains": [
        "allbirds.com",
        "ridgewallet.com"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("rebra_api/shopify-product-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 = {
    "domains": [
        "allbirds.com",
        "ridgewallet.com",
    ],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("rebra_api/shopify-product-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 '{
  "domains": [
    "allbirds.com",
    "ridgewallet.com"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call rebra_api/shopify-product-scraper --silent --output-dataset

```

## MCP server setup

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