# Website Health Check: Broken Links, SEO and SSL (`edgef-4/website-health-check`) Actor

Website audit for agencies: up to 50 client sites per run. Broken links, redirect chains, SEO tags, alt text, mixed content and SSL expiry, with a 0 to 100 score, the top 5 fixes and a printable report per site. Pay per event: $0.06 for a 20-page site.

- **URL**: https://apify.com/edgef-4/website-health-check.md
- **Developed by:** [Edge](https://apify.com/edgef-4) (community)
- **Categories:** SEO tools, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 site reports

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

**For web and SEO agencies that look after many client sites.** Website Health Check audits up to 50 websites in one run and gives each one a 0 to 100 health score, the top 5 fixes in plain language and a printable report you can hand to the client.

**The job in one line:** paste your client home pages, get broken links, SEO tag gaps and SSL expiry for every site, plus one report per site.

**What one run costs (pay per event):**

| Event | Price |
|---|---|
| Site report (one site scored and added to the report) | $0.02 |
| Page checked (one page fetched and analyzed) | $0.002 |
| Actor start (once per run, Apify's standard fee) | $0.00005 |

One 20-page site costs $0.06. Fifty client sites of 20 pages each cost $3.00. A real run on 17 Oct 2026 of one 1-page site (www.example.com) took 3.6 seconds and cost a buyer $0.02205. A site that cannot be loaded is marked "Not checked" and gets no site report charge.

### Quick start

```json
{
    "startUrls": [
        { "url": "https://www.example.com" },
        { "url": "https://www.python.org" }
    ],
    "maxPagesPerSite": 20,
    "delayMs": 500
}
```

Click **Start**, then open the **Output** tab: the HTML report (`OUTPUT.html`) is ready to print or save as PDF, and the dataset has one row per site and one row per page.

### Output example

One `site` row per website. This row is from a real local run on the demo site behind the sample report (local address replaced, `finalUrl`, `pointsLost`, `error` and `certError` left out here):

```json
{
    "rowType": "site",
    "site": "http://cornerbakery.example/",
    "score": 61,
    "topFixes": [
        "Serve the site over HTTPS with a valid certificate and redirect every http:// address to https://.",
        "Publish a sitemap.xml and list it in robots.txt so every page gets found.",
        "Fix 1 broken link to your own pages: point them at live pages or add redirects.",
        "Write a meta description for 1 page: one or two sentences that sell the click in search results.",
        "Add alt text to 2 images. It helps blind visitors and image search."
    ],
    "https": false,
    "certDaysLeft": null,
    "robotsTxt": true,
    "sitemapXml": false,
    "pagesChecked": 4,
    "linksChecked": 8,
    "linksNotChecked": 0,
    "brokenInternalLinksCount": 1,
    "brokenExternalLinksCount": 1,
    "notes": [
        "skipped by robots.txt: http://cornerbakery.example/private/staff",
        "not an HTML page, checked as a link only: http://cornerbakery.example/menu.pdf"
    ]
}
```

Each `page` row has `finalUrl`, `status`, `redirectChain`, `responseMs`, `pageBytes`, `title`, `titleLength`, `metaDescription`, `metaDescriptionLength`, `h1Count`, `canonical`, `robotsMeta`, `viewport`, `ogTitle`, `ogDescription`, `ogImage`, `imagesMissingAlt`, `brokenInternalLinks`, `brokenExternalLinks` and `mixedContentCount`.

### Three agency use cases

1. **Monthly client health report.** Put every retainer client's home page in one run on a monthly schedule. Each client gets a score, the top 5 fixes and a printable page to attach to the monthly report. The score shows whether last month's fixes worked.
2. **Pre-sale audit for prospects.** Run a prospect's site before the sales call and bring the printed report: broken links, missing titles and meta descriptions, images without alt text and the SSL expiry date, in plain words a business owner reads.
3. **SSL and broken link watch across the portfolio.** A weekly run over all managed sites flags certificates that expire within 14 or 30 days and new broken links, before the client notices. The dataset goes straight into Google Sheets, Excel or your own dashboard through the API.

### What it checks

- **Broken links:** every unique link on the checked pages, internal and external, up to 300 per site. A link that answers 400 or higher, or does not answer, is reported with its page and status code.
- **Redirect chains:** the full chain per page, hop by hop.
- **SEO tags:** title and its length (10 to 60 characters counts as well sized), meta description and its length (50 to 160), H1 count, canonical, robots noindex, mobile viewport, Open Graph title, description and image, images with no alt text.
- **Security basics:** HTTPS on or off, days left on the SSL certificate, mixed content (http:// files on https:// pages).
- **Crawl files:** robots.txt and sitemap.xml present.
- **Speed signal:** response time per page; pages over 2 seconds are flagged as slow.

The score starts at 100 and each rule takes away up to a fixed maximum (for example up to 20 points for no HTTPS, up to 20 for broken internal links). The top 5 fixes are the rules that cost the most points.

### Limits and what it does not do

- Depth 1: it reads the start page and the same-site pages it links to (default 20, up to 100 per site). Deeper pages are not read, but links to them are checked.
- No JavaScript rendering: pages are read as plain HTML, so sites that build links with JavaScript show fewer pages and links.
- No Core Web Vitals, Lighthouse or lab speed scores; no keyword rankings, backlinks, domain authority or traffic numbers.
- No security header scan, structured data check, accessibility (WCAG) audit or uptime monitoring.
- SSL: validity and days left only, not the certificate chain, ciphers or a letter grade.
- It obeys robots.txt and sends one request at a time per server with a pause (500 ms by default), so a large site with many links on one server takes minutes. Measured on a local test site: 20 pages and about 270 requests took 227 seconds at the default delay.
- Read only: GET and HEAD requests. Only check sites you own or have permission to audit.

### FAQ

**Can I hand the report to clients under my own name?** The HTML report carries no Apify name or logo: each site page is headed "Website health check" with the site address and the check date. It does not add your agency logo. Open it in a browser and print or save it as PDF.

**How do I cap my spend on a big run?** Set a maximum cost per run in the run options. The checker checks what is left of that budget before each charge, never charges past it, and saves the report after every site, so finished sites are never lost.

**Why is a link reported broken when it opens in my browser?** Some servers block automated requests or answer slowly. The report shows the status code or error so you can check it by hand.

**How much memory should I choose?** The default 512 MB is enough for normal runs (a 20-page site peaked at 122 MB in our tests). For 50 sites of 100 pages (peak 441 MB in our tests), choose 1024 MB.

**Can I run it on a schedule?** Yes. Save your input as an Apify task and add a schedule (weekly or monthly). Each run writes a new dataset and a new report.

Keywords: website audit for agencies, broken link checker, bulk SEO audit, SSL certificate expiry check, client SEO report, redirect chain checker, meta description checker, alt text audit

# Actor input Schema

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

Home page addresses of the sites to check, up to 50. Each site is checked on its own: the start page plus same-site pages linked from it.

## `maxPagesPerSite` (type: `integer`):

How many pages to check per site, counting the start page. Pages are the same-site links found on the start page (depth 1).

## `delayMs` (type: `integer`):

Wait time between two requests to the same server, in milliseconds. Keep it at 500 or more for small sites.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.example.com"
    }
  ],
  "maxPagesPerSite": 20,
  "delayMs": 500
}
```

# Actor output Schema

## `report` (type: `string`):

Printable report, each site on a new page.

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

Page rows and site summary rows.

# 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://www.example.com"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("edgef-4/website-health-check").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://www.example.com" }] }

# Run the Actor and wait for it to finish
run = client.actor("edgef-4/website-health-check").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://www.example.com"
    }
  ]
}' |
apify call edgef-4/website-health-check --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,edgef-4/website-health-check"
        }
    }
}
```

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/8XjBWudHAI74QIV5R/builds/Z9LBXCyG9ifh4vwFA/openapi.json
