# Shopify & WooCommerce Catalog Change Monitor (`leadercorp/shopify-woocommerce-catalog-change-monitor`) Actor

Monitors public Shopify and WooCommerce product catalogs and emits normalized change events between runs.

- **URL**: https://apify.com/leadercorp/shopify-woocommerce-catalog-change-monitor.md
- **Developed by:** [Leadercorp](https://apify.com/leadercorp) (community)
- **Categories:** E-commerce, Other
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.001 / result

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 & WooCommerce Catalog Change Monitor

Monitor public Shopify and WooCommerce product catalogs and emit normalized change events between Actor runs.

### What it does

This Actor fetches public product catalog endpoints from Shopify and WooCommerce stores, normalizes products into a common structure, compares the current catalog with the previous snapshot stored in the default Apify Key-Value Store, and writes product-level change events to the dataset.

It is designed for lightweight monitoring of public e-commerce catalogs without browser automation, login flows, CAPTCHA bypass, or proxies by default.

### Use cases

- Track new and removed products across competitor or partner stores.
- Monitor price and availability changes for public catalog items.
- Build recurring catalog intelligence feeds from simple Shopify and WooCommerce stores.
- Detect added or removed variants when stores expose variant data publicly.

### Input

```json
{
  "stores": [
    {
      "url": "https://www.allbirds.com",
      "platform": "shopify"
    },
    {
      "url": "https://woocommerce.com"
    }
  ],
  "autoDetectPlatform": true,
  "maxProductsPerStore": 500,
  "compareWithPreviousRun": true,
  "emitUnchangedProducts": false,
  "includeVariants": true,
  "requestTimeoutSecs": 30,
  "snapshotStoreName": "catalog-change-monitor-snapshots"
}
````

#### Input fields

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `stores` | array | yes | - | Stores to monitor. Each item must include `url` and may include `platform`. |
| `stores[].url` | string | yes | - | Public store homepage or catalog URL. |
| `stores[].platform` | string | no | - | Optional platform override: `shopify` or `woocommerce`. |
| `autoDetectPlatform` | boolean | no | `true` | When no platform is provided, try Shopify first and WooCommerce second. |
| `maxProductsPerStore` | integer | no | `500` | Maximum number of products to fetch per store. |
| `compareWithPreviousRun` | boolean | no | `true` | Compare against the previous snapshot in the default Key-Value Store. |
| `emitUnchangedProducts` | boolean | no | `false` | Emit `unchanged` events for products with no detected changes. |
| `includeVariants` | boolean | no | `true` | Include variants in normalization and variant add/remove detection. |
| `requestTimeoutSecs` | integer | no | `30` | Timeout for each catalog HTTP request. |
| `snapshotStoreName` | string | no | `catalog-change-monitor-snapshots` | Named Apify Key-Value Store used to persist snapshots across Actor runs. |

### Output

Each dataset item is a normalized event:

```json
{
  "storeUrl": "https://www.allbirds.com",
  "platform": "shopify",
  "eventType": "price_changed",
  "productId": "1234567890",
  "handle": "wool-runner",
  "title": "Wool Runner",
  "productUrl": "https://www.allbirds.com/products/wool-runner",
  "variantId": null,
  "variantTitle": null,
  "currency": null,
  "oldPrice": "98.00",
  "newPrice": "109.00",
  "oldAvailable": true,
  "newAvailable": true,
  "imageUrl": "https://cdn.shopify.com/example.jpg",
  "scrapedAt": "2026-05-23T10:00:00.000Z",
  "errorMessage": null
}
```

#### Event types

| Event type | Description |
| --- | --- |
| `new_product` | Product exists in the current snapshot but not the previous snapshot. |
| `removed_product` | Product existed in the previous snapshot but not the current snapshot. |
| `price_changed` | Product-level normalized price changed. |
| `availability_changed` | Product-level normalized availability changed. |
| `variant_added` | Variant exists in the current product but not the previous product. |
| `variant_removed` | Variant existed in the previous product but not the current product. |
| `unchanged` | Product did not change and `emitUnchangedProducts` is enabled. |
| `store_error` | Store could not be fetched or platform detection failed. |

### How comparison works

For each store, the Actor stores a normalized snapshot in the named Apify Key-Value Store configured by `snapshotStoreName` under a stable key derived from the normalized store URL. On the next run, the Actor loads that snapshot, compares products by normalized product ID, compares variants by normalized variant ID, emits dataset events, and then saves the latest snapshot.

If `compareWithPreviousRun` is `false`, every fetched product is emitted as `new_product` and the latest snapshot is still saved for future runs.

### Limitations

- Only public Shopify `/products.json` and WooCommerce Store API catalog endpoints are supported.
- Shopify product currency is not exposed by `/products.json`, so `currency` is usually `null` for Shopify.
- WooCommerce variant detail depends on what the public Store API exposes.
- The Actor does not log in, bypass CAPTCHA, use browser automation, or use proxies by default.
- Snapshots are stored in the named Key-Value Store configured by `snapshotStoreName`; changing this value starts a separate comparison history.
- Store-level failures are emitted as `store_error` events and do not fail the whole run.

### Performance and costs

The Actor uses plain HTTP requests. Shopify is fetched in pages of up to 250 products and WooCommerce in pages of up to 100 products. Runtime and dataset size are mainly controlled by `stores`, `maxProductsPerStore`, and `emitUnchangedProducts`.

### Responsible use

Use this Actor only with websites and data you are allowed to access. Respect target website terms, robots policies where applicable, and applicable laws. Do not use it to collect personal data, bypass access controls, or overload websites.

### Changelog

#### 0.1.0

- Initial MVP with Shopify and WooCommerce public catalog support.
- Added platform auto-detection, normalized snapshots, change events, and store-level error events.
- Added unit tests for normalization and diff behavior.

# Actor input Schema

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

Public Shopify or WooCommerce stores to monitor.

## `autoDetectPlatform` (type: `boolean`):

Try Shopify first, then WooCommerce when platform is not provided.

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

Maximum number of products to fetch from each store.

## `compareWithPreviousRun` (type: `boolean`):

Compare the current normalized snapshot with the previous snapshot saved in the default Key-Value Store.

## `emitUnchangedProducts` (type: `boolean`):

Emit unchanged events for products without detected changes.

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

Normalize and compare product variants when available.

## `requestTimeoutSecs` (type: `integer`):

Timeout for each catalog HTTP request.

## `snapshotStoreName` (type: `string`):

Named Key-Value Store used to persist catalog snapshots across Actor runs.

## Actor input object example

```json
{
  "autoDetectPlatform": true,
  "maxProductsPerStore": 500,
  "compareWithPreviousRun": true,
  "emitUnchangedProducts": false,
  "includeVariants": true,
  "requestTimeoutSecs": 30,
  "snapshotStoreName": "catalog-change-monitor-snapshots"
}
```

# Actor output Schema

## `catalogChanges` (type: `string`):

Normalized change events between catalog snapshots. Each event describes a product or variant that was added, changed, removed, or caused an error.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("leadercorp/shopify-woocommerce-catalog-change-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("leadercorp/shopify-woocommerce-catalog-change-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 '{}' |
apify call leadercorp/shopify-woocommerce-catalog-change-monitor --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Shopify & WooCommerce Catalog Change Monitor",
        "description": "Monitors public Shopify and WooCommerce product catalogs and emits normalized change events between runs.",
        "version": "0.1",
        "x-build-id": "cBDAmB0cVQnNhSWdy"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/leadercorp~shopify-woocommerce-catalog-change-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-leadercorp-shopify-woocommerce-catalog-change-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/leadercorp~shopify-woocommerce-catalog-change-monitor/runs": {
            "post": {
                "operationId": "runs-sync-leadercorp-shopify-woocommerce-catalog-change-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/leadercorp~shopify-woocommerce-catalog-change-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-leadercorp-shopify-woocommerce-catalog-change-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "stores"
                ],
                "properties": {
                    "stores": {
                        "title": "Stores",
                        "type": "array",
                        "description": "Public Shopify or WooCommerce stores to monitor.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "title": "Store URL",
                                    "type": "string",
                                    "description": "Store homepage or catalog URL."
                                },
                                "platform": {
                                    "title": "Platform",
                                    "type": "string",
                                    "description": "Optional platform override.",
                                    "enum": [
                                        "shopify",
                                        "woocommerce"
                                    ]
                                }
                            }
                        }
                    },
                    "autoDetectPlatform": {
                        "title": "Auto-detect platform",
                        "type": "boolean",
                        "description": "Try Shopify first, then WooCommerce when platform is not provided.",
                        "default": true
                    },
                    "maxProductsPerStore": {
                        "title": "Maximum products per store",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum number of products to fetch from each store.",
                        "default": 500
                    },
                    "compareWithPreviousRun": {
                        "title": "Compare with previous run",
                        "type": "boolean",
                        "description": "Compare the current normalized snapshot with the previous snapshot saved in the default Key-Value Store.",
                        "default": true
                    },
                    "emitUnchangedProducts": {
                        "title": "Emit unchanged products",
                        "type": "boolean",
                        "description": "Emit unchanged events for products without detected changes.",
                        "default": false
                    },
                    "includeVariants": {
                        "title": "Include variants",
                        "type": "boolean",
                        "description": "Normalize and compare product variants when available.",
                        "default": true
                    },
                    "requestTimeoutSecs": {
                        "title": "Request timeout in seconds",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Timeout for each catalog HTTP request.",
                        "default": 30
                    },
                    "snapshotStoreName": {
                        "title": "Snapshot Key-Value Store name",
                        "type": "string",
                        "description": "Named Key-Value Store used to persist catalog snapshots across Actor runs.",
                        "default": "catalog-change-monitor-snapshots"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
