# WeChat Mini Program Catalog Monitor — Price & Stock Changes (`scrupulous_buckler/wechat-mini-program-catalog-price-stock-monitor`) Actor

Compare customer-provided WeChat Mini Program product snapshots and detect new or removed SKUs, price changes, restocks, stockouts, low stock, assortment shifts, and evidence-linked catalog changes. This is a snapshot analyzer, not a Mini Program scraper.

- **URL**: https://apify.com/scrupulous\_buckler/wechat-mini-program-catalog-price-stock-monitor.md
- **Developed by:** [Peng Lyu](https://apify.com/scrupulous_buckler) (community)
- **Categories:** Social media, Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.99 / up to 2,000 products per snapshot and full catalog change report

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.

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

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.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/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

## WeChat Mini Program Catalog Monitor — Price & Stock Changes

Compare **customer-provided WeChat Mini Program product snapshots** and receive
an evidence-linked report of new or removed SKUs, price changes, restocks,
stockouts, low stock, assortment shifts, brand mix, and category mix.

**This is a catalog snapshot analyzer, not a Mini Program scraper.** It does
not log in to WeChat, control an account, reverse engineer a Mini Program,
bypass access controls, collect private data, place orders, or change stock.

**Unofficial tool. This Actor is not affiliated with, sponsored by, or endorsed
by Tencent, WeChat, Weixin, or any Mini Program operator.**

### What the customer buys

One successful report costs **$4.99** and compares up to **2,000 normalized
products per snapshot**.

The delivery contains:

- one catalog-level change report
- evidence-linked product change rows
- new and removed SKU lists
- price increases and decreases above the configured threshold
- price delta amount and percentage for every comparable product
- stockout, restock, stock increase, stock decrease and low-stock signals
- current brand and category mix
- source Dataset IDs, URLs, image URLs and capture timestamps when supplied
- transparent data-quality and coverage warnings

No usable current products means no report event is created.

### Why this is different

This Actor does not compete with WeChat article, video, comment, chat or brand
monitoring Actors. It compares **commerce catalog snapshots**.

It also does not pretend to be a universal Mini Program crawler. Customers
first export, transform, scrape, or otherwise lawfully obtain product rows they
are authorized to analyze. The Actor turns those rows into a repeatable catalog
change report.

### Input modes

#### 1. Static example preview

The default demo compares two clearly labeled synthetic product snapshots. It
demonstrates price decreases, price increases, low stock, stockout, restock, a
new SKU and a removed SKU without triggering the $4.99 custom report event.
Apify may still show the small Actor-start or platform usage charge.

#### 2. Existing Apify Datasets

```json
{
  "mode": "datasetSnapshots",
  "currentDatasetId": "CURRENT_DATASET_ID",
  "previousDatasetId": "PREVIOUS_DATASET_ID",
  "hasRightToAnalyze": true,
  "catalogLabel": "Competitor Mini Program catalog",
  "defaultCurrency": "CNY",
  "priceChangePercentThreshold": 1,
  "lowStockThreshold": 5,
  "maxProductsPerSnapshot": 2000
}
````

`previousDatasetId` is optional. Without it, the Actor creates a first baseline
instead of falsely labeling every current product as new.

#### 3. Uploaded JSON snapshots

```json
{
  "mode": "uploadedSnapshots",
  "hasRightToAnalyze": true,
  "catalogLabel": "Brand flagship Mini Program",
  "uploadedPreviousProducts": [
    {
      "sku": "SKU-001",
      "name": "Example product",
      "price": 129,
      "stock": 20
    }
  ],
  "uploadedCurrentProducts": [
    {
      "productId": "SKU-001",
      "productName": "Example product",
      "currentPrice": 119,
      "inventoryQuantity": 4,
      "status": "在售"
    }
  ]
}
```

### Recognized product fields

The normalizer recognizes common aliases:

- product ID: `product_id`, `productId`, `itemId`, `skuId`, `sku`, `spuId`,
  `goodsId`, `id`
- title: `title`, `name`, `productName`, `goodsName`, `itemName`
- variant: `variant`, `variantName`, `spec`, `specification`, `skuName`
- price: `price`, `currentPrice`, `salePrice`, `sellingPrice`, `minPrice`,
  `amount`
- list price: `listPrice`, `originalPrice`, `marketPrice`, `regularPrice`,
  `rrp`, `msrp`
- stock: `stock`, `stockQuantity`, `inventory`, `inventoryQuantity`,
  `quantity`, `qty`, `availableStock`
- availability: `availability`, `stockStatus`, `status`, `inStock`,
  `available`
- brand/category/store: common snake\_case and camelCase variants
- evidence: product URL, image URL and capture/update timestamp aliases

Exact product or SKU ID is the preferred match key. If no ID is supplied, the
Actor uses normalized title, variant and store. Duplicate keys keep the last
row in that snapshot and produce a warning.

### Analysis rules

- Price change = current numeric price minus previous numeric price.
- Percentage change uses the previous price as denominator.
- A price signal is promoted only when the configured absolute threshold is
  met; smaller numeric changes remain visible in row data.
- Stock signals use only numeric quantities and supplied availability/status
  fields.
- Products without numeric stock are never guessed to be in or out of stock.
- Currency values are retained but not converted or summed across currencies.
- A missing previous snapshot creates a baseline report.
- The Actor uses deterministic comparisons and does not claim to use AI.

### Important limits

- Findings describe only the supplied snapshots, not a Mini Program's complete
  live catalog.
- A removed product can mean delisting, filtering, crawl failure or incomplete
  source coverage; review its source evidence.
- Product matching depends on stable IDs or consistent titles, variants and
  store names.
- Price ranges are reduced to the first parseable numeric value.
- Image URLs are preserved when requested but images are not downloaded or
  inspected.
- This Actor does not create alerts by itself. Schedule repeated upstream
  exports and pass the latest and previous Datasets into runs.
- This is not legal, compliance, platform-policy or commercial advice.

### Billing

Main event:

`catalog-change-report` — **$4.99**

It is triggered once only when the complete report row is written. Product
change rows are then delivered without an additional per-row event.

# Actor input Schema

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

Run the paid synthetic example, compare two existing Apify Datasets, or compare two pasted JSON product snapshots.

## `currentDatasetId` (type: `string`):

Apify Dataset containing the latest customer-owned or authorized Mini Program product export.

## `previousDatasetId` (type: `string`):

Optional earlier product snapshot. Leave empty to create a first baseline report.

## `uploadedCurrentProducts` (type: `array`):

Latest JSON product snapshot. Common product ID, SKU, title, price, stock, brand, category, store, URL and image aliases are recognized.

## `uploadedPreviousProducts` (type: `array`):

Optional earlier JSON product snapshot used to calculate changes.

## `hasRightToAnalyze` (type: `boolean`):

Required outside demo mode. Confirm the supplied or referenced product records are customer-owned, authorized, public, or otherwise lawfully processed.

## `catalogLabel` (type: `string`):

Name the Mini Program, competitor, store, campaign, category or catalog represented by the snapshots.

## `defaultCurrency` (type: `string`):

Used only when a product row does not contain its own currency code.

## `priceChangePercentThreshold` (type: `number`):

Price movements below this absolute percentage remain visible in row data but are not promoted as price-change signals.

## `lowStockThreshold` (type: `integer`):

Current quantities at or below this number are flagged as low stock. Rows without numeric stock are not guessed.

## `maxProductsPerSnapshot` (type: `integer`):

One $4.99 report reads and normalizes at most 2,000 product rows from each snapshot.

## `includeUnchangedProducts` (type: `boolean`):

Off by default to keep the output focused on baselines and changes. The report still counts unchanged matched products.

## `includeProductImages` (type: `boolean`):

Keeps image URLs already present in the supplied records. The Actor does not download or inspect product images.

## Actor input object example

```json
{
  "mode": "demo",
  "currentDatasetId": "",
  "previousDatasetId": "",
  "uploadedCurrentProducts": [],
  "uploadedPreviousProducts": [],
  "hasRightToAnalyze": false,
  "catalogLabel": "WeChat Mini Program catalog",
  "defaultCurrency": "CNY",
  "priceChangePercentThreshold": 1,
  "lowStockThreshold": 5,
  "maxProductsPerSnapshot": 2000,
  "includeUnchangedProducts": false,
  "includeProductImages": true
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `report` (type: `string`):

No description

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

// Run the Actor and wait for it to finish
const run = await client.actor("scrupulous_buckler/wechat-mini-program-catalog-price-stock-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("scrupulous_buckler/wechat-mini-program-catalog-price-stock-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 scrupulous_buckler/wechat-mini-program-catalog-price-stock-monitor --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "WeChat Mini Program Catalog Monitor — Price & Stock Changes",
        "description": "Compare customer-provided WeChat Mini Program product snapshots and detect new or removed SKUs, price changes, restocks, stockouts, low stock, assortment shifts, and evidence-linked catalog changes. This is a snapshot analyzer, not a Mini Program scraper.",
        "version": "0.1",
        "x-build-id": "w2YOuZ4l6gEQqf0iC"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/scrupulous_buckler~wechat-mini-program-catalog-price-stock-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-scrupulous_buckler-wechat-mini-program-catalog-price-stock-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/scrupulous_buckler~wechat-mini-program-catalog-price-stock-monitor/runs": {
            "post": {
                "operationId": "runs-sync-scrupulous_buckler-wechat-mini-program-catalog-price-stock-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/scrupulous_buckler~wechat-mini-program-catalog-price-stock-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-scrupulous_buckler-wechat-mini-program-catalog-price-stock-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",
                "properties": {
                    "mode": {
                        "title": "Data source",
                        "enum": [
                            "demo",
                            "datasetSnapshots",
                            "uploadedSnapshots"
                        ],
                        "type": "string",
                        "description": "Run the paid synthetic example, compare two existing Apify Datasets, or compare two pasted JSON product snapshots.",
                        "default": "demo"
                    },
                    "currentDatasetId": {
                        "title": "Current product Dataset ID",
                        "type": "string",
                        "description": "Apify Dataset containing the latest customer-owned or authorized Mini Program product export.",
                        "default": ""
                    },
                    "previousDatasetId": {
                        "title": "Previous product Dataset ID",
                        "type": "string",
                        "description": "Optional earlier product snapshot. Leave empty to create a first baseline report.",
                        "default": ""
                    },
                    "uploadedCurrentProducts": {
                        "title": "Current product records",
                        "type": "array",
                        "description": "Latest JSON product snapshot. Common product ID, SKU, title, price, stock, brand, category, store, URL and image aliases are recognized.",
                        "default": []
                    },
                    "uploadedPreviousProducts": {
                        "title": "Previous product records",
                        "type": "array",
                        "description": "Optional earlier JSON product snapshot used to calculate changes.",
                        "default": []
                    },
                    "hasRightToAnalyze": {
                        "title": "I have the right to analyze these records",
                        "type": "boolean",
                        "description": "Required outside demo mode. Confirm the supplied or referenced product records are customer-owned, authorized, public, or otherwise lawfully processed.",
                        "default": false
                    },
                    "catalogLabel": {
                        "title": "Catalog or competitor label",
                        "type": "string",
                        "description": "Name the Mini Program, competitor, store, campaign, category or catalog represented by the snapshots.",
                        "default": "WeChat Mini Program catalog"
                    },
                    "defaultCurrency": {
                        "title": "Default currency",
                        "type": "string",
                        "description": "Used only when a product row does not contain its own currency code.",
                        "default": "CNY"
                    },
                    "priceChangePercentThreshold": {
                        "title": "Minimum price-change percentage",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "number",
                        "description": "Price movements below this absolute percentage remain visible in row data but are not promoted as price-change signals.",
                        "default": 1
                    },
                    "lowStockThreshold": {
                        "title": "Low-stock quantity threshold",
                        "minimum": 0,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Current quantities at or below this number are flagged as low stock. Rows without numeric stock are not guessed.",
                        "default": 5
                    },
                    "maxProductsPerSnapshot": {
                        "title": "Products per snapshot (maximum 2,000)",
                        "minimum": 1,
                        "maximum": 2000,
                        "type": "integer",
                        "description": "One $4.99 report reads and normalizes at most 2,000 product rows from each snapshot.",
                        "default": 2000
                    },
                    "includeUnchangedProducts": {
                        "title": "Deliver unchanged matched products",
                        "type": "boolean",
                        "description": "Off by default to keep the output focused on baselines and changes. The report still counts unchanged matched products.",
                        "default": false
                    },
                    "includeProductImages": {
                        "title": "Keep supplied product image URLs",
                        "type": "boolean",
                        "description": "Keeps image URLs already present in the supplied records. The Actor does not download or inspect product images.",
                        "default": true
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
