# Competitor Price & Stock Monitor (MAP Alerts) (`individual_chimpanzee/price-monitor`) Actor

Monitor product prices and stock on any online store (Shopify, WooCommerce, Magento...). Get email alerts on price drops, increases, out-of-stock and MAP violations, plus Google Sheets export and price history charts.

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

## Pricing

from $2.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

## Competitor Price & Stock Monitor (MAP Alerts)

Track product prices and stock on **any online store** and get a clear email when something changes:

> **Transparent Labs** dropped the price of "Creatine HMB Variety Pack" by 13.34% ($14.99 → $12.99)
> **A1 Supplements** is out of stock on "Optimum Nutrition Beta-Alanine"
> **Store X** sells "Whey Protein 5 lb" at $49.99, below the minimum advertised price of $59.99 (−16.67%)

No coding, no browser extension. Paste product URLs, schedule a daily run, and read the email.

### Who it's for

- **Online stores** — watch competitors' prices and stock, react to promotions the same day.
- **Brands** — **MAP monitoring**: set a minimum advertised price per product and get alerted when a reseller goes below it.
- **Buyers & resellers** — catch price drops and restocks on products you buy.

### What you get

- ✅ **Automatic price detection** — schema.org JSON-LD, meta tags and microdata. Works out of the box on Shopify, WooCommerce, Magento, PrestaShop, BigCommerce and most custom stores. Strikethrough "compare at" prices are ignored.
- 🔔 **Alerts** on price drops, price increases (with a % threshold), out-of-stock, back-in-stock, removed products, and **MAP violations**.
- 📧 **Email summary** — only when something changed (or every run, your choice). English or French.
- 📊 **Google Sheets export** — one row per product per run, ready for pivot tables and charts.
- 📈 **HTML report** with a price history chart per product, at a fixed shareable link.
- 🗂 **Separate histories** per client or project, so one account can run many monitors.

Tested on real stores, including Vitacost, A1 Supplements, Myprotein, Transparent Labs, IKEA and Shopify stores.

### How to use

1. Paste product page URLs in **Product pages to monitor**.
2. Optional: enter your email, and a Google Sheet ID.
3. Click **Start** once to record today's prices.
4. Go to **Schedules** and run it every day (or every few hours). Each run compares with the previous one.

#### Store names and MAP prices

Switch the URL list to JSON mode to add details per URL:

```json
[
  { "url": "https://store-a.com/products/whey-5lb", "userData": { "label": "Store A", "mapPrice": 59.99 } },
  { "url": "https://store-b.com/whey-protein-5-lb.html", "userData": { "label": "Store B", "mapPrice": 59.99 } }
]
```

`label` replaces the domain name in alerts. `mapPrice` raises an alert on every run where the price is below it.

### Output

Each checked page produces one dataset item:

```json
{
  "url": "https://www.transparentlabs.com/products/creatine-hmb-variety-pack",
  "shop": "Transparent Labs",
  "title": "Creatine HMB - 6 Serving Variety Pack",
  "price": 12.99,
  "currency": "USD",
  "availability": "InStock",
  "previousPrice": 14.99,
  "changePercent": -13.34,
  "status": "PRICE_DROP",
  "alert": true,
  "mapPrice": null,
  "mapViolation": false,
  "priceSource": "json-ld",
  "priceConfidence": "high",
  "checkedAt": "2026-10-29T16:22:52.000Z"
}
```

`status` is one of `NEW`, `UNCHANGED`, `PRICE_DROP`, `PRICE_INCREASE`, `OUT_OF_STOCK`, `BACK_IN_STOCK`, `PRODUCT_GONE`, `PRICE_NOT_FOUND`, `ERROR`.

`priceConfidence` is `low` when the store has no structured data and the price was guessed from the page. Check it once, or set **Price CSS selector**.

The `OUTPUT` record of the run contains the alerts, ready-to-send sentences (`alertMessages`) and the report link — easy to connect to Slack, Zapier or Make.

### Google Sheets setup (5 minutes)

1. In [Google Cloud Console](https://console.cloud.google.com), enable the **Google Sheets API**.
2. Create a **service account**, then a **JSON key** for it.
3. Paste the whole JSON file into **Google service account key** (stored encrypted).
4. Share your spreadsheet as **Editor** with the service account email (`...@...iam.gserviceaccount.com`).
5. Paste the spreadsheet ID (between `/d/` and `/edit` in its URL).

### Cost

You pay only for the product pages checked: **$2 per 1,000 checks** (plus a tiny $0.00005 per run start).

| What you monitor | Checks per month | Cost per month |
|---|---|---|
| 20 products, once a day | ~600 | ~$1.20 |
| 50 products, once a day | ~1,500 | ~$3 |
| 200 products, twice a day | ~12,000 | ~$24 |

Emails, the HTML report and the Google Sheets export are included. You can cap the cost of any run with the **Max total charge** option when you start it.

### Limitations

- Some large retailers (Amazon, Walmart, Target, iHerb…) block bots aggressively. Pages that are blocked return `ERROR`; residential proxies may help, without guarantee. This Actor is designed for the long tail of independent and mid-size stores.
- Prices rendered only by JavaScript, with no structured data, may require the **Price CSS selector**.
- Respect the terms of service of the websites you monitor.

# Actor input Schema

## `startUrls` (type: `array`):

Product page URLs, one per line. They can come from different stores. In JSON mode, add userData to name the store and set a minimum advertised price (MAP): {"url": "https://...", "userData": {"label": "Store name", "mapPrice": 34.99}}

## `language` (type: `string`):

Language of the email alerts, the HTML report and the Google Sheet header.

## `reportTitle` (type: `string`):

Shown at the top of the report and in the email subject. Example: Price watch – Acme Supplements

## `alertThresholdPercent` (type: `integer`):

Alert when the price changes by at least this percentage. 0 = any change.

## `alertOnStockChange` (type: `boolean`):

Alert when a product goes out of stock or comes back in stock.

## `notificationEmail` (type: `string`):

Address(es) that receive the summary, comma-separated. Leave empty for no email.

## `emailOnlyOnAlerts` (type: `boolean`):

Uncheck to receive an email on every run, even without changes.

## `resendApiKey` (type: `string`):

Send emails through resend.com with your own sender address. Without a key, emails are sent by the free apify/send-mail Actor.

## `emailFrom` (type: `string`):

Example: Price Alerts <alerts@yourdomain.com>. The domain must be verified in Resend.

## `googleSpreadsheetId` (type: `string`):

The part between /d/ and /edit in the spreadsheet URL. Share the spreadsheet (as Editor) with the service account email.

## `googleSheetName` (type: `string`):

Created automatically if it does not exist.

## `googleServiceAccountKey` (type: `string`):

Full content of the .json key file from Google Cloud (IAM → Service accounts → Keys).

## `priceSelector` (type: `string`):

Only needed if the price is not found automatically. Example: .product-price

## `historyStoreName` (type: `string`):

Use a different name per client or project to keep separate histories and reports (letters, digits and hyphens).

## `maxRequestsPerCrawl` (type: `integer`):

Safety limit to avoid unexpected costs.

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

Proxies reduce the risk of being blocked by stores.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.vitacost.com/products/bio-nutrition-glp-1-support-wellness-60-capsules-151159"
    },
    {
      "url": "https://a1supplements.com/optimum-nutrition-beta-alanine"
    }
  ],
  "language": "en",
  "alertThresholdPercent": 0,
  "alertOnStockChange": true,
  "emailOnlyOnAlerts": true,
  "googleSheetName": "Prices",
  "historyStoreName": "price-monitor-history",
  "maxRequestsPerCrawl": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One item per product page: price, previous price, change %, stock status, MAP violation and alert flag.

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

Today's alerts, a summary table and a price history chart per product.

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

Alert count, ready-to-send alert sentences, report and sheet links. Handy for Zapier, Make or Slack.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.vitacost.com/products/bio-nutrition-glp-1-support-wellness-60-capsules-151159"
        },
        {
            "url": "https://a1supplements.com/optimum-nutrition-beta-alanine"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("individual_chimpanzee/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 = {
    "startUrls": [
        { "url": "https://www.vitacost.com/products/bio-nutrition-glp-1-support-wellness-60-capsules-151159" },
        { "url": "https://a1supplements.com/optimum-nutrition-beta-alanine" },
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("individual_chimpanzee/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 '{
  "startUrls": [
    {
      "url": "https://www.vitacost.com/products/bio-nutrition-glp-1-support-wellness-60-capsules-151159"
    },
    {
      "url": "https://a1supplements.com/optimum-nutrition-beta-alanine"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call individual_chimpanzee/price-monitor --silent --output-dataset

```

## MCP server setup

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