Technical SEO Audit Tool avatar

Technical SEO Audit Tool

Pricing

from $1.79 / 1,000 results

Go to Apify Store
Technical SEO Audit Tool

Technical SEO Audit Tool

Review technical SEO signals across a website or a supplied set of URLs. Each HTML page record includes titles, headings, canonicals, indexability directives, redirect details, links, image alt gaps, schema types and rule-based issue codes. Uses plain HTTP without a browser or API key.

Pricing

from $1.79 / 1,000 results

Rating

0.0

(0)

Developer

Axiom Works

Axiom Works

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Returns: one row per web page with finalUrl, statusCode, title, metaDescription, h1, canonical, noindex, wordCount and a list of issues. Input: {"startUrls": [{"url": "https://www.example.com/"}], "maxDepth": 1, "maxPages": 50} Best for: technical SEO audits for clients, pre-launch and post-migration checks, monitoring titles, canonicals and indexability across a site.

{
"finalUrl": "https://www.python.org/",
"statusCode": 200,
"title": "Welcome to Python.org",
"titleLength": 21,
"h1Count": 5,
"canonical": null,
"isIndexable": true,
"issues": ["title_too_short", "meta_description_too_short", "multiple_h1", "missing_canonical", "redirected"]
}

What does Website SEO Audit Tool do?

Website SEO Audit Tool is an on-page SEO checker and site crawler. Give it a website URL and it follows the internal links breadth-first, fetches each page over plain HTTP and returns one record per HTML page with the on-page SEO data an audit needs: the title and meta description with their lengths, H1 and H2 headings, the canonical URL and whether it points to the page itself, robots meta and X-Robots-Tag directives, whether robots.txt disallows the path, hreflang alternates, the html lang attribute, Open Graph and Twitter card tags, viewport and charset, the HTTP status with the full redirect chain and response time, image counts and missing alt text, a boilerplate-free word count, schema.org types from JSON-LD and microdata, and internal, external and nofollow link counts.

Every record also carries a list of plain issue codes such as missing_meta_description, multiple_h1, canonical_mismatch, noindex or http_404, so you can sort and filter a whole site in a spreadsheet without reading HTML. There is no made-up score: each code comes from a fixed, documented rule (see the FAQ).

It works on any public website. You can crawl a site from its homepage, or set maxDepth to 0 and paste a list of URLs to audit just those pages. No login, no API key and no browser are needed. Use it as a website SEO audit API, a scheduled regression check, or a tool for AI agents.

What data can you get from a website SEO audit?

FieldDescriptionExample
idStable ID: the first 16 hex characters of the SHA-1 of finalUrl1ab11d99cba1c395
urlURL as requested (normalised start URL or the internal link followed)https://python.org/
finalUrlURL after redirects; same as sourceUrlhttps://www.python.org/
statusCodeHTTP status of the final response200
redirectCountNumber of redirect hops1
redirectChain{url, statusCode} for each 3xx hop; empty when no redirect[{"url": "https://python.org/", "statusCode": 301}]
contentTypeMIME type of the responsetext/html
responseTimeMsTime to fetch the page, redirects included60
htmlSizeBytesSize of the decoded HTML52282
depthCrawl depth, 0 for start URLs0
titleText of <title>; null when missingWelcome to Python.org
titleLengthCharacters in the title (0 when missing)21
metaDescriptionContent of the meta description; null when missingThe official home of the Python Programming Language
metaDescriptionLengthCharacters in the meta description52
metaKeywordsContent of meta keywords; null when missingPython programming language ...
h1, h2Text of every H1 and H2 on the page["Functions Defined", ...]
h1Count, h2Count, h3CountNumber of H1, H2 and H3 elements5, 9, 0
canonicalAbsolute URL from <link rel=canonical>; null when missinghttps://www.mozilla.org/en-US/
canonicalMatchestrue when the canonical equals finalUrl; null without a canonicaltrue
robotsMetaContent of <meta name=robots>noindex
xRobotsTagX-Robots-Tag response headernoindex
robotsTxtDisallowedtrue when robots.txt disallows the path for User-agent: *false
noindex, nofollowDirectives found in robots meta or X-Robots-Tagfalse
isIndexableStatus 200, not noindex, canonical absent or self-referencingtrue
langValue of <html lang>en
hreflang, hreflangCount{lang, href} alternates and their number85
ogTitle, ogDescription, ogImageOpen Graph tagshttps://www.python.org/static/opengraph-icon-200x200.png
twitterCardContent of twitter:cardsummary
viewport, charsetViewport meta and declared charsetwidth=device-width, initial-scale=1.0, utf-8
imagesTotal, imagesMissingAltNumber of <img> and of those without a non-empty alt22, 17
imagesMissingAltSrcUp to 10 absolute src URLs of images missing alt["https://www.mozilla.org/media/..."]
wordCountWords in the body text with navigation, header, footer, aside, scripts and styles removed409
schemaTypesschema.org types from JSON-LD and microdata["WebSite", "SearchAction"]
internalLinksCount, externalLinksCount, nofollowLinksCountUnique links to the same site, to other hosts, and with rel=nofollow64, 63, 0
internalLinks, externalLinksUp to 20 unique link URLs of each kind["https://www.python.org/jobs/", ...]
issues, issueCountDetected issue codes and how many["multiple_h1", "missing_canonical"], 2
scrapedAtWhen the page was audited (ISO 8601)2026-10-20T00:20:35.701Z
sourceUrlThe audited pagehttps://www.python.org/

At the end of each run the key-value store also gets a SUMMARY record: the start URLs, pages crawled, pages with issues, a count per issue code, the URLs skipped because they were not HTML (PDF, XML, images) and the URLs that gave no response, with the reason.

How to use Website SEO Audit Tool

  1. Open the Actor in Apify Console and go to the Input tab.
  2. In Start URLs, enter the site to audit, for example [{"url": "https://www.example.com/"}]. A bare host such as example.com works too.
  3. Set Crawl depth: 0 audits only the URLs you gave, 1 also audits the pages they link to, 2 goes one level further.
  4. Set Maximum pages to fetch and Maximum results to the size of the audit you want. Both are shared by all start URLs.
  5. Click Start. Records appear in the Output tab as pages are audited.
  6. Use the SEO audit view for the key columns, or export everything as JSON, CSV, Excel, XML or HTML.

Tips:

  1. To audit a list of landing pages, paste them all into Start URLs and set Crawl depth to 0. Each URL becomes one record, including pages that answer 404 or 500.
  2. Exclude sections you do not care about with Exclude URL patterns, for example /tag/ or \?page=.
  3. Leave the proxy off for most sites. If a start page answers 403, 429 or 503, the Actor retries it once through Apify Proxy datacenter and then residential IPs on its own.
  4. Turn on Respect robots.txt if you want the crawl to stay out of disallowed sections. The robotsTxtDisallowed field is reported either way.

Input

FieldTypeRequiredDescription
startUrlsarrayYes (or url / urls / startUrl)Pages to start from, as {"url": ...} objects or plain strings. Full URLs or bare hosts.
maxDepthintegerNoLink levels to follow, 0-10, default 1. 0 = URL-list mode.
maxPagesintegerNoPages fetched across all start URLs, 1-10000, default 50.
maxItemsintegerNoRecords returned across all start URLs, 1-100000, default 50.
includeSubdomainsbooleanNoTreat subdomains as internal, default false.
respectRobotsTxtbooleanNoSkip links disallowed by robots.txt, default false.
excludeUrlPatternsarray of stringsNoRegular expressions; matching internal links are not crawled.
maxRedirectsintegerNoRedirect hops to follow per page, 0-30, default 10.
requestTimeoutSecsintegerNoSeconds to wait for each response, 3-120, default 15.
maxConcurrencyintegerNoPages fetched in parallel, 1-20, default 3 (at most 2 per host).
userAgentstringNoCustom User-Agent; default is desktop Chrome.
proxyConfigurationobjectNoProxy for all requests. Default: none, with an automatic Apify Proxy retry for blocked start pages.
{
"startUrls": [{ "url": "https://www.mozilla.org/en-US/" }],
"maxDepth": 1,
"maxPages": 25,
"maxItems": 25,
"includeSubdomains": false,
"respectRobotsTxt": false,
"excludeUrlPatterns": ["/wp-admin/"],
"proxyConfiguration": { "useApifyProxy": false }
}

Output

Real records from a local run: the python.org homepage reached through a redirect, and a test page that answers 404 with noindex. Some fields are left out here for space.

[
{
"id": "1ab11d99cba1c395",
"url": "https://python.org/",
"finalUrl": "https://www.python.org/",
"statusCode": 200,
"redirectCount": 1,
"redirectChain": [{ "url": "https://python.org/", "statusCode": 301 }],
"contentType": "text/html",
"responseTimeMs": 60,
"htmlSizeBytes": 52282,
"depth": 0,
"title": "Welcome to Python.org",
"titleLength": 21,
"metaDescription": "The official home of the Python Programming Language",
"metaDescriptionLength": 52,
"h1": ["Functions Defined", "All the Flow You’d Expect", "Compound Data Types", "Intuitive Interpretation", "Quick & Easy to Learn"],
"h1Count": 5,
"h2Count": 9,
"canonical": null,
"canonicalMatches": null,
"robotsTxtDisallowed": false,
"noindex": false,
"isIndexable": true,
"lang": "en",
"hreflangCount": 0,
"ogTitle": "Welcome to Python.org",
"ogImage": "https://www.python.org/static/opengraph-icon-200x200.png",
"viewport": "width=device-width, initial-scale=1.0",
"charset": "utf-8",
"imagesTotal": 1,
"imagesMissingAlt": 0,
"wordCount": 409,
"schemaTypes": ["WebSite", "SearchAction"],
"internalLinksCount": 64,
"externalLinksCount": 63,
"issues": ["title_too_short", "meta_description_too_short", "multiple_h1", "missing_canonical", "redirected"],
"issueCount": 5,
"scrapedAt": "2026-10-20T00:20:35.701Z",
"sourceUrl": "https://www.python.org/"
},
{
"id": "9c72b15b852b8684",
"url": "https://crawler-test.com/robots_protocol/non_200_with_noindex",
"finalUrl": "https://crawler-test.com/robots_protocol/non_200_with_noindex",
"statusCode": 404,
"redirectCount": 0,
"title": "Non-200 with Noindex",
"titleLength": 20,
"h1Count": 0,
"robotsMeta": "noindex",
"noindex": true,
"isIndexable": false,
"wordCount": 4,
"issues": ["title_too_short", "missing_meta_description", "missing_h1", "missing_canonical", "noindex", "thin_content", "missing_viewport", "missing_html_lang", "http_404"],
"issueCount": 9,
"sourceUrl": "https://crawler-test.com/robots_protocol/non_200_with_noindex"
}
]

How much does it cost to run a website SEO audit?

Website SEO Audit Tool is charged per result: one result is one audited page. You pay only for the records returned, and maxItems caps how many there can be, so a run never costs more than you planned. Pages that give no response and non-HTML files are not records and are not charged. See the Pricing tab for the current price.

Use with AI agents (MCP)

Connect Website SEO Audit Tool to Claude, Cursor or any MCP client through the Apify MCP server:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com/?tools=axiomworks/website-seo-audit-tool"
}
}
}

Example prompts:

  1. "Audit https://www.example.com/ two levels deep and list every page with a missing meta description or more than one H1."
  2. "Check these 10 landing pages with crawl depth 0 and tell me which ones are not indexable and why."
  3. "Crawl our blog, find pages under 300 words, and suggest which ones to merge."

Integrations and API

Run Website SEO Audit Tool from your own code with the Apify API. Set APIFY_TOKEN to your Apify API token (send it in the Authorization header, never in the URL).

Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("axiomworks/website-seo-audit-tool").call(run_input={
"startUrls": [{"url": "https://www.example.com/"}],
"maxDepth": 1,
"maxPages": 50,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["finalUrl"], item["statusCode"], item["issues"])

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('axiomworks/website-seo-audit-tool').call({
startUrls: [{ url: 'https://www.example.com/' }],
maxDepth: 1,
maxPages: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

cURL

curl -X POST "https://api.apify.com/v2/acts/axiomworks~website-seo-audit-tool/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"startUrls": [{"url": "https://www.example.com/"}], "maxDepth": 0}'

The Integrations tab connects the Actor to Make, Zapier, n8n, Google Sheets, Slack and webhooks, so a scheduled audit can drop its results into a sheet or alert you when new issues appear.

FAQ

Which rules produce the issue codes? missing_title; title_too_long (over 60 characters) and title_too_short (under 30); missing_meta_description; meta_description_too_long (over 160) and meta_description_too_short (under 70); missing_h1 and multiple_h1; missing_canonical and canonical_mismatch (canonical is not the page's own final URL); noindex; robots_txt_disallowed; images_missing_alt; thin_content (under 300 words); redirected; not_https; missing_viewport; missing_html_lang; and http_<status> for any status other than 200. They are fixed thresholds, not a judgement about rankings, so treat them as a checklist.

How is the word count calculated? The body text is taken after removing scripts, styles, noscript, template, svg, nav, header, footer and aside elements, then split on whitespace. It is a heuristic: a site that puts its main content inside a <header> or <nav> gets a lower count.

Does it render JavaScript? No. It reads the HTML the server sends, which is what most search engine crawlers see first. Content that only appears after JavaScript runs is not counted.

Which links count as internal? Links whose host, ignoring a leading www., equals the host the start URL lands on. A start URL python.org that redirects to www.python.org makes both internal. Subdomains such as docs.python.org count as external unless you turn on includeSubdomains. A link that redirects to another site is audited (status and redirect chain) but its own links are not followed.

Why did my run return 0 results? The start URL gave no HTTP response (the host does not exist, refused the connection, timed out, or redirected too many times), or it is not an HTML page (a PDF or XML file). The status message names the URL and the reason, and the SUMMARY record lists every skipped or failed URL. A page that answers 404 or 500 still gets a record with its status.

Is robots.txt obeyed? By default the crawl reports robots.txt (robotsTxtDisallowed) without obeying it, so you can see blocked pages that are still linked. Set respectRobotsTxt to true to keep the crawl out of disallowed paths.

Can I schedule it? Yes. Save your input as a task and add a weekly schedule, then compare the SUMMARY issue counts between runs.

Website SEO Audit Tool reads only publicly available pages, the same HTML any visitor's browser receives, and does not log in or bypass access controls. It crawls politely and can respect robots.txt on request. You are responsible for how you use the results and for having the right to audit the sites you crawl; when pages contain personal data, data protection laws such as the GDPR may apply. This is not legal advice.

Website SEO Audit Tool is an independent tool. It is not affiliated with, endorsed by or sponsored by any of the websites it audits, including the sites used in the examples above.

ActorWhat it does
Sitemap URL ExtractorLists every URL in a site's sitemaps, a good start list for a URL-list audit
Link Status CheckerChecks links for broken or redirecting targets
PageSpeed Insights CheckerGets Core Web Vitals and Lighthouse scores for pages

Feedback

Found a bug or need a field that isn't here? Open an issue on the Issues tab and we'll look at it.