# Broken Link Checker - Find Dead 404 Links (`logiover/broken-link-checker`) Actor

Site-wide broken link checker: crawl any website, find 404 and dead links, export the link audit to CSV or JSON with source page and status code.

- **URL**: https://apify.com/logiover/broken-link-checker.md
- **Developed by:** [Logiover](https://apify.com/logiover) (community)
- **Categories:** SEO tools, Developer tools
- **Stats:** 26 total users, 8 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Broken Link Checker — Crawl a Whole Website for Dead 404 Links (No API Key) 🔗

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-00A8E8?logo=apify\&logoColor=white)](https://apify.com/logiover/broken-link-checker)
[![No API key required](https://img.shields.io/badge/No%20API%20key-required-2ea44f)](https://apify.com/logiover/broken-link-checker)
[![Pay per result](https://img.shields.io/badge/Pricing-Pay%20per%20result-blueviolet)](https://apify.com/logiover/broken-link-checker)
[![Category](https://img.shields.io/badge/Category-SEO%20%26%20Website%20Audit-orange)](https://apify.com/logiover/broken-link-checker)
[![Export](https://img.shields.io/badge/Export-JSON%20%7C%20CSV%20%7C%20Excel-informational)](https://apify.com/logiover/broken-link-checker)

**Find every broken link on a website automatically.** This **broken link checker** crawls an entire site, follows internal links across the whole domain, and validates **every internal and external link** for **404, 410 and 5xx** errors, plus timeouts, DNS failures and unreachable hosts. For each link you get the **source page it was found on**, the **anchor text**, the **link type** (internal/external) and the exact **HTTP status code** — so you know precisely *where* each dead link lives and can fix it fast. Give it **one URL** and it discovers and audits thousands of pages and links for you. **No login, no proxy setup, no headless browser** — pure HTTP, fast, cheap and schedulable.

> ### 🏆 Why this Broken Link Checker?
>
> **8 data fields per link** · **thousands of pages per run** · **fast pure-HTTP crawl (HEAD + GET fallback)** · **no API key, no browser, no login** · **export to JSON, CSV, Excel or API**

***

### ✨ What this Actor does / Key features

- 🕷️ **Full-site crawl** — start from one URL and automatically follow internal `<a>` links across the entire domain, discovering pages you forgot existed.
- 🔗 **Checks every link** — validates internal *and* external (outbound) links, not just a flat list you paste in.
- 🚦 **Exact HTTP status** — reports `200`, `301`, `404`, `410`, `500` and more, plus network errors (timeouts, unreachable hosts, DNS failures) that have no status code.
- 📄 **Source page + anchor text** — every row tells you the exact page the broken link sits on and its clickable text, so fixes take seconds.
- ⚡ **Fast & cheap** — pure HTTP with a lightweight `HEAD` request (auto-falling back to `GET`), no headless browser. Each unique URL is checked **only once** and cached across pages.
- 🎛️ **Flexible output** — export *only broken links* for a clean fix-list, or a *full audit* of every link on the site for a complete inventory.
- 🗓️ **Schedulable monitoring** — run it daily or weekly and catch dead links the moment they appear.
- 🌐 **Works on any site** — blogs, docs, e-commerce, marketing sites, knowledge bases — anything reachable over HTTP.

### 🚀 Quick start (3 steps)

1. **Configure** — paste one or more website URLs into **Start URLs**. Optionally set **Max pages to crawl** (`0` = whole site) and toggle **Check external links** / **Only output broken links**.
2. **Run** — click **Save & Start**. The crawler follows internal links and checks every link it finds.
3. **Get your data** — download results as **JSON, CSV, Excel or HTML**, pull them via the **REST API**, or schedule the run to repeat.

### 📥 Input

The only required field is **Start URLs** — one or more websites to crawl. Everything else has sensible defaults.

#### Example — audit one whole website

```json
{
  "startUrls": [{ "url": "https://example.com/" }],
  "maxPagesToCrawl": 0,
  "checkExternalLinks": true,
  "onlyBroken": false,
  "maxConcurrency": 10
}
```

#### Example — fast broken-links-only fix list

```json
{
  "startUrls": [{ "url": "https://example.com/blog" }],
  "maxPagesToCrawl": 500,
  "checkExternalLinks": false,
  "onlyBroken": true,
  "maxConcurrency": 10
}
```

#### Example — monitor several sites at once

```json
{
  "startUrls": [
    { "url": "https://example.com/" },
    { "url": "https://docs.example.com/" },
    { "url": "https://shop.example.com/" }
  ],
  "maxPagesToCrawl": 2000,
  "checkExternalLinks": true,
  "onlyBroken": true,
  "maxConcurrency": 5
}
```

| Field | Type | Description |
|-------|------|-------------|
| `startUrls` | array | **Required.** Websites to crawl. The crawler follows internal links from each start URL and checks every link it finds along the way. |
| `maxPagesToCrawl` | integer | Maximum pages to crawl per run. More pages = more links checked. Set `0` for no limit (crawl the whole site). Default `5`. |
| `checkExternalLinks` | boolean | Also verify links that point to other domains, not just internal links. Default `false`. |
| `onlyBroken` | boolean | Save only broken links (4xx / 5xx / unreachable). Turn off to export a full audit row for every link checked. Default `false`. |
| `maxConcurrency` | integer | Number of parallel requests. Lower this if the target site rate-limits you (`429`). Default `10`. |

> 💡 **Tip:** Set `maxPagesToCrawl` to `0` for complete site-wide coverage, and turn on **Only output broken links** to get a clean dead-link list ready to import into a spreadsheet. Drop `maxConcurrency` to `3–5` for fragile or rate-limited servers.

### 📤 Output

Each row is **one link checked**, with the source page, target URL, anchor text, link type, HTTP status and a clear broken/OK flag. Here is a trimmed sample:

```json
{
  "sourceUrl": "https://example.com/blog/post-1",
  "linkUrl": "https://example.com/old-page",
  "anchorText": "see our old guide",
  "linkType": "internal",
  "statusCode": 404,
  "ok": false,
  "error": null,
  "checkedAt": "2026-07-06T14:08:46.306Z"
}
```

<details><summary><b>📋 Full field reference (click to expand)</b></summary>

| Field | Type | Description |
|-------|------|-------------|
| `sourceUrl` | string | The page the link was found on. |
| `linkUrl` | string | The link target (absolute URL). |
| `anchorText` | string | The clickable text of the link. |
| `linkType` | string | `internal` (same domain) or `external` (outbound). |
| `statusCode` | number | HTTP status code returned by the link (e.g. `200`, `301`, `404`, `500`). |
| `ok` | boolean | `true` if the link works, `false` if it's broken. |
| `error` | string / null | Network error (`timeout`, `unreachable`, DNS failure, …) when there is no status code; otherwise `null`. |
| `checkedAt` | string | ISO 8601 timestamp of the check. |

</details>

Turn on **Only output broken links** for a clean list of just the dead links, or leave it off to export a complete link audit of the entire website. Two built-in dataset views — **All links** and **Broken links only** — let you preview either result set in the Apify UI.

### 💡 Use cases

- **🔍 SEO audits** — broken internal links waste crawl budget and hurt rankings. Find and fix them across the whole site before Google penalizes you.
- **🚚 Website migrations & redesigns** — catch every `404` before and after a launch, domain move or CMS switch, so nothing silently breaks.
- **📚 Content & docs maintenance** — keep large blogs, documentation and knowledge bases link-clean as they grow.
- **💸 Affiliate & outbound link monitoring** — make sure the external links you earn commissions from still resolve and aren't dead.
- **🗓️ Ongoing link monitoring** — schedule the actor daily/weekly and get a fresh broken-link report the moment something breaks.
- **🤝 Agency client reporting** — deliver a clean, exportable dead-link audit to clients as a repeatable, white-labelable deliverable.

### 👥 Who uses it

SEO specialists & technical SEO auditors · web developers & QA engineers · digital agencies & freelancers · content teams & documentation maintainers · affiliate marketers & bloggers · e-commerce managers · site reliability & DevOps teams · migration consultants · growth marketers · anyone maintaining a large website who needs a fast, site-wide **dead link finder** without wrestling with browser-based crawlers.

### 💰 Pricing

This actor runs on a simple **pay-per-result** model — you're billed for the links it checks and returns, with no monthly subscription and no API keys to manage. Small spot-checks cost pennies; full site-wide audits scale with how many pages and links you crawl. See the **Pricing** tab on this page for the current rate.

### ❓ Frequently Asked Questions

**What counts as a broken link?** Any link returning a 4xx or 5xx status code (e.g. `404`, `410`, `500`), or one that can't be reached at all (timeout, DNS failure, connection refused). These rows have `ok: false`.

**Is it legal to check a website for broken links?** Yes. The actor only requests publicly available pages and links exactly as a browser or search-engine crawler would, reading HTTP status codes. It does not log in, bypass paywalls or collect private data. Always respect a site's Terms of Service and use reasonable concurrency.

**Does a website need a public API for this to work?** No. There's no API involved — the checker reads normal public HTML pages over HTTP and follows the `<a>` links it finds, so it works on virtually any website.

**Can I use this without an API key or login?** Absolutely. No API key, no account credentials, no headless browser and no proxy setup are required. Paste a URL and run.

**How do I export broken links to CSV or JSON?** Run the crawl, then download the results in one click as **CSV, JSON**, Excel or HTML — or pull them via the REST API. Turn on **Only output broken links** for a clean dead-link list ready to import into a spreadsheet.

**How much data can I get?** As much as you like. The crawler follows internal links up to `maxPagesToCrawl` (set it to `0` for no limit) and can audit thousands of pages and links in a single run, checking each unique URL only once for efficiency.

**Is there a broken link checker that crawls a whole website without a browser?** Yes — this actor is a **site-wide dead link finder** that uses pure HTTP (no headless browser, no login, no proxy), so it crawls thousands of pages and audits every internal and external link fast and cheaply.

**Can I find all 404 pages on a site and export the audit?** Yes. It discovers pages by following internal links and reports the exact HTTP status for each one, giving you a complete **404 finder report** with the source page and anchor text, ready to export.

**Does it crawl other websites too?** It *checks* the status of external links but only *crawls deeper* within your own domain, so you always stay in control of scope. Toggle **Check external links** off to skip outbound checks entirely.

**Will it find every page on my site?** It follows internal links up to `maxPagesToCrawl`. Increase that limit — or set it to `0` — for complete coverage.

**Can I check several sites at once?** Yes — just add multiple Start URLs.

### 🔗 Related website & lead-gen tools by logiover

| Actor | What it does |
|-------|--------------|
| [Bulk URL Status Checker](https://apify.com/logiover/bulk-url-status-checker) | Check a flat list of URLs for status codes & redirects. |
| [Website SEO Audit Crawler](https://apify.com/logiover/website-seo-audit-crawler) | Full on-page SEO audit for every page on a site. |
| [Website Link Graph Crawler](https://apify.com/logiover/website-link-graph-crawler) | Map internal & outbound links site-wide. |
| [Website Text & Markdown Crawler](https://apify.com/logiover/website-text-markdown-crawler) | Extract clean page text & Markdown at scale. |
| [Sitemap to URL Crawler](https://apify.com/logiover/sitemap-to-url-crawler) | Extract every URL from any sitemap.xml. |
| [URL to Markdown](https://apify.com/logiover/url-to-markdown) | Convert any page into clean Markdown. |
| [Website Change Monitor](https://apify.com/logiover/website-change-monitor) | Track changes on any page and get alerted. |
| [Website Contact Scraper](https://apify.com/logiover/website-contact-scraper) | Extract emails, phones & socials from sites. |
| [Website Tech Stack Detector](https://apify.com/logiover/website-tech-stack-detector) | Detect the technologies a website runs on. |
| [Bulk HTTP Security Headers](https://apify.com/logiover/bulk-http-security-headers) | Audit security headers across many URLs. |
| [Website Image & Media Extractor](https://apify.com/logiover/website-image-media-extractor) | Pull all images & media assets from a site. |
| [JSON-LD Schema & Meta Tag Extractor](https://apify.com/logiover/json-ld-schema-meta-tag-extractor) | Extract structured data & meta tags at scale. |

👉 Browse all **[logiover scrapers on Apify Store](https://apify.com/logiover)** — 180+ actors across real estate, jobs, crypto, social media & B2B data.

### ⏰ Scheduling & integration

Put the actor on an **Apify schedule** to run daily or weekly so newly broken `404` and `5xx` links are caught automatically. Results plug straight into **Make, n8n, Zapier**, the **Apify API**, **webhooks** and **Google Sheets**, so you can push fresh dead-link reports into Slack, email, a spreadsheet or your own dashboard without lifting a finger.

### ⭐ Support & feedback

Found a bug or need a new field? Open an issue on the **Issues** tab of this actor and I'll take a look. If this Broken Link Checker saves you time, please leave a **★★★★★ review** on the actor page — it genuinely helps others find it and helps me keep improving it.

### ⚖️ Legal

This actor only accesses **publicly available** web pages and the links within them, reading HTTP status codes exactly as a browser or search-engine crawler would. It does not log in, bypass access controls, or collect private or personal data. You are responsible for using it in compliance with the target website's Terms of Service, `robots.txt`, and all applicable laws. Use reasonable concurrency and crawl only sites you are authorized to audit.

***

### 📝 Changelog

#### 2026-08-01

- Completed the August 2026 full health check: verified empty/programmatic default, Console UI default, and two source-informed alternative inputs on Apify.
- Confirmed successful live execution, non-empty structured output, dataset-field/type integrity, and logical sample quality within the 5-minute quality window.

#### 2026-07-06

- ✨ README overhaul: richer output sample, ready-to-run example scenarios, cross-promo links, clearer quick-start and expanded FAQ.

#### 2026-07-01

- Maintenance pass: re-verified end-to-end on live data and confirmed successful runs within the 5-minute quality window on the default input.
- Sharpened Store metadata (SEO title & description) and expanded the FAQ with high-intent, long-tail questions for easier discovery in Google and Apify Store search.
- Added ready-to-run example tasks that cover common real-world use cases.

#### 2026-06-15

- Reliability pass: re-verified end-to-end on live data with real-world inputs. Routine maintenance build.

#### 2026-06-07

- Docs: added coverage for exporting broken links to CSV/JSON, site-wide 404 finding without a browser, and full dead-link audit export.

#### 2026-06-05

- 🛡️ Reliability fix: results are no longer dropped by strict output validation — runs now complete cleanly even at high volume (thousands of results).
- ⚡ Stability & performance hardening; fresh rebuild.

#### 2026-06-04

- Verified live & refreshed build — reliability/maintenance pass.

***

\*Maintained: last verified 2026-09-01 — checked end-to-end against live run history (reliability, output fields and types, and time/memory budgets).

# Actor input Schema

## `startUrls` (type: `array`):

Websites to crawl. The crawler follows internal links from each start URL and checks every link it finds along the way. Leave empty to run a demo crawl on a public sample site.

## `maxPagesToCrawl` (type: `integer`):

Maximum pages to crawl per run. More pages = more links checked. Set 0 for no limit (crawl the whole site).

## `checkExternalLinks` (type: `boolean`):

Also verify links that point to other domains, not just internal links.

## `onlyBroken` (type: `boolean`):

Save only broken links (4xx/5xx/unreachable). Turn off to export a full audit row for every link checked.

## `maxConcurrency` (type: `integer`):

Number of parallel requests. Lower this if the target site rate-limits you.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://quotes.toscrape.com/"
    }
  ],
  "maxPagesToCrawl": 20,
  "checkExternalLinks": true,
  "onlyBroken": false,
  "maxConcurrency": 10
}
```

# Actor output Schema

## `results` (type: `string`):

All records extracted by this run. Open the Dataset tab to browse, filter, and export as CSV, JSON, or Excel.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://quotes.toscrape.com/"
        }
    ],
    "maxPagesToCrawl": 20,
    "maxConcurrency": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("logiover/broken-link-checker").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://quotes.toscrape.com/" }],
    "maxPagesToCrawl": 20,
    "maxConcurrency": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("logiover/broken-link-checker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://quotes.toscrape.com/"
    }
  ],
  "maxPagesToCrawl": 20,
  "maxConcurrency": 10
}' |
apify call logiover/broken-link-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,logiover/broken-link-checker"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/yI1FdubDlBW73yndF/builds/NMKCx2588ICTOivBS/openapi.json
