Website Change Monitor: Text Diff, Markdown & Screenshot avatar

Website Change Monitor: Text Diff, Markdown & Screenshot

Pricing

from $1.20 / 1,000 page checkeds

Go to Apify Store
Website Change Monitor: Text Diff, Markdown & Screenshot

Website Change Monitor: Text Diff, Markdown & Screenshot

Website change monitor for a list of URLs: see exactly what changed since the last run as added and removed lines of page text, plus a content hash, clean Markdown and a screenshot per page. Schedule it to watch prices or docs. From $1.20 per 1,000 pages ($2 on the Free plan, less on paid plans).

Pricing

from $1.20 / 1,000 page checkeds

Rating

0.0

(0)

Developer

Otama Labs

Otama Labs

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 hours ago

Last modified

Share

Website change monitor for anyone who needs to know when a web page changes (competitor prices, product docs, terms of service, job or tender pages, sources of a RAG index): give it a list of URLs and get one row per page with what changed since the last run as added and removed lines of text, plus a content hash, the clean page text as Markdown and a screenshot. Schedule it and you have a change feed you can read in a spreadsheet, a webhook, an AI agent or a script.

Most screenshot tools give you a picture and leave the comparing to you. This Actor renders each page in a real Chromium browser, turns the main content into clean Markdown, and compares it with the version it saw last time, so a diff like -Starter: $10 / +Starter: $12 lands straight in your dataset.

What you get for each page

A real row (the test page returns a new random id on every load, so the second run reports a change):

{
"url": "https://httpbin.org/uuid",
"finalUrl": "https://httpbin.org/uuid",
"httpStatus": 200,
"status": "changed",
"checkedAt": "2026-10-20T06:31:49.259881+00:00",
"previousCheckedAt": "2026-10-20T06:31:44.787828+00:00",
"contentHash": "f117a982ef6b9cbb9b6dc869ea08cd851f68d655d483d09b7d1f00053992f435",
"addedLines": 1,
"removedLines": 1,
"diff": [
"-\"uuid\": \"8342f2be-c43b-4f6f-a302-42b7607a2c94\"",
"+\"uuid\": \"47b97d11-309a-493a-bb9a-973d21035e7b\""
],
"wordCount": 6,
"screenshotUrl": null,
"screenshotError": null,
"markdown": "```\n{\n\"uuid\": \"47b97d11-309a-493a-bb9a-973d21035e7b\"\n}\n```",
"error": null
}
FieldMeaning
statusnew (first check under this monitor name), changed, unchanged or error
diffChanged lines of the page text: + added, - removed (up to Max diff lines)
addedLines, removedLinesComplete counts, even when the diff is cut
contentHashSHA-256 of the page text. Same text, same hash
markdownMain content as Markdown: headings, lists, links, tables. Scripts, styles and images are left out
screenshotUrlJPEG of the first screen (1280×800) or the full page, stored in the run's key-value store
screenshotErrorSet when a full-page screenshot was too slow (then the first screen is saved) or failed; the text check still counts
title, httpStatus, finalUrlPage title, HTTP status, address after redirects
errorWhy a page could not be checked (blocked address, HTTP 404, timeout...). These rows are free

The run's key-value store also has a SUMMARY record: pages checked, changed, new, unchanged and errors.

How to use it in 5 minutes

  1. Click Try for free. The form is filled with two example pages; press Start. Both come back as new in a few seconds.
  2. Replace them with the pages you care about and pick a Monitor name, for example competitor-pricing.
  3. Run it once to store the first version, then add a Schedule (daily or hourly) with the same input.
  4. Every later run returns changed rows with the diff. Filter the dataset on status = changed, or connect an integration (email, Slack, webhook) that fires when the run finishes.

Tip: if a page shows a clock, a visitor counter or rotating offers, put their CSS selectors in Ignore these elements, or compare only the part you care about with Compare only this part of the page (e.g. #pricing). Otherwise every run reports a change.

Input

FieldDefaultDescription
urls(required)Public http/https pages, up to 100 per run
monitorNamedefaultThe memory the next run compares against. Same name for the same watch list
contentSelectormain contentCSS selector of the part to compare
ignoreSelectorsnoneCSS selectors removed before comparing
maxDiffLines200Diff lines kept per page (0 to 5,000)
screenshotviewportviewport, fullPage (cut at 16,000 px) or none
includeMarkdowntrueAdd the page text to each row
waitSeconds0Extra wait after load for late content (0 to 15)

Pricing

Pay per event: $2 per 1,000 pages checked ($0.002 per page) on the Free plan, lower on paid Apify plans (Bronze $0.0018, Silver $0.0015, Gold and above $0.0012), plus a tiny start fee of $0.00005 per GB of memory per run (the default 1 GB counts as one). Platform usage is included. Pages that fail (blocked, 4xx/5xx, timeout) are not charged.

Example: watching 50 pages once a day for 30 days is 1,500 checks = $3.00 on the Free plan.

What it does not do

  • No pages behind a login, no form filling, no CAPTCHA solving. Bot-protected pages may return a challenge page instead of the content; such a page is still compared as it was rendered.
  • Public pages only. URLs that point to localhost, private networks (10.x, 192.168.x...), link-local or cloud metadata addresses are refused, also when a public page redirects there. This is a best-effort guard based on the DNS answer at check time, not a network firewall.
  • No notifications of its own. Use Apify integrations or webhooks on the finished run.
  • The comparison is on text, not on pixels: a changed image or color without a text change is not reported.
  • The stored version is the first 300,000 characters of a page's text; a change beyond that point is caught by the hash but not shown in the diff.
  • Two pages are loaded at once. Loading a page may take up to 30 seconds, plus up to 5 seconds for network activity to settle, your extra wait and the screenshot. Very large rows are cut: Markdown at 1,000,000 characters and each diff line at 2,000.

Please respect each site's terms of use when choosing pages to monitor.

FAQ

Where is the previous version stored? In a named key-value store page-snapshot-state in your own Apify account, one record per page and monitor name. Nobody else can read it; delete it to start over.

How do I call it from code, Make, n8n or Zapier? Run the Actor with the Apify API or the official Apify apps for Make, n8n and Zapier, then read the dataset items. With the Apify MCP server, AI agents can call it as a tool. LangChain and LlamaIndex have Apify loaders for the dataset.

Why did a page change although nothing visible changed? Dynamic text (dates, counters, recommendations) is part of the page text. Exclude it with Ignore these elements or narrow the comparison with Compare only this part of the page.

Can I get only the changed pages? Read the dataset items and keep the rows with status == "changed". All checked pages are returned so you also see unchanged and error rows.

ActorWhat it does
PDF to MarkdownPDF, Word, Excel and PowerPoint to Markdown and RAG chunks
PDF OCRScanned PDFs and images to text and a searchable PDF
ATS JobsJob openings from company job boards (Greenhouse, Lever, Ashby and more)
RemoteOK & Jobicy Remote Jobs APIRemote job listings from the Remote OK and Jobicy APIs

For AI Agents

Agents that keep a knowledge base fresh, watch a competitor or follow a changelog need one answer: "did this page change, and how?". This Actor returns exactly that as data (status, diff, addedLines, removedLines), so the agent reads a few lines instead of a whole page. It needs no login, is paid per page through Apify (pay per event) and runs with limited permissions.

Apify MCP server, restricted to this Actor:

{
"mcpServers": {
"website-change-monitor": {
"url": "https://mcp.apify.com?tools=tamatama/website-change-monitor"
}
}
}

Authorize with OAuth in the client, or pass Authorization: Bearer <APIFY_TOKEN>. A check is started through the tool tamatama--website-change-monitor, and get-dataset-items (added by the server) reads the rows when there are many pages. Example input for an agent that follows a changelog:

{ "urls": ["https://example.com/changelog"], "monitorName": "changelog-watch", "screenshot": "none", "includeMarkdown": false }

Keep the same monitorName on every call: that name is what links a run to the previous version. The first call returns status: "new"; later calls return changed or unchanged, and error (with the reason in error) when a page could not be loaded.

OpenAPI: https://api.apify.com/v2/acts/tamatama~website-change-monitor/builds/default/openapi.json. REST: POST https://api.apify.com/v2/acts/tamatama~website-change-monitor/run-sync-get-dataset-items with the JSON input.