Site Audit: Full-Site SEO Audit with Fixes avatar

Site Audit: Full-Site SEO Audit with Fixes

Pricing

from $3.50 / 1,000 page auditeds

Go to Apify Store
Site Audit: Full-Site SEO Audit with Fixes

Site Audit: Full-Site SEO Audit with Fixes

Audit every page of a website for SEO problems in one run. Each page gets a score from 0 to 100, its issues and a one-line fix for each. Run it again and each page is marked new, changed or unchanged, with pages that are gone. $0.005 per page, no browser, no monthly fee.

Pricing

from $3.50 / 1,000 page auditeds

Rating

0.0

(0)

Developer

Brian Gomes

Brian Gomes

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 hours ago

Last modified

Share

Site Audit checks every page of a website for SEO problems, scores each page from 0 to 100, and gives you a one-line fix for every issue it finds.

Run it again next week and it tells you what changed: which pages are new, which got worse, which issues you fixed, and which pages are gone.

It works over plain HTTP. One request per page, no browser. That keeps it fast and cheap: $0.005 per page audited. A 500-page site costs $2.50.

What it checks on every page

CheckIssue idSeverity
The page answers with an error (4xx or 5xx)http-errorerror (the page scores 0)
The page redirects before it answers. The full chain is listedredirectwarning
Slow response, over 3,000 ms by defaultslow-responsewarning
Title missing or emptytitle-missingerror
Title over 60 or under 10 characterstitle-too-long, title-too-shortnotice
Same title as another pagetitle-duplicatewarning
More than one title elementtitle-multiplenotice
Meta description missingmeta-description-missingwarning
Meta description over 160 or under 50 charactersmeta-description-too-long, meta-description-too-shortnotice
Same meta description as another pagemeta-description-duplicatewarning
No H1h1-missingwarning
More than one H1h1-multiplenotice
No canonical linkcanonical-missingnotice
A canonical that points to another URLcanonical-elsewherenotice
noindex in meta robots or the X-Robots-Tag headernoindexwarning
noindex on a page the sitemap listsnoindex-in-sitemaperror
No lang attribute on <html>lang-missingnotice
Images with no alt attribute (alt="" counts as present, since it marks a decorative image)images-missing-altwarning
Internal links that are broken, each listed with its status or errorbroken-internal-linkserror
Images, scripts, stylesheets or frames loaded over http on an https pagemixed-contentwarning
HTML over 2 MBpage-too-largewarning
The page was cut off (over 5 MB, it stopped arriving, or its HTML couldn't be parsed past a point)page-incompletewarning

The score and the fixes

Every page starts at 100. It loses 30 for each error, 10 for each warning and 3 for each notice, and stops at 0. A page that answers with an error status scores 0.

Every issue comes with a fix you can hand to whoever runs the site. Two examples, word for word from the output:

  • title-too-long: "Shorten the
  • noindex-in-sitemap: "Either remove noindex or remove the page from the sitemap: the two contradict each other."

The summary row at the end gives the site score (the average over the pages audited), the issue counts by type, and the ten fixes that matter most across the whole site, ranked by severity times the number of pages.

What changed since the last run

This is the part you'll use every week.

The first run audits the site. Every run after that on the same start URL compares against the last one and marks each page:

  • new: it wasn't there last time
  • changed: its score, its issues, its status code or its visible text changed
  • unchanged: nothing changed
  • removed: it was there last time and isn't now

Each page row also carries previousScore, newIssues (issues that appeared) and fixedIssues (issues that went away). The summary row counts all of it, plus the pages that answered fine last time and now redirect or fail.

So you don't read a 500-row audit every week. You read what moved.

How it works: the Actor keeps a small record of each page's score, issues, status code and a fingerprint of its text, in your own account's key-value store named site-audit-history. Delete that store in Storage to start fresh. Turn off Compare with the previous run to skip it.

A run that stops early (at your page limit or your maximum charge) never calls a page removed. It keeps the pages it didn't reach in the record for next time.

To be told when something breaks, schedule the Actor with Apify Schedules and connect a webhook or an integration like Slack, email or Google Sheets.

Sitemap or crawl

  • Auto (the default): it reads the sitemap first. It looks for Sitemap lines in robots.txt, then /sitemap.xml and /sitemap_index.xml, follows sitemap indexes and reads gzipped sitemaps. If the site has no sitemap, it follows links from the start page instead.
  • Sitemap only: audits the pages the sitemap lists, including ones no menu links to anymore. Only pages found in a sitemap get the noindex-in-sitemap check.
  • Crawl only: follows links from the start page, on the same site only (with or without www.), up to the depth you set. Links to files like images, PDFs, CSS and JS aren't followed as pages.

You can also give it a sitemap URL as the start URL, and it reads that sitemap directly.

Page content as Markdown (optional)

Turn on Include page content as Markdown and each row gets the page's main content as Markdown: headings, paragraphs, lists and code blocks. It takes <main> or <article> when the page has one. Otherwise it takes the body and leaves out navigation, header, footer, sidebars and forms. Up to 50,000 characters per page. Link targets aren't kept. It costs nothing extra.

Input

FieldWhat it doesDefault
startUrlThe website, like https://example.com, or a sitemap URL.required
maxPagesStop after auditing this many pages. Only pages that answer are counted and charged. 1 to 50,000.100
discoveryauto, sitemap or crawl.auto
maxDepthWhen crawling, how many clicks from the start page to follow. 0 audits the start page only.5
checkInternalLinksCheck each link to the same site once and list the broken ones on every page that has them.true
compareWithPreviousRunMark each page new, changed, unchanged or removed since the last run.true
includeMarkdownAdd the page's main content as Markdown.false
slowThresholdMsA page slower than this gets a slow-response issue.3000
maxConcurrencyRequests in flight at once, 1 to 20. Never more than 4 to one host.5
requestTimeoutSecsHow long to wait for any one request.20

The form starts at 10 pages, so your first audit costs $0.05.

Example input:

{
"startUrl": "https://example.com",
"maxPages": 500,
"discovery": "auto",
"checkInternalLinks": true,
"compareWithPreviousRun": true
}

Output

Export the dataset as CSV, JSON, Excel, XML or HTML, or read it through the Apify API. It has four kinds of rows:

  • one row per page audited (type: page)
  • one row per page that disappeared since the last run (type: page, change: removed)
  • an error row when something couldn't be read, like a missing sitemap (type: error)
  • one summary row at the end (type: summary)

A page row holds: url, audited, score, issueCount, issues (each with id, severity, message and fix), change, previousScore, newIssues, fixedIssues, statusCode, finalUrl, redirectCount, redirectChain, responseTimeMs, contentType, htmlBytes, title, titleLength, metaDescription, metaDescriptionLength, h1Count, canonicalUrl, noindex, lang, imagesMissingAlt, internalLinks, brokenInternalLinks (up to 20 listed, all counted), mixedContent (up to 20 listed), wordCount, contentHash, foundIn (sitemap or crawl), depth, markdown, markdownTruncated, error, startUrl.

Example page row (example data, real field names):

{
"type": "page",
"url": "https://example.com/pricing",
"audited": true,
"score": 57,
"issueCount": 3,
"issues": [
{
"id": "title-too-long",
"severity": "notice",
"message": "The title is 74 characters.",
"fix": "Shorten the <title> to 60 characters or fewer so search results don't cut it off."
},
{
"id": "meta-description-missing",
"severity": "warning",
"message": "The page has no meta description.",
"fix": "Add a meta description, 70 to 160 characters, that sums up the page."
},
{
"id": "broken-internal-links",
"severity": "error",
"message": "1 internal link(s) are broken.",
"fix": "Fix or remove the links listed in brokenInternalLinks."
}
],
"change": "changed",
"previousScore": 97,
"newIssues": ["broken-internal-links", "meta-description-missing"],
"fixedIssues": [],
"statusCode": 200,
"finalUrl": "https://example.com/pricing",
"redirectCount": 0,
"responseTimeMs": 412,
"title": "Pricing plans for teams of every size, billed monthly or yearly | Example",
"titleLength": 74,
"metaDescription": null,
"h1Count": 1,
"canonicalUrl": "https://example.com/pricing",
"noindex": false,
"lang": "en",
"imagesMissingAlt": 0,
"internalLinks": 38,
"wordCount": 912,
"foundIn": "sitemap",
"depth": 0,
"error": null
}

Any text in the output that starts with =, +, - or @ (a title, a meta description, Markdown, a header value, a URL) gets a leading ', so it can't run as a formula when you open the dataset in a spreadsheet.

Pricing

You pay per page audited. There's no monthly fee.

  • Each page audited: $0.005. A page counts when it answers with a status code, errors and redirects included.
  • Free: pages skipped for robots.txt, pages that never answer, internal link checks, Markdown, removed-page rows, error rows and the summary row.
  • Discounts: on Apify's discount tiers the price drops to $0.0045 (Bronze), $0.004 (Silver) and $0.0035 (Gold and above).
  • Apify's standard start fee applies to each run.

Worked examples, at the base price:

  • A 100-page site: $0.50 per audit.
  • A 500-page site: $2.50 per audit. Every week, about $10 a month.
  • A 5,000-page site: $25 per audit.

For a hard ceiling, set maxPages or a maximum charge per run. The run stops cleanly when it reaches your maximum charge.

Limits

  • No JavaScript rendering. A page built in the browser by a client-side framework is audited on the HTML the server sends, which may be thin.
  • Some pages are fetched twice when crawling. Each internal link is checked once per run, up to 100 new links per page, and the link check doesn't read the page body. When crawling, a page that was link-checked is requested again when its turn comes to be audited. You're charged once.
  • It stops on its own when a site stops answering: 20 requests in a row with no answer, or 10 minutes spent waiting.
  • No proxies, no logins, no forms submitted.

robots.txt and good manners

  • It respects robots.txt (RFC 9309). If robots.txt can't be reached, nothing on that site is fetched, and a row says why.
  • It honours Crawl-delay up to 10 seconds, and sends at most 4 requests at a time to one host.
  • It identifies itself honestly as SiteAuditHTTP/0.1.

Public websites only

Addresses on private networks, loopback and cloud metadata ranges are refused, including when a public page redirects to one.

FAQ

How do I run an SEO audit on my whole website? Put your homepage in startUrl and run it. Sort the page rows by score, lowest first, and work from the summary row's top ten fixes.

How do I see only what changed since last week? Filter the page rows on change. Anything changed, new or removed moved since the last run. newIssues and fixedIssues say exactly what.

Why does a page have a lower score than last time? Look at newIssues on that row. Each one has a message and a fix.

Can I call it from my own code? Yes. Start it and read the results through the Apify API or the Python and JavaScript clients.

Integrations

This Actor runs on Apify, so everything the platform does works with it.

  • API. Start a run and read the results from your own code, in any language. Apify API
  • Schedules. Run it weekly and each run tells you what changed since the last one. Schedules
  • Tasks. Save your input once as a task and run it again with one click, or on a schedule. Tasks
  • Webhooks. Get a call to your own URL when a run succeeds or fails. Webhooks
  • Google Sheets and Drive. Download the results as CSV or Excel and open them in Sheets. Or add a Google Sheets step after this Actor in Make or Zapier. Or send the files to a Google Drive folder. Datasets and exports, Google Drive
  • Zapier, Make and n8n. Start a run from another app and send the results on to the next step. Zapier, Make, n8n
  • AI agents (MCP). Claude, ChatGPT and other MCP clients can find and run this Actor through the Apify MCP server. Apify MCP server
  • Other Actors. Pass this Actor's results to another Actor when a run finishes. Actor-to-Actor

Works with

Support

Found a bug or need a feature? Open an issue on this Actor's Issues tab. Include the run ID and the URL you gave it.