# Shopify Products Scraper - Prices, Variants, Stock & Images (`pipiagent/shopify-products-scraper`) Actor

Scrape all products of any Shopify store: title, vendor, type, tags, prices and sale prices, variants with SKU and stock, images and description. Whole stores, collections or single products, one row per product or per variant. No login.

- **URL**: https://apify.com/pipiagent/shopify-products-scraper.md
- **Developed by:** [Frank0306](https://apify.com/pipiagent) (community)
- **Categories:** E-commerce, Lead generation, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

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 Products Scraper

Get every product of any [Shopify](https://www.shopify.com) store: title, vendor, product type, tags, prices and sale prices, variants with SKU and stock, options, images and description. Paste a store, a collection or a product link and download one clean table.

Use it for competitor price monitoring, stock and restock tracking, product research and dropshipping, catalog migration, market research across many brands, and feeding product data to AI tools.

- **Any Shopify store.** Custom domains (allbirds.com) and myshopify.com addresses, whole stores, single collections or single products.
- **Prices, discounts and stock.** Lowest and highest price, compare-at price, discount percent, in-stock flag and the number of variants in stock.
- **Product or variant rows.** One row per product with a variants list, or one row per size or color with its own price, SKU and stock, ready for price tracking in a spreadsheet.
- **Filters before you pay.** Keywords, excluded words, in stock only, on sale only, price range and new arrivals. You are charged only for products that match.
- **Fast.** 250 products per request, so a store with 10,000 products takes about a minute.
- **No login, no API key, no proxy.** The Actor reads the public product list that every Shopify store publishes.
- **Low price.** $0.50 per 1,000 results.

### What data can you get?

| Field | Example | Notes |
|---|---|---|
| `storeName`, `storeUrl`, `currency` | Allbirds, https://www.allbirds.com, USD | From the store's public info |
| `productId`, `handle`, `title`, `url` | Women's Allbirds Flip Flop - Dusty Pink | |
| `vendor`, `productType`, `tags` | Allbirds, Shoes | As the store sets them |
| `priceMin`, `priceMax` | 50, 50 | Lowest and highest variant price, in the store's currency |
| `isOnSale`, `maxDiscountPercent` | true, 30 | A variant has a compare-at price above its price |
| `isAvailable`, `variantCount`, `availableVariantCount` | true, 7, 1 | In-stock flags as shown on the store |
| `options` | Size: 5, 6, 7... | Option names and values |
| `variants` | | Each variant's ID, title, SKU, price, compare-at price, stock flag, options, weight and image |
| `imageUrl`, `images` | | Main image and all image URLs |
| `publishedAt`, `createdAt`, `updatedAt` | 2026-09-25T23:58:13Z | ISO 8601 UTC |
| `description`, `descriptionHtml` | | Plain text by default, HTML optional |

In **Variant** mode every row has the product fields plus `variantId`, `variantTitle`, `sku`, `price`, `compareAtPrice`, `isAvailable`, `option1Name`/`option1` to `option3Name`/`option3`, `weightGrams` and `variantImage`.

### How to use it

1. Click **Try for free**.
2. Add one or more stores, collections or products to **Store URLs**.
3. Optional: choose **Variant** rows, or add filters such as keywords, on sale only or a price range.
4. Click **Start**, then download the results as JSON, CSV or Excel, or read them through the API.

To track prices or stock, create a schedule in Apify (for example every morning) and compare the runs.

### Input examples

All products of two stores:

```json
{
    "storeUrls": ["https://www.allbirds.com", "https://kyliecosmetics.com"]
}
```

One row per variant of a collection, in stock only, for price and stock tracking:

```json
{
    "storeUrls": ["https://www.allbirds.com/collections/mens"],
    "outputMode": "variants",
    "availableOnly": true
}
```

Products on sale between 20 and 100, published in the last 30 days:

```json
{
    "storeUrls": ["colourpop.com"],
    "onSaleOnly": true,
    "minPrice": "20",
    "maxPrice": "100",
    "publishedWithinDays": 30
}
```

### Output example

```json
{
    "storeName": "Allbirds",
    "storeUrl": "https://www.allbirds.com",
    "currency": "USD",
    "productId": 7340901859408,
    "handle": "womens-allbirds-flip-flop-dusty-pink",
    "title": "Women's Allbirds Flip Flop - Dusty Pink",
    "vendor": "Allbirds",
    "productType": "Shoes",
    "tags": ["allbirds::gender => womens", "allbirds::hue => pink", "allbirds::material => sugar"],
    "url": "https://www.allbirds.com/products/womens-allbirds-flip-flop-dusty-pink",
    "priceMin": 50,
    "priceMax": 50,
    "isOnSale": false,
    "maxDiscountPercent": null,
    "isAvailable": true,
    "variantCount": 7,
    "availableVariantCount": 1,
    "options": [{"name": "Size", "values": ["5", "6", "7", "8", "9", "10", "11"]}],
    "imageUrl": "https://cdn.shopify.com/s/files/1/1104/4168/files/A12513_26Q2_Allbirds-Flip-Flop-Dusty-Pink_PDP_LEFT.png?v=1774646345",
    "publishedAt": "2026-09-25T23:58:13Z",
    "createdAt": "2026-03-27T21:03:50Z",
    "updatedAt": "2026-11-01T17:27:30Z",
    "variants": [
        {
            "variantId": 42146889039952,
            "variantTitle": "5",
            "sku": "A12513W050",
            "price": 50,
            "compareAtPrice": null,
            "isAvailable": false,
            "option1Name": "Size",
            "option1": "5",
            "weightGrams": 455
        }
    ],
    "description": "Sun on your feet. Comfort underneath. Light, easy, and made for warm weather..."
}
```

### How much does it cost?

You pay per saved result: **$0.50 per 1,000 results**. A result is one product, or one variant in Variant mode. There is no start fee and no monthly rental.

| Run | Results | Cost |
|---|---|---|
| A store with 300 products | 300 | $0.15 |
| A store with 10,000 products | 10,000 | $5.00 |
| Daily price check of 1 collection (60 variants) for a month | 1,800 | $0.90 |

Set a maximum charge per run in the run options and the Actor stops when it is reached.

### Limits you should know

- **Shopify stores only.** The Actor reads the public product list (`/products.json`) that Shopify stores publish. Sites on other platforms, password-protected stores and a few stores with custom storefronts that turn the list off are reported in the log and skipped.
- **Stock is a yes/no flag.** Shopify's public list says whether a variant can be bought, not how many units are left.
- **Prices are in the store's main currency**, without taxes, as the store sets them. International prices shown to visitors from other countries are not included.
- **Only published products.** Drafts and products hidden from the online store are not visible.
- **This is unofficial.** The Actor is not made by, endorsed by or connected to Shopify or the stores.

### Related Actors

- [AliExpress Search Scraper](https://apify.com/pipiagent/aliexpress-search-scraper): products, prices, orders and ratings from AliExpress search.
- [Alibaba Search Scraper](https://apify.com/pipiagent/alibaba-search-scraper): wholesale products, prices, minimum orders and suppliers.
- [Website Contact Scraper](https://apify.com/pipiagent/website-contact-scraper): emails, phone numbers and social links of the stores.

### FAQ

**Is it legal?** The Actor reads only product data that Shopify stores publish for every visitor. It does not log in and does not collect customer data. Respect the stores' copyright if you republish their descriptions and images.

**Can it find Shopify stores for me?** No. Add the stores you want; any Shopify store URL works.

**Something is broken or missing?** Open a ticket in the Issues tab. Issues are usually answered within a day.

# Actor input Schema

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

One per line: a store (https://www.allbirds.com or allbirds.com), a collection (https://www.allbirds.com/collections/mens) or a single product (.../products/handle). Custom domains and myshopify.com addresses both work.

## `outputMode` (type: `string`):

Product: one row per product, with its variants in a list. Variant: one row per size or color, with its own price, SKU and stock - best for price and stock tracking in a spreadsheet.

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

Stop after this many results from each store. Leave empty for all.

## `maxItems` (type: `integer`):

Stop after this many results in total. Leave empty for all.

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

Keep products whose title, product type, vendor or tags contain one of these. Every word of a phrase must appear. Whole words only.

## `excludeKeywords` (type: `array`):

Skip products whose title contains one of these, for example "gift card".

## `availableOnly` (type: `boolean`):

Keep only products with at least one variant in stock. In Variant rows mode, keep only the variants in stock.

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

Keep only products with a reduced price (a compare-at price above the price). In Variant rows mode, keep only the reduced variants.

## `minPrice` (type: `string`):

Keep products that cost at least this much, in the store's currency.

## `maxPrice` (type: `string`):

Keep products whose lowest price is at most this much, in the store's currency.

## `publishedWithinDays` (type: `integer`):

Keep only products published in the last N days (new arrivals).

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

In Product mode, add the list of variants with price, SKU, options and stock.

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

Add the product description as plain text.

## `includeDescriptionHtml` (type: `boolean`):

Also add the original description HTML.

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

Not needed for most stores. Use the Apify datacenter proxy if a store limits your requests.

## Actor input object example

```json
{
  "storeUrls": [
    "https://www.allbirds.com",
    "https://kyliecosmetics.com/collections/lips"
  ],
  "outputMode": "products",
  "maxItems": 100,
  "availableOnly": false,
  "onSaleOnly": false,
  "includeVariants": true,
  "includeDescription": true,
  "includeDescriptionHtml": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Products (or variants) saved by the run.

# 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",
        "https://kyliecosmetics.com/collections/lips"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("pipiagent/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",
        "https://kyliecosmetics.com/collections/lips",
    ],
    "maxItems": 100,
}

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

```

## MCP server setup

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