Shopify Price Tracker & Stock Monitor - New Products avatar

Shopify Price Tracker & Stock Monitor - New Products

Under maintenance

Pricing

from $2.10 / 1,000 detected changes

Go to Apify Store
Shopify Price Tracker & Stock Monitor - New Products

Shopify Price Tracker & Stock Monitor - New Products

Under maintenance

Shopify price tracker and stock monitor. Each run compares the store's public catalog with the last run and returns only what changed: new products, price drops and increases, sell-outs, restocks, removals. Pay per change. No login or browser. No stock quantities. Not affiliated with Shopify.

Pricing

from $2.10 / 1,000 detected changes

Rating

0.0

(0)

Developer

Muhammet Mustafa Dincer

Muhammet Mustafa Dincer

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

an hour ago

Last modified

Security

Limited permissions

Share

Shopify Store Monitor: change types NEW_PRODUCT, PRICE_DROP, PRICE_INCREASE, OUT_OF_STOCK, BACK_IN_STOCK and REMOVED_PRODUCT for public Shopify stores

What is Shopify Store Monitor?

Shopify Store Monitor is an Apify Actor that tracks public Shopify stores and returns only what changed since your last run: new products, price drops, price increases, sold-out products, restocks and removed products. Enter one or more store domains, click Start, and from the second run on you get one row per detected change instead of another full catalog dump.

It works as a Shopify price tracker, a Shopify stock monitor, a restock alert and a new product alert in one tool. It needs no login, no browser and no API key. It reads the catalog that every Shopify store publishes at /products.json, so a store with 1,000 products is checked in a few seconds. You pay a small fee per store checked and a fee per detected change, not per catalog product.

Quick answer: when should you (or an AI agent) pick this Actor?

Pick Shopify Store Monitor when the goal is to notice changes in one or more Shopify stores over time: competitor price monitoring, restock and sell-out alerts, new product launches, or a supplier catalog watch. Run it on a schedule and read only the change rows.

Pick something else when you need exact stock quantities, sales or revenue estimates, reviews, store owner contacts, full product descriptions, or stores that are not built on Shopify. This Actor does not return any of those.

Defaults that work: send {"stores": ["allbirds.com"]}. The first run saves a baseline and returns no changes. Run the same input again later to receive the changes. Keep the same monitorName between runs, because runs with the same name compare against each other.

At a glance

DoesCompares each store's public catalog with the previous run and returns only the differences. A second mode lists all products of a store as they are now
Inputstores (required, up to 200 domains or URLs). Optional: mode, changeTypes, minPriceChangePercent, keyword filters, monitorName
OutputOne row per detected change: changeType, title, price, previousPrice, priceChangePercent, available, url, variantChanges, detectedAt. One summary row per store
Change typesNEW_PRODUCT, PRICE_DROP, PRICE_INCREASE, OUT_OF_STOCK, BACK_IN_STOCK, REMOVED_PRODUCT
NeedsNo login, no API key, no browser. Apify Proxy is optional
SpeedAbout 250 products per request. A store with 1,000 products takes a few seconds
PricingPay per event. Free plan: $0.001 per run, $0.002 per 1,000 products checked, $0.003 per detected change. A run without changes costs only the start and scan fees
Does notStock quantities, sales or revenue estimates, reviews, store owner contacts, product descriptions or full-size image lists

Key terms used in this README

  • Baseline: the saved snapshot of a store's catalog from the previous run. The first run of a store only saves a baseline.
  • Detected change: one new product, price change, sell-out, restock or removed product found by comparing the current catalog with the baseline. Each detected change is one billable event and one change row.
  • Change row: a dataset row with recordType: "change". It is flat and self-contained, so it can be sent to a webhook as it is.
  • Store row: a dataset row with recordType: "store". One per store and run, with the outcome (status) and the number of products and changes.
  • Watchlist: a named baseline, set with monitorName. Use one watchlist per purpose, for example competitors and suppliers.

What can you use it for?

Competitor price monitoring

Add the stores of your competitors and schedule a daily run. You get a PRICE_DROP or PRICE_INCREASE row only when a price moves, with previousPrice, price and priceChangePercent. Set minPriceChangePercent to 1 to 5 to ignore moves of a few cents.

{
"stores": ["competitor-one.com", "competitor-two.com"],
"changeTypes": ["PRICE_DROP", "PRICE_INCREASE"],
"minPriceChangePercent": 2,
"monitorName": "competitors"
}

Restock and sell-out alerts

Watch a store or a single collection and report OUT_OF_STOCK and BACK_IN_STOCK. Stock is a yes/no flag: a product is out of stock when none of its variants can be bought. Hourly runs make sense for limited drops.

{
"stores": ["https://example-store.com/collections/limited-edition"],
"changeTypes": ["OUT_OF_STOCK", "BACK_IN_STOCK"],
"monitorName": "restock-alerts"
}

New product and launch tracking

Report every NEW_PRODUCT that a brand adds, and every REMOVED_PRODUCT it drops. Use Only watch products matching to follow one product line.

{
"stores": ["brand-store.com"],
"changeTypes": ["NEW_PRODUCT", "REMOVED_PRODUCT"],
"includeKeywords": ["sneaker"],
"monitorName": "launches"
}

Supplier and dropshipping catalog watch

Keep a separate watchlist for your suppliers to learn when an item is delisted, goes out of stock or changes cost. A separate monitorName keeps these baselines apart from your competitor watchlist.

Data for spreadsheets, repricing tools and alerts

Every change row has the store, product, URL, old and new price and old and new availability. Send the rows to Google Sheets, a repricing script, a Slack channel or your own database. See the automation recipes below.

How does it work?

  1. First run (baseline). The Actor downloads the store's catalog and saves a compact snapshot in a named key-value store in your own Apify account (shopify-store-monitor-state). You get one store row per store with status baseline_saved. A baseline run is charged only the start fee and the catalog scan fee, never a change fee. If the run is not allowed to create that named store, it does not crash. Apify's automated store test uses a token that answers the create call with HTTP 403 (insufficient-permissions). The Actor then writes the snapshot to this run's default key-value store and still checks the catalog. That copy is not kept for the next run, so the check is a first baseline. A run that can create the named store keeps using it.
  2. Next runs (compare). The Actor downloads the catalog again, compares it with the baseline and writes one change row per detected change. Then it saves the new baseline.
  3. Schedule it. Put the Actor on a daily or hourly schedule in the Apify Console, or call it from your own system. Every run reports the changes since the previous run.

Use the Watchlist name field to keep several independent watchlists on the same stores.

What changes does it detect?

changeTypeMeaning
NEW_PRODUCTA product that was not in the previous baseline
PRICE_DROPAt least one variant got cheaper. price and previousPrice show the variant with the biggest move; variantChanges lists all
PRICE_INCREASEAt least one variant got more expensive (same fields)
OUT_OF_STOCKThe product had at least one variant in stock before and has none now
BACK_IN_STOCKThe product had no variant in stock before and has at least one now
REMOVED_PRODUCTA product that is no longer in the public catalog (deleted, unpublished or hidden)

One product can produce several rows in one run, for example a price drop and a restock. Use Minimum price change (%) to ignore tiny price moves.

How to monitor a Shopify store (step by step)

  1. Open the Actor and click Try for free.
  2. Enter one or more store domains, for example allbirds.com. A collection URL such as https://allbirds.com/collections/mens watches only that collection.
  3. Keep Mode on Changes since the last run and click Start. This first run saves the baseline.
  4. Run it again later, or open Schedules and run it every day. Download the results from the Output tab or read them through the API.

To see all products of a store instead, set Mode to Snapshot (full product list). Snapshot mode does not compare and does not save anything.

Input

{
"stores": ["allbirds.com", "colourpop.com"],
"mode": "changes",
"changeTypes": ["PRICE_DROP", "BACK_IN_STOCK", "NEW_PRODUCT"],
"minPriceChangePercent": 5,
"monitorName": "competitors"
}
FieldWhat it does
storesStore domains or URLs, one per line. Collection URLs are supported. Up to 200 per run
modechanges (default) or snapshot
changeTypesWhich changes to report. Changes you leave out are not charged and are not reported later
minPriceChangePercentIgnore price moves smaller than this percentage
includeKeywords, excludeKeywordsWatch only matching products, or skip matching ones (title, brand, type, tags). Changing them saves a new baseline
monitorNameName of the saved baseline, to keep separate watchlists
maxProductsPerStoreProduct limit per store (default 5,000, maximum 50,000)
includeVariantsSnapshot mode: add SKU, price and availability of every variant
respectRobotsTxtOn by default: stores whose robots.txt disallows the catalog are skipped and not charged
requestsPerSecondSpeed per store (default 2)
proxyConfigurationOptional Apify Proxy

Output

Example output of Shopify Store Monitor in snapshot mode: a table of products from allbirds.com with type, price, stock status and variants count

Real run, mode snapshot, store allbirds.com. First 8 of 337 products.

The default dataset has three kinds of rows, told apart by recordType: change, store and product (snapshot mode only). Field names and changeType values are treated as a stable contract: new fields can be added, but existing names are not renamed without a version bump and a note in the changelog.

A change row (values are illustrative):

{
"recordType": "change",
"changeType": "PRICE_DROP",
"store": "allbirds.com",
"productId": "7340901859408",
"handle": "mens-tree-runner-go",
"title": "Men's Tree Runner Go - Basin Blue",
"vendor": "Allbirds",
"productType": "Shoes",
"url": "https://allbirds.com/products/mens-tree-runner-go",
"currency": "USD",
"price": 98,
"previousPrice": 110,
"priceChangePercent": -10.91,
"compareAtPrice": 110,
"available": true,
"previousAvailable": true,
"variantsCount": 13,
"variantChanges": [
{ "variantId": "41384771862608", "variantTitle": "9", "sku": "TR3MBB090", "previousPrice": 110, "price": 98, "priceChangePercent": -10.91, "previousAvailable": true, "available": true }
],
"detectedAt": "2026-11-03T08:00:04.120Z",
"previousCheckedAt": "2026-11-02T08:00:03.870Z"
}

Key fields of a change row:

FieldTypeMeaning
recordTypestringAlways change for a detected change
changeTypestringOne of the six change types above
storestringStore domain, or domain/collections/handle when a collection is watched
title, vendor, productType, urlstringProduct title, brand, type set by the store and public product page
price, previousPricenumberPrice after and before the change (price changes only for previousPrice)
priceChangePercentnumberSigned percentage, rounded to two decimals. Negative for a price drop
available, previousAvailablebooleantrue when at least one variant can be bought
variantChangesarrayThe variants that changed, with old and new values
detectedAtstringISO 8601 time the change was detected

Every run also writes one store row per store, with status (baseline_saved, no_changes, changes_found, or a failure code such as not_shopify, access_denied, blocked_by_robots), the number of products read and the number of changes:

{
"recordType": "store",
"store": "allbirds.com",
"storeName": "Allbirds",
"currency": "USD",
"status": "no_changes",
"productsFound": 337,
"changesFound": 0,
"checkedAt": "2026-11-03T08:00:04.120Z",
"previousCheckedAt": "2026-11-02T08:00:03.870Z"
}

In snapshot mode every product is a recordType: "product" row with title, vendor, productType, price, maxPrice, compareAtPrice, available, variantsCount, tags, createdAt, publishedAt, updatedAt and, with Include variants, the variant list. A run summary (stores checked and failed, changes delivered, warnings) is saved under the key RUN_SUMMARY in the run's key-value store.

How much does it cost to monitor a Shopify store?

This Actor uses pay-per-event pricing. You pay only for the events below. Platform usage is included. Prices per event on the Apify free plan (higher plans get lower prices):

EventFREEBRONZESILVERGOLD
Actor start (per run)$0.001$0.001$0.001$0.001
Catalog scan (per 1,000 products checked, at least one per store, changes mode)$0.002$0.00175$0.00158$0.0014
Detected change (changes mode)$0.003$0.00263$0.00237$0.0021
Product record (snapshot mode)$0.0008$0.0007$0.00063$0.00056

Examples on the free plan:

  • One store with about 340 products, checked daily, no changes: $0.001 + $0.002 = $0.003 per run, about $0.09 per month.
  • The same store checked every hour, no changes: 24 runs × $0.003 = $0.072 per day, about $2.16 per month.
  • The same store with 5 changes in a run: $0.003 + 5 × $0.003 = $0.018.
  • 20 stores with about 1,000 products each, nothing changed: $0.001 + 20 × $0.002 = $0.041 per run.
  • Snapshot of 1,000 products: 1,000 × $0.0008 + $0.001 = $0.801.

You are charged per detected change, not per catalog product, so a big store with a few changes stays cheap. Stores that fail (not Shopify, hidden catalog, blocked by robots.txt) are not charged. You can cap any run with the run's maximum cost: when the cap is reached the Actor stops cleanly and keeps the old baseline for the unfinished store, so no change is lost.

Shopify Store Monitor compared with other approaches

Shopify Store MonitorProduct scraper plus your own comparisonManual checks
OutputOnly the changes, one row eachEvery product on every run; you build the diffWhatever you notice
BaselineSaved for you in your Apify accountYou store and compare previous runsNone
BillingSmall fee per store and per detected changeUsually per product row on every runYour time
Best forOngoing monitoring on a scheduleOne-off exports and large catalog analysisA single product, once
Stock quantitiesNo (yes/no per variant only)Depends on the toolNot visible to visitors either

Use Snapshot mode of this Actor when you just need a one-off list of a store's products. Use Changes mode when you want to be told what moved.

Tips for best results

  • Run the first check once, then schedule it. A baseline is needed before changes can be found.
  • Set Minimum price change (%) to 1 to 5 if a store adjusts prices by cents.
  • Use Only watch products matching to follow one product line and keep runs smaller.
  • For very large stores, raise Max products per store. When a store is cut off at the limit, removed-product detection is switched off for that run, because products beyond the limit would look removed.
  • Use one Watchlist name per purpose. Changing the stores in a watchlist is fine: new stores get a baseline, existing ones keep theirs.

Limits and good to know

  • Only stores that publish /products.json work. Some stores turn it off, put the store behind a password, or block automated requests; they appear as not_shopify or access_denied rows and cost nothing.
  • Stock is a yes/no flag per variant. Shopify does not publish stock quantities in the public catalog, so the Actor reports OUT_OF_STOCK when no variant can be bought and BACK_IN_STOCK when one can again.
  • A product that disappears from the catalog is reported as REMOVED_PRODUCT. The store may have deleted it, unpublished it or hidden it; the Actor cannot tell which.
  • A catalog that comes back completely empty after a saved baseline is reported as empty_catalog and does not mark every product removed. An empty list is often a password page or a region redirect, and charging a removal for each product would bill a glitch. The previous baseline is kept. The store row says why nothing was listed, including when your filters matched no product (no_matches).
  • The baseline is stored in your account in a named key-value store (shopify-store-monitor-state). Deleting that store starts new baselines. A run that is refused permission to create the named store (HTTP 403) uses this run's default key-value store instead, finishes the check, and does not keep that snapshot for the next run.
  • Prices are numbers in the store's currency (currency is read from the store's public shop info and can be null).
  • Runs read the public catalog only: no cart, no checkout, no customer data, no admin access.

Use it from AI agents, the API and code

Apify MCP server (ChatGPT, Claude, Cursor and other MCP clients). Connect https://mcp.apify.com, then follow these steps:

  1. search-actors with a short query such as Shopify price tracker.
  2. fetch-actor-details for mmdincer/shopify-store-monitor to read the input schema.
  3. call-actor with the input below and a spending cap in callOptions.
  4. get-dataset-items with the returned dataset ID. call-actor returns the dataset ID, not the rows.
{
"actor": "mmdincer/shopify-store-monitor",
"input": {
"stores": ["allbirds.com"],
"mode": "changes",
"monitorName": "agent-watchlist"
},
"callOptions": { "maxTotalChargeUsd": 0.5 }
}

The first call for a store only saves a baseline, so tell the user that changes appear from the second call. Keep monitorName the same between calls. This Actor uses limited permissions, so it is not blocked from the MCP server.

To give an MCP client this Actor as its own tool (no search step), connect https://mcp.apify.com?tools=mmdincer/shopify-store-monitor.

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('mmdincer/shopify-store-monitor').call(
{ stores: ['allbirds.com'], mode: 'changes' },
{ maxTotalChargeUsd: 0.5 },
);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const changes = items.filter((row) => row.recordType === 'change');

Python

import os
from decimal import Decimal
from apify_client import ApifyClient
client = ApifyClient(token=os.environ['APIFY_TOKEN'])
run = client.actor('mmdincer/shopify-store-monitor').call(
run_input={'stores': ['allbirds.com'], 'mode': 'changes'},
max_total_charge_usd=Decimal('0.5'),
)
items = client.dataset(run['defaultDatasetId']).list_items().items
changes = [row for row in items if row['recordType'] == 'change']

HTTP (one request, returns the rows)

curl -X POST "https://api.apify.com/v2/acts/mmdincer~shopify-store-monitor/run-sync-get-dataset-items?maxTotalChargeUsd=0.5" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"stores": ["allbirds.com"], "mode": "changes"}'

The synchronous endpoint waits for the run to finish, so use it for a few stores. For many stores, start the run asynchronously and read the dataset when it ends.

Automation recipes

Slack or email alert through a webhook. In the Apify Console open Integrations (or Webhooks) and add a webhook on Run succeeded. In your handler fetch the run's dataset (the webhook payload contains the run, including defaultDatasetId) and keep the rows where recordType is change. Send one message per row, for example: PRICE_DROP: {title} {previousPrice} -> {price} ({priceChangePercent}%) {url}.

Zapier. Create a Zap with Apify as the trigger for a finished Actor or task run, add an Apify step that fetches the run's dataset items, filter for recordType equal to change, then add a Slack, Gmail or Google Sheets step. See the Apify Zapier integration.

Make. Add the Apify module that runs an Actor (or watches for a finished run), then the module that gets dataset items, filter on recordType equal to change and route the bundles to your app. See the Apify Make integration.

Google Sheets or a database. Fetch the dataset as JSON or CSV with the API (/v2/datasets/{id}/items?format=csv) after each run and append the change rows. The changeType and detectedAt columns make filtering and pivot tables easy.

Scheduling. Save your input as a task (for example competitors, daily at 08:00) and add a schedule in the Apify Console. Keep the same monitorName so every run compares with the previous one.

The Actor reads only the product catalog that each store publishes to every visitor at /products.json and the store's public shop info. It does not log in, does not use any Shopify API or account, and does not collect personal data. By default it also reads each store's robots.txt and skips stores that disallow the catalog path. Store owners can still have their own terms of use, and Shopify's own terms restrict automated access to Shopify's services; you are responsible for using the results in line with the terms of the stores you monitor and with the laws that apply to you. This Actor is an independent tool and is not affiliated with, endorsed by or sponsored by Shopify Inc. or any store it reads. All trademarks belong to their owners.

Trademarks. Not affiliated with, endorsed by, or sponsored by Shopify. Trademarks belong to their respective owners. The Shopify name and logo are used only to say which platform the Actor reads; the icon shows the Shopify mark for the same purpose.

FAQ

How do I track price changes on a Shopify store? Enter the store domain, run the Actor once to save a baseline, then run it again on a schedule. Every price move appears as a PRICE_DROP or PRICE_INCREASE row with the old and new price.

How do I get Shopify restock alerts? Set changeTypes to OUT_OF_STOCK and BACK_IN_STOCK, schedule the Actor and send the rows to a webhook, Slack or email. A product counts as back in stock when at least one variant can be bought again.

Can I monitor competitor Shopify stores? Yes. Add the competitor domains to stores and give the watchlist a name such as competitors. Only public catalog data is read.

Does it need an API key, cookies or a login? No.

Why did my first run return no changes? The first run of a store saves the baseline and returns a baseline_saved store row. Changes appear from the next run with the same monitorName.

How often should I run it? As often as you need the alerts. Daily is common for price monitoring; hourly can make sense for restock alerts on drops. Each run only compares with the previous run.

How is this different from a Shopify scraper? A scraper returns the whole catalog on every run. This Actor compares each run with the previous one and returns only the detected changes, which is what you pay for. If you need the full catalog once, use Snapshot mode.

Can I watch just one collection? Yes, enter a collection URL such as https://store.com/collections/sale.

Can I get all products instead of changes? Yes: set Mode to Snapshot (full product list).

Does it show stock quantities? No. Shopify's public catalog only says whether a variant can be bought.

Does it work for stores that are not on Shopify? No. WooCommerce, Magento and marketplace listings are not supported.

What happens when a run stops at its maximum cost? Stores that were not finished keep their old baseline, so their changes are reported in the next run.

Why is a store listed as not_shopify or access_denied? The store has no public /products.json, sits behind a password page, or refuses automated requests. Try again later, lower requestsPerSecond, or enable Apify Proxy.

Can an AI agent use this Actor? Yes. It works through the Apify MCP server, the Apify API and the Apify clients; see "Use it from AI agents, the API and code". Set a maximum charge per run.

How do I report a problem or ask for a feature? Open an issue in the Issues tab and include a link to your run.