# Product Price Scraper - Any Store, Price History, Restocks (`martin10291/price-drop-monitor`) Actor

Watches product prices in any online store and alerts you on price drops, increases and restocks via Discord, Slack, Telegram or any webhook. Keeps price history, lowest and highest price.

- **URL**: https://apify.com/martin10291/price-drop-monitor.md
- **Developed by:** [Martin Petrov](https://apify.com/martin10291) (community)
- **Categories:** E-commerce, Automation, Integrations
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.05 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Drop & Restock Monitor - Any Store + Discord/Slack

Track the price of **any product in any online store** and get an alert **the moment the price drops or the item is back in stock**. Alerts go to **Discord, Slack, Telegram** or any webhook (**Zapier, Make, n8n**). Schedule it hourly or daily and it keeps a full price history for you.

### Why use it

- **Any store**: Shopify, WooCommerce, Magento, BigCommerce and most modern shops (reads the real price from the product page's structured data)
- **Price drops, increases, restocks and sell-outs** compared with the previous run
- **Price history**: lowest and highest price seen, "lowest ever" flag
- **Alerts anywhere**: Discord, Slack, Telegram or JSON webhook
- **Separate watchlists**: one actor, many product lists
- No browser, no login, fast and cheap

### Who it's for

E-commerce sellers watching competitors, repricing and arbitrage, deal hunters and deal sites, procurement teams, dropshippers.

### Quick start

1. Paste product page URLs into **productUrls**.
2. Add a Discord/Slack webhook, Telegram bot, or a Zapier/Make webhook.
3. Run once (the first run saves the current prices), then **Schedule** it. Every next run reports only real changes in the alert.

### Output

| Field | Description |
|---|---|
| `title`, `store`, `url` | Product and store |
| `price`, `currency`, `previousPrice` | Current and previous price |
| `change` | `new`, `price_drop`, `price_increase`, `back_in_stock`, `out_of_stock`, `no_change` |
| `changeAmount`, `changePercent` | Size of the change |
| `lowestPrice`, `highestPrice`, `isLowestEver` | Price history |
| `inStock`, `availability` | Stock status |
| `compareAtPrice`, `brand`, `gtin`, `sku`, `image` | Product details |

A `RUN_SUMMARY` record lists drops, increases, restocks, alert status and pages without a readable price.

### Example alert

```
Price alert: 1 change
📉 Men's Tree Runners: 98.00 USD → 78.00 USD (-20.4%)
https://www.allbirds.com/products/mens-tree-runners
```

### Pricing

Pay per result: one result per product checked. Turn on **onlyChanges** to pay only for products that changed.

### FAQ

**Which stores work?** Any store whose product pages include standard product data (most do). Some marketplaces block automated access; Apify Proxy is on by default.
**Where is the history kept?** In a named key-value store in your Apify account, per watchlist.

### Use it as an integration (chain it after another actor)

This actor can run automatically after any actor whose results contain a URL.

1. Open the source actor in Apify Console and go to the **Integrations** tab.
2. Click **Add integration** -> **Actor**, pick this actor and set **Dataset** to `{{resource.defaultDatasetId}}` (leave `productUrls` empty). Set your other options and save.
3. When the source run finishes, this actor reads its dataset and processes every row. The field is detected automatically; set **Dataset field** if your column has another name.

You can also start it by hand with `datasetId` (pick a dataset or paste its ID) to process an existing dataset.

Good sources to chain from:

- martin10291/shopify-store-products
- any e-commerce product scraper with a url column

# Actor input Schema

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

Product pages from any online stores (Shopify, WooCommerce, Magento, BigCommerce and most shops with product data).

## `watchlistName` (type: `string`):

Keeps price history per watchlist. Use different names for different product lists. Empty = derived from the URLs.

## `alertOn` (type: `array`):

Changes that trigger an alert: price_drop, price_increase, back_in_stock, out_of_stock.

## `minDropPercent` (type: `integer`):

Ignore price drops smaller than this percentage.

## `discordWebhookUrl` (type: `string`):

Server Settings → Integrations → Webhooks → Copy URL.

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

Slack app → Incoming Webhooks.

## `telegramBotToken` (type: `string`):

Token from @BotFather (use with chat ID).

## `telegramChatId` (type: `string`):

User, group or channel ID for alerts.

## `webhookUrl` (type: `string`):

Receives a JSON POST with the changes.

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

Dataset contains only products whose price or stock changed (cheaper on schedules).

## `maxItems` (type: `integer`):

Hard limit on dataset rows (and cost).

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

Apify Proxy helps with stores that block servers.

## `datasetId` (type: `string`):

Optional. Pick a dataset (or paste its ID) to read the input from, for example the result of Google Maps Scraper. When this actor runs as an integration, the dataset of the triggering run is used automatically (payload.resource.defaultDatasetId), so you can leave this empty. If set, the values found in the dataset replace the main input list.

## `datasetField` (type: `string`):

Optional. The item field that holds the value, for example website, url or videoUrl (dot paths like author.url work). Empty = detected automatically.

## `datasetMaxItems` (type: `integer`):

Upper limit of unique values taken from the dataset, to keep the cost under control.

## Actor input object example

```json
{
  "productUrls": [
    "https://www.allbirds.com/products/mens-tree-runners",
    "https://www.allbirds.com/products/womens-tree-runners",
    "https://www.allbirds.com/products/mens-wool-runners",
    "https://www.allbirds.com/products/mens-canvas-runner-nz",
    "https://www.allbirds.com/products/womens-canvas-runner-nz",
    "https://www.allbirds.com/products/mens-cruiser-terry",
    "https://www.allbirds.com/products/womens-cruiser-slip-on",
    "https://www.allbirds.com/products/mens-dasher-nz-light-burnt-olive"
  ],
  "alertOn": [
    "price_drop",
    "back_in_stock"
  ],
  "minDropPercent": 0,
  "onlyChanges": false,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "datasetMaxItems": 1000
}
```

# Actor output Schema

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

Items extracted by the Actor.

# 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 = {
    "productUrls": [
        "https://www.allbirds.com/products/mens-tree-runners",
        "https://www.allbirds.com/products/womens-tree-runners",
        "https://www.allbirds.com/products/mens-wool-runners",
        "https://www.allbirds.com/products/mens-canvas-runner-nz",
        "https://www.allbirds.com/products/womens-canvas-runner-nz",
        "https://www.allbirds.com/products/mens-cruiser-terry",
        "https://www.allbirds.com/products/womens-cruiser-slip-on",
        "https://www.allbirds.com/products/mens-dasher-nz-light-burnt-olive"
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("martin10291/price-drop-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 = {
    "productUrls": [
        "https://www.allbirds.com/products/mens-tree-runners",
        "https://www.allbirds.com/products/womens-tree-runners",
        "https://www.allbirds.com/products/mens-wool-runners",
        "https://www.allbirds.com/products/mens-canvas-runner-nz",
        "https://www.allbirds.com/products/womens-canvas-runner-nz",
        "https://www.allbirds.com/products/mens-cruiser-terry",
        "https://www.allbirds.com/products/womens-cruiser-slip-on",
        "https://www.allbirds.com/products/mens-dasher-nz-light-burnt-olive",
    ],
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("martin10291/price-drop-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 '{
  "productUrls": [
    "https://www.allbirds.com/products/mens-tree-runners",
    "https://www.allbirds.com/products/womens-tree-runners",
    "https://www.allbirds.com/products/mens-wool-runners",
    "https://www.allbirds.com/products/mens-canvas-runner-nz",
    "https://www.allbirds.com/products/womens-canvas-runner-nz",
    "https://www.allbirds.com/products/mens-cruiser-terry",
    "https://www.allbirds.com/products/womens-cruiser-slip-on",
    "https://www.allbirds.com/products/mens-dasher-nz-light-burnt-olive"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call martin10291/price-drop-monitor --silent --output-dataset

```

## MCP server setup

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