Broken Link Checker from Sitemap avatar

Broken Link Checker from Sitemap

Pricing

from $0.70 / 1,000 link checkeds

Go to Apify Store
Broken Link Checker from Sitemap

Broken Link Checker from Sitemap

Check every page in your XML sitemap for broken links. It reads the sitemap, visits each page and checks the links on it. You get 404s, server errors, redirect chains and slow pages, each with the page it was found on. If a site blocks the run, a row says why. Export to CSV or JSON.

Pricing

from $0.70 / 1,000 link checkeds

Rating

0.0

(0)

Developer

Brian Gomes

Brian Gomes

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 hours ago

Last modified

Share

Broken Link Checker from Sitemap checks every page in a website's XML sitemap, and the links on those pages, and lists each broken one with the page it's on.

What it does

Give it a website or a sitemap URL. It reads the sitemap, checks the status of every page in it, then opens each page and checks the links it finds there. You get one row per problem: a 404, a server error, a redirect or a slow response, with the page the link was found on.

It starts from the sitemap, not from a crawl. So it checks the pages the site says it has, including ones no menu links to anymore.

When something goes wrong, the run doesn't fail silently. A site with no sitemap, a 403, a 429 or a timeout gives you a row that says what happened.

Here's what five rows look like:

resultlinkUrlstatusCodesourcePage
brokenhttps://example.com/old-pricing404https://example.com/blog/launch
brokenhttps://partner.example.org/guide500https://example.com/docs/start
brokenhttps://example.com/careers404https://example.com/sitemap.xml
redirectedhttp://example.com/about200https://example.com/
ok (slow)https://example.com/files/spec.pdf200https://example.com/docs/api

(Example data. A page from the sitemap that is itself broken shows the sitemap as sourcePage. For a redirected link, statusCode is where the redirects end and redirectCount says how many there were.)

Who it's for

  • SEO audits. Find every broken internal link before a search engine does.
  • After a site migration. Check that every page in the new sitemap loads and nothing still points at an old URL.
  • Content and docs teams. Find links to partner sites and files that have gone dead since the page was written.
  • Scheduled checks. Run it weekly and catch a broken link the week it breaks.

Input

FieldWhat it doesDefault
Websites or sitemap URLsOne or more homepages (https://example.com) or sitemaps (https://example.com/sitemap.xml). It works out which one you gave it.none, required
Maximum pages to scanStops after this many pages from the sitemap. Use it to test on a big site first.100
Maximum links to checkStops after checking this many unique links.5,000
Check external linksAlso checks links that go to other websites. Off: only links on your own site (with or without www.).on
Include working linksAlso lists links that answered 200 quickly with no redirect. Off: only broken, redirected, slow and unchecked links are listed.off
Slow response threshold (ms)A page or link that takes longer than this to respond is flagged slow, and always listed.3,000
Maximum concurrent requestsRequests in flight at once, never more than 4 to one site.5
Request timeout (seconds)The most any one page or link request may take, from connecting to the last byte.20

Input field names in the API: startUrls, maxPages, maxLinks, checkExternalLinks, includeOkLinks, includeNotChecked, slowThresholdMs, maxConcurrency, requestTimeoutSecs.

The form starts small: 10 pages and up to 100 links, so your first run costs at most $0.11. Raise both when you're ready for the whole site.

Example input:

{
"startUrls": [{ "url": "https://example.com" }],
"checkExternalLinks": true,
"maxPages": 500
}

Output

One row per problem link on each page it's on (and per working link too, with "Include working links" on), plus a row for anything it couldn't read. Export it from the Console as CSV, JSON, Excel, XML or HTML, or read it through the Apify API.

FieldWhat it holds
typelink for a page or link that was checked, error for something it couldn't read (no sitemap, a sitemap that failed).
resultbroken (4xx, 5xx, timeout, unreachable or a malformed URL), redirected (ended on a working page after one or more redirects), ok, not-checked (robots.txt said no, it was over maxLinks, or the run stopped first; error says which; only listed when includeNotChecked is on, otherwise counted by reason in the run's status message), or error.
sourcePageThe page the link was found on. For a page from the sitemap, the sitemap it's listed in.
linkUrlThe link that was checked.
anchorTextThe link's visible text (or its image's alt text), up to 300 characters.
isInternaltrue when the link is on the same site as your input (with or without www.).
statusCodeThe HTTP status code it ended on.
finalUrlWhere the URL ends up after redirects.
redirectCountHow many redirects it followed.
responseTimeMsTime to the response headers, in milliseconds, redirects included.
slowtrue when the response took longer than your threshold.
foundInpage for a link found on a page, sitemap for a page listed in the sitemap.
errorEmpty when the row is fine. Otherwise it says what went wrong, like HTTP 404, timed out after 20 s or not checked: disallowed by robots.txt.
startUrlThe input this row came from.

Example row (JSON):

{
"type": "link",
"result": "broken",
"sourcePage": "https://example.com/blog/launch",
"linkUrl": "https://example.com/old-pricing",
"anchorText": "see our pricing",
"isInternal": true,
"statusCode": 404,
"finalUrl": "https://example.com/old-pricing",
"redirectCount": 0,
"responseTimeMs": 212,
"slow": false,
"foundIn": "page",
"error": "HTTP 404",
"startUrl": "https://example.com/"
}

Pricing

You pay per page scanned and per link checked. There's no monthly fee.

  • Each page from the sitemap that answers: $0.0005 (50 cents per 1,000 pages).
  • Each link checked: $0.001 (1 dollar per 1,000 links), on top of the page price. A link that appears on many pages is checked and charged once, and reported on every page it's on. A link to a page it has already opened isn't checked or charged again.
  • Not charged: anything robots.txt disallows, links it never requested because the run stopped, links and pages that time out or can't be reached (reported as broken, with the reason), and malformed links (reported as broken without a request).

A worked example. A site has 500 pages in its sitemap and 3,000 unique links across them.

  • Pages and links: 500 × $0.0005 + 3,000 × $0.001 = $0.25 + $3.00 = $3.25.
  • Internal links only (Check external links off): the same sum with only the links on your own site counted. If 1,200 of the 3,000 are internal, that's $0.25 + $1.20 = $1.45.

Apify also charges its standard start fee for each run. Set Maximum pages, or a maximum cost per run, for a hard ceiling: the run checks nothing it can't charge for, stops cleanly when it reaches your maximum cost, and its status line says so.

How it handles the hard cases

  • No sitemap. You get one row with the error "no sitemap found" and nothing else is charged. The run finishes normally.
  • Nested sitemap indexes and gzipped sitemaps. It reads them the same way as Sitemap URL Extractor & Status Checker.
  • 403 and 429. A blocked request or a rate limit is recorded in the error field instead of failing the run. It doesn't retry a 429 in this version.
  • Redirect chains. It follows up to 10 redirects and records how many it took. A link that redirects is reported even when it ends on a 200, so you can point it at the final URL.
  • A site that stops answering. After 20 requests in a row get no answer (or 10 minutes spent waiting on them), the run stops and its status line says why, rather than timing out page after page for hours. Those requests aren't charged.
  • Typos in links. A link with a broken host name (like http://www..example.com/) or a bad port is reported as broken, with the reason, and the run carries on.
  • Private addresses. It never connects to a private, internal or loopback address, even when a page links there or a redirect points there. Those links are listed with the reason.
  • Spreadsheet safety. Anchor text that starts with =, +, - or @ gets a leading ' so a CSV opened in Excel or Sheets can't run it as a formula.
  • Timeouts. A page or link that doesn't answer in time is recorded as an error row. The timeout covers the whole request, from connecting to the last byte, and is 20 seconds unless you change it. The row's error says timed out after 20 s.
  • robots.txt. It respects robots.txt on your site and on every site it checks a link on. A disallowed URL is counted in the status message (listed only with includeNotChecked on), not fetched, and not charged. If robots.txt itself returns a server error, it requests nothing else on that site and counts those links as not checked. If the site can't be reached at all (no DNS, connection refused, timeout), its links are reported as broken, with the reason, and not charged.
  • Load on the site. At most 4 requests at a time to any one host, and it honours a Crawl-delay of up to 10 seconds; a site asking for longer has its URLs counted as not checked rather than holding your run for hours. It identifies itself with an honest user agent, SitemapBrokenLinkChecker/0.1.

Compared with the free tools

You can do this for free. Google Search Console lists 404s that Google found on your site. The W3C Link Checker checks one page's links in a browser. Desktop crawlers like Screaming Frog check a whole site, and the free version stops at 500 URLs. For a small site, one of those is enough.

This Actor fits when the site is bigger, when you want it on a schedule, or when you want the result in your own code through the API. It runs in the cloud, so nothing has to stay open on your computer.

Compared with other broken link checkers in the store, the difference is the starting point. It checks every page the sitemap lists, including orphan pages a crawl would never reach. And a site it can't read gives you a row that says why, not a failed run.

FAQ

How do I find broken links on my website? Put your homepage or sitemap URL in the input and run it. Every row in the result is a page or link that returned an error, redirected, was slow or couldn't be checked, and result says which. Export it as CSV and fix from the top.

What counts as a broken link? Any link that returns a 4xx or 5xx status, times out or can't be reached. Redirects and slow responses are reported too, but they're flagged separately (result is redirected; slow is true) so you can tell them apart.

Why was I charged for links that weren't broken? Every link has to be checked to know whether it's broken. With "Include working links" off, the good ones are left out of the dataset, but they were still checked. A link on many pages is charged once.

Does it check links to other websites? Yes, with "Check external links" on. Turn it off to check only links within your own site.

Why did my run return nothing? Check the error field. It says "no sitemap found", a status like 403, or a timeout. If your sitemap lives somewhere unusual, put its full URL in the input instead of the homepage.

Does it respect robots.txt? Yes, on your site and on every site it checks a link on. It also limits how fast it requests pages from any one host.

Can I run it on a schedule? Yes. Use Apify Schedules to run it weekly with the same input. Each run makes a new dataset, so you can see what broke since last time.

Can I call it from my own code? Yes. Start it and read the results through the Apify API or the Python and JavaScript clients. It also works with webhooks, Make, Zapier and Google Sheets.

Limits

  • It checks the pages in your sitemap and the links on them. It doesn't follow links further than that, so a page that isn't in the sitemap is only checked if a sitemap page links to it, and its own links aren't followed.
  • It reads links from the HTML as served. Links added later by JavaScript aren't seen.
  • It checks links in <a href> (and image-map <area href>) only. Images, scripts and stylesheets aren't checked in this version. It reads the first 5 MB of each page and the first 5,000 links on it; a page past either limit says so in a row.
  • It works on public pages. It doesn't log in.
  • It reads XML sitemaps, including gzipped ones. Plain-text and RSS sitemaps aren't read in this version.
  • It runs in 256 MB by default. A sitemap file over 55 MB uncompressed is refused.

Integrations

This Actor runs on Apify, so everything the platform does works with it.

  • API. Start a run and read the results from your own code, in any language. Apify API
  • Schedules. Run it weekly and catch a broken link the week it breaks. Schedules
  • Tasks. Save your input once as a task and run it again with one click, or on a schedule. Tasks
  • Webhooks. Get a call to your own URL when a run succeeds or fails. Webhooks
  • Google Sheets and Drive. Download the results as CSV or Excel and open them in Sheets. Or add a Google Sheets step after this Actor in Make or Zapier. Or send the files to a Google Drive folder. Datasets and exports, Google Drive
  • Zapier, Make and n8n. Start a run from another app and send the results on to the next step. Zapier, Make, n8n
  • AI agents (MCP). Claude, ChatGPT and other MCP clients can find and run this Actor through the Apify MCP server. Apify MCP server
  • Other Actors. Pass this Actor's results to another Actor when a run finishes. Actor-to-Actor

Works with

Support

Found a bug or need a feature? Open an issue on this Actor's Issues tab. Include the run ID and the URL you gave it.