Broken Link Checker: Find Broken Links, Images & Redirects
Pricing
from $0.50 / 1,000 link checkeds
Broken Link Checker: Find Broken Links, Images & Redirects
Broken link checker: crawl a website and find broken links, 404 pages, dead images, redirect chains and mixed content, with the pages where each broken link appears. Never charges for a failed or empty result.
Pricing
from $0.50 / 1,000 link checkeds
Rating
0.0
(0)
Developer
Pavel Tashev
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
24 days ago
Last modified
Categories
Share
What does Broken Link Checker do?
Broken Link Checker crawls your website and checks every link, image, script, stylesheet and embed once, then tells you exactly which links are broken and on which pages they appear. Enter a website such as example.com and it finds 404 pages, server errors, dead domains (DNS failures), timeouts, SSL problems, redirect loops, long redirect chains and insecure (mixed content) resources.
Each problem is one row with every page that links to it, the link text, a plain-language explanation and the full redirect chain, so you know what to fix and where. Because it runs on the Apify platform, you get API access, scheduling (weekly site-health checks), webhooks, integrations (Make, Zapier, n8n, Google Sheets, Slack) and run monitoring.
What you pay for
Every unique link checked is charged once, including links that turn out to be fine and links that are filtered out of the results when Report all links is off. A link that appears on 50 pages is checked and charged once. Crawling the pages to find those links is free.
Two ceilings keep a run predictable: maximum pages to crawl (default 500) and maximum links to check (default 5,000) per website. Sites with faceted search or calendars can generate far more links than pages, so raise the link ceiling deliberately rather than by accident.
You are never charged for a failed or empty result
This Actor charges per link checked, because the check is the work. Its item-level status field is the HTTP status code; the result quality lives in category.
category | Meaning | Charged |
|---|---|---|
ok | The link works | Yes — every link checked is work done |
broken | 404, dead domain, timeout or TLS failure | Yes — the check is the work |
redirect / possibly-blocked | Moved, or the site refused automated checks | Yes — the check is the work |
| (link never checked) | The website could not be crawled at all | No |
| (stopped at your cost limit) | Remaining links are not checked | No |
If every input fails, the run itself fails with an explanation instead of reporting success with no data.
Why use Broken Link Checker?
- SEO and user experience: broken links waste crawl budget and frustrate visitors; redirect chains slow pages down.
- Website migrations and redesigns: verify that nothing broke after moving pages or changing URLs.
- Content audits: find dead outbound links in old blog posts and documentation.
- Fewer false alarms: sites that block bots (HTTP 401/403/429, Cloudflare challenges) are marked possibly-blocked, not broken, and every failed HEAD request is confirmed with a GET before it is reported.
- Scheduled monitoring: run it weekly and get a webhook or email only when new broken links appear.
How to find broken links on a website
- Click Try for free.
- In Websites to check, enter one or more websites or pages (for example
example.com). - Optionally set Maximum pages to crawl per website and Maximum crawl depth.
- Click Start.
- Open the Output tab. Overview lists broken, blocked and redirected links with the pages where they appear; Redirects shows each redirect chain. A summary per website is in the key-value store as
SITE_SUMMARY.
Input
| Field | Description | Default |
|---|---|---|
| Websites to check | Websites, domains or start pages. Pages on the same website are crawled; links to other websites are checked but not crawled | – |
| Maximum pages to crawl per website | Crawl limit (up to 2,000); all links on crawled pages are still checked | 500 |
| Maximum links to check per website | Cost ceiling: the run stops checking a website after this many unique links | 5,000 |
| Maximum crawl depth | Clicks away from the start page (0 = only the start page's links) | 5 |
| Check links to other websites | Check external links too | on |
| Check images, scripts and stylesheets | Also check img (including srcset), script, stylesheets, icons, iframe, video, audio | on |
| Report redirected links | Include working links that redirect, with the chain | on |
| Report all links | Save working links as well | off |
| Detect soft 404 pages | Pages that return 200 but say "not found" in the title count as broken | off |
| Also crawl pages from the sitemap | Add sitemap pages, so orphan pages are checked | off |
| Skip URLs matching | Glob (*/tag/*), text (/cart) or regex between slashes | none |
| Respect robots.txt | Skip pages and links the website's robots.txt disallows. Turn off only for websites you own | on |
| Parallel requests | Total parallel checks (same-host requests are limited to half, 4–10) | 10 |
| Request timeout (seconds) | Slower links are reported as timeout | 15 |
| Identify as a web browser | Send a Chrome User-Agent instead of BrokenLinkChecker/1.0 | off |
| User agent | Send your own User-Agent string instead of the built-in one. Overrides the toggle above. | – |
| Report links slower than (ms) | Mark links that took at least this long with isSlow. 0 turns it off. | 0 (off) |
| Maximum redirects to follow | 1–20. A link needing more hops is reported as too-many-redirects, which counts as broken. | 10 |
Example input:
{"startUrls": ["example.com"],"maxPagesPerSite": 1000,"excludePatterns": ["*/tag/*", "/\\?replytocom=/"]}
Output
One item per problem link. Real examples from a run on 15 September 2026 against crawler-test.com (a public test site full of intentional errors):
{"site": "https://crawler-test.com","linkUrl": "https://crawler-test.com/redirects/redirect_1","finalUrl": "https://crawler-test.com/redirects/redirect_target","status": 200,"statusCode": 200,"category": "redirect","message": null,"isExternal": false,"linkType": "a","mixedContent": false,"redirectChain": [{ "url": "https://crawler-test.com/redirects/redirect_1", "status": 301 },{ "url": "https://crawler-test.com/redirects/redirect_target", "status": 200 }],"sourceCount": 1,"sourcePages": [{ "pageUrl": "https://crawler-test.com/", "anchorText": "Redirect 301", "element": "a", "attribute": "href" }],"checkedAt": "2026-09-15T12:07:24.193340+00:00"}
A broken link looks like "status": 404, "category": "broken", "message": "HTTP 404: the page was not found."; a dead domain like "status": "dns-error", "message": "The domain name could not be resolved (DNS failure); the domain may not exist.".
That run crawled 29 pages and checked 414 unique links in 60 seconds: 70 broken, 11 redirects, 5 possibly blocked, 2 mixed-content resources, 13 URLs skipped because robots.txt disallows them.
You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.
Output fields
| Field | Meaning |
|---|---|
category | broken, redirect, possibly-blocked or ok |
status | HTTP status code, or an error: dns-error, timeout, ssl-error, connection-refused, connection-error, too-many-redirects, invalid-redirect, protocol-error, soft-404 |
statusCode, message | Numeric HTTP status (when there was a response) and a plain-language explanation |
linkUrl, finalUrl | Link as found (normalized, without #fragment) and where it ends up after redirects |
redirectChain | Every hop with its status code |
linkType | Element the link came from: a, img, script, link, iframe, source, video, audio, sitemap |
isExternal, mixedContent | Points to another website; http:// resource embedded in an https:// page |
sourcePages, sourceCount | Up to 20 pages containing the link (with anchor text) and the total number of occurrences |
site, checkedAt | Website crawled and check time (UTC) |
SITE_SUMMARY (key-value store) has per website: pages crawled, links checked, broken, redirects, blocked, mixed content, URLs skipped by robots.txt, whether robots.txt was respected (robotsTxtRespected), and the 10 pages with the most broken links.
How much does it cost to check a website for broken links?
This Actor uses pay-per-event pricing: you pay per unique link checked (each URL is checked once per run, however many pages link to it). Crawled pages count as links. Platform compute is included. See the Pricing tab for the price per 1,000 links. A typical 200-page small-business site has 1,000–3,000 unique links.
You can set a maximum cost per run: the Actor stops starting new checks when the budget is reached and still saves everything checked so far.
Finding slow links as well as broken ones
Set Report links slower than (ms) and every checked link gains two fields: responseTimeMs, the wall time
for the whole check with redirect hops included and our own polite pacing excluded, and isSlow.
A slow link is never counted as broken. It keeps whatever verdict its status code earns, and isSlow sits
beside that verdict rather than replacing it — a page that takes four seconds and returns 200 is a working page
that needs attention, not a dead one, and reporting it as dead would put a false claim in front of whoever
reads your report.
responseTimeMs is filled in for every check, even without a threshold, so you can sort by it afterwards. It is
null only when no response arrived at all, such as a DNS failure — an unknown time is reported as unknown
rather than guessed at as zero.
Tips
- Start small: try 50 pages first to see how many links your site has.
- Big sites: raise Parallel requests to 20–30 and exclude endless URL patterns (calendars, filters,
?sort=), or turn off external links. - Many
possibly-blockedlinks? Social networks and some CDNs block automated checks. Turn on Identify as a web browser, or simply verify those few links manually. - Long crawls: increase the run timeout; the Actor stops starting new checks two minutes before the timeout and saves results.
- Orphan pages: turn on Also crawl pages from the sitemap.
Related tools
More website audit tools:
- Sitemap URL Extractor: list every URL of a website from its sitemaps, or only new and removed pages.
- SEO Audit & Metadata Checker: check titles, meta descriptions, canonicals and other on-page SEO for pages or whole sites.
- Website Tech Stack Detector: detect the CMS, frameworks, analytics and hosting of any website.
FAQ, limitations and support
Does it respect robots.txt? Yes, by default. Pages disallowed for crawlers are not requested and are counted in SITE_SUMMARY.
Can I check my own site even when its robots.txt blocks crawlers? Yes — turn Respect robots.txt off. Many sites Disallow: / for everything except search engines, which stops a link check of your own site before it starts. With the toggle off we do not request /robots.txt at all: nothing is skipped for robots reasons, skippedByRobotsTxt and skippedUnreadableRobotsTxt are 0, robotsTxtRespected is false in SITE_SUMMARY, and the run's status message says so. Because robots.txt is not read, sitemaps are then looked for at the usual addresses (/sitemap.xml, /sitemap_index.xml, …) instead of the ones robots.txt names. Only turn it off for websites you own or have permission to crawl — you take responsibility for the requests, and every other limit still applies unchanged: the per-website link and page ceilings, the crawl depth, the parallel-request limits and the run timeout.
What happens when a site won't let us read its robots.txt? Some sites put their /robots.txt behind bot protection and answer 403 or time out. We then can't tell what the site allows, so we follow one rule everywhere: the address you entered is still read, and addresses we would have worked out ourselves are not. A site with no robots.txt at all (404) is treated as allowing everything. For this Actor that means the start URL you entered is still checked, but the crawl does not follow links deeper into that site and no sitemap is guessed. SITE_SUMMARY counts those separately as skippedUnreadableRobotsTxt, so you can tell them from pages a real Disallow rule covered. If it is your own site, turning Respect robots.txt off lifts this too. It uses at most 4–10 parallel requests per host with small delays.
Does it run JavaScript? No. It reads the HTML the server sends, like search engines' first pass. Links added only by JavaScript are not found.
What about email and phone links? mailto:, tel: and javascript: links are skipped and never saved.
Why is a working link marked possibly-blocked? The server refused an automated request (401, 403, 429, 999 or a Cloudflare/Akamai challenge). It usually works in a browser.
Something wrong or missing? Open an issue in the Issues tab. Custom website audits and integrations are available on request.
Only check websites you are allowed to crawl.