# Broken Link Checker (`zaden/my-actor-3`) Actor

Fast, no-browser broken link checker. Extracts every link from one or more pages and checks its HTTP status, so you can catch dead links before your users or Google do. Flags internal vs. external links, with clear timeout and error reasons. Also in Full Site Health Suite.

- **URL**: https://apify.com/zaden/my-actor-3.md
- **Developed by:** [Zaden](https://apify.com/zaden) (community)
- **Categories:** SEO tools, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.45 / 1,000 link checkeds

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

A fast, no-browser broken link checker built for teams, not just one-off checks. Point it at one or more pages; it extracts every link, checks them **in parallel**, and hands back a per-page letter grade plus a triage-ready, severity-tagged list -- so you catch dead links before your users, your boss, or Google does.

### What you get

**Per page**

- A **letter grade (A+ to F)** and 0-100 score summarizing link health at a glance
- A one-line **executive summary** ("3 of 42 links are broken -- review recommended")

**Per link**

- Status code and pass/fail, checked **concurrently** (configurable, up to 20 at once) so a 200-link page finishes in seconds, not minutes
- A **severity** tag -- `critical` (dead link), `warning` (redirects somewhere else), or `ok` -- for instant triage in any BI tool or spreadsheet
- Redirect detection with the final destination URL, and response time in milliseconds
- Anchor text, so you know exactly which piece of link copy points where
- Internal vs. external flag, with an option to skip external links entirely

### Why this instead of checking manually

| | Manual spot-checks | Broken Link Checker |
|---|---|---|
| Coverage | Whatever you click | Every link on the page, automatically |
| Speed | Minutes per page | Seconds, via parallel checking |
| Triage | You guess what's urgent | Pre-classified severity + letter grade |
| Repeatability | Forgotten next sprint | One click, or schedule it |
| Output | Notes in a doc | Structured dataset, exportable to CSV/JSON/BI tools |

### Who this is for

- Dev and QA teams running a pre-launch or post-migration link audit
- Content and marketing teams auditing old blog posts or resource pages
- Agencies checking a client's site health alongside an SEO audit
- Anyone wiring a scheduled link-rot regression check into their workflow

### How to use it

1. Add one or more **pages to scan**. Each page's HTML is fetched once and every link on it is checked.
2. Leave **check external links** on (default) to check every link, or turn it off to only check links on the same domain.
3. Tune **concurrency** (default 8) to trade speed for gentleness on slow servers, and **max links per page** to bound very link-heavy pages.
4. Run it once for a snapshot, or schedule it to catch link rot as it happens.

### Example output (one item)

```json
{
  "sourceUrl": "https://example.com/",
  "linkUrl": "https://example.com/old-page",
  "linkText": "Read more",
  "isExternal": false,
  "statusCode": 404,
  "ok": false,
  "severity": "critical",
  "redirected": false,
  "finalUrl": null,
  "responseTimeMs": 412,
  "error": null,
  "pageTotalLinksChecked": 42,
  "pageBrokenLinks": 3,
  "pageScore": 93,
  "pageGrade": "A-",
  "pageSummary": "3 of 42 link(s) are broken -- review recommended.",
  "checkedAt": "2026-08-20T12:00:00.000Z"
}
```

### Pricing

This Actor uses pay-per-event pricing:

- **Page scanned** -- charged once per page URL processed (covers fetching the page and extracting its links), whether the page loaded successfully or not.
- **Link checked** -- charged once per unique link actually checked on a page.

You only pay for links that get checked -- if a page has fewer links than your max, or you skip external links, you pay less. Parallel checking doesn't cost more -- it just finishes faster.

### FAQ

**Does this render JavaScript?**
No -- it reads the raw HTML response and extracts `<a href>` links from it, the same way a search engine's initial crawl would see the page. Links injected purely by client-side JavaScript won't be found.

**Does it follow links and crawl deeper into the site?**
No -- this checks the links found on the pages you give it, one level deep. It's a fast link-rot check, not a full-site crawler.

**What counts as "broken" vs. a "warning"?**
`critical` means the request failed outright (non-2xx status after redirects, timeout, DNS error, connection reset). `warning` means the link resolved successfully but redirected somewhere else -- not broken, but often worth cleaning up (e.g. pointing links straight at the final URL).

**Will higher concurrency get me rate-limited?**
It can, on servers with aggressive rate limiting. Start at the default (8) and lower it if you see a spike in timeouts for a particular site.

**Does this send any data anywhere besides your own Apify account?**
No. It only makes standard HTTP requests to the pages and links you provide and returns what it finds -- no login, no third-party analytics calls.

# Actor input Schema

## `urls` (type: `array`):

One or more page URLs. Each page's HTML is fetched once and every link on it is extracted and checked.

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

Also check links that point to a different domain than the page they were found on. Turn off to only check same-site links.

## `maxLinksPerPage` (type: `integer`):

Safety cap on how many unique links are checked per page, to keep runs bounded and predictable on link-heavy pages.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for each link before marking it as timed out.

## `concurrency` (type: `integer`):

How many links on a page to check in parallel. Higher values finish faster at the same cost; lower values are gentler on slow servers.

## Actor input object example

```json
{
  "urls": [
    "https://example.com/"
  ],
  "checkExternalLinks": true,
  "maxLinksPerPage": 200,
  "requestTimeoutSecs": 10,
  "concurrency": 8
}
```

# Actor output Schema

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

Every checked link with its status, whether it's broken, and which page it was found on.

# 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 = {
    "urls": [
        "https://example.com/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("zaden/my-actor-3").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 = { "urls": ["https://example.com/"] }

# Run the Actor and wait for it to finish
run = client.actor("zaden/my-actor-3").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 '{
  "urls": [
    "https://example.com/"
  ]
}' |
apify call zaden/my-actor-3 --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,zaden/my-actor-3"
        }
    }
}

```

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/C3LFntP9JOtlRshqx/builds/yE4YoTv0nqLaZukKd/openapi.json
