Broken Link Checker & SEO Site Audit - 404s & Redirects avatar

Broken Link Checker & SEO Site Audit - 404s & Redirects

Pricing

from $3.00 / 1,000 page crawled and auditeds

Go to Apify Store
Broken Link Checker & SEO Site Audit - 404s & Redirects

Broken Link Checker & SEO Site Audit - 404s & Redirects

Crawl a website and check every internal and external link: 404s, 5xx, DNS errors, timeouts and redirect chains, with the page and anchor text. Plus an on-page SEO audit per page. Bot-blocked links are flagged, not false 'broken'. $0.003 per page.

Pricing

from $3.00 / 1,000 page crawled and auditeds

Rating

0.0

(0)

Developer

rj

rj

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

12 hours ago

Last modified

Features

Limited permissions

Share

Crawl any website and check every internal and external link it contains: 404s, 5xx errors, DNS failures, timeouts and redirect chains, each reported with the page it appears on and its anchor text. Every crawled page also gets an on-page SEO audit (title, meta description, H1, canonical, noindex, word count, images without alt). You pay $0.003 per page and all links on that page are checked at no extra cost, which is about 15x cheaper than per-link checkers on a typical page with 50 links. Links to big sites that block bots (LinkedIn, Amazon, Cloudflare captchas) are flagged as unverified instead of being reported as false "broken" links.

What data can you get

Item typeFields
broken-linklinkStatus (broken / timeout / redirect), statusCode, error (ENOTFOUND, ECONNREFUSED, SSL_ERROR, timeout), targetUrl, sourceUrl (page it's on), anchorText, linkType (internal / external / image), finalUrl, redirectChain
pageurl, statusCode, finalUrl, redirectChain, responseTimeMs, depth, title + length, metaDescription + length, h1, h1Count, canonical, metaRobots, noindex, lang, wordCount, internalLinks, externalLinks, brokenLinksOnPage, redirectLinksOnPage, unverifiedLinksOnPage, imagesWithoutAlt, issues[]
link (all-links mode)Same fields as broken-link, for every checked link, including ok, unverified and rate-limited ones
SUMMARY recordPages crawled, URLs checked, link counts by status, broken links by status code, top SEO issues, per-site results, requests and warnings

Link statuses: ok · broken (4xx/5xx, DNS error, connection refused, SSL error) · redirect (internal link that goes through 3xx hops) · unverified (external site answered 401/403/999 or a captcha/Cloudflare challenge, so it blocks bots and can't be verified) · rate-limited (429 even after a retry) · timeout (no answer in 8 s).

SEO issue codes: missing-title, title-too-long (>60 chars), title-too-short (<10), missing-meta-description, meta-description-too-long (>160), missing-h1, multiple-h1, noindex, canonical-other-page, images-missing-alt, slow-response (>3 s), broken-links, redirect-chain (the page was reached through a redirect, or links to internal URLs that redirect).

Use cases

  • SEO agencies: run a site audit for a new client and hand over a list of broken links with the exact page and anchor text to fix.
  • Site owners and marketers: find 404s after a migration or redesign, and internal links that still point at old (redirecting) URLs.
  • Link-building teams: find dead outbound links on a site (broken-link building outreach).
  • QA and developers: check a staging site or docs section before release; schedule it after deploys.
  • Monitoring: schedule it weekly with Only new broken links and get alerted only when something new breaks.

How to use

  1. Add one or more Start URLs (a homepage, or a section such as https://example.com/blog/ combined with an include pattern).
  2. Set Max pages per site (each page is one charged event).
  3. Run. Open the Broken links view for the fix list and the Page SEO audit view for on-page issues.

The crawler stays on the start URL's host (www. is ignored), follows links breadth-first up to Max crawl depth, and checks every link it finds (HEAD first, GET if the server refuses HEAD). Each URL is checked once per run, even if hundreds of pages link to it, and every occurrence is reported.

Input examples

Quick audit of a small site:

{
"startUrls": [{ "url": "https://books.toscrape.com/" }],
"maxPages": 10,
"checkExternalLinks": true
}

Only a documentation section, with broken images, every link listed:

{
"startUrls": [{ "url": "https://crawlee.dev/js/docs/quick-start" }],
"includeUrlPatterns": ["https://crawlee.dev/js/docs/*"],
"maxPages": 200,
"checkImages": true,
"outputMode": "all-links"
}

Weekly monitor that only reports new problems:

{
"startUrls": [{ "url": "https://quotes.toscrape.com/" }],
"maxPages": 500,
"onlyNew": true,
"excludeUrlPatterns": ["*/tag/*", "/\\?page=\\d+/"]
}

Patterns are globs where * matches anything (https://example.com/blog/*), or regular expressions wrapped in slashes (/\/docs\//). They decide which pages are crawled; links to other pages are still checked.

Output example

Real output from a 3-page run on quotes.toscrape.com (the site's author links redirect with HTTP 308, so they show up as internal redirect links):

[
{
"type": "page",
"id": "3379c189862fef41",
"url": "https://quotes.toscrape.com/",
"statusCode": 200,
"finalUrl": "https://quotes.toscrape.com/",
"redirectChain": [],
"responseTimeMs": 107,
"depth": 0,
"title": "Quotes to Scrape",
"titleLength": 16,
"metaDescription": null,
"metaDescriptionLength": 0,
"h1Count": 1,
"h1": "Quotes to Scrape",
"canonical": null,
"metaRobots": null,
"lang": "en",
"wordCount": 277,
"internalLinks": 47,
"externalLinks": 2,
"imagesWithoutAlt": 0,
"noindex": false,
"brokenLinksOnPage": 0,
"redirectLinksOnPage": 8,
"unverifiedLinksOnPage": 0,
"linksChecked": 49,
"issues": [
"missing-meta-description",
"redirect-chain"
],
"siteUrl": "https://quotes.toscrape.com/",
"scrapedAt": "2026-11-08T12:33:36.041Z"
},
{
"type": "broken-link",
"id": "37aea823408e082b",
"url": "https://quotes.toscrape.com/author/Albert-Einstein",
"sourceUrl": "https://quotes.toscrape.com/",
"targetUrl": "https://quotes.toscrape.com/author/Albert-Einstein",
"anchorText": "(about)",
"linkType": "internal",
"linkStatus": "redirect",
"statusCode": 200,
"error": null,
"finalUrl": "http://quotes.toscrape.com/author/Albert-Einstein/",
"redirectChain": [
{
"url": "https://quotes.toscrape.com/author/Albert-Einstein",
"statusCode": 308
}
],
"scrapedAt": "2026-11-08T12:33:36.041Z"
}
]

Pricing

Pay per event, no monthly fee:

EventPriceWhen
page$0.003One crawled and audited HTML page, including all of its link checks (deduplicated across the crawl, max 100 external links per page by default)

broken-link and link items are free. Pages that fail to load, non-HTML files and robots.txt-blocked URLs are not charged.

Worked example: a 200-page site costs 200 × $0.003 = $0.60, however many links it has. A per-link checker at $0.001 per link would charge about $10 for the same site at 50 links per page.

Set Maximum cost per run in the run options to cap spending: the Actor stops crawling cleanly when the budget is reached.

Tips and limits

  • Start small (maxPages 10-50) to see how many pages your site has; maxPages: 0 means no limit.
  • Large menus cost time, not money: a page with 300 internal links triggers up to 300 checks, but each URL is checked only once per run, so later pages are mostly cached and fast.
  • External links from datacenter IPs: some big sites (LinkedIn, Amazon, Instagram, Stack Overflow) answer bots with 403/999 or a captcha. These are unverified, not broken; check them by hand if they matter.
  • No JavaScript rendering: links that only exist after client-side JavaScript runs are not seen. Server-rendered and static sites (WordPress, Shopify, Docusaurus, Next.js SSR) work well.
  • robots.txt is respected for crawling by default; single link checks to disallowed URLs (one HEAD request each) are still made so you know whether they work.
  • url on link items is the link target; the page to fix is sourceUrl.
  • Concurrency defaults to 3 parallel requests per host, with an 8 s timeout and a retry for 5xx / 429 / connection resets.
  • Page and link items share one dataset. Each view shows its own columns but lists every item, so filter or sort by type when you export.

FAQ

Why is a link "unverified" instead of "broken"? The external site blocked the request as a bot (HTTP 401, 403, 999 or a Cloudflare/captcha page). The link probably works for humans. Reporting these as broken would flood your report with false positives.

Does a redirect count as broken? No. Internal links that redirect are reported with linkStatus: "redirect" and the full chain, because updating them to the final URL saves a hop and crawl budget. Turn off Report internal redirects to treat them as ok. External redirects are always ok.

How does "Only new broken links" work? The Actor remembers, per site, which broken links it reported in the previous run (in a named key-value store, broken-link-checker-state). Each run outputs only links that were not broken last time; page items are still output. A link that gets fixed and breaks again is reported again.

Can I use a proxy? Usually not needed. If your site blocks the run's IP, enable Apify Proxy (datacenter). Residential proxies are not supported: if selected, the Actor falls back to Apify datacenter proxy with a warning.

Is it legal? The Actor only requests public pages, like a browser or a search engine crawler would, and respects robots.txt by default. It does not log in or collect personal data. You are responsible for having the right to crawl the sites you audit and for complying with their terms and applicable law.

Integrations

  • API: start runs and fetch results with the Apify API or the JavaScript / Python clients:

    curl -X POST "https://api.apify.com/v2/acts/rjmacarthy~broken-link-checker/run-sync-get-dataset-items?token=YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"startUrls":[{"url":"https://example.com/"}],"maxPages":50}'
  • Make, Zapier, n8n: send new broken links to Slack, e-mail, Google Sheets or Jira.

  • MCP: use it from Claude, Cursor or any MCP client through the Apify MCP server.

  • Schedules and webhooks: run weekly and trigger an alert when the run finishes.

Changelog

  • 0.1 (2026-11): first release: link checking (HEAD/GET fallback, dedupe, unverified detection), redirect chains, on-page SEO audit, all-links mode, only-new monitoring.

More scrapers by the same developer

Browse all my Actors on my Apify Store profile.

Support

Found a bug or need a feature? Open an issue on the Actor's Issues tab and include the run ID.