# SEO Audit Crawler - On-Page SEO Checker for Whole Websites (`uianalize/seo-audit-crawler`) Actor

Crawl one or many websites and audit every page: titles, meta descriptions, H1, canonical, noindex, alt text, thin content, Open Graph, structured data, duplicates and slow pages. Site score and issue summary. Pay per page.

- **URL**: https://apify.com/uianalize/seo-audit-crawler.md
- **Developed by:** [Webstack Data](https://apify.com/uianalize) (community)
- **Categories:** SEO tools, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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.

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

## SEO Audit Crawler – on-page SEO checker for whole websites

Give it one or many websites. It crawls each site within its own domain and audits **every HTML page** for the on-page issues that cost rankings and clicks. You get one row per page with its issues, plus a **site summary with a score out of 100** and the most common problems.

### What does it check?

| Check | Issue code |
|---|---|
| HTTP errors (404, 5xx) | `HTTP_ERROR` |
| Missing, too long (>60) or too short (<20) title | `TITLE_MISSING`, `TITLE_TOO_LONG`, `TITLE_TOO_SHORT` |
| Missing, too long (>160) or too short (<70) meta description | `META_DESCRIPTION_*` |
| Duplicate titles and meta descriptions across pages | `DUPLICATE_TITLE`, `DUPLICATE_META_DESCRIPTION` |
| Missing or multiple H1 | `H1_MISSING`, `H1_MULTIPLE` |
| Missing canonical, or canonical pointing to another page | `CANONICAL_MISSING`, `CANONICAL_POINTS_ELSEWHERE` |
| noindex in meta robots or X-Robots-Tag | `NOINDEX` |
| Missing lang attribute and mobile viewport | `LANG_MISSING`, `VIEWPORT_MISSING` |
| Images without alt text | `IMAGES_WITHOUT_ALT` |
| Thin content (<300 words) | `THIN_CONTENT` |
| Missing Open Graph title/image | `OPEN_GRAPH_MISSING` |
| No structured data (JSON-LD / schema.org) | `NO_STRUCTURED_DATA` |
| Slow server response (>2 s) | `SLOW_RESPONSE` |

Each page row also includes the title, meta description, H1, word count, number of images and images without alt, canonical, robots directives, language and response time. You can use them directly in a spreadsheet.

### Who is it for?

- **SEO agencies and freelancers**: audit prospects and clients in bulk, then export to Excel or Google Sheets for the report.
- **Site owners and marketers**: find the quick wins after a redesign, migration or CMS change.
- **Developers**: run it from CI or on a schedule and fail a release if the score drops.

### Input

```json
{ "startUrls": ["example.com"], "maxPagesPerSite": 100, "onlyPagesWithIssues": true }
```

### Output

```json
{
  "type": "page",
  "url": "https://example.com/pricing",
  "statusCode": 200,
  "issueCount": 3,
  "issues": ["META_DESCRIPTION_MISSING", "H1_MULTIPLE", "IMAGES_WITHOUT_ALT"],
  "title": "Pricing | Example",
  "titleLength": 17,
  "h1Count": 2,
  "wordCount": 612,
  "imagesWithoutAlt": 4,
  "responseTimeMs": 420
}
```

```json
{
  "type": "site-summary",
  "site": "example.com",
  "score": 81,
  "pagesAudited": 100,
  "topIssues": [{ "code": "IMAGES_WITHOUT_ALT", "description": "Images without alt text", "pagesAffected": 64 }]
}
```

### Pricing

Pay per event: **$0.0015 per page audited** ($1.50 per 1,000 pages) plus a tiny start fee. Sites that cannot be reached are free. Set a maximum cost per run and the Actor stops when it is reached.

### Good to know

- It reads the HTML the server sends. Content rendered only by JavaScript in the browser is not executed, so very JavaScript-heavy sites may show thin content.
- It respects robots.txt by default, stays within the domain and uses polite concurrency. It does not log in or collect personal data.
- Pair it with [Broken Link Checker](https://apify.com/uianalize/broken-link-checker) for a full technical audit.

### Integrations

Schedule it, call it from the Apify API, or connect it to n8n, Make, Zapier, Google Sheets or an AI agent through the Apify MCP server. Templates: https://github.com/uunnaaiii/webstack-data

***

#### En español

Rastrea webs completas y audita el SEO on-page de cada página (títulos, descripciones, H1, canonical, noindex, alt, contenido pobre, Open Graph, datos estructurados, duplicados y lentitud), con una puntuación por sitio. Pagas por página auditada.

# Actor input Schema

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

Websites or start pages to audit, one per line (e.g. example.com). Each one is crawled within its own domain.

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

How many HTML pages of each site to audit.

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

Skip pages that pass every check. The site summary always includes all pages.

## `respectRobotsTxt` (type: `boolean`):

Do not crawl pages disallowed by the site's robots.txt.

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

Parallel requests per site. Keep it low to be polite to the site.

## `timeoutSecs` (type: `integer`):

How long to wait for each page before giving up.

## Actor input object example

```json
{
  "startUrls": [
    "apify.com"
  ],
  "maxPagesPerSite": 50,
  "onlyPagesWithIssues": false,
  "respectRobotsTxt": true,
  "maxConcurrency": 5,
  "timeoutSecs": 15
}
```

# Actor output Schema

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

No description

# 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": [
        "apify.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("uianalize/seo-audit-crawler").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": ["apify.com"] }

# Run the Actor and wait for it to finish
run = client.actor("uianalize/seo-audit-crawler").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": [
    "apify.com"
  ]
}' |
apify call uianalize/seo-audit-crawler --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,uianalize/seo-audit-crawler"
        }
    }
}
```

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/1EupaCSvV9DMg6h9v/builds/mcWBR3hpmZGnEKtiy/openapi.json
