# Shopify Price & Stock Monitor — Track Any Store (`vertaizen/shopify-price-monitor`) Actor

Shopify price tracker & competitor monitoring via any store's public products.json. Get prices, sale prices, stock & new arrivals in clean JSON. Monitor mode returns only CHANGES — price drops, out-of-stock, restocks & launches. Webhook alerts, pay per result.

- **URL**: https://apify.com/vertaizen/shopify-price-monitor.md
- **Developed by:** [Diego Moragues](https://apify.com/vertaizen) (community)
- **Categories:** E-commerce, AI, Automation
- **Stats:** 2 total users, 1 monthly users, 96.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 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/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 Price & Stock Monitor — Track Prices, Stock & New Products in Any Store

This **Shopify price tracker** and **competitor price monitoring** tool extracts the full product catalog of any Shopify store — prices, sale prices, stock availability, new arrivals — straight from the store's public `products.json` endpoint. No browser, no proxies, no fragile HTML scraping. Point it at your competitors' Shopify stores and get clean, structured **e-commerce pricing data** in seconds. Turn on **monitor mode** and it becomes a **price change alert system**: scheduled runs return only what changed since the last run — price drops, price increases, out-of-stock events, back-in-stock restocks, and newly launched products.

Unlike a plain **Shopify product scraper** that dumps the whole catalog every run, this actor's monitor mode returns **only the changes** — so a scheduled run is a clean, actionable feed of price drops and restocks, not a haystack you have to diff yourself.

### Why a price monitor beats a plain product scraper

| | **This Price & Stock Monitor** | Plain Shopify product scraper |
|---|---|---|
| Full catalog snapshot | ✅ (baseline run) | ✅ |
| Only NEW / CHANGED items on later runs | ✅ `changeType` diff | ❌ Re-dumps everything |
| Price-drop detection | ✅ `price-change` + `priceChangePct` | ❌ Diff it yourself |
| Restock / out-of-stock detection | ✅ `stock-change` | ❌ |
| New-product detection | ✅ `new-product` | ❌ |
| Webhook alerts on change | ✅ Filter by `changeType` | ❌ |
| Proxies / browser | ❌ None needed | Varies |
| Pay-per-result | ✅ | Varies |

- **Nearly every Shopify store exposes `/products.json` publicly** — the same data that powers the storefront, in clean JSON.
- **Real-time competitor pricing** — see price changes the moment your scheduled run fires, not days later via a pricing tool's crawl cycle.
- **Stock-outs are opportunities.** When a competitor's bestseller goes out of stock, that's your window. When your reseller's price drops below MAP, that's your alert.
- **AI-agent ready** — flat input, clean JSON output. Works out of the box via MCP for AI agents and LLM pipelines.

### What you get for each product variant

```json
{
  "store": "www.allbirds.com",
  "productId": 4547069902916,
  "title": "Men's Wool Runners",
  "handle": "mens-wool-runners",
  "url": "https://www.allbirds.com/products/mens-wool-runners",
  "vendor": "Allbirds",
  "productType": "Shoes",
  "variantId": 39250875613252,
  "variantTitle": "10",
  "sku": "WR2MNBG100",
  "price": 110,
  "compareAtPrice": 125,
  "available": true,
  "createdAt": "2020-01-14T10:42:00-05:00",
  "updatedAt": "2026-07-01T08:12:33-04:00",
  "imageUrl": "https://cdn.shopify.com/s/files/1/1104/4168/products/wool-runner.jpg",
  "checkedAt": "2026-07-02T12:00:00.000Z"
}
```

In **monitor mode**, each item additionally carries a `changeType`:

- `baseline` — first run for a store: the whole catalog is output and remembered.
- `new-product` — a variant that wasn't in the catalog last run.
- `price-change` — with `oldPrice`, `newPrice` and `priceChangePct` (e.g. `-12.5` for a 12.5% price drop).
- `stock-change` — with `stockStatus`: `back-in-stock` or `out-of-stock`.

### How to use it

1. **Add stores** — full URLs (`https://www.allbirds.com`) or bare domains (`gymshark.com`).
2. **(Optional) Set a product cap** — `maxProductsPerStore` (default 250, max 2000).
3. **(Optional) Enable monitor mode** and **schedule the actor** (e.g. daily at 6:00). The first run seeds the memory; every run after that outputs only real changes.
4. **Add a webhook** on run-succeeded to push price drops and stock alerts to Slack, email, Zapier, or your repricing engine. Filter on `changeType: "price-change"` with a negative `priceChangePct` to alert on price drops only.

### Use cases

Each of these is a real search buyers make:

- **"Track competitor prices on Shopify"** — monitor rival stores daily and undercut or match automatically with a repricing rule fed by the `price-change` feed.
- **"Get a Slack alert when a competitor drops a price"** — schedule + webhook + `changeType: "price-change"` filter = a message the second a rival cuts a price.
- **"Monitor resellers for MAP violations"** — watch reseller stores and get alerted the moment anyone lists below your minimum advertised price.
- **"Get back-in-stock alerts for a Shopify product"** — catch restocks for buying, or to time a promo against a competitor's stock-out.
- **"Detect a competitor's new product launches"** — `new-product` items reveal a rival's roadmap the day it ships.
- **"Feed Shopify pricing data to an AI agent"** — stream structured pricing to an LLM workflow via the Apify MCP server.

#### MAP compliance monitoring

A high-value use for brands: point the actor at your authorized resellers' Shopify stores in monitor mode, then alert on any `price-change` where `newPrice` falls below your MAP threshold. You get a timestamped, structured record of every violation — the evidence you need to enforce your pricing policy.

### Pricing

Pay per product checked — one event per product variant delivered to the dataset. No subscription, no minimum. Failed stores are never charged.

### FAQ

#### Is it legal to read a store's products.json?

The actor reads the same public, unauthenticated JSON endpoint that powers each store's own storefront and is served to any visitor. No login, no personal data, no rate-limit abuse — requests are throttled to one page per 500 ms with a descriptive user-agent. Review each store's terms and your local regulations for your specific use case.

#### How do I get a Slack alert when a competitor drops a price?

Enable `monitorMode`, schedule the actor (e.g. daily), and attach an Apify [webhook or integration](https://docs.apify.com/platform/integrations) to the run-succeeded event. Because monitor mode emits only changes, filter on `changeType: "price-change"` with a negative `priceChangePct` and route those items to Slack, email, or your repricing tool.

#### Which stores work with this actor?

Any Shopify store with a public `/products.json` endpoint — the vast majority of Shopify stores. If a store is password-protected or has disabled the endpoint, it is reported in the run's `FAILED` record instead (and you're not charged for it).

#### How does monitor mode work exactly?

The actor keeps a per-store map of `{variantId: {price, available}}` in a persistent named key-value store (`SHOPIFY-MONITOR-STATE`). On each run it compares the live catalog against that map and outputs only differences, then updates the map. The very first run for a store outputs the full catalog tagged `changeType: "baseline"` so you have a starting snapshot.

#### How many products can it fetch per store?

Up to 2,000 products per store (`maxProductsPerStore`, default 250). Pagination runs at 250 products per page — Shopify's maximum — with a 500 ms politeness delay between pages. Output rows are per *variant*, so a store with 100 products × 5 sizes yields up to 500 rows.

#### Why do some stores fail?

Three common reasons: the store is password-protected (pre-launch or members-only), the merchant disabled the public `products.json` endpoint, or the domain isn't actually a Shopify store. Failed stores appear in the `FAILED` record with the reason — they never appear in the dataset and are never charged.

#### How do I schedule daily monitoring with alerts?

Create the actor task with your store list and `monitorMode: true`, add a [Schedule](https://docs.apify.com/platform/schedules) (e.g. every morning), then attach a webhook or integration to the run-succeeded event. Every dataset item in a scheduled run is a real change — filter on `changeType` to route price drops, stock-outs and new launches to different channels.

#### Can AI agents use this actor?

Yes — the input schema is flat and agent-friendly, and every Apify actor is consumable via the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp), so agents can call it as a tool ("check if any competitor dropped prices today").

# Actor input Schema

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

Shopify store URLs or bare domains. Examples: `https://www.allbirds.com`, `gymshark.com`. Any store with a public `/products.json` endpoint works (the vast majority of Shopify stores).

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

Safety cap on the number of products fetched per store (each product may have several variants; every variant row counts as one product check).

## `monitorMode` (type: `boolean`):

When enabled, the actor remembers each store's previous prices and stock status and only outputs changes: `new-product`, `price-change` (with old/new price and % change) and `stock-change` (back-in-stock / out-of-stock). The first run seeds the memory and outputs everything as `baseline`. Ideal for scheduled runs with webhook alerts.

## Actor input object example

```json
{
  "stores": [
    "https://www.allbirds.com",
    "gymshark.com"
  ],
  "maxProductsPerStore": 250,
  "monitorMode": false
}
```

# 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": [
        "https://www.allbirds.com",
        "gymshark.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("vertaizen/shopify-price-monitor").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": [
        "https://www.allbirds.com",
        "gymshark.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("vertaizen/shopify-price-monitor").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 '{
  "stores": [
    "https://www.allbirds.com",
    "gymshark.com"
  ]
}' |
apify call vertaizen/shopify-price-monitor --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/dOtXzaCPmdXxs49dK/builds/ApliZ1fdVBt77qI0m/openapi.json
