SEO Audit Crawler: On-Page and Technical SEO Check for Every Page

A cloud site audit that crawls like a search engine and gives every page a list of issues, a severity for each and a 0-100 score.

Run on Apify →See pricing

What it does

Spot-checking a few pages misses the problems that only show up across a site: duplicate titles, pages nothing links to, internal links that hit 404s or redirect chains. The SEO Audit Crawler follows your links and your sitemap, respects robots.txt and runs more than 40 technical and on-page checks on every HTML page it fetches.

Each page gets HTTP status and redirect chain, indexability (meta robots, X-Robots-Tag, canonical), title and meta description checks including duplicates, H1 and heading outline, word count and thin content, images missing alt text, link counts, broken internal links, inlinks, hreflang, Open Graph and Twitter cards, schema.org JSON-LD, mixed content and URL hygiene. Issues are graded error, warning or notice, and the page score starts at 100 and drops 10, 5 or 1 point per distinct issue.

A site summary adds average score, top issues by pages affected, duplicate title and description groups, the most-linked broken URLs and orphan pages that are in your sitemap but linked from nowhere. It costs $6 per 1,000 pages audited ($0.60 for a 100-page site), and pages that answer an error are reported free. It suits SEOs, agencies and developers who want a scheduled audit without installing desktop software.

How it works

  1. You give one or more startUrls; the crawl stays on that site and under each URL's path unless you set includeGlobs.
  2. It follows links up to maxDepth clicks and, with useSitemap on, reads sitemap.xml and sitemaps listed in robots.txt, then audits sitemap URLs no page links to as orphan pages.
  3. Pages are fetched as static HTML, at most 3 requests at a time, pausing on HTTP 429 for the Retry-After period.
  4. Once the crawl finishes it computes the cross-page checks (duplicates, broken internal links, inlinks, hreflang return links) and writes one row per page.
  5. The site-level summary is saved to the run's key-value store as the OUTPUT record.

Input example

A typical run input (JSON). Every field is also available as a form in the Apify console.

{
  "startUrls": [
    "https://crawlee.dev/js/docs/guides"
  ],
  "maxPages": 500,
  "maxDepth": 20,
  "includeSubdomains": false,
  "excludeGlobs": [
    "**/tag/**",
    "**/page/*"
  ],
  "useSitemap": true,
  "respectRobotsTxt": true
}
All input fields
FieldTypeRequiredDefaultWhat it does
startUrlsarrayyesWhere to start the audit. The crawl follows links on the same site and stays under each URL's path: https://example.com audits the whole site, https://example.com/blog only the blog.
maxPagesintegerno200Stop after auditing this many HTML pages. Each audited page is one 'page-audited' event; pages that answer an error are reported for free and don't count.
maxDepthintegerno20How many clicks away from a start URL to crawl. 0 = audit only the start pages.
includeSubdomainsbooleannofalseAlso audit subdomains of the start site (e.g. blog.example.com when starting at example.com).
includeGlobsarrayno[]Only audit pages matching one of these, e.g. https://example.com/docs/ ( = anything, * = anything except /). Replaces the default 'stay under the start path' rule.
excludeGlobsarrayno[]Never audit pages matching these, e.g. /tag/ or /page/* (archive and pagination pages).
useSitemapbooleannotrueRead sitemap.xml (and sitemaps listed in robots.txt). After the pages reachable by links, sitemap URLs that no page links to are audited too and reported as orphan pages.
respectRobotsTxtbooleannotrueDon't audit pages that robots.txt disallows. Turn off to audit them anyway (they are then flagged 'blocked-by-robots-txt', since search engines can't crawl them).

Output example

Each audited page is one row with its score, status, indexability, key lengths, inlinks and issue codes, as in the sample below.

urlscorestatusCodeindexabletitleLengthmetaDescriptionLengthh1CountwordCountinlinksissues
https://crawlee.dev/js/docs/guides/motivation83200true68146180meta-description-duplicate, thin-content, title-too-long, orphan-page, structured-data-missing
https://crawlee.dev/js/docs/guides/cheerio-crawler-guide89200true7856162219meta-description-duplicate, title-too-long, meta-description-too-short
https://crawlee.dev/js/docs/guides/custom-http-client94200true9966147419title-too-long, meta-description-too-short
https://crawlee.dev/js/docs/quick-start95200true691181120721title-too-long

Pricing

Pay per event: you are charged only for the results you receive, with no subscription. Set a maximum total charge on any run and it stops cleanly at the cap.

Charged forWhenPricePer 1,000Worked example
Page auditedCharged per HTML page of your site fetched and audited (one dataset row)$0.006$6100 pages = $0.60; a 1,000-page site = $6.00. Pages that answer 4xx/5xx or time out are reported free
Actor Start (platform start fee)Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event).$0.00005—One run at 1 GB = $0.00005

Prices are read from the live Apify Store listing when this page is built. The listing is always authoritative.

Try SEO Audit Crawler on Apify. Pay only for the results you get.

Run on Apify →

Use cases

Pre-launch or post-migration check

Audit a staging or freshly migrated site to catch missing titles, noindex tags left on by mistake, canonicals pointing elsewhere and redirect chains before search engines find them.

Find orphan pages in your sitemap

With useSitemap on, sitemap URLs that no crawled page links to are audited and flagged orphan-page. Raise maxPages to cover the whole site so the result is conclusive. The sitemap audit guide walks through it.

Weekly score tracking

Schedule a weekly run and compare the average score and top issues in the summary. A sudden jump in errors usually points to a template change or a deploy that broke something.

Audit one section only

Start at https://example.com/blog to audit just the blog, or use includeGlobs and excludeGlobs to target docs and skip tag and pagination archives.

How it compares

ActorForge SEO AuditDesktop SEO crawlerSaaS site audit platform
Install requiredNo, runs in the cloudYesNo
Pricing model$6 per 1,000 pages auditedLicence, often with free tierMonthly subscription
JavaScript renderingNo, static HTML onlyOften optionalOften optional
Core Web VitalsNoOften via integrationsOften yes
Orphan sitemap pagesYesUsually yesUsually yes
External link checkingNo, internal links onlyUsually yesUsually yes
OutputJSON, CSV or Excel via the dataset, plus APIExports from the appDashboards and exports

If your site renders content client-side or you need Core Web Vitals and external link checks, a desktop crawler with JavaScript rendering or a full SaaS platform covers more. This actor is for fast, cheap static-HTML audits you can schedule and pull through an API.

Limits and honest notes

FAQ

How do I audit every page of my website for SEO?

Put your homepage in startUrls and set maxPages above your site's page count (it defaults to 200). Leave useSitemap on so pages only reachable via the sitemap are included too. Each page becomes one row with its issues and score.

What counts as a title that is too long or a thin page?

Titles are checked against 30-60 characters and meta descriptions against 70-160. Thin content means under 200 words in the page body, excluding navigation, header, footer, sidebars and scripts. URLs over 115 characters and responses slower than 2 seconds are also flagged.

Does it render JavaScript?

No. Pages are fetched as static HTML, which is fast and cheap but means content that only appears after JavaScript runs is not seen. That is also how many search engine and AI crawlers first see a site.

Are pages that return errors charged?

No. Pages that answer 4xx/5xx, time out or are refused by bot protection are reported as rows free of charge. Only HTML pages fetched and audited are charged, at $0.006 each.

Where is the site-wide summary?

It is saved in the run's default key-value store as the OUTPUT record. It lists pages audited, average score, top issues, duplicate groups, broken internal links, orphan sitemap pages and whether robots.txt and a sitemap exist.

Use it from code

Run the actor through the Apify API with the input above.

cURL

curl -X POST "https://api.apify.com/v2/acts/actor-forge~seo-audit/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls": ["https://crawlee.dev/js/docs/guides"], "maxPages": 500, "maxDepth": 20, "includeSubdomains": false, "excludeGlobs": ["**/tag/**", "**/page/*"], "useSitemap": true, "respectRobotsTxt": true}'

JavaScript (Node.js)

// Node.js 18+ (built-in fetch). Set APIFY_TOKEN in your environment.
const input = {
  "startUrls": [
    "https://crawlee.dev/js/docs/guides"
  ],
  "maxPages": 500,
  "maxDepth": 20,
  "includeSubdomains": false,
  "excludeGlobs": [
    "**/tag/**",
    "**/page/*"
  ],
  "useSitemap": true,
  "respectRobotsTxt": true
};

const res = await fetch(
  "https://api.apify.com/v2/acts/actor-forge~seo-audit/run-sync-get-dataset-items",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.APIFY_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(input),
  }
);
const items = await res.json();
console.log(items.length, items[0]);

Python

# pip install apify-client   (set APIFY_TOKEN in your environment)
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run_input = {
    "startUrls": [
        "https://crawlee.dev/js/docs/guides"
    ],
    "maxPages": 500,
    "maxDepth": 20,
    "includeSubdomains": False,
    "excludeGlobs": [
        "**/tag/**",
        "**/page/*"
    ],
    "useSitemap": True,
    "respectRobotsTxt": True
}

run = client.actor("actor-forge/seo-audit").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

The run-sync-get-dataset-items endpoint waits for the run (up to 5 minutes) and returns the dataset rows directly. For longer runs, start the run asynchronously and read the dataset when it finishes, as the Python example does. Replace APIFY_TOKEN with your own token from the Apify console.

Step-by-step guides

How to Audit Every URL in Your Sitemap and Find Orphan Pages

Run the SEO Audit Crawler with useSitemap on and maxPages above your site's size; it audits every page it can reach plus every sitemap URL, and…

Related actors

Keyword Suggestions — Google, YouTube, Bing Autocomplete

Bulk keyword suggestions from Google, YouTube, Bing and Baidu autocomplete. Expand each seed with a-z, question words or prepositions for long-tail…

$0.30 per 1,000 · seed expanded

Wayback Machine Scraper — Archive.org Snapshots & URL History

Every Wayback Machine (archive.org) capture of a URL, folder, host or domain: timestamp, status, MIME type, digest and archive links. Unique…

$2 per 1,000 · snapshot

Google Trends Scraper — Trending Now & Interest Over Time

Google Trends scraper and API: Trending Now searches for 125 countries from the official feed (traffic, start time, picture, news articles), plus…

$0.50 per 1,000 · trend result

Try SEO Audit Crawler on Apify. Pay only for the results you get.

Run on Apify →

More SEO & Marketing Intelligence tools · All actors