# Shopify Price & Stock Monitor (`fifo.link/shopify-price-monitor`) Actor

Track prices, stock and new/removed products on any Shopify store. Get only what changed since the last run, with optional Slack alerts.

- **URL**: https://apify.com/fifo.link/shopify-price-monitor.md
- **Developed by:** [Gecko Data](https://apify.com/fifo.link) (community)
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 store checkeds

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 Price & Stock Monitor

Track **price changes, stock changes and new or removed products** on any Shopify store. Each run compares the store with the previous run and outputs **only what changed**, with optional **Slack alerts**.

Schedule it daily or hourly and you'll know when a competitor runs a sale, a product sells out, or a new collection drops.

### What you get

Each run outputs one row per change:

| changeType | Meaning |
|---|---|
| `PRICE_CHANGE` | Variant price went up or down (with old price, new price and % change) |
| `OUT_OF_STOCK` | Variant became unavailable |
| `BACK_IN_STOCK` | Variant became available again |
| `NEW_VARIANT` | New product or variant appeared |
| `REMOVED_VARIANT` | Product or variant disappeared |
| `STORE_SUMMARY` | One row per store per run: variants checked and number of changes found |

The **first run** for a store saves a baseline and outputs the full catalog (`changeType: SNAPSHOT`), so you also get a complete product export.

#### Example output

```json
{
  "changeType": "PRICE_CHANGE",
  "store": "https://www.example-store.com",
  "title": "Classic Runner",
  "variantTitle": "Black / 9",
  "sku": "CR-BLK-9",
  "oldPrice": 120.0,
  "newPrice": 96.0,
  "changePercent": -20.0,
  "compareAtPrice": 120.0,
  "url": "https://www.example-store.com/products/classic-runner?variant=4123",
  "image": "https://cdn.shopify.com/..."
}
```

Fields: `store`, `productId`, `variantId`, `title`, `variantTitle`, `vendor`, `sku`, `oldPrice`, `newPrice`, `changePercent`, `compareAtPrice`, `available`, `url`, `image`.

### How to use

1. Add one or more **store URLs** (any page of the store works).
2. Run once to create the baseline.
3. Add a **schedule** (Apify Console → Schedules), for example every day at 08:00.
4. Optional: paste a **Slack incoming webhook URL** to get a summary message whenever something changes.
5. Optional: set **Minimum price change (%)** to ignore tiny changes.

Export results as JSON, CSV or Excel, or pull them from the API, Make, Zapier or n8n.

### How it works

The tool reads the store's public product feed (`/products.json`), which most Shopify stores expose. It doesn't log in, doesn't use a browser, and sends polite, rate-limited requests through Apify Proxy (on by default, since many stores rate-limit cloud servers), so runs are fast and cheap. If a store can't be reached, you get a STORE_SUMMARY row with the error instead of silent failure. A store with a few thousand variants is checked in seconds.

Snapshots are kept in a named key-value store (`shopify-price-monitor-state`), so every scheduled run picks up where the last one stopped.

### Limitations

- Works only with Shopify stores that keep `/products.json` enabled (most do). Other stores return a clear error and are skipped.
- Prices are in the store's default currency.
- Stock is available or unavailable only; Shopify doesn't publish exact quantities in this feed.

### Use cases

- Competitor price monitoring for e-commerce brands
- Sale and restock alerts for resellers
- Catalog change tracking for market research and price-comparison sites

Need a custom version (other platforms, Google Sheets output, email alerts, historical price charts)? Contact the author.

# Actor input Schema

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

Shopify store homepages, e.g. https://www.kyliecosmetics.com. Any page URL works; only the domain is used.

## `minPriceChangePercent` (type: `integer`):

Ignore price changes smaller than this percentage. 0 reports every change.

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

Safety limit on catalog size per store.

## `outputFullSnapshot` (type: `boolean`):

Also push every variant (changeType = SNAPSHOT). The first run for a store always outputs the full catalog as a baseline.

## `slackWebhookUrl` (type: `string`):

Incoming webhook URL. When set, a summary is posted for each store with changes.

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

Apify Proxy is on by default because many Shopify stores rate-limit cloud servers. Turn it off only if your stores allow direct access.

## Actor input object example

```json
{
  "storeUrls": [
    "https://www.kyliecosmetics.com"
  ],
  "minPriceChangePercent": 0,
  "maxProductsPerStore": 5000,
  "outputFullSnapshot": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One row per detected change (price change, out of stock, back in stock, new or removed variant). On the first run for a store, the full catalog as SNAPSHOT rows.

## `summary` (type: `string`):

Per-store summary: variants checked, whether this was a baseline run, and counts per change type.

# 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.kyliecosmetics.com"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("fifo.link/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 = {
    "storeUrls": ["https://www.kyliecosmetics.com"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("fifo.link/shopify-price-monitor").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.kyliecosmetics.com"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call fifo.link/shopify-price-monitor --silent --output-dataset

```

## MCP server setup

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

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/M2FTMvzwVEkABw9jG/builds/WvptDNd4wOOwTCJ1D/openapi.json
