# SEO Audit: On-Page Checker for Any List of URLs (`tidelane/seo-audit`) Actor

Audit pages for on-page SEO in bulk: title and meta description length, H1 and headings, canonical, noindex, lang, mobile viewport, image alt texts, word count, Open Graph, structured data (JSON-LD), HTTPS and mixed content, load time. Score 0-100 with a clear issue list per page.

- **URL**: https://apify.com/tidelane/seo-audit.md
- **Developed by:** [Tidelane Data](https://apify.com/tidelane) (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.75 / 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

## SEO Audit: On-Page Checker for Any List of URLs

Check the on-page SEO of many pages at once. For each URL you get a **score from 0 to 100**, a **clear list of issues** (errors, warnings, notices) and all the facts behind them: title and meta description length, H1 and heading structure, canonical, noindex, language, mobile viewport, image alt texts, word count, internal and external links, Open Graph, structured data (JSON-LD), HTTPS and load time.

- ✅ **Bulk audits**: paste your sitemap URLs or a client's key pages
- ✅ **Real browser**: JavaScript-rendered content and tags are checked as Google sees them after rendering
- ✅ **22 checks** with plain-English messages, ready for client reports
- ✅ **Structured data types** (Organization, Product, Article, FAQPage …) and invalid JSON-LD detection
- ✅ **Fair billing**: pages that fail, error pages and pages excluded by robots.txt are free

### Checks

| Severity | Checks |
|---|---|
| Error | missing title, missing meta description, missing H1, noindex (meta or X-Robots-Tag), no mobile viewport, invalid JSON-LD, no HTTPS |
| Warning | title under 30 or over 60 characters, description under 70 or over 160, several H1s, no lang attribute, images without alt, under 300 words, mixed content, load time over 3 s |
| Notice | no canonical or canonical to another URL, no Open Graph title or image, no structured data, no favicon |

The score starts at 100 and loses 12 points per error, 5 per warning and 1 per notice.

### Input example

```json
{ "urls": ["https://apify.com", "https://books.toscrape.com/"] }
```

### Output example

Real output from a test run:

```json
{
    "url": "https://books.toscrape.com/",
    "finalUrl": "https://books.toscrape.com/",
    "score": 80,
    "issues": [
        {"code": "no_description", "severity": "error", "message": "The page has no meta description."},
        {"code": "no_canonical", "severity": "notice", "message": "The page has no canonical URL."},
        {"code": "no_og", "severity": "notice", "message": "Open Graph tags (og:title, og:image) are missing; shared links look plain."},
        {"code": "no_structured_data", "severity": "notice", "message": "No structured data (JSON-LD) found."},
        {"code": "mixed_content", "severity": "warning", "message": "The HTTPS page loads images, scripts or styles over plain HTTP."}
    ],
    "issueCounts": {"error": 1, "warning": 1, "notice": 3},
    "statusCode": 200,
    "redirected": false,
    "title": "All products | Books to Scrape - Sandbox",
    "titleLength": 40,
    "metaDescription": null,
    "metaDescriptionLength": 0,
    "h1": ["All products"],
    "headingCounts": {"h1": 1, "h2": 0, "h3": 20, "h4": 0, "h5": 0, "h6": 0},
    "canonical": null,
    "metaRobots": "NOARCHIVE,NOCACHE",
    "lang": "en-us",
    "hreflang": [],
    "wordCount": 308,
    "images": 20,
    "imagesWithoutAlt": 0,
    "linksInternal": 94,
    "linksExternal": 0,
    "openGraph": {"title": null, "description": null, "image": null, "type": null, "url": null},
    "twitterCard": null,
    "structuredDataTypes": [],
    "loadTimeMs": 237,
    "htmlBytes": 5576,
    "auditedAt": "2026-10-23T14:30:22.998Z"
}
```

A summary per URL is saved as `OUTPUT` in the key-value store.

### Pricing

A fixed price per audited page. In our tests 6 pages took 26 seconds with the default 2 GB memory.

Paid Apify plans pay less: 10% off on Starter, 20% on Scale and 30% on Business and higher plans.

### FAQ

**Is this a full site crawler?** No, it audits the pages you list. Take the URLs from your sitemap or analytics to audit a whole site.

**Why do images with `alt=""` not count as missing?** An empty alt is the correct way to mark decorative images. Only images without any alt attribute are reported.

**Why is a page "blocked_by_robots"?** By default the Actor respects robots.txt. Turn off **Respect robots.txt** only for your own sites or with the owner's permission.

### More tools from Tidelane Data

- [Lighthouse Audit](https://apify.com/tidelane/lighthouse-audit): bulk PageSpeed, Core Web Vitals and SEO scores
- [Broken Link Checker](https://apify.com/tidelane/broken-link-checker): find 404s, redirects and dead links
- [Sitemap Extractor](https://apify.com/tidelane/sitemap-extractor): all URLs of a website from its sitemaps, with lastmod
- [Accessibility Checker](https://apify.com/tidelane/accessibility-checker): WCAG 2.2, EAA and ADA audits with axe-core
- [Tech Stack Detector](https://apify.com/tidelane/tech-stack-detector): CMS, frameworks and technologies of any website

All our tools: [apify.com/tidelane](https://apify.com/tidelane)

***

#### Impressum

Levi Griesinger, Tidelane Data\
Besigheimer Straße 18\
74369, Löchgau, Deutschland\
E-Mail: LeviGriesinger@gmail.com

# Actor input Schema

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

Pages to audit, one per line. "example.com" works too.

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

Skip pages whose robots.txt forbids automated access. Turn off only for your own sites or with the owner's permission.

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

Pages that take longer fail and are not charged.

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

More is faster but needs more memory.

## Actor input object example

```json
{
  "urls": [
    "https://apify.com",
    "https://en.wikipedia.org/wiki/Search_engine_optimization"
  ],
  "respectRobotsTxt": true,
  "timeoutSecs": 45,
  "maxConcurrency": 3
}
```

# Actor output Schema

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

All results of the run as dataset items.

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

Summary per input with status (ok, error and the reason).

# 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://apify.com",
        "https://en.wikipedia.org/wiki/Search_engine_optimization"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tidelane/seo-audit").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://apify.com",
        "https://en.wikipedia.org/wiki/Search_engine_optimization",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("tidelane/seo-audit").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://apify.com",
    "https://en.wikipedia.org/wiki/Search_engine_optimization"
  ]
}' |
apify call tidelane/seo-audit --silent --output-dataset

```

## MCP server setup

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

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/bmUqh1E7SZ7R2B5eq/builds/Dxe4Z65PBoEYngxC1/openapi.json
