# Website Change Monitor & AI Alerts (`thescrapelab/ai-content-changes-detector`) Actor

Monitor public web pages for price, policy, product, job, and content changes. Get structured diffs, optional AI summaries, and webhook alerts.

- **URL**: https://apify.com/thescrapelab/ai-content-changes-detector.md
- **Developed by:** [Inus Grobler](https://apify.com/thescrapelab) (community)
- **Categories:** Automation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.50 / 1,000 page checks

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/platform/actors/running/actors-in-store#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 & AI Alerts

Monitor public web pages for the changes that matter. Paste one or more URLs, run the Actor once to create a baseline, then run it again—or schedule it—to receive clear, structured change results.

Use it to track price updates, product availability, policy and legal pages, job listings, documentation, public announcements, and status pages. It can return concise change summaries, detailed added and removed text, optional AI classifications, and webhook alerts for your workflows.

### Start in three steps

1. Add the public page URLs you want to watch.
2. Run the Actor. The first successful run saves a baseline for each page.
3. Run the same input again or schedule it. Later runs show whether the page changed and why.

You do not need to configure storage, timeouts, retries, or AI settings for a normal monitoring workflow. Each URL and page-selection setting keeps its own comparison history automatically.

### Simple input

Paste URLs into the **Pages to monitor** field in the Apify Console, or send the same small JSON object through the API:

```json
{
  "urls": ["https://example.com/pricing", "https://example.com/terms"]
}
```

The first result for a page has `changeType: "baseline"`. That is expected: it means the Actor saved the starting version for later comparison.

### Pricing

**$3.50 per 1,000 successful page checks** ($0.0035 each). Error rows are free. With **Only return meaningful changes** enabled, unchanged checks filtered from the dataset are also free.

When optional AI is enabled and a detected change is sent for classification, the Actor reserves one page-check charge before contacting the provider. That same charge covers the resulting dataset row, so it is never charged twice. The charge still applies when AI classifies a change as cosmetic and **Only return meaningful changes** filters the row, because the AI work was completed. Apify platform usage can be billed separately according to the client's Apify plan and the Actor's current platform-usage billing setting.

Set a maximum spend for each run in Apify to keep a firm budget. The Actor stops processing further results as soon as the page-check spending limit is reached.

### Optional controls

The Console groups less-common settings into collapsible sections.

- **Monitor a page section:** Add one CSS selector, such as `main`, `.price`, `#availability`, or `article`, to compare only that part of every page in the run.
- **Ignore page noise:** Add selectors such as `.cookie-banner` or `.last-updated` so routine banners and timestamps do not create false alerts.
- **Keep results focused:** Enable **Only return meaningful changes** to suppress routine unchanged rows. First-run baselines and errors are still returned.
- **Send webhook alerts:** Provide a public endpoint to receive meaningful changes automatically. If it needs bearer authentication, add your own **Webhook bearer token** secret. Receivers should deduplicate repeated `eventId` values. Console alerts use meaningful changes by default.
- **Add AI summaries:** AI is opt-in. When it is available, bounded text from changed public pages is sent to the configured provider for classification; normal change detection still works without it. AI requests run one at a time so spend limits stop cleanly.

Saved Apify Tasks automatically keep separate monitoring histories, so there is no history setting to manage in the Console. API users can still provide `stateStoreName` when they intentionally need to share or isolate history outside a saved Task. Operational safety limits use tested defaults: downloads default to 400 KB, are capped at 500 KB, and automatically keep no more than 1 MB of response payloads in flight.

### Optional AI setup

AI summaries require one Actor environment variable: `OPENROUTER_API_KEY`. Add that value as an Apify secret named `OPENROUTER_API_KEY` and enable **Add an AI change summary** when you want it. No environment variables are required for ordinary monitoring, selectors, webhook alerts, or history. Apify supplies its own runtime variables automatically.

### What you receive

The default dataset contains one row per checked page. The **Change overview** view highlights the fields most clients need:

| Field | Meaning |
| --- | --- |
| `status` | `ok` when a page was checked, or `error` when it could not be fetched or extracted. |
| `changed` | Whether the normalized page content differs from the prior successful check. |
| `isMeaningful` | Whether the change passed the importance rules. |
| `changeType` | A useful category such as `price`, `availability`, `policy`, `job`, `product`, `news`, or `cosmetic`. |
| `summary` | A readable explanation of the result. |
| `addedLines` / `removedLines` | Bounded text showing the detected change. |
| `errorCode` | A machine-readable reason when a check could not complete. |

Example change result:

```json
{
  "status": "ok",
  "url": "https://example.com/pricing",
  "changed": true,
  "isMeaningful": true,
  "changeType": "price",
  "summary": "1 line added and 1 line removed (8.33% changed).",
  "addedLines": ["Pro plan: $29/month"],
  "removedLines": ["Pro plan: $19/month"]
}
```

Each run also stores a `RUN_SUMMARY` record with the number of pages checked, changes found, errors, alerts sent, AI usage, and run duration.

### Schedule recurring checks

After the baseline run, schedule the same task or input at the interval you need. Keep the interval longer than the expected run time so two runs do not update the same history at once. For price or availability monitoring, a short interval may fit; for policies and documentation, daily or weekly checks are often enough.

### Privacy and safe use

- This Actor monitors publicly accessible HTTP or HTTPS pages only. It does not log in, bypass access controls, or access private or local networks.
- AI analysis is disabled by default. If you enable it, only bounded normalized text and change data from changed public pages are sent to the configured AI provider.
- Webhook delivery is best-effort and may repeat an event. Use `eventId` to make your receiver idempotent.
- The Actor applies download, retry, concurrency, AI-prompt, and text-size limits to keep runs predictable.

### Troubleshooting

- **The first result says `baseline`:** This is normal. Run the same input again to compare the page with that saved starting version.
- **A page reports `error`:** Confirm that it is publicly accessible without a login and that its important content appears in the initial HTML response.
- **Routine updates create unwanted changes:** Use **Elements to ignore** for timestamps, cookie notices, banners, and similar page noise.
- **No webhook arrived:** Check `notificationSent`, `notificationAttempts`, and `notificationError` in the dataset. Your endpoint must be public and should accept repeated `eventId` values.
- **No AI summary appears:** AI must be enabled and available for the Actor. The built-in analysis remains active when AI is unavailable.

### Limitations

- This version reads the initial HTTP response. It may not capture content that exists only after JavaScript rendering or user interaction.
- If a page blocks automated requests, requires a login, or returns an unsupported format, the dataset returns an error row instead of a change result.
- Very large pages are safely capped; the result indicates when downloaded or retained text was truncated.
- AI classification is a helpful summary, not a substitute for human review in high-stakes legal, financial, safety, or compliance decisions.

### Python API example

```python
import os

from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run = client.actor("thescrapelab/ai-content-changes-detector").call(
    run_input={
        "urls": ["https://example.com/pricing"],
        "onlyMeaningfulChanges": True,
    }
)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["url"], item["changed"], item["changeType"], item["summary"])
```

For the simplest experience, run the Actor once in the Console, review the baseline result, and then schedule the same task for ongoing website change monitoring.

# Actor input Schema

## `urls` (type: `array`):

Paste one or more public page URLs. Start with one; you can add more whenever you need them.

## `selector` (type: `string`):

For example: main, .price, #availability, or article.

## `ignoreSelectors` (type: `array`):

Optional CSS selectors for timestamps, cookie banners, ads, or other noise.

## `onlyMeaningfulChanges` (type: `boolean`):

Turn this on to keep the dataset focused on important changes.

## `emitUnchanged` (type: `boolean`):

Internal default that keeps routine successful checks in the dataset unless meaningful-only results are selected.

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

Your public HTTP or HTTPS endpoint. It should safely handle a repeated event ID.

## `webhookAuthToken` (type: `string`):

Optional. Your own bearer token for this webhook endpoint; it is never included in results or alerts.

## `notifyOn` (type: `string`):

API-only override. Console alerts use meaningful changes by default.

## `aiEnabled` (type: `boolean`):

Use AI to classify changed pages. Built-in analysis remains available if the provider fails.

## `maxAiCalls` (type: `integer`):

Internal safety limit for optional AI summaries during one run.

## `stateStoreName` (type: `string`):

API-only override. Saved Apify Tasks automatically use separate monitoring histories.

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

API-only operational override.

## `timeoutSecs` (type: `integer`):

API-only operational override.

## `maxRetries` (type: `integer`):

API-only operational override.

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

API-only operational override.

## `maxBytes` (type: `integer`):

API-only operational override. Concurrency is reduced automatically for larger responses.

## `maxContentChars` (type: `integer`):

API-only operational override.

## Actor input object example

```json
{
  "urls": [
    "https://apify.com/thescrapelab"
  ],
  "ignoreSelectors": [],
  "onlyMeaningfulChanges": false,
  "emitUnchanged": true,
  "notifyOn": "meaningful",
  "aiEnabled": false,
  "maxAiCalls": 100,
  "minChangePercent": 0.5,
  "timeoutSecs": 15,
  "maxRetries": 2,
  "maxConcurrency": 3,
  "maxBytes": 400000,
  "maxContentChars": 12000
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

Structured results emitted by the run. Result filters can omit unchanged or non-meaningful checks; baselines and errors are included.

## `runSummary` (type: `string`):

Counts for checked pages, changes, errors, alerts, AI use, and duration.

# 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 = {
    "urls": [
        "https://apify.com/thescrapelab"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("thescrapelab/ai-content-changes-detector").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 = { "urls": ["https://apify.com/thescrapelab"] }

# Run the Actor and wait for it to finish
run = client.actor("thescrapelab/ai-content-changes-detector").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 '{
  "urls": [
    "https://apify.com/thescrapelab"
  ]
}' |
apify call thescrapelab/ai-content-changes-detector --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,thescrapelab/ai-content-changes-detector"
        }
    }
}

```

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/ACNohlL7FbsLaU1Uq/builds/ECUoza4A9dNvCSMuK/openapi.json
