# Competitor Price Monitor (`codepal/competitor-price-monitor`) Actor

Track competitor prices and stock on any online store on a schedule. Detects price drops and stock changes, keeps price history, compares retailers, and sends alerts to Slack, Teams, Zapier or any webhook.

- **URL**: https://apify.com/codepal/competitor-price-monitor.md
- **Developed by:** [Jared Keanche](https://apify.com/codepal) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / 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.

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 Monitor

Add competitor product URLs, schedule the Actor, and get alerted when prices or stock change.

### Output per check

`product_id`, `retailer`, `product_name`, `variant`, `price`, `currency`, `availability`, `previous_price`, `price_changed`, `price_change` and `price_change_percent`, `stock_changed`, `lowest_price_seen`, `highest_price_seen`, `average_price`, `alerts`, `checked_at`, plus `status`/`error` when a page can't be read.

### Features

- **Works on many stores.** It reads Shopify and WooCommerce product APIs (down to an exact `?variant=`) and schema.org data such as JSON-LD and microdata. For sites without structured data, you can add your own CSS selector.
- **Price history**: every run is compared with the last one, and each check is also appended to a named `price-history-<monitor>` dataset for charts and exports.
- **Alerts**: price drop or increase, back in stock, out of stock, target price reached, and lowest price ever. Alerts go to Slack, Teams, Zapier, Make or n8n by webhook, and you can set a noise threshold in %.
- **Retailer comparison**: give products the same `group` to see the cheapest retailer and each one's % gap. Set `my_price` to see who undercuts you.
- **HTML report** with sparklines. Export as JSON, CSV or Excel. Choose **changes-only** output for lean scheduled runs.

### Quick start

```json
{ "monitorName": "blenders-ke",
  "products": [
    { "url": "https://shop-a.example/blender-x", "userData": { "group": "Blender X", "my_price": 5000, "target_price": 4500 } },
    { "url": "https://shop-b.example/p/blender-x", "userData": { "group": "Blender X", "retailer": "Shop B" } } ] }
```

Then **Save as task**, then **Schedule** (e.g. every 6 hours). Keep the same `monitorName` so history continues.

### Pricing

**$1.00 per 1,000 successful product checks.** Failed or blocked pages are free.

Monitoring 100 products 4 times a day costs about $12 a month.

### Notes

Prices that only appear after JavaScript runs, or after login, can't be read. Those checks report an error instead of a wrong price. robots.txt is respected by default.

# Actor input Schema

## `products` (type: `array`):

Product page URLs from any retailer. Optional per-product settings go in each row's user data: {"group":"iPhone 15 128GB","retailer":"Jumia","target_price":95000,"my_price":99000,"sku":"…","price_selector":".price","stock_selector":"#stock"}. Rows with the same group are compared across retailers. Shopify ?variant= URLs track that exact variant.

## `monitorName` (type: `string`):

Each name keeps its own price history. Use one name per saved task/schedule (e.g. "blenders-ke").

## `outputMode` (type: `string`):

All products every run, or only products whose price/stock changed or that raised an alert (first run always outputs all).

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

Which events count as alerts (in the dataset and the webhook).

## `minChangePercent` (type: `number`):

e.g. 1 to ignore rounding noise. 0 = any change.

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

POSTs alerts after each run. Works with Slack, Microsoft Teams/Power Automate, Zapier, Make and n8n incoming webhooks.

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

ISO code used only when a page shows no currency, e.g. KES.

## `usePlatformApis` (type: `boolean`):

Exact prices and per-variant stock from the store's public product JSON.

## `respectRobotsTxt` (type: `boolean`):

Skip product pages the store's robots.txt disallows (reported as errors, not charged).

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

Pages fetched in parallel.

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

Use Apify Proxy (residential for strict retailers) if checks fail with 403/429.

## Actor input object example

```json
{
  "products": [
    {
      "url": "https://www.allbirds.com/products/mens-tree-runners"
    }
  ],
  "monitorName": "default",
  "outputMode": "all",
  "alertOn": [
    "price_drop",
    "price_increase",
    "back_in_stock",
    "out_of_stock",
    "below_target"
  ],
  "minChangePercent": 0,
  "webhookUrl": "",
  "defaultCurrency": "",
  "usePlatformApis": true,
  "respectRobotsTxt": true,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `checks` (type: `string`):

One row per product: price, currency, availability, previous price, change, alerts, retailer comparison.

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

Current prices, changes, sparklines of price history and retailer comparison.

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

Checks, failures, price and stock changes, alerts, history dataset name.

# 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 = {
    "products": [
        {
            "url": "https://www.allbirds.com/products/mens-tree-runners"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("codepal/competitor-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 = { "products": [{ "url": "https://www.allbirds.com/products/mens-tree-runners" }] }

# Run the Actor and wait for it to finish
run = client.actor("codepal/competitor-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 '{
  "products": [
    {
      "url": "https://www.allbirds.com/products/mens-tree-runners"
    }
  ]
}' |
apify call codepal/competitor-price-monitor --silent --output-dataset

```

## MCP server setup

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