# Shopify Price Tracker & Scraper (`insanedev/shopify-price-tracker`) Actor

Scrape any Shopify or WooCommerce store: products, variants, prices, stock, barcodes, apps & theme. Track competitors: only new products, price drops, sales and stock changes since the last run.

- **URL**: https://apify.com/insanedev/shopify-price-tracker.md
- **Developed by:** [Insane Developer](https://apify.com/insanedev) (community)
- **Categories:** E-commerce, 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/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 Price Tracker & Scraper** reads the full public catalogue of any **Shopify or WooCommerce store** — every product and variant with prices, compare-at (sale) prices, stock, barcodes (GTIN/UPC) and inventory counts where the store shows them — and **tracks competitors for you**: after the first run it delivers **only what changed** (new products, price drops and increases, sales starting and ending, sell-outs, restocks, estimated units sold). Add a store row with the store's **theme, installed apps and catalogue KPIs**, and you have a competitor dashboard in one scheduled run.

No browser, no login, no Shopify app to install: enter store domains, get a clean dataset via API, CSV, Excel, JSON or straight into Google Sheets, Slack, Make, n8n or Zapier. You pay only for what you get.

### What does Shopify Price Tracker & Scraper do?

- **Shopify products scraper**: all products and variants from `products.json` — title, vendor (brand), type, tags, prices, compare-at price, availability, SKU, weight, images, publish dates.
- **Shopify competitor price monitoring**: schedule it daily; after the first run you get only change rows — `PRICE_DROP`, `PRICE_INCREASE`, `SALE_STARTED`, `SALE_ENDED`, `NEW_PRODUCT`, `PRODUCT_REMOVED`, `NEW_VARIANT`, `VARIANT_REMOVED`, `OUT_OF_STOCK`, `BACK_IN_STOCK`, `INVENTORY_DECREASE`, `INVENTORY_INCREASE`.
- **Shopify inventory tracker**: turn on *Barcodes & inventory counts* to get per-variant stock (about half of Shopify stores expose it) and **estimated units sold** from inventory decreases between runs.
- **WooCommerce scraper**: the same for WooCommerce stores through the public WooCommerce Store API (prices, sale prices, stock, ratings, categories, brands, variations).
- **Shopify apps & theme detector**: one row per store with the theme, detected apps (Klaviyo, Attentive, Recharge, Okendo, Yotpo, Gorgias, Rebuy, Intelligems, Klarna, Afterpay, 60+ more), web pixels, country, currency, product and collection counts. To find stores by app, country or niche instead of checking stores you already know, use [Shopify Store Leads & Finder](https://apify.com/insanedev/shopify-store-list).
- **Catalogue KPIs**: share of products on sale, median discount, share in stock, price range and median, new products in the last 7 and 30 days, top brands carried.

### Why use it?

- **Competitor price monitoring without a SaaS subscription** — pay per product checked instead of $50+ per competitor per month.
- **Only the signal, not the noise** — change rows instead of a full dump every day; ignore moves under a threshold (e.g. 2%) while small drifts still add up.
- **Market research** — what brands a retailer carries, how often it launches products, how deep its discounts go, which apps it runs.
- **Sales estimates** — inventory decreases between runs show which products actually sell.
- **Product data for your own catalogue** — barcodes (GTIN/UPC), SKUs, variants and images from supplier or brand stores.

### How to use it

1. Click **Try for free** and add store domains to **Stores** (e.g. `allbirds.com`, `deathwishcoffee.com`, any WooCommerce shop).
2. Choose **What to get**: *Products* for the full catalogue, or *Changes since the last run* to track prices.
3. Optional: turn on **Barcodes & inventory counts**, set **Ignore price changes smaller than (%)**.
4. Click **Start**. For tracking, **save it as a task and add a schedule** (daily or hourly) — each task keeps its own memory of what it has already seen.
5. Get the results in the **Output** tab or via API, or connect Google Sheets, Slack, email, Make, n8n or Zapier.

### Input

| Field                 | What it does                                                                                       |
| --------------------- | -------------------------------------------------------------------------------------------------- |
| `stores`              | Shopify or WooCommerce domains or URLs (up to 500 per run); the platform is detected automatically |
| `mode`                | `products` (full catalogue) or `changes` (only what changed since the last run of this tracker)    |
| `maxProductsPerStore` | stop after N products per store (0 = all)                                                          |
| `includeDetails`      | barcodes (GTIN/UPC) and per-variant inventory counts where the store exposes them                  |
| `includeStoreInfo`    | store row: theme, apps, pixels, catalogue KPIs (on by default)                                     |
| `minPriceChangePct`   | change tracking: ignore price moves smaller than this %                                            |
| `trackerKey`          | change tracking: name a tracker so several trackers can watch the same stores                      |

```json
{
    "stores": ["allbirds.com", "www.deathwishcoffee.com"],
    "mode": "changes",
    "includeDetails": true,
    "minPriceChangePct": 2
}
```

### Output

#### Product row

```json
{
    "rowType": "product",
    "store": "deathwishcoffee.com",
    "platform": "shopify",
    "title": "White Chocolate Pistachio Klean Kanteen (20oz)",
    "url": "https://www.deathwishcoffee.com/products/white-chocolate-pistachio-klean-kanteen-20oz",
    "vendor": "Klean Kanteen",
    "productType": "Drinkware",
    "priceMin": 40,
    "priceMax": 40,
    "compareAtPriceMax": null,
    "onSale": false,
    "currency": "USD",
    "available": true,
    "variantsCount": 1,
    "inventoryTotal": null,
    "barcodes": [],
    "publishedAt": "2026-09-25T08:48:06-04:00",
    "variants": [{ "id": "42349075562551", "sku": "UKWHCP26", "price": 40, "available": true, "weightGrams": 907 }]
}
```

#### Change row (change tracking)

```json
{
    "rowType": "change",
    "store": "bestself.co",
    "changeType": "INVENTORY_DECREASE",
    "productTitle": "BestSelf Complete Sticker Pack",
    "variantTitle": "Default Title",
    "oldValue": 105,
    "newValue": 98,
    "delta": -7,
    "estimatedUnitsSold": 7,
    "estimatedRevenue": 104.93,
    "price": 14.99,
    "currency": "USD",
    "previousCheckAt": "2026-09-28T19:05:12.000Z",
    "detectedAt": "2026-09-29T19:05:10.000Z"
}
```

#### Store row

```json
{
    "rowType": "store",
    "store": "deathwishcoffee.com",
    "platform": "shopify",
    "status": "ok",
    "name": "Death Wish Coffee",
    "country": "US",
    "currency": "USD",
    "productsCount": 146,
    "theme": "Dawn",
    "apps": [
        { "name": "Klaviyo", "category": "Email & SMS" },
        { "name": "Postscript", "category": "Email & SMS" },
        { "name": "Rebuy", "category": "Upsell & personalisation" },
        { "name": "Gorgias", "category": "Support & chat" }
    ],
    "pixelsCount": 11,
    "onSaleShare": 0.25,
    "medianDiscountPct": 27.8,
    "newProducts30d": 14,
    "topVendors": [{ "name": "Death Wish Coffee", "products": 7 }]
}
```

Products and changes are in the default dataset (views *Products* and *Changes since the last run*); store rows are in the *Stores* dataset; a run summary (per-store status, counts) is in the `SUMMARY` record. You can download everything as JSON, CSV, Excel, XML or HTML.

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

Pay per event — you never pay for errors, blocked stores or empty results, and no platform usage is added on top.

| Event                                       | Free plan     | Gold plan     |
| ------------------------------------------- | ------------- | ------------- |
| Product row                                 | $2.00 / 1,000 | $1.40 / 1,000 |
| Change row                                  | $2.00 / 1,000 | $1.40 / 1,000 |
| Product checked without a change (tracking) | $0.20 / 1,000 | $0.10 / 1,000 |
| Barcodes & inventory for a product          | $1.00 / 1,000 | $0.70 / 1,000 |
| Store row (theme, apps, KPIs)               | $0.005        | $0.003        |

Examples (Free plan): a 500-product competitor → $1.00 for the catalogue; then tracking it daily costs about **$0.10 a day plus $0.002 per change** — roughly $3–4 a month per competitor. The run stops cleanly at the maximum cost you set.

### Tips

- **Don't know your competitors' domains yet?** Get a list of Shopify stores in your niche and country (with their apps and popularity) from [Shopify Store Leads & Finder](https://apify.com/insanedev/shopify-store-list), then paste the domains here.
- **Track, don't re-scrape**: use *Changes since the last run* on a schedule; the first run is your baseline.
- **One task per competitor set** — each saved task tracks independently (or set `trackerKey`).
- **Noise filter**: `minPriceChangePct` of 1–5 hides penny moves; the old price is kept, so a slow drift is still reported once it adds up.
- **Inventory**: only stores that expose stock return counts; others are reported as unknown (never as zero).
- **Speed**: a catalogue is read in seconds (985 products from 3 stores in 7 s; 26,400 products from 15 stores in about 2 minutes). Barcodes & inventory need one request per product, and Shopify asks bots to slow down to about 1 request per second per store — we respect that, so plan about 1 product per second per store (stores run in parallel).
- Removed products are reported only when the whole catalogue was read (no product limit).

### FAQ

**Which stores work?** Any Shopify store with a standard storefront and any WooCommerce store with the Store API enabled. Headless storefronts (e.g. Shopify Hydrogen) don't publish product JSON and are reported as `unsupported`; stores that block automated requests are reported as `blocked` — we never try to get around a block. Each store row says why.

**Is it legal?** The Actor reads only public, unauthenticated product data — the same JSON Shopify documents for read-only agents in its storefront `agents.md` — with an honest user agent, respecting `robots.txt` and rate limits. It never touches carts, checkouts or accounts and collects no personal data. You are responsible for how you use the data.

**Do I need a Shopify account or app?** No. Nothing is installed in any store.

**Can I use it from AI agents?** Yes — it works through the Apify API and the Apify MCP server.

Found a problem or need a feature? Open an issue in the **Issues** tab — we reply fast.

# Changelog

This Actor's version history is a separate document: https://apify.com/insanedev/shopify-price-tracker/changelog.md

# Actor input Schema

## `stores` (type: `array`):

Shopify or WooCommerce store domains or URLs, one per line (e.g. <code>allbirds.com</code>, <code>https://www.deathwishcoffee.com</code>). The platform is detected automatically; any path in a URL is ignored. Up to 500 stores per run.

## `mode` (type: `string`):

<b>Products</b>: every product with variants, prices, stock status and images.<br><b>Changes since the last run</b>: price tracking. The first run of a tracker delivers the whole catalogue (your baseline); every later run delivers only what changed — new and removed products, price drops and increases, sales starting and ending, out of stock and back in stock, inventory decreases (estimated units sold). Schedule it daily to monitor competitors.

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

Stop after this many products per store. <code>0</code> = the whole public catalogue. In change tracking, removed products are only reported when the whole catalogue is read.

## `includeDetails` (type: `boolean`):

Fetch each product's detail JSON for barcodes and per-variant inventory counts where the store exposes them (about half of Shopify stores do). Needed for <b>inventory decrease / estimated units sold</b> in change tracking. One extra request per product; billed only when it succeeds.

## `includeStoreInfo` (type: `boolean`):

Add one row per store with its theme, detected apps (Klaviyo, Recharge, Okendo, Gorgias, …), web pixels, country, currency and catalogue KPIs: share on sale, sold-out share, price range, new products in the last 7/30 days, top brands carried.

## `minPriceChangePct` (type: `integer`):

Change tracking only. Price increases and drops smaller than this percentage are not reported (e.g. 2 ignores a $0.50 move on a $30 product). Small moves still add up: the old price is kept until the total change crosses the threshold. 0 = report every change.

## `trackerKey` (type: `string`):

Change tracking only. Runs with the same tracker name share their memory of what was already seen. Leave empty to use the saved task (each task tracks on its own) or, without a task, the list of stores.

## `storeConcurrency` (type: `integer`):

How many stores are read at the same time.

## `detailsConcurrency` (type: `integer`):

Parallel detail requests per store (barcodes & inventory). Kept low to be polite; the robots.txt Crawl-delay is always honoured.

## Actor input object example

```json
{
  "stores": [
    "deathwishcoffee.com"
  ],
  "mode": "products",
  "maxProductsPerStore": 20,
  "includeDetails": false,
  "includeStoreInfo": true,
  "minPriceChangePct": 0,
  "storeConcurrency": 5,
  "detailsConcurrency": 3
}
```

# Actor output Schema

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

No description

## `changes` (type: `string`):

No description

## `stores` (type: `string`):

No description

## `summary` (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 = {
    "stores": [
        "deathwishcoffee.com"
    ],
    "maxProductsPerStore": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("insanedev/shopify-price-tracker").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 = {
    "stores": ["deathwishcoffee.com"],
    "maxProductsPerStore": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("insanedev/shopify-price-tracker").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 '{
  "stores": [
    "deathwishcoffee.com"
  ],
  "maxProductsPerStore": 20
}' |
apify call insanedev/shopify-price-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,insanedev/shopify-price-tracker"
        }
    }
}
```

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/oJBu5ByRU2OilkHdy/builds/SaF6kaxjlcrr9Be13/openapi.json
