# Technical SEO Site Audit & Broken Link Checker (`api-co/seo-site-auditor`) Actor

Crawl a website and run a technical SEO site audit on every page: 30+ checks, 0-100 score, broken link checker (internal and external), meta tags, titles, H1s, canonicals, noindex, structured data and duplicates. A cloud Screaming Frog alternative.

- **URL**: https://apify.com/api-co/seo-site-auditor.md
- **Developed by:** [Emilio Cisneros](https://apify.com/api-co) (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 $1.60 / 1,000 page auditeds

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?

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

## Technical SEO Site Audit & Broken Link Checker

Crawl a website and get a **technical SEO audit for every page**: 30+ checks, a 0-100 score, a prioritized issue list and **broken links** (internal and external). You also get a **site-wide summary** with duplicate titles and meta descriptions, issue totals and every broken link with the page it was found on.

### How to use

1. Enter your website's home page in **Start URLs**.
2. Set *Max pages* and choose whether to check internal links only or all links.
3. Click **Start**. You get one row per page with its SEO score and issues, plus a `SUMMARY` record with broken links and duplicate titles.

### Checks per page

- **Status and indexability**: HTTP errors, redirects, `noindex` (meta robots and X-Robots-Tag), canonical (missing, self, points elsewhere, cross-domain).
- **Titles and meta**: missing/too long/too short title and meta description, multiple titles.
- **Headings**: missing or multiple H1, skipped heading levels.
- **Content**: word count and thin content, images missing alt text, language attribute, mobile viewport.
- **Social and structured data**: Open Graph (title/description/image), Twitter card, JSON-LD and microdata types, invalid JSON-LD.
- **Links**: broken internal/external links (4xx/5xx/DNS errors), internal links pointing to redirects, internal/external/nofollow counts, hreflang alternates.
- **Security and performance**: mixed content, non-HTTPS pages, slow server response, long or unclean URLs.

Each issue has a `code`, a `severity` (error, warning or notice) and a readable message, so you can filter and prioritize in a spreadsheet.

### Why this Actor

| | This Actor | Typical SEO audit Actors |
|---|---|---|
| Price | **$2 / 1,000 pages** (link checks included) | $5 to $40 / 1,000 pages, or per link |
| Broken links with source page | **Yes** | Separate Actor |
| Site summary (duplicates, totals) | **Yes** | Rarely |
| Sitemap + robots.txt aware | **Yes** | Varies |

### Input

```json
{ "startUrls": ["https://example.com/"], "maxPages": 500, "checkLinks": "all", "useSitemap": true }
```

### Output (per page)

```json
{ "url": "https://example.com/blog/post", "statusCode": 200, "seoScore": 78, "issueCounts": { "error": 1, "warning": 1, "notice": 3 },
  "issues": [ { "code": "BROKEN_LINKS", "severity": "error", "message": "2 broken link(s)" }, { "code": "META_DESCRIPTION_MISSING", "severity": "warning", "message": "Missing meta description" } ],
  "title": "My post", "titleLength": 7, "metaDescription": null, "h1": "My post", "h1Count": 1, "canonical": "https://example.com/blog/post", "indexable": true,
  "wordCount": 1240, "imagesMissingAlt": 3, "structuredDataTypes": ["BlogPosting"], "openGraph": { "title": "My post", "image": null },
  "brokenLinks": [ { "url": "https://example.com/old-page", "status": 404, "internal": true } ], "responseTimeMs": 412 }
```

**Key-value store `SUMMARY`**: pages audited, average score, totals per issue code, all broken links with the page they were found on, and duplicate titles/descriptions.

### Pricing (pay per event)

**$0.002 per audited page** ($2 per 1,000). Link checks, the site summary and error records are free.

### How much does it cost?

You only pay for results, never for compute time:

| You get | You pay (Starter/Bronze plan price) |
|---|---|
| 100 pages | $0.20 |
| 1,000 pages | $2.00 |
| 10,000 pages | $20.00 |

Apify's **free plan includes $5 of usage every month**, and free-plan users pay **half price** on this Actor, so that covers about **5,000 pages** at no cost. Paid plans get volume discounts (Silver -10%, Gold -20%). Set a *maximum cost per run* and the Actor stops cleanly at your limit.

### Notes

This is an HTTP crawler with no JavaScript rendering. It audits the HTML that search engines receive first. robots.txt is honored by default and the site is limited to 4 requests/second.

### Use cases

- **SEO agencies**: fast technical audits for prospects and clients, exported to a spreadsheet.
- **Site owners**: find broken links, missing meta descriptions and noindex mistakes before they cost traffic.
- **Migrations**: compare a site before and after a redesign.
- **Monitoring**: a weekly scheduled audit that alerts you to new errors.

### Run it from code (API, Python, JavaScript)

```bash
curl -X POST "https://api.apify.com/v2/acts/api-co~seo-site-auditor/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" -d '{"startUrls": ["https://books.toscrape.com/"], "maxPages": 20}'
```

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("api-co/seo-site-auditor").call(run_input={"startUrls": ["https://books.toscrape.com/"], "maxPages": 20})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('api-co/seo-site-auditor').call({"startUrls": ["https://books.toscrape.com/"], "maxPages": 20});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

It also works from **AI agents through the Apify MCP server**, and with Zapier, Make, n8n, Google Sheets and webhooks. You can schedule it in the Apify Console.

### FAQ

**Is this a Screaming Frog alternative?**
For technical audits, yes: it crawls the site, checks titles, meta descriptions, headings, canonicals, indexability, structured data and broken links, and runs in the cloud on a schedule.

**Does it render JavaScript?**
No. It audits the HTML that search engines receive first, which keeps it fast and cheap. Sites that build all content client-side will show thin content.

**Can I audit a client's site every week?**
Yes. Schedule the Actor and send the dataset to Google Sheets, Slack or email.

**Are broken links charged separately?**
No. Link checks are included in the per-page price.

# Actor input Schema

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

Homepage (or section) to audit, e.g. https://example.com/. Pages on the same site are crawled.

## `maxPages` (type: `integer`):

Maximum pages to audit (also caps what you pay).

## `maxDepth` (type: `integer`):

Clicks away from the start URL.

## `useSitemap` (type: `boolean`):

Seed the crawl from robots.txt sitemaps and /sitemap.xml.

## `includeUrlPatterns` (type: `array`):

Only audit URLs matching these globs (\*\* = anything) or /regex/, e.g. https://example.com/blog/\*\*

## `excludeUrlPatterns` (type: `array`):

Skip URLs matching these globs or /regex/.

## `includeSubdomains` (type: `boolean`):

Also crawl subdomains of the start host.

## `respectRobots` (type: `boolean`):

Skip pages disallowed by robots.txt (disable only for your own site).

## `checkLinks` (type: `string`):

Check the HTTP status of every link found on audited pages.

## `maxLinkChecks` (type: `integer`):

Cap on unique links checked per run (free; included in the page price).

## `onlyPagesWithIssues` (type: `boolean`):

Return (and charge) only pages that have at least one error or warning. The site summary still covers all pages.

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

Parallel page fetches (the site is also capped at 4 requests/second).

## Actor input object example

```json
{
  "startUrls": [
    "https://books.toscrape.com/"
  ],
  "maxPages": 20,
  "maxDepth": 5,
  "useSitemap": true,
  "includeSubdomains": false,
  "respectRobots": true,
  "checkLinks": "internal",
  "maxLinkChecks": 2000,
  "onlyPagesWithIssues": false,
  "maxConcurrency": 8
}
```

# Actor output Schema

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

One item per audited page with SEO checks, issues and link status.

## `summary` (type: `string`):

Site-level audit summary: issue counts, broken links, duplicate titles.

# 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": [
        "https://books.toscrape.com/"
    ],
    "maxPages": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("api-co/seo-site-auditor").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": ["https://books.toscrape.com/"],
    "maxPages": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("api-co/seo-site-auditor").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": [
    "https://books.toscrape.com/"
  ],
  "maxPages": 20
}' |
apify call api-co/seo-site-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,api-co/seo-site-auditor"
        }
    }
}
```

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/3P8MyL5V1mFeLCh3R/builds/sP9vva8HbqJ8GFCo5/openapi.json
