Crawl a site politely and check every internal and external link, image, script and stylesheet: 404s, dead domains, redirect chains and loops, mixed content and missing #anchors. Report grouped by source page, CSV/PDF export, monitoring and Slack alerts.
Fix: when the max total charge runs out, start URLs that were not reached now each get a free error row ("Not checked: max total charge reached before this site (nothing charged)") instead of being silently left out, and the status message starts with "Partial (max total charge reached)" and says how many sites were not checked.
Fix: the status message no longer says "Reports in the key-value store" when the report did not fit in the budget. The summary row then has reportsNote; the report is not charged.
Fix: a site whose pages, links or report were stopped by the max total charge is now partial: true (was false with stoppedBy: "budget"). The summary row and SUMMARY record carry partialReason ("budget" or "time", was the English note) and a new partialNote with the plain-English text; stoppedBy says "time" for the run time limit (was "budget"), budgetStop is true only for a budget stop. The HTML/PDF report shows the PARTIAL RESULT banner for budget stops too, unchecked links say "Not checked: max total charge reached (not charged)", and a budget-limited check never becomes the monitoring baseline.
Privacy: the crawler user agent now carries the role contact hello@webrevenuescan.com.
Billing: links refused by our own safety guard (private, local or internal address, directly or on a redirect hop) are no longer charged as link-checked. Their row says "Refused: … not checked and not charged", and every link row now has charged: true/false.
Dependencies: patch updates follow-redirects 1.16.2, undici 7.30.1, ip-address 10.7.5 (lockfile only; clears both high npm audit advisories).
Security: a refused alert webhook URL is never repeated in the error or status message (fixed wording instead).
1.0.6 — 15 Oct 2026 (public-15 remediation)
Default run memory is now really 1,024 MB (defaultMemoryMbytes in actor.json). The old defaultRunOptions key is not read by Apify, so runs silently used 4,096 MB; measured peak use was 83 MB. You can still choose more memory per run.
The Console example (prefill) now scans 5 pages instead of 30, so the first run finishes in about 1.5 minutes instead of about 4.5 (the old example used 272 of 300 seconds). Defaults for API and scheduled runs are unchanged (300 pages).
1.0.x — 15 Oct 2026
Fix: runs no longer hit the platform timeout and lose all results. The Actor now reads its run time limit and stops starting new page scans and link checks before it, keeping a reserve to save the dataset and reports. Unchecked targets are listed as not-checked; the status message says "Partial (run time limit)". The summary row and SUMMARY carry partial: true with a plain-English partialReason, the HTML and PDF reports show a "PARTIAL RESULT" banner with the number of unchecked targets, unchecked links say "Not checked: run time limit reached", and a partial check is not saved as the monitoring baseline. Complete runs have partial: false and no partial wording.
Cause: 818 internal targets checked one host at a time with the polite 500 ms delay needed ~7 minutes, longer than a 5-minute run.
1.0.0 — 2026-10-11
First release.
Polite crawl (robots.txt on every host and hop, sitemap seeding, per-host pacing for your site and for each external host).
Each unique link target is checked once. HEAD is used with a GET fallback, and HEAD failures are confirmed with GET.
Finds broken links and resources, dead domains, redirect chains and loops, internal links to redirects, missing #anchors (same-page and cross-page), active/passive mixed content and http links to your own https site.
Honest "unverifiable" class for 401/403/429/999 (never reported as broken) and "robots-skipped" for disallowed targets.
Report by source page: HTML, PDF, CSV and a JSON summary. Monitoring diff and Slack/webhook alerts (HTTPS only, secret input).