# Website Change Monitor (`inestimable_zoysia/website-change-monitor`) Actor

Monitor any list of web pages for changes. Every scheduled run compares each page to its last snapshot and reports a readable diff — lines added and removed. CSS-selector scoping and number-masking kill false alarms. Watch competitor prices, job boards, ToS pages, and stock status on autopilot.

- **URL**: https://apify.com/inestimable\_zoysia/website-change-monitor.md
- **Developed by:** [Uncle Glooby](https://apify.com/inestimable_zoysia) (community)
- **Categories:** Automation, Developer tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 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?

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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Website Change Monitor

Watch any list of web pages and get a clear report of exactly what changed since the last check — added text, removed text, or nothing. Schedule it and never manually re-check a page again.

### What people monitor

- **Competitor pricing pages** — know the day they change a price
- **Job boards & career pages** — new postings the moment they appear
- **Terms of service / policy pages** — get an audit trail of every revision
- **Product pages** — stock status, spec changes
- **Government & permit pages** — tenders, filings, announcements

### How it works

1. **First run** saves a baseline snapshot of each page (`status: "first_snapshot"`)
2. **Every later run** compares each page against its stored snapshot and reports `changed`, `unchanged`, or `unreachable`
3. Changed pages include a readable diff: how many lines were added/removed, with samples of each — so you can see *what* changed without opening the page

Snapshots persist between runs in a named key-value store, so this Actor is built to be **scheduled** (daily and weekly are the common choices).

### Killing false alarms

Change monitors live or die on noise control:

- **CSS selector** — watch only the part of the page that matters (`#price`, `.job-listings`, `main`). Rotating banners and footers stop triggering alerts.
- **Ignore numbers** — masks all numbers before comparing, so view counters, dates, and visitor stats don't count as changes (price watchers: leave this OFF).
- Whitespace and layout-only changes are normalized away automatically; scripts and styles are ignored.

### Input example

```json
{
    "startUrls": [{ "url": "https://competitor.com/pricing" }],
    "cssSelector": "main",
    "ignoreNumbers": false
}
```

### Output example

```json
{
    "url": "https://competitor.com/pricing",
    "checkedAt": "2026-08-26T09:00:12.000Z",
    "status": "changed",
    "previousSnapshotAt": "2026-08-25T09:00:09.000Z",
    "linesAdded": 1,
    "linesRemoved": 1,
    "addedSamples": ["Pro plan – $59/month"],
    "removedSamples": ["Pro plan – $49/month"]
}
```

Results are sorted with `changed` pages first. A `SUMMARY` record (counts of changed/unchanged/unreachable) is saved to the run's key-value store, and the run's status message reads like "2 of 15 page(s) CHANGED" so scheduled-run notifications are informative at a glance.

### Getting notified

Use Apify's built-in integrations on this Actor (Integrations tab → add):

- **Email or Slack** on run finished — the status message tells you immediately whether anything changed
- **Webhook** to pipe changed results anywhere else

### Scheduling (the point of this Actor)

Console → this Actor → Schedules → e.g. every day at 9:00. Each scheduled run compares against the previous one. That's the whole setup.

### Tips

- The first run of any URL always reports `first_snapshot` — that's the baseline, not a bug.
- If you change the CSS selector or the "ignore numbers" setting, expect one round of `changed` reports as new baselines are established.
- `resetSnapshots: true` wipes the slate and re-baselines everything.
- Some sites block automated traffic (`status: "unreachable"`); enabling Apify Proxy in the input usually fixes it.

### Pricing

Pay-per-result: billed per page check (one output row per URL per run). Monitoring 20 pages daily costs roughly a dollar a month.

# Actor input Schema

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

List of page URLs to watch for changes.

## `cssSelector` (type: `string`):

Watch only the part of each page matching this selector, e.g. '#price', '.job-listings', 'main'. Strongly recommended — it prevents false alarms from rotating banners, footers, and ads. Leave empty to watch the whole page body.

## `ignoreNumbers` (type: `boolean`):

Mask all numbers before comparing, so view counters, visitor stats, and dates don't trigger change alerts. Leave OFF if you're monitoring prices.

## `snapshotStoreName` (type: `string`):

Name of the key-value store where page snapshots persist between runs. Use different names to keep separate monitoring projects isolated.

## `resetSnapshots` (type: `boolean`):

Wipe stored snapshots for the monitored URLs and save fresh baselines. Every URL will report 'first\_snapshot' on this run.

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

Use Apify Proxy or custom proxies if monitored sites block automated traffic.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://example.com"
    }
  ],
  "ignoreNumbers": false,
  "snapshotStoreName": "CHANGE-MONITOR-SNAPSHOTS",
  "resetSnapshots": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (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 = {
    "startUrls": [
        {
            "url": "https://example.com"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("inestimable_zoysia/website-change-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://example.com" }],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("inestimable_zoysia/website-change-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://example.com"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call inestimable_zoysia/website-change-monitor --silent --output-dataset

```

## MCP server setup

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