# Price Monitor: Price Drops & Stock Alerts (`digital_influx/price-monitor`) Actor

Watch prices and stock in any online store: every run reports price drops and increases (amount and %), back in stock, sold out, new and removed products. Whole stores or chosen products, with a minimum change threshold. Shopify, WooCommerce and more.

- **URL**: https://apify.com/digital\_influx/price-monitor.md
- **Developed by:** [Bruno Petrelli](https://apify.com/digital_influx) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 product 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

## Price Monitor: Price Drops & Stock Alerts

Watch the prices and stock of **any online store** and get **only what changed** since the last run:

- **Price drops and increases**, with the old price, the new price, the amount and the percent.
- **Back in stock** and **sold out**, for the product.
- **New products** added to the store and products **removed** from it.

Give whole stores (every product in the store's sitemap) or just the product pages you care about, for example your competitors' best sellers. Schedule the Actor daily or weekly in Apify and connect the results to email, Slack or a spreadsheet with Apify's integrations.

### Input

| Field | What it does |
|---|---|
| Store URLs | Whole stores, one per line (`thesill.com`). Every product in the store's sitemap is checked, up to the limit. |
| Product URLs | Single product pages from any store, for example the competitor products you want to watch. |
| Max products per store | 100 by default, up to 5,000. Product pages you list yourself are always read. |
| Only changes | On by default: only new products and products whose price, currency or stock changed are saved. Every product checked is charged either way. |
| Minimum price change (%) | Ignore small moves, for example 5 %. The last reported price stays the reference, so a price that creeps up 1 % a day is reported once the total passes 5 %. |
| Memory name | The last prices live in a key-value store named `price-monitor-state` in your account. Give a name to keep a separate history, for example one per client, or a new name to start over. |
| Variants / Description | Each size or color with its own price, SKU, GTIN and stock (on by default); the first 1,000 characters of the description (off by default). |

```json
{
  "storeUrls": ["https://www.thesill.com"],
  "productUrls": ["https://www.cotopaxi.com/products/allpa-50l-duffel"],
  "maxProductsPerStore": 1000,
  "minPriceChangePercent": 3
}
```

### Output

The first run saves every product with `changes: null`, because there is nothing to compare with yet. From then on, each run saves only what changed:

```json
{
  "type": "product",
  "store": "shop.com",
  "url": "https://shop.com/products/walnut-chair",
  "name": "Walnut Chair",
  "price": 180,
  "currency": "USD",
  "listPrice": 240,
  "availability": "in_stock",
  "changes": {
    "status": "changed",
    "price": { "from": 200, "to": 180, "change": -20, "percent": -10 },
    "availability": null,
    "currency": null
  },
  "checkedAt": "2026-09-26T08:00:00.000Z"
}
```

`changes.status` is `new` (the first time this product is checked: when the whole store fits in the limit, a product added to the store), `changed` or `unchanged`. Each product row has the full product data too: brand, SKU, GTIN, sale price, variants with their own price and stock, rating and image.

When you watch a whole store, one summary row per store counts:

- new products;
- price drops and increases;
- products back in stock and sold out;
- products removed from the store, with their URLs.

Removed products are only reported when the whole catalog was read, so a run cut by the limit never claims a product disappeared.

### What it works on

It reads the product data stores publish for Google and link previews: schema.org JSON-LD, microdata, Open Graph and the product object of every Shopify page. It was checked live on 2026-09-25 with Shopify, WooCommerce and Salesforce Commerce Cloud stores.

Big retailers that block automated visits, and pages built only by JavaScript, are reported as blocked or without product data, and are not charged. The Actor respects robots.txt and Crawl-delay, and never tries to get around a block.

Some stores show prices in the visitor's currency. If a store switches currency, the change is reported as `currency: { from, to }` and the prices are not compared.

### Pricing

**Pay per event:** one `product` event per product checked, whether it changed or not, since checking is the work. Store summaries, pages without product data, blocked pages and errors are free.

Watching 100 products once a day is 3,000 checks a month.

Use it on stores whose terms allow reading their public pages. The User-Agent names the Actor, so store owners can see it and allow or block it in their robots.txt.

To extract whole catalogs without monitoring, see the **E-commerce Product Scraper** from the same developer.

# Actor input Schema

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

One store per line, for example thesill.com. Every product in the store's sitemap is checked, up to the limit below. Schedule the Actor (daily, weekly) to get only what changed since the last run.

## `productUrls` (type: `array`):

One product page per line, from any store, for example the competitor products you want to watch.

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

How many products to read from each store (1 to 5000). Product pages you list yourself are always read.

## `onlyChanges` (type: `boolean`):

Save only new products and products whose price, currency or stock changed. Turn it off to also save unchanged products (every product checked is charged either way). The first run saves every product: there is nothing to compare with yet.

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

Price changes smaller than this percent are not reported (0 = every change). The last reported price stays the reference, so small changes that add up are reported once the total passes the threshold.

## `stateKey` (type: `string`):

The last price of each product is kept in a key-value store named "price-monitor-state" in your account. Give a name to keep a separate history, for example one per client, or a new name to start over.

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

Each size, color or pack with its own price, SKU, GTIN and stock (up to 100 per product).

## `includeDescription` (type: `boolean`):

The product description (first 1000 characters).

## `maxConcurrency` (type: `integer`):

How many stores are read at the same time (1 to 10). Each store is read at most 2 pages at a time, or one page at a time with the pause its robots.txt asks for (Crawl-delay).

## Actor input object example

```json
{
  "storeUrls": [
    "https://www.thesill.com"
  ],
  "maxProductsPerStore": 50,
  "onlyChanges": true,
  "minPriceChangePercent": 5,
  "includeVariants": true,
  "includeDescription": false,
  "maxConcurrency": 4
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "storeUrls": [
        "https://www.thesill.com"
    ],
    "maxProductsPerStore": 50,
    "minPriceChangePercent": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("digital_influx/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.thesill.com"],
    "maxProductsPerStore": 50,
    "minPriceChangePercent": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("digital_influx/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.thesill.com"
  ],
  "maxProductsPerStore": 50,
  "minPriceChangePercent": 5
}' |
apify call digital_influx/price-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,digital_influx/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/DHjvFbrCfUmSeaaxE/builds/pjJ6PbBGYJPIcpcGj/openapi.json
