Website Change Monitor – Text Diff per Page avatar

Website Change Monitor – Text Diff per Page

Pricing

$1.00 / 1,000 page checkeds

Go to Apify Store
Website Change Monitor – Text Diff per Page

Website Change Monitor – Text Diff per Page

Watch web pages, or one part of each with a CSS selector, and get the lines added and removed since the last run. Schedule it and pay per page checked.

Pricing

$1.00 / 1,000 page checkeds

Rating

0.0

(0)

Developer

Gabor Molnar

Gabor Molnar

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

15 hours ago

Last modified

Share

Give it a list of pages and it tells you, for each, whether its text changed since the last run, and which lines were added and removed. Watch a whole page or just one part of it with a CSS selector, such as a pricing table, a terms-of-service section or a job list. Put it on an Apify schedule and it becomes a monitor. You pay per page checked, and a check that couldn't see the page is free.

What you get

One dataset item per page. Here is an example: a pricing page whose price moved between two scheduled runs.

{
"url": "https://acme.com/pricing",
"selector": "#plans",
"reasonCode": "changed",
"httpStatus": 200,
"contentHash": "5f0c…e21a",
"previousCheckedAt": "2026-09-26T06:00:04.118Z",
"added": ["$12 per month", "New: SSO on every plan"],
"removed": ["$10 per month"],
"addedCount": 2,
"removedCount": 1,
"checkedAt": "2026-09-27T06:00:03.902Z"
}

The first run for a page stores its baseline and reports first_seen. Every run after that reports unchanged, changed or gone.

Use it when

  • You track competitors' pricing pages, plans or feature lists.
  • You need to know when terms of service, a privacy policy or a regulation page is edited.
  • You watch a careers page, a changelog or a status page for new entries.
  • An agent needs "what's new on this page since yesterday" as data, not a screenshot.

Input

FieldTypeRequiredWhat it does
urlsarray of stringsyesUp to 1,000 http or https URLs per run. A URL is checked once per run, however it is spelled: case in the scheme and host, a default port and a #fragment make no difference. The path and query string do.
selectorstringnoA CSS selector (#plans, main .pricing-table, article) for the part of each page to watch. Defaults to the whole page body. Applies to every URL in the run: to watch different parts of different pages, use one run (or one scheduled task) per selector.
monitorNamestringnoKeeps this monitor's snapshots apart from any other monitor watching the same URLs. Use one per scheduled task. Change it to start over from a fresh baseline. Lowercase letters, digits and hyphens, up to 40.

How a change is detected

The page's visible text is read one line per paragraph, heading, list item, table cell or other block, with whitespace collapsed. Scripts, styles, markup and attributes are not watched, so a rotated security token or a new asset hash in the HTML is not a change. A text/plain or other non-HTML response is watched line by line as it is.

changed means the watched text differs from the previous snapshot. added and removed list the lines that appear in only one of the two versions, up to 100 each, and addedCount and removedCount give the full numbers. A change that only reorders lines, or changes how often the same line repeats, is changed with both lists empty. The same goes for a change past the first 10,000 lines of a very long page: it is detected, but only the first 10,000 lines are stored and diffed.

Snapshots are kept in a key-value store named website-change-monitor in your own Apify account, one per page, selector and monitorName. Deleting that store resets every baseline.

Pricing

Pay per event, $1.00 per 1,000 pages checked ($0.001 each), charged on the page-checked event.

A check is charged when it compared the page against its baseline, or took the baseline. unchanged is an answer too, and on a schedule it is the one you get most often.

reasonCodeCharged
first_seen (no earlier snapshot for this page, selector and monitorName: the baseline is taken)yes
unchanged (the watched text is the same as last time)yes
changed (the watched text differs; see added and removed)yes
gone (the page now answers 404 or 410; removed lists what it held)yes
not_found (404 or 410 on a page never seen before, most likely a wrong URL)no
blocked (401, 403 or 429: a bot wall or login)no
unreachable (no answer, a timeout, a 5xx or any other error status)no
selector_not_found (the page loaded but the selector matched nothing, or is not valid CSS)no
no_content (the page, or the selected part, has no text, typically a page that renders with JavaScript)no
invalid_url (not an http(s) URL on a domain name: an IP address, localhost and credentials in the URL are refused before any request)no

A free check leaves the stored baseline alone, so the next check that can see the page still compares against the last one that did.

If you set a maximum total charge for a run, the Actor stops as soon as that limit is reached instead of working for free. Items after that point are left out of the dataset and not charged, and the run log says how many; submit them in a new run.

Limits

  • Pages are read as served, without running JavaScript. A page that renders its content client-side shows up as no_content, or its selector as selector_not_found.
  • Only text is watched. An image, a style or a link target that changes without its text changing is not reported.
  • Text that differs on every load (a live counter, a "posted 3 minutes ago" line) reports a change every run. Point selector at the part you care about to leave it out.
  • If a run fails after a snapshot is saved but before its row is written, that one change is not reported; the next run compares against the new snapshot.
  • Pages are fetched one after another. If the run reaches its timeout it stops there; the rows already written stay in the dataset.

Data sources

The pages themselves, fetched over HTTP(S). No third-party service, and nothing leaves your Apify account.