Broken Link Checker & Sitemap Validator (Monitor Mode)
Pricing
from $1.40 / 1,000 page crawleds
Broken Link Checker & Sitemap Validator (Monitor Mode)
Find broken links, 404s, redirects and sitemap errors on your site. A 4xx is confirmed with GET, temporary errors are retried and bot-blocked links are re-checked in a real browser. Optional monitor mode flags only new issues. No subscription: pay per page and per link.
Pricing
from $1.40 / 1,000 page crawleds
Rating
0.0
(0)
Developer
Mateus Correia
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 hours ago
Last modified
Categories
Share
Find broken links, 404s, redirects and sitemap errors. In monitor mode, get alerted only about new ones.
This broken link checker crawls your site, status-checks the links, images, scripts and stylesheets on the pages it crawls (up to maxLinksToCheck unique URLs), and validates your XML sitemap. A 4xx is confirmed with a GET request before it's reported, and 5xx, 408, 429 and network errors are retried. Bot-blocked links are re-checked in a real browser; if they still can't be verified, they're a warning, not an error.
Use cases
- SEO agencies: a weekly link and sitemap check per client, with an HTML report.
- Site owners: catch dead links after a migration or a deleted page.
- Developers: run it after a deploy and fail the pipeline when
errors > 0.
Sample output (shortened, real run of the example input: web-scraping.dev with limits of 20 pages, 300 link checks and 50 sitemap URLs):
{"category": "link","issueType": "broken-link","severity": "error","url": "https://web-scraping.dev/api/graphql","statusCode": 404,"explanation": "HTTP 404 Not Found.","foundOnCount": 18,"firstFoundOn": "https://web-scraping.dev/","anchorText": "Graphql","checkedWith": "HTTP GET"}
That run took 27 seconds: 19 pages crawled, 108 link checks (85 page links + 23 sitemap URLs not already checked; the other 27 sitemap URLs reused earlier results at no charge). Cost: 19 × $0.002 + 108 × $0.0005 = $0.092.
No subscription. You pay $0.002 per page crawled and $0.0005 per link checked, only when it runs.
What does it check?
| Result | What it means | How it's verified |
|---|---|---|
broken-link | 4xx such as 404, 410 or 400 | HEAD first; any failure is re-checked with GET |
server-error | 5xx that keeps failing | Retried with backoff; Retry-After is respected |
unreachable | DNS, connection or certificate failure | Re-checked; reason given in plain language |
blocked-unverified | Possible bot protection (403, 429, 999, Cloudflare). Not proof the link is broken | Retried, then the first 25 (by default) are opened in headless Chrome. A browser 404/410 is reported as broken; the rest stay a warning |
soft-404 | Answers 200 but shows a "not found" page | Compared with your site's 404 response and "not found" titles in several languages |
redirect, redirect-chain, redirect-loop | The link redirects, once, several times or in a loop | Every hop is recorded |
login-required, malformed-url | HTTP 401 (info only); an href that isn't a valid URL | – |
Each unique URL is checked once per run, including sitemap URLs already checked as links. Every row lists where the link was found (up to 25 pages) and how it was checked (checkedWith).
Sitemap validator
It finds sitemaps via robots.txt or common locations, follows indexes and .gz files, and reports:
- Sitemap URLs that are broken, redirect, are soft 404s, need a login or are blocked by robots.txt.
noindexpages in the sitemap, which send search engines contradictory signals, and canonicalised URLs whose canonical tag points elsewhere.- Orphan pages (in the sitemap, but nothing links to them) and pages missing from the sitemap.
- File problems: missing sitemap, no
<urlset>/<sitemapindex>root, over 50,000 URLs or 50 MB uncompressed, bad<lastmod>, duplicates, a brokenSitemap:line in robots.txt.
It checks structure, not the full XML schema. Reading stops at maxSitemapUrls. URLs pointing to another host are flagged, not checked.
Input
| Field | Description | Default |
|---|---|---|
startUrls | Your site, usually the homepage. Other sites are checked, not crawled. | – |
maxPagesToCrawl | Internal pages to crawl for links | 100 |
maxLinksToCheck | Cap on unique URL checks (links, resources and sitemap URLs) | 2,000 |
checkExternalLinks, checkResources | Also check links to other sites, and images, scripts and stylesheets | true |
validateSitemap, sitemapUrls, maxSitemapUrls | Validate the sitemap; extra sitemap URLs; how many sitemap URLs to read | true, –, 500 |
verifyBlockedInBrowser, maxBrowserChecks | Re-check bot-blocked links in headless Chrome (free) | true, 25 |
renderJavaScript | Find links added by JavaScript (slower; use 2 GB+ memory) | false |
reportRedirects | Which redirecting links to report: internal, all or none | internal |
excludeUrlPatterns | Skip URLs matching these regular expressions or plain text | – |
monitorMode, monitorStoreName, outputOnlyNewIssues, alertOn | Compare with the previous run; output or alert on new issues only | off, new-errors |
webhookUrl | Slack, Discord, n8n, Make or Zapier webhook | – |
notificationEmail | Optional email alert | – |
maxConcurrency, requestTimeoutSecs, proxyConfiguration | Advanced | 16, 20, none |
The Console form is prefilled with smaller limits (20 pages, 300 link checks, 50 sitemap URLs) for a quick first try; the defaults apply when a field is empty. Several start URLs share one budget, so use one run or Task per site.
Output
One dataset row per issue, sorted by severity, then a category: "summary" row with the totals (pagesCrawled, linksChecked, errors, brokenLinks, crawlComplete, and in monitor mode newIssues and resolvedIssues). It's always added, even when nothing is wrong.
The key-value store holds report.html (a shareable report) and OUTPUT (the summary as JSON).
Monitor mode and scheduled checks
Monitor mode is off by default. For a scheduled check that reports only changes:
- Turn on Monitor mode and save the input as a Task, one per site.
- In Apify Console, open Schedules and add the Task with a cron expression, for example
0 6 * * 1for Mondays at 06:00. - Add a
webhookUrl. WithalertOn: new-errors(the default), an alert is sent when a new error appears or when an earlier issue is resolved.
Each issue gets isNew and firstSeenAt. The first run is the baseline: every issue on it is new, so it alerts on every error. Set maxPagesToCrawl above your site's page count: when the limit is hit, different pages can be crawled each run and issues can flip between new and resolved. See Apify schedules.
Use it from n8n, Make and Zapier
Apify's official integrations can run a Task, get its dataset items, or start a workflow when a run finishes. For example:
- Client sheet: append the
summaryrow's totals to a Google Sheet. - Ticket per new broken link: with monitor mode on, filter rows with
isNew: trueandseverity: "error"and create a Jira, Linear or Trello card. Skip the first (baseline) run, or it will open a card for every existing issue. - After a deploy: run the Task and stop the release when the summary has
errors > 0.
The webhook sends JSON with a text field (Slack, n8n, Make, Zapier) and a content field (Discord). Guides: n8n, Make, Zapier.
Pricing (pay per event)
| Event | Price |
|---|---|
Page crawled (page-crawled): an HTML page on your site downloaded and scanned for links | $0.002 |
Link checked (link-checked): each unique URL status-checked, including sitemap URLs | $0.0005 |
Crawled pages aren't also charged as link checks. Retries, browser re-checks, the summary row and the report are free.
Example: a 100-page site with 2,000 unique URLs (the 100 pages plus 1,900 other links, images, scripts and sitemap URLs) costs 100 × $0.002 + 1,900 × $0.0005 = $1.15 per check. That's about $5 a month weekly or $35 a month daily. With the default limits one site costs at most about $1.20 per run. Set Maximum cost per run for a hard cap; the Actor stops cleanly when it's reached.
FAQ
Will it report links that actually work? It tries not to, but bot protection makes some links impossible to verify. Those are warnings to check by hand; exclude sites that always block it.
I run a shop. Why are there so many URLs?
Each query-string variant (?sort=, filters, ?add-to-cart=) is a separate URL and is charged separately. Add patterns such as \?sort=, \?filter or add-to-cart to excludeUrlPatterns.
Do I need email alerts?
No, they're optional. If you enter an address, the alert is sent by Apify's apify/send-mail Actor on your own account, which uses a little platform credit.
Limitations
- Crawling stays on the start URL's site. Other subdomains are checked as links but not crawled.
- Links built by JavaScript are only found with
renderJavaScript. Images referenced in CSSurl()aren't checked. - Every 403 is treated as possible bot blocking and reported as
blocked-unverified, even when the page really is forbidden. - Bursts of 403 or 429 answers from big external sites are reported as warnings. The Actor doesn't yet slow down automatically for those sites.
- Links are checked before sitemap URLs, so when
maxLinksToCheckruns out, remaining sitemap URLs are skipped. - Orphan pages are only reported when the whole site was crawled and the sitemap fully read; missing-from-sitemap needs a fully read sitemap.
Keywords
Broken link checker, dead link checker, 404 checker, sitemap validator, link monitor, redirect checker, soft 404 checker.