# Website Change Monitor Pro – Visual Evidence (`systra_ai/systra-ai-website-change-monitor`) Actor

Monitor any public website for pricing, stock, content, SEO and visual changes. Get clear before-and-after values, a branded evidence report, focused screenshots for each detected visible change, severity scoring, noise suppression, and email, Slack or webhook alerts. No external AI key required.

- **URL**: https://apify.com/systra\_ai/systra-ai-website-change-monitor.md
- **Developed by:** [Troy Hendrick](https://apify.com/systra_ai) (community)
- **Categories:** Automation, SEO tools, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 1,000 standard 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.
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?

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 & Visual Diff Alerts

**Know what changed. See where it changed. Decide whether it matters.**

Monitor public websites for pricing, availability, content, SEO and visual changes. Every meaningful change is returned as structured data with a plain-English summary, severity, confidence, before/after values and audit-ready visual evidence.

[**Run Website Change Monitor on Apify →**](https://apify.com/systra_ai/systra-ai-website-change-monitor)

No OpenAI key, external AI service or separate monitoring account is required.

[![SYSTRA AI website change intelligence report](https://raw.githubusercontent.com/Troy-hen/systra-ai-actor-assets/main/website-change-monitor/pricing-change-intelligence.webp)](https://raw.githubusercontent.com/Troy-hen/systra-ai-actor-assets/main/website-change-monitor/pricing-change-intelligence.webp)

*A commercial price change identified, classified and presented with clear before-and-after values. Select the image to view it full size.*

### What you get

- **Clear change intelligence:** results explain the affected product, plan, page section or property—not merely that a hash changed.
- **Focused visual proof:** every detected visible change can receive its own before, after and difference screenshots with a red `SYSTRA · CHANGE` frame.
- **Branded evidence reports:** each changed row links to a responsive SYSTRA evidence centre with summaries, values, context, screenshots and technical provenance.
- **Commercial and availability monitoring:** recognize prices, plans, offers and stock-state changes with structured previous and current values.
- **SEO monitoring:** detect titles, descriptions, canonical URLs, robots directives, Open Graph content, headings and important links.
- **Explainable prioritization:** severity, confidence, impact, recommended action and noise reasons are calculated deterministically.
- **Useful alerts:** send only qualifying changes through email, Slack or a signed custom webhook.
- **Lower-cost automatic operation:** use HTTP for ordinary checks and launch a browser only when rendering or visual evidence is required.
- **Persistent baselines:** scheduled runs compare against the last successful observation using a named Apify key-value store.

### Example result

```json
{
  "status": "CHANGED",
  "name": "Pricing page",
  "changeSummary": "AI+ pricing changed from £149.99 to £119.99.",
  "changeImpact": "commercial",
  "changeTypes": ["price"],
  "changeLabel": "AI+",
  "previousValue": "£149.99",
  "currentValue": "£119.99",
  "severity": "high",
  "confidence": 98,
  "recommendedAction": "Review the pricing change and notify the commercial team.",
  "likelyNoise": false,
  "alertMatched": true,
  "evidenceReportUrl": "https://api.apify.com/v2/key-value-stores/.../REPORT_HTML"
}
```

The dataset stays useful for people, spreadsheets, dashboards, webhooks and downstream automation.

### Popular use cases

| Use case | What it can detect | Recommended mode |
| --- | --- | --- |
| Competitor intelligence | Pricing, packages, offers, product copy and CTAs | `auto` or `price` |
| Product availability | In-stock, out-of-stock and availability text | `stock` |
| SEO monitoring | Titles, descriptions, canonicals, robots, headings and links | `auto` |
| Compliance and policy watch | Terms, policies, disclosures and regulated copy | `text` or `element` |
| Product and release monitoring | Release notes, documentation and feature pages | `text` or `element` |
| Visual QA | Layout, styling, images, creative and interface changes | `visual` |
| Procurement and vendor watch | Pricing, service status, policy and product-page changes | `auto` |

### Quick start

1. Open the Actor and add one or more public URLs under **Web pages**.
2. Leave **Automatic** selected for the best general-purpose starting point.
3. Run it once. Successful first observations return `BASELINE`.
4. Create an Apify Task and schedule it hourly, daily or weekly.
5. Later runs return `UNCHANGED`, `CHANGED` or `ERROR`.

Keep `stateStoreName` and `stateNamespace` unchanged between runs. Changing either intentionally creates a separate set of baselines.

#### Minimal input

```json
{
  "startUrls": [{ "url": "https://example.com/pricing" }],
  "mode": "auto"
}
```

### Ready-to-run recipes

#### 1. Competitor pricing monitor

Use a narrow selector when you know the price element. This gives the cleanest comparison and lowest noise.

```json
{
  "startUrls": [],
  "monitors": [
    {
      "name": "Competitor product price",
      "url": "https://example.com/product",
      "mode": "price",
      "selector": ".product-price"
    }
  ],
  "captureOnChange": true,
  "alertCommercialChanges": true,
  "minimumAlertSeverity": "medium"
}
```

#### 2. SEO and landing-page monitor

Automatic mode monitors visible page content and important metadata together.

```json
{
  "startUrls": [
    { "url": "https://example.com/" },
    { "url": "https://example.com/pricing" }
  ],
  "mode": "auto",
  "captureOnChange": true,
  "alertSeoChanges": true,
  "suppressLikelyNoise": true
}
```

#### 3. Mixed website watchlist

Different targets and modes can run together while retaining independent baselines.

```json
{
  "startUrls": [],
  "monitors": [
    {
      "name": "Pricing",
      "url": "https://example.com/pricing",
      "mode": "auto"
    },
    {
      "name": "Release notes",
      "url": "https://example.com/releases",
      "mode": "element",
      "selector": "main",
      "ignoreSelectors": [".last-updated"]
    },
    {
      "name": "Homepage visual",
      "url": "https://example.com/",
      "mode": "visual"
    }
  ],
  "captureOnChange": true
}
```

### Evidence that explains the change

With `captureOnChange: true`, changed rows include a clickable SYSTRA-branded HTML report. Instead of returning only added and removed text, the Actor identifies nearby semantic labels and context—for example:

> **AI+ pricing changed from £149.99 to £119.99.**

[![SYSTRA AI branded evidence centre](https://raw.githubusercontent.com/Troy-hen/systra-ai-actor-assets/main/website-change-monitor/evidence-centre.webp)](https://raw.githubusercontent.com/Troy-hen/systra-ai-actor-assets/main/website-change-monitor/evidence-centre.webp)

*The evidence centre keeps the normalized content, rendered HTML, wider captures and focused visual evidence together in one inspection interface.*

The report can include:

- an executive summary and impact classification;
- structured before and after values;
- surrounding content before and after the change;
- a separate focused evidence set for every detected visible change;
- annotated before, after and pixel-difference screenshots;
- wider page captures for audit context;
- content hashes, response information and a tamper-evident manifest chain;
- notification delivery status and attempt history.

Before browser screenshots, the Actor performs a bounded page walkthrough to activate lazy-loaded images, intersection observers and scroll-reveal sections. Focused image selection favours the complete surrounding product, pricing plan, card, offer, list item or section—not an isolated text node.

For a newly detected area, the first focused capture may contain only an accurate **after** image because a historical crop cannot be reconstructed honestly. That run seeds an independent rolling visual baseline. The next change to the same labelled area can include before, after and difference images.

Each `changeVisualEvidence` item reports one of four honest coverage states:

- `complete` — before, after and difference evidence is available;
- `after-only` — the current evidence is available and a visual baseline has now been seeded;
- `unavailable` — a reliable DOM target could not be captured;
- `not-visual` — the change affects metadata or another non-visible property.

### How it differs from a basic change detector

| Capability | Basic text monitor | SYSTRA Website Change Monitor |
| --- | :---: | :---: |
| Detect page-text changes | ✓ | ✓ |
| Monitor prices, stock, SEO and visuals | Limited | ✓ |
| Explain what changed in plain English | — | ✓ |
| Return structured previous/current values | Limited | ✓ |
| Separate focused evidence for each visible change | — | ✓ |
| Annotated before/after/difference screenshots | — | ✓ |
| Severity, confidence and recommended action | — | ✓ |
| Dynamic-noise assessment and suppression | Limited | ✓ |
| Email, Slack and signed webhook alerts | Limited | ✓ |
| Alert delivery audit | — | ✓ |
| External AI key required | Varies | No |

### Monitoring modes

| Mode | Best for | Change rule |
| --- | --- | --- |
| `auto` | Comprehensive general monitoring | Visible text plus headings, links, CTAs, images and page metadata |
| `text` | Articles, policies and release notes | Normalized text hash |
| `element` | A specific section or component | Text and structured content inside a supplied CSS selector |
| `price` | Product or plan prices | Parsed numeric price and currency |
| `stock` | Product availability | `IN_STOCK`, `OUT_OF_STOCK` or `UNKNOWN` |
| `visual` | Layout, creative or UI changes | Rendered PNG hash plus pixel-change percentage |

For price and stock monitoring, a narrow selector produces the most stable results. Visual mode always uses the rendered-check event.

### Result statuses

- `BASELINE` — the first successful observation for this URL, mode, selector and namespace.
- `UNCHANGED` — the monitored value matches the stored baseline.
- `CHANGED` — the value changed and the new observation becomes the next baseline.
- `ERROR` — the page could not be checked. The previous baseline is retained and the row is free.

The default dataset contains one row per attempted page. The `OUTPUT` key-value-store record contains totals, run status, state-store name and event names.

### Intelligent alert rules

By default, notifications are eligible for commercial, availability, SEO or high-impact `CHANGED` results. Configure categories with:

- `alertCommercialChanges`
- `alertAvailabilityChanges`
- `alertSeoChanges`
- `alertHighImpactChanges`
- `alertOtherChanges`

High impact means the result reaches either `highImpactChangeCount` (default `3`) or `highImpactPercent` (default `5`) across text, full-page visual or per-change focused visual differences.

Two final safeguards reduce alert fatigue:

- `minimumAlertSeverity` defaults to `medium`; available values are `info`, `low`, `medium`, `high` and `critical`.
- `suppressLikelyNoise` defaults to `true` and suppresses timestamp, counter, identifier and similar volatile-content alerts.

Nothing is discarded. Dataset rows still include `severity`, `confidence`, `recommendedAction`, `likelyNoise`, `noiseReasons`, `alertMatched`, `alertCategories`, `alertReasons` and an explainable `signalRationale`.

### Notification channels

Configure any combination:

- `notificationEmails` — 1–20 comma-separated recipients receive a responsive SYSTRA email with before/after values and a verified-evidence button. Delivery uses the official `apify/send-mail` Actor; its platform and recipient limits apply.
- `slackWebhookUrl` — a Slack incoming webhook receives structured severity, confidence, action, summary, page and evidence blocks.
- `webhookUrl` — a custom public HTTPS endpoint receives the complete dataset record as JSON.
- `webhookSecret` — optionally signs custom webhook bodies with HMAC-SHA256. Verify the raw body against `X-Systra-Signature: sha256=<hex>`.

Custom webhook requests also include `X-Systra-Delivery-Id` and `X-Systra-Event: website.change`. Slack and custom webhooks retry transient failures up to three times. Email is sent once to avoid ambiguous duplicate delivery.

An eligible result includes `deliveryId`, `deliveryChannels` and `deliveryAuditUrl`. The audit record lists each channel, attempt count, final status, delivery time and a sanitized error when delivery fails.

### Pricing

Pay only for successfully processed checks. Platform usage is included and failed rows do not call a paid custom event.

| Event | Free | Starter | Scale | Business |
| --- | ---: | ---: | ---: | ---: |
| Standard page check | $1.20 / 1,000 | $1.10 / 1,000 | $1.00 / 1,000 | $0.90 / 1,000 |
| Rendered page check | $6.00 / 1,000 | $5.50 / 1,000 | $5.00 / 1,000 | $4.50 / 1,000 |
| Actor start | $0.00005 | $0.00005 | $0.00005 | $0.00005 |

Example costs at the Free-plan event rate:

| Schedule | Checks per month | Standard | Rendered |
| --- | ---: | ---: | ---: |
| 10 pages checked daily | About 300 | About $0.36 | About $1.80 |
| 50 pages checked daily | About 1,500 | About $1.80 | About $9.00 |
| 10 pages checked hourly | About 7,200 | About $8.64 | About $43.20 |

Automatic and text-heavy monitoring can remain on the lower-cost standard event. A check is charged as rendered when it requires browser rendering or screenshot evidence.

### Scheduling tips

- Save a dedicated Apify **Task** for each customer, project or watchlist so its input remains fixed.
- Hourly checks suit important prices and availability; daily checks suit competitor pages, SEO and policies.
- Start with direct access. Enable Apify Proxy only when a target blocks data-centre traffic.
- Use one state namespace per logically independent monitor set.
- Keep concurrency at 1–3 for visual-heavy runs and increase it for HTTP-only batches.
- Add `ignoreSelectors` or ignore patterns for known clocks, counters, rotating testimonials and other volatile content.

### Evidence retention and security

Historical evidence is saved under unique keys in the named state store so later runs do not overwrite it. Restricted evidence records use signed URLs generated by the Apify SDK, allowing report links to open without manually adding an API token. Evidence remains available while the named state store and its records are retained.

Change manifests form a SHA-256 hash chain to expose later modification. This is tamper-evident provenance, not a legal timestamping or certification service.

The Actor blocks private, loopback, link-local, documentation and metadata-network targets. Redirects and browser subrequests are revalidated. Do not put credentials in monitored URLs; webhook URLs and signing secrets are encrypted secret inputs in saved Actor configurations.

### Responsible use and limitations

This Actor monitors changes observable in a public HTML response or rendered page. It does not log in, complete user journeys, inspect private APIs, accept consent on a user's behalf, solve CAPTCHAs or access intranets. Backend behaviour that produces no observable page, DOM, metadata, destination, image or screenshot change cannot be detected.

Sites can change markup or block automated traffic, so selectors may occasionally need maintenance. Ensure your monitoring complies with the target website's terms, robots expectations, applicable law and reasonable request rates.

### FAQ

#### Why did my first run return `BASELINE`?

A change needs two observations. The first successful run stores the original state. The next scheduled or manual run compares the page against it.

#### Why was a page charged as rendered in Automatic mode?

Automatic mode starts with the lower-cost HTTP path. It can launch a browser when the static response has too little usable content, the page needs JavaScript, or screenshot evidence is required for a detected change.

#### Why is focused evidence marked `after-only`?

The changed area did not yet have a matching historical crop. The current run stores one, so the next change to the same area can return a complete before/after comparison.

#### Why did I receive no alert for a detected change?

The dataset still records every result. Check `alertMatched`, `alertReasons`, `severity`, `likelyNoise` and the configured category switches. By default, low-severity or likely-noise results are not sent.

#### Can it monitor any URL?

It can monitor most publicly accessible HTTP or HTTPS pages. Login-protected pages, CAPTCHAs, private networks and sites that block automated traffic are outside the supported scope.

#### Does it require an OpenAI key?

No. Classification, prioritization and summaries are deterministic and do not call an external AI model.

#### How do I reset a baseline?

Use a new `stateNamespace`, a different `stateStoreName`, or delete the relevant baseline records from the existing state store. Changing the namespace is the safest way to preserve the old evidence while starting fresh.

#### Where should I report a problem?

Use the **Issues** tab on the Actor's Apify Store page and include the run ID, target domain, selected mode and any relevant selector. Never post tokens or private webhook URLs.

### Output fields

Important fields include `status`, `changeSummary`, `severity`, `confidence`, `recommendedAction`, `likelyNoise`, `noiseReasons`, `signalRationale`, `changeCount`, `changeTypes`, `changeImpact`, `changes`, `affectedSections`, `changeLabel`, `previousValue`, `currentValue`, `contextBefore`, `contextAfter`, `changeVisualEvidence`, `alertMatched`, `alertCategories`, `alertReasons`, `deliveryId`, `deliveryChannels`, `deliveryAuditUrl`, `pageTitle`, `responseTimeMs`, `screenshotCoverage`, `monitorId`, `url`, `checkedAt`, `mode`, `method`, `contentHash`, `similarity`, `changePercent`, `focusedVisualChangePercent`, `visualChangePercent`, `evidenceReportUrl`, `evidence`, `manifestHash` and `error`.

`monitorId` is deterministic from namespace + canonical URL + mode + selector, so reordered inputs continue using the correct baseline.

### Local development

```bash
npm ci
npm test
npm run dev
```

Node.js 22 is required. The production Docker image includes Playwright Chrome. Email uses the caller's Apify account through `apify/send-mail`.

### License

MIT

# Actor input Schema

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

Public HTTP(S) pages to monitor. Authentication and private-network URLs are intentionally unsupported.

## `mode` (type: `string`):

Automatic detects visible copy plus headings, links, CTAs, images and page metadata. Text compares copy only. Element limits comprehensive comparison to a CSS selector. Price, Stock and Visual use specialized rules.

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

Optional selector such as main, #price, or .product-card. Required for Element mode and strongly recommended for Price or Stock.

## `renderJavaScript` (type: `boolean`):

Use a real browser. Enable for client-rendered sites. Rendered checks use the higher rendered-page-check price event.

## `browserFallback` (type: `boolean`):

If a cheap HTTP check finds too little text, retry with a browser. The successful browser result is billed as a rendered check.

## `monitors` (type: `array`):

Objects support url, name, mode, selector, ignoreSelectors, ignorePatterns, renderJavaScript, browserFallback, and waitAfterLoadMs.

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

Examples: .cookie-banner, .live-clock, \[data-ad].

## `ignorePatterns` (type: `array`):

Regular expressions removed before hashing, for example Updated at:.\*$.

## `captureOnChange` (type: `boolean`):

Save a branded evidence report, text, HTML, full-page captures, and focused before/after/difference screenshots. Baseline or changed HTTP checks may use a browser and the rendered-page-check event to produce screenshot evidence.

## `fullPageScreenshot` (type: `boolean`):

Capture the full rendered page up to the safety height limit. Focused change screenshots are generated separately when the changed element can be located.

## `viewportWidth` (type: `integer`):

Viewport width in pixels for rendered checks and screenshots.

## `viewportHeight` (type: `integer`):

Viewport height in pixels for rendered checks and screenshots.

## `maxScreenshotHeight` (type: `integer`):

Maximum captured page height in pixels to control memory usage on unusually long pages.

## `waitAfterLoadMs` (type: `integer`):

Extra wait after DOM load for client-rendered content.

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

Named key-value store used for rolling baselines.

## `stateNamespace` (type: `string`):

Change this to maintain an independent baseline set with the same URLs.

## `alertCommercialChanges` (type: `boolean`):

Notify for price, offer, and other commercially classified changes.

## `alertAvailabilityChanges` (type: `boolean`):

Notify when stock or availability changes.

## `alertSeoChanges` (type: `boolean`):

Notify for title, description, canonical, robots, Open Graph, language, and other metadata changes.

## `alertHighImpactChanges` (type: `boolean`):

Notify when change count or text/visual change percentage reaches the configured high-impact threshold.

## `alertOtherChanges` (type: `boolean`):

Also notify for content, navigation, media, visual, and technical changes that do not match another enabled rule.

## `highImpactChangeCount` (type: `integer`):

Treat a result as high impact when it contains at least this many classified changes.

## `highImpactPercent` (type: `number`):

Treat a result as high impact when text, focused visual, or full visual change reaches this percentage.

## `minimumAlertSeverity` (type: `string`):

Suppress notifications below this severity while retaining every detected result for audit.

## `suppressLikelyNoise` (type: `boolean`):

Do not notify for timestamp, counter, identifier, and similar volatile-content changes. Suppressed results remain visible in the dataset.

## `notificationEmails` (type: `string`):

Optional comma-separated list of 1–20 recipients for branded email alerts. Apify account and Send Mail Actor limits apply.

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

Optional Slack incoming webhook for structured SYSTRA alerts with an evidence-report button.

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

Optional public HTTPS endpoint notified with the complete result after alert rules and severity filtering pass.

## `webhookSecret` (type: `string`):

Optional secret used to create the X-Systra-Signature HMAC-SHA256 header. Use at least 8 characters.

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

Optional Apify Proxy configuration for websites that restrict direct data-center traffic.

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

Keep low for browser-heavy runs.

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

Maximum time allowed for each HTTP request or browser navigation.

## `maxBodyBytes` (type: `integer`):

Safety cap for non-browser downloads.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://example.com/"
    }
  ],
  "mode": "auto",
  "renderJavaScript": false,
  "browserFallback": true,
  "monitors": [],
  "ignoreSelectors": [],
  "ignorePatterns": [],
  "captureOnChange": true,
  "fullPageScreenshot": true,
  "viewportWidth": 1440,
  "viewportHeight": 900,
  "maxScreenshotHeight": 20000,
  "waitAfterLoadMs": 1500,
  "stateStoreName": "systra-website-monitor-state",
  "stateNamespace": "default",
  "alertCommercialChanges": true,
  "alertAvailabilityChanges": true,
  "alertSeoChanges": true,
  "alertHighImpactChanges": true,
  "alertOtherChanges": false,
  "highImpactChangeCount": 3,
  "highImpactPercent": 5,
  "minimumAlertSeverity": "medium",
  "suppressLikelyNoise": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "maxConcurrency": 3,
  "timeoutSecs": 45,
  "maxBodyBytes": 3000000
}
```

# Actor output Schema

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

No description

## `manifest` (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/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("systra_ai/systra-ai-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/" }] }

# Run the Actor and wait for it to finish
run = client.actor("systra_ai/systra-ai-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/"
    }
  ]
}' |
apify call systra_ai/systra-ai-website-change-monitor --silent --output-dataset

```

## MCP server setup

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