Page Change Monitor: Text Diff & Change Alerts API avatar

Page Change Monitor: Text Diff & Change Alerts API

Pricing

from $1.00 / 1,000 page checkeds

Go to Apify Store
Page Change Monitor: Text Diff & Change Alerts API

Page Change Monitor: Text Diff & Change Alerts API

Watch any web page (or one CSS section of it) for text changes. Each run returns changed true/false, a clean line diff (added/removed lines), a short summary and stable JSON for agents, MCP, schedules and webhooks. Ignores timestamps, ads and counters. $0.001 per page check.

Pricing

from $1.00 / 1,000 page checkeds

Rating

0.0

(0)

Developer

Tallow Lane Labs

Tallow Lane Labs

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Security

Limited permissions

Share

Page Change Monitor: text diff and change alerts for any web page

Watch any public web page, or one section of it, and get a clean answer on every run: changed: true/false, the exact lines added and removed, and a one-line summary. Built for Apify schedules, webhooks and AI agents (MCP), and it ignores noise like timestamps, ads, cookie banners and view counters.

Monitoring cost: a page with no changes costs $0.001 per check, so watching 10 pages daily is about $0.32 a month, plus $0.004 per change detected.

By Tallow Lane Labs. Checks only the pages you list, at most once per interval, politely and without unblockers. Tallow Lane Labs is not affiliated with the websites you monitor.

Why this one

  • A real diff, not just "something changed". Line-level added and removed lists, exact counts, a changeRatio, and a summary like Changed: 1 line added, 1 line removed. Added: "Pro $24/month". Removed: "Pro $20/month".
  • No false alarms from noise. Built-in rules ignore clock times, ISO timestamps, "5 minutes ago", view/like/comment counters, ad slots and cookie banners. Add your own CSS selectors or regular expressions. Calendar dates are kept, so a new "Last updated" date counts.
  • Watch just the part you care about: a CSS selector (#pricing, main article) or a text region ("from Changelog to Footer"), set globally or per page.
  • Stable JSON for agents. The same fields on every record, whatever happened: status (ok, tooSoon, blocked, robotsDisallowed, httpError, error, ...), changed, firstSeen, changeType, diff, textHash, previousTextHash and timestamps.
  • Stateful by design. Snapshots live in a named key-value store, keyed by a hash of URL + selector + region, so a schedule simply runs the same input again.
  • Polite and honest. One request at a time per site, a minimum check interval per page (5-minute floor), robots.txt respected, a truthful User-Agent, no proxies, no captcha solving. If a site blocks the check (403, 429, captcha or challenge page), the record says blocked and why, and the old snapshot is kept.

Use cases

  • Competitor pricing and plan pages: get the exact price line that changed.
  • Terms, privacy and policy pages: see what changed in a ToS or privacy policy.
  • Docs, changelogs and status pages: get new releases or incidents as diffs.
  • Government, procurement and regulatory notices.
  • Agent memory: let an AI agent ask "did this page change since I last read it, and how?"

Quick start

  1. Click Try for free and run the example page, or leave urls empty for a 2-page demo.
  2. Add your pages, one URL per line. Optionally set a CSS selector.
  3. Schedule the Actor (for example daily or hourly). The first run stores a baseline, and every later run reports changes.
  4. Add a webhook or Slack/Zapier/Make integration on Run succeeded. RUN_SUMMARY.changedUrls lists what changed.

Input example

{
"urls": ["https://www.iana.org/help/example-domains"],
"pages": [
{ "url": "https://acme.com/pricing", "selector": "#plans", "label": "Acme pricing" },
{ "url": "https://acme.com/legal/terms", "regionStart": "Terms of Service", "regionEnd": "Contact us",
"minCheckIntervalMinutes": 1440 }
],
"ignorePatterns": ["^Sponsored.*$"],
"outputMode": "all",
"minCheckIntervalMinutes": 60
}

Main options:

  • urls: leave empty for a demo.
  • pages: per-page selector, regionStart / regionEnd, ignoreSelectors, ignorePatterns, label and minCheckIntervalMinutes.
  • Global selector, region and ignore rules.
  • useDefaultIgnoreRules: on by default.
  • minCheckIntervalMinutes: 60 by default, minimum 5.
  • outputMode: all (default) or changesOnly.
  • includeText, maxDiffLines and respectRobotsTxt.
  • domainDelayMs: 2,000 ms by default, minimum 1,000.
  • stateStoreName, stateKeyPrefix and resetState.

See the Input tab for every field.

Output example

An example record for a changed page (hashes shortened):

{
"recordType": "page",
"url": "https://acme.com/pricing",
"label": "Acme pricing",
"finalUrl": "https://acme.com/pricing",
"status": "ok",
"httpStatus": 200,
"changed": true,
"firstSeen": false,
"changeType": "changed",
"summary": "Acme pricing: Changed: 1 line added, 1 line removed (25% of the text) since 2026-11-02T12:00:03.101Z. Added: \"Pro $24 per month\". Removed: \"Pro $20 per month\".",
"diff": {
"added": ["Pro $24 per month"],
"removed": ["Pro $20 per month"],
"addedCount": 1, "removedCount": 1, "truncated": false, "changeRatio": 0.25, "algorithm": "myers"
},
"textHash": "9f2c…", "previousTextHash": "41d8…",
"lineCount": 4,
"title": "Pricing - Acme",
"selector": "#plans",
"checkedAt": "2026-11-03T12:00:02.877Z",
"previousCheckedAt": "2026-11-02T12:00:03.101Z",
"lastChangedAt": "2026-11-03T12:00:04.950Z",
"nextCheckAllowedAt": "2026-11-03T13:00:04.950Z",
"blockedReason": null,
"error": null
}
statusMeaningCharged
okChecked. changeType is firstSeen, changed, unchanged or baselineReset (ignore rules changed)page check (+ change if changed)
tooSoonChecked less than minCheckIntervalMinutes ago. Not fetched; nextCheckAllowedAt says whenno
blocked403, 429, captcha or bot challenge. blockedReason is rateLimited, challenge, captcha, forbidden, authRequired or legalno
robotsDisallowedThe site's robots.txt disallows the pageno
httpError / error / invalidUrl / unsupportedContent404 and similar errors, network failure, a bad URL, or a PDF or imageno
selectorNotFound / regionNotFoundThe selector or region start text is not on the page (the old snapshot is kept)no
  • Error records, blocked records and tooSoon records are never charged.
  • RUN_SUMMARY (key-value store) has totals, changedUrls, blockedUrls, a per-page list and HTTP stats.
  • Dataset views: Page checks, Diffs, and Skipped, blocked and failed.

Pricing (pay per event)

EventPriceWhen
Page checked$0.001Each page fetched and compared (first check, changed or unchanged)
Change detected$0.004Extra, only when the page's cleaned text changed (with diff and summary)
Actor start$0.0005Once per run (same at 256, 512 or 1,024 MB)

Not charged: tooSoon skips, blocked pages, robots.txt skips, failed fetches, selector or region misses, and error records.

  • 20 pages, no changes: $0.0205 per run (about $0.62 a month daily).
  • 10 pages hourly with no changes: about $7.56 a month. A changed page costs $0.005 in total for that check.
  • Set Apify's maximum cost per run for a hard cap. The Actor stops before pages it can't pay for. A change it can't pay for is reported on the next run, never lost.

Integrations

  • Schedules: Apify Console → Schedules → run this Actor with your input daily or hourly. Use a minCheckIntervalMinutes equal to the schedule period. A 10% early-start tolerance means an hourly schedule is never skipped as tooSoon.
  • Webhooks, Slack, email, Make, Zapier, n8n: add an integration on Run succeeded. Use outputMode: changesOnly so the dataset holds only changes and problems.
  • Apify API: POST https://api.apify.com/v2/acts/tallowlanelabs~page-change-monitor/run-sync-get-dataset-items, or
from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("tallowlanelabs/page-change-monitor").call(
run_input={"urls": ["https://acme.com/pricing"], "selector": "#plans"})
for page in client.dataset(run["defaultDatasetId"]).iterate_items():
if page["changed"]:
print(page["summary"])
  • AI agents (MCP): https://mcp.apify.com?tools=tallowlanelabs/page-change-monitor lets an assistant answer "did this page change, and what changed?"

FAQ

Why did my first run say firstSeen and not show a diff? There was nothing to compare with yet. The first check stores the baseline, and changes are reported from the next run.

Why tooSoon? Each page is fetched at most once per minCheckIntervalMinutes (at least 5 minutes), however often the Actor runs. This keeps monitoring polite. The record says when the next check is allowed.

A timestamp or counter keeps triggering changes. Add a regular expression to ignorePatterns (for example Last refreshed .*) or a CSS selector to ignoreSelectors. Changing ignore rules re-baselines the page (baselineReset) instead of reporting a false change.

Does it render JavaScript? No. It reads the HTML the server sends, plus plain text, JSON and XML. Pages that build their content only in the browser may show little text. Point it at the site's server-rendered page or JSON endpoint instead.

What if a site blocks it? You get status: "blocked" with the reason. The Actor never uses unblockers, rotating proxies or captcha solvers, and it doesn't retry blocks.

Is it legal? It reads public pages you choose, once per interval, honouring robots.txt, with a User-Agent that names the tool. Don't monitor logged-in pages or personal profiles, and follow each site's terms. (General information, not legal advice.)

Limits

  • Public pages only: no logins and no JavaScript rendering.
  • Up to 1,000 pages per run, and 5 MB of HTML per page.
  • Stored text is capped at 1,000,000 characters per page.
  • Up to 200 diff lines per side by default (counts are always exact).
  • 256 MB of memory covers normal pages. Use 512 MB for many very large pages.

Support

Open an issue on the Issues tab or email Tallow Lane Labs at wdeornellas+tallowlanelabs@gmail.com.