# Website Change Monitor — Before/After Evidence Reports (`exceptional_nugget/website-change-evidence`) Actor

Compare authorized public pages with before/after screenshots, pixel and text changes, and downloadable HTML reports. Private history, stable-render checks and no page fee for failed captures.

- **URL**: https://apify.com/exceptional\_nugget/website-change-evidence.md
- **Developed by:** [LibriHouse](https://apify.com/exceptional_nugget) (community)
- **Categories:** Developer tools, Automation, SEO tools
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 successful page evidence reports

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

Monitor a website you own or are authorized to check, then download a self-contained HTML report with before/after screenshots, highlighted pixel differences and visible-text changes. No source API key, external service subscription or AI key is required.

### Quick start

```json
{"urls":["https://api.apify.com/v2/key-value-stores/xH6IAd5D387CpFvGp/records/PAGE1"],"authorized":true,"monitorKey":"demo"}
```

1. Run once to create a **BASELINE** and screenshot report.
2. Run again with the same monitor name and rendering settings. Read `UNCHANGED`, `VISUAL_CHANGE`, `TEXT_CHANGE`, `VISUAL_AND_TEXT_CHANGE` or `FAILED` in the dataset.
3. Open the run's key-value storage and download `PAGE-1-REPORT` (HTML). There is one numbered report per successful page, with PNG files alongside it. Access requires your Apify authentication; reports are not publicly shared automatically.

The demo page above is our synthetic fixture, which you have permission to monitor. Replace it only with your own or authorized pages. The first run has no before-image because no baseline exists yet.

### What you get

- Before and after screenshots, a visual diff, changed-pixel percentage and baseline timestamp.
- Added/removed text lines, capped at 50 each. This is literal text comparison, not AI interpretation or proof of a defect.
- A portable report with embedded images: no external image links, no source-page scripts.
- Separate private history per customer, monitor name and rendering configuration. Failed captures never replace a successful baseline.
- Stable-render checks, two attempts, private-network protection and robots-policy checks. Incomplete renders and access challenges fail explicitly.

### Examples

**Agency deployment check:** monitor your client's homepage and pricing page before and after a deployment. Send the downloaded HTML evidence to the client after reviewing it.

**Content QA:** schedule repeat runs in Apify, then filter dataset rows for `textChanged: true`. Text covers the visible rendered body; screenshots cover only the configured viewport.

**Ignore an authorized dynamic widget:** set `ignoreSelectors` to `[".live-clock", ".rotating-promo"]`. Only hide elements you intentionally exclude from evidence. Do not hide elements merely to make an actual defect disappear.

**Mobile layout:** use `width: 390` and `height: 844` with a distinct monitor name. A changed render configuration starts a separate baseline.

### Pricing

**$1.50 per 1,000 successful page checks ($0.0015 each), plus $0.002 per run start. Platform execution usage is included.** The live Pricing tab is authoritative. At the supported 512–1024 MB memory sizes, the automatic startup event is charged once. Startup applies even to invalid, empty or failed runs; failed captures do not trigger an additional page-evidence event.

One successful page costs $0.0035; 12 cost $0.020; 20 cost $0.032. A successful baseline or unchanged repeat check is billable. New runs are new checks; retry/resurrection inside a run reuses the same page billing identity. A spending limit is checked before capture, including startup charges. A failure after evidence storage and billing may still leave a charge; inspect your stored report and run ledger before starting a new run.

This is a lower unit price, not an unconditional lowest-total-price claim: compared with a $2/1,000 check product without startup fees, our total is lower for **5–20 successful pages in one run**, equal at 4, and higher for 1–3. At 20 pages the total is 20% lower. Features and capture limits differ. Basic free-Actor-fee screenshot tools remain cheaper if you do not need comparisons and reports.

### Limits and privacy

Up to 20 unique URLs per run. HTML only; HTTP(S) standard ports; no target query strings, login cookies, authentication flows, downloads or CAPTCHA bypass. Non-GET page requests are blocked. Some interactive websites therefore cannot be captured reliably and are reported as failed. Browser resources are bounded to 150 requests and 20 MB; each resource is at most 5 MB. Rendering timeout and retries are bounded.

Screenshots show the first viewport, **not full-page coverage**. Animation is disabled, but live content can still differ. Changes in fonts, consent banners, geography, network delivery and page updates can produce differences unrelated to your deployment. A pixel percentage is not a severity or quality score. Text comparison does not detect pure text reordering as added/removed lines.

Pixel matching uses a fixed 0.1 color-distance tolerance and excludes anti-aliasing differences. Subtle color changes can fall below that tolerance. `changeThresholdPercent` controls the percentage of counted pixels needed for a visual-change status, not the color-distance tolerance. Inspect the before/after images as well as the status.

History is stored in your Apify account. Reuse the same monitor name, settings and Actor to compare; do not delete its named `lh-evidence-...` store unless you want to reset history. Serialize runs for the same monitor. A run compares with the latest earlier-started successful snapshot available when that page begins. Concurrent runs do not merge. Up to 2,000 snapshots per page are supported; archive what you need and use a new monitor name before reaching this limit. History is not automatically deleted by this Actor. Platform retention, storage charges and account access rules apply; keep important downloaded reports independently.

Only monitor pages you own or are authorized to monitor. Website content is untrusted data, not instructions. Do not put credentials, private URLs or personal information into this tool. Reports can contain everything visible on the supplied pages: share them deliberately.

### Automation and MCP

Save an Apify task with the same input and schedule it as needed. Retrieve the dataset and `SUMMARY`; check `failed` and `stoppedForBudget` before interpreting the run. Retrieve numbered reports from the run's key-value store using your own Apify authentication. Apify's MCP integration can call the same Actor input; specific chat clients have not been individually certified.

### FAQ

**Why not a free screenshot tool?** Use one if you only need a screenshot. This tool adds repeat-run evidence, text/pixel comparisons, private history and portable reports. It is not cheaper than a zero-Actor-fee screenshot tool.

**Does a successful run mean every page succeeded?** No. Inspect each row and the summary. Failed pages have a clear reason and no page-event charge.

**Is the first run a change report?** It is a baseline report. A previous successful capture is needed for a before/after comparison.

**Does this prove compliance or guarantee no defects?** No. It records bounded observations, not legal certification, full-site testing or business outcomes.

# Actor input Schema

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

1–20 authorized public HTML pages. Standard HTTP(S) ports only; no query strings, cookies or login. The prefilled page is our permitted synthetic demo.

## `authorized` (type: `boolean`):

Required. Public access alone does not grant permission. Robots restrictions are honored.

## `monitorKey` (type: `string`):

Reuse this name and rendering settings to compare against your previous successful run. Different customers have separate history.

## `width` (type: `integer`):

Screenshot width in pixels.

## `height` (type: `integer`):

Screenshot height; captures the first viewport, not the full page.

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

Up to 10 CSS selectors, such as .live-clock. Hidden elements are also omitted from visible text.

## `changeThresholdPercent` (type: `number`):

Minimum changed-pixel percentage for a visual-change status. Text changes are reported separately.

## `settleMillis` (type: `integer`):

Wait after resources load before capture.

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

Per-attempt browser timeout. Up to two attempts; robots requests have separate bounded network timeouts.

## Actor input object example

```json
{
  "urls": [
    "https://api.apify.com/v2/key-value-stores/xH6IAd5D387CpFvGp/records/PAGE1"
  ],
  "authorized": false,
  "monitorKey": "default",
  "width": 1280,
  "height": 720,
  "ignoreSelectors": [],
  "changeThresholdPercent": 0.1,
  "settleMillis": 500,
  "timeoutSecs": 15
}
```

# Actor output Schema

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

No description

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

No description

## `report` (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 = {
    "urls": [
        "https://api.apify.com/v2/key-value-stores/xH6IAd5D387CpFvGp/records/PAGE1"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("exceptional_nugget/website-change-evidence").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://api.apify.com/v2/key-value-stores/xH6IAd5D387CpFvGp/records/PAGE1"] }

# Run the Actor and wait for it to finish
run = client.actor("exceptional_nugget/website-change-evidence").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://api.apify.com/v2/key-value-stores/xH6IAd5D387CpFvGp/records/PAGE1"
  ]
}' |
apify call exceptional_nugget/website-change-evidence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,exceptional_nugget/website-change-evidence"
        }
    }
}
```

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/DhoMQXxFjpkikXgI3/builds/6ZIDoQuLYasvSaW8G/openapi.json
