# Changelog of Website Screenshots: Full Page, Mobile, PDF & Change Alerts (`rookdev/website-screenshot-monitor`) Actor

- **URL**: https://apify.com/rookdev/website-screenshot-monitor/changelog.md
- **Full Actor documentation**: https://apify.com/rookdev/website-screenshot-monitor.md

## Changelog

### Unreleased

- Playwright is no longer pinned: the Actor uses the version the Apify base image ships. The first push failed at the build self-check because a 1.63.0 pin looked for a Chromium the image (now 1.64.1) does not have, and any pin would break the same way when the image next moves (2 Nov 2026).
- Store title changed to lead with the plain job, not monitoring (2 Nov 2026; see docs/research/2026-11-02-store-crowding.md). The Actor name in its URL and all behaviour are unchanged.

### 0.1.1 (2026-10-30)

Cost protection after an audit of how the Actor could be made to cost more than it earns (prices unchanged):

- A run stops starting new pages, comparisons, waits, retries and delays once its browser time is more than $0.05 ahead of what it has earned (about 7.5 minutes at 2 GB with no paid result); 50 failed pages in a row stop it too. Pages not reached share one free `skipped` row and are listed in `RUN_SUMMARY`, which also reports the run's estimated cost.
- Limits per run: at most 5,000 URLs (bad lines de-duplicated and written in one go), at most 4 pages in parallel, maximum memory 2 GB. Per page: at most 60 s of loading and waiting with the delay counted inside (90 s with the capture); a page making more than 1,500 requests is stopped (free row); popups are never opened.
- Pages taller than the max height are captured by enlarging the window, with window-height sections pinned to their normal size: about 1 s instead of 15 to 30 s and far less memory for very long pages. Big captures run one at a time; PNGs over 15 MB are saved as JPEG (larger images are refused).
- Comparisons: identical screenshots are not compared; images reach the comparison as binary (14 MB pairs compare in under 5 s); a comparison that fails makes the new screenshot the baseline (a charged `new` row) instead of failing for free on every run.
- Private networks: a host the guard cannot look up is refused (fail closed); the real server address of every response is checked (DNS rebinding); WebSockets are never opened.
- Monitoring memory: records of pages not checked for 30 days are deleted with their images (one small sweep a day).
- **24-hour cap per Apify account:** the cost guard's $0.05 per-run allowance now comes out of $0.40 of unpaid compute per account per 24 hours, across runs (template `AllowanceLedger`, one record in the fixed store `website-screenshot-monitor-limits`), so runs started back to back cannot add up to a large unpaid bill. A run stopped by it says so in plain words in its free `skipped` row and status message ("this Apify account has used today's allowance...; it resets within 24 hours"). If the record cannot be read, the run goes ahead. The guard now starts before the input is read, so the whole run counts.

### 0.1 (2026-10-30)

- First release: screenshots of any list of URLs in headless Chromium (Playwright): full page or window, desktop, mobile or tablet, custom window size, PNG or JPEG, optional A4 PDF (also from the leader's `format: "pdf"`), one element by CSS selector, wait for an element, extra delay, dark mode.
- Clean captures: cookie banners of about 25 consent tools and unknown banners found by their wording (only small boxes, never one holding the page's own content), their dark overlays and chat launchers are hidden (never clicked); lazy images are scrolled in; CSS animations and the text cursor are frozen.
- Visual change monitoring: each page is compared with its last reported screenshot in the browser (no image library), with the changed share of pixels, the changed area, the previous screenshot link and an image with the changes in red; colour differences up to 24 of 255 do not count and the default threshold is 0.1% of the page; changes-only rows, quiet first run, memory per task and per set of capture options (selectors in any order are one set); small changes add up until reported; a page that suddenly renders blank (at most 50 pixels of another colour) is held for one run (free) instead of raising a false alert.
- Safe billing and limits: screenshots charged only when delivered, comparisons only after their row; failed, blocked, login, not-found, blank and skipped pages are free rows; spending limit stops cleanly and re-reports undelivered changes; once a row is delivered, a failing charge or memory write (retried once) is logged and never adds an error row or a second charge; one failing page never fails the run; hard per-page time budget; every image at most 3,840 CSS pixels wide, 16,000 pixels tall and 16 megapixels, measured by Chromium (CDP) so page scripts cannot defeat the cap; bounded parallel pages; browser relaunch after a crash; maximum memory 4 GB.
- Never captures pages behind a login (401, redirects to login pages, visible password fields, also when a page breaks the in-page checks) or bot checks (reported as `blocked`).
- Private networks: URLs with private, local or reserved addresses are refused in any spelling (dotted, short `127.1`, hex, octal, IPv6, IPv4-mapped); every request a page makes is checked and requests to hosts that resolve to private addresses are aborted; a page whose redirect chain, final URL or frames lead to a private address gets a free `blocked` row. (WebSockets and DNS rebinding were covered in 0.1.1.)
- Known by design: older `previousScreenshotUrl` links stop working after two more changes of the same page (two screenshots per page are kept); the monitoring store grows with the number of monitored pages and capture settings until you delete it.
