Technical SEO Page Audit avatar

Technical SEO Page Audit

Pricing

from $20.00 / 1,000 page auditeds

Go to Apify Store
Technical SEO Page Audit

Technical SEO Page Audit

Audit public pages for technical SEO with 44 deterministic checks: indexability, robots.txt, canonical, titles, headings, links, images, JSON-LD, hreflang, HTTPS and headers. Every check carries its evidence. No JavaScript rendering, no AI.

Pricing

from $20.00 / 1,000 page auditeds

Rating

0.0

(0)

Developer

Alijah Konikowski

Alijah Konikowski

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

8 days ago

Last modified

Categories

Share

Audits public web pages for technical SEO and returns one JSON report per page: 44 fixed checks, each with a status, the evidence it was decided on, and a fixed recommendation when it warns or fails. The same HTML and response headers always give the same checksSha256.

It reads what a crawler reads: the server HTML, response headers, robots.txt and, if you ask, the status of the page's links. It does not run JavaScript and uses no AI model.

Input

FieldTypeDefault
urlsarray of http(s) URLsPages to audit, up to 100
sitemapUrlURLOptional sitemap or sitemap index; same-host pages are added in sitemap order
maxPages1-10010Pages taken from the sitemap
checkLinksbooleanfalseHEAD-request the page's links and report 4xx/5xx
maxLinksToCheck1-5020Links checked per page
timeoutSecsPerUnit10-30060Time allowed per page

Give urls, sitemapUrl, or both. Example:

{
"urls": [
"https://example.com/"
]
}

Output

One dataset item per audited page:

  • score.overall (0-100) and score.categories, computed from check weights: pass counts fully, warn half, fail zero
  • counts of pass / warn / fail / info / not_applicable / not_checked
  • checks[]: id, category, title, weight, status, evidence, recommendation (null unless the check warns or fails), measured (true for the two time-dependent checks)
  • page: title, meta description, canonical, robots directives, H1s, word count, link and image counts, JSON-LD types, Open Graph, hreflang
  • http: status, redirect chain, response time, HTML bytes, transfer bytes, content encoding
  • completeness: whether robots.txt and the link check were fully read
  • htmlSha256 (the HTML that was judged) and checksSha256 (the checks, excluding the two time-dependent ones)

A page that cannot be audited (DNS failure, timeout, 4xx/5xx, non-HTML, blocked address) produces an item with ok: false and an error.code instead. The key-value store record OUTPUT lists every page with whether it was charged and why.

Real output for the example input above, shortened to 3 of the 44 checks and 6 of the page fields:

{
"url": "https://example.com/",
"finalUrl": "https://example.com/",
"ok": true,
"score": {
"categories": {
"content": 84,
"indexability": 93,
"links": 75,
"performance": 100,
"security": 92,
"structured_data": 50
},
"overall": 86
},
"counts": {
"fail": 0,
"info": 5,
"not_applicable": 10,
"not_checked": 1,
"pass": 20,
"warn": 8
},
"completeness": {
"linkCheck": "skipped",
"robotsTxt": "absent"
},
"htmlSha256": "25ddf2c883e0d1958ea971d279a7e4f0fd446724ee3db7db19dadabd4a62e484",
"checksSha256": "80404755eac37451a50a6046a764bdb094592c32ead1074bc4bf41a6a4680935",
"fetchedAt": "2026-10-08T02:51:10Z",
"checks": [
{
"category": "indexability",
"evidence": {
"canonical": []
},
"id": "IDX004",
"measured": false,
"recommendation": "Add one <link rel=\"canonical\"> with an absolute URL in <head>; remove duplicates.",
"status": "warn",
"title": "Exactly one absolute canonical URL",
"weight": 2
},
{
"category": "indexability",
"evidence": {
"http_status": 404,
"note": "no robots.txt: everything is allowed",
"robots_url": "https://example.com/robots.txt"
},
"id": "IDX006",
"measured": false,
"recommendation": null,
"status": "pass",
"title": "robots.txt allows crawling this URL",
"weight": 5
},
{
"category": "content",
"evidence": {
"h1": [],
"h1_count": 0
},
"id": "CNT005",
"measured": false,
"recommendation": "Use exactly one <h1> that states the page topic.",
"status": "warn",
"title": "Exactly one H1",
"weight": 2
}
],
"page": {
"title": "Example Domain",
"metaDescription": null,
"canonical": null,
"lang": "en",
"h1": [],
"wordCount": 25
},
"http": {
"status": 200,
"redirects": [],
"responseMs": 50,
"htmlBytes": 577,
"transferBytes": 400,
"contentEncoding": "gzip"
}
}

Pricing

Pay per event:

  • page-audited: $0.02 per page that produced a report. A page is charged only after its report is validated against the output schema and saved to the dataset.
  • Apify's run-start event, apify-actor-start: $0.00005 per run (one event: this Actor's memory is capped at 1 GB).
  • Platform usage (compute, storage, data transfer) is not charged to you on top of these events.

Never charged: pages that fail to load (DNS, timeout, connection reset, 4xx/5xx, rate limiting), non-HTML responses, invalid or private-network URLs, and any page the run's maximum charge cannot cover (the run stops before fetching it). A report whose robots.txt or link check could not be completed is still a report and is charged; completeness says which part is missing.

Checks

IdCategoryRuleWeight
IDX001indexabilityFinal response is HTTP 2005
IDX002indexabilityAt most one redirect before the page1
IDX003indexabilityPage is not marked noindex5
IDX004indexabilityExactly one absolute canonical URL2
IDX005indexabilityCanonical points to this page1
IDX006indexabilityrobots.txt allows crawling this URL5
IDX007indexabilityrobots.txt declares a sitemap1
IDX008indexabilityResponse is HTML3
CNT001contentPage has a title4
CNT002contentTitle length 10-60 characters2
CNT003contentPage has a meta description2
CNT004contentMeta description length 50-160 characters1
CNT005contentExactly one H12
CNT006contentHeading levels are not skipped1
CNT007contentAt least 200 words of visible text1
CNT008content declares lang1
CNT009contentMobile viewport meta tag2
CNT010contentCharacter encoding declared1
LNK001linksPage links to other pages on the site2
LNK002linksEvery link has an accessible name1
LNK003linksNo broken links among those checked3
LNK004linksNo placeholder links (# or javascript:)1
IMG001mediaEvery image has an alt attribute2
IMG002mediaImages declare width and height1
SD001structured dataJSON-LD structured data present1
SD002structured dataAll JSON-LD blocks parse3
SD003structured dataJSON-LD nodes have schema.org @context and @type2
SD004structured dataOpen Graph title, description and image1
SD005structured dataTwitter card declared1
INT001internationalhreflang values and URLs are valid2
INT002internationalhreflang set includes this page2
INT003internationalhreflang set has x-default1
SEC001securityFinal URL uses HTTPS5
SEC002securityHTTP redirects to HTTPS1
SEC003securityStrict-Transport-Security header2
SEC004securityNo mixed content3
SEC005securityX-Content-Type-Options: nosniff1
SEC006securityContent-Security-Policy header1
SEC007securityTLS certificate valid for 21+ more days3
PRF001performanceHTML document under 500 KB2
PRF002performanceHTML is compressed in transit2
PRF003performanceAt most 2 render-blocking scripts in 2
PRF004performanceServer answered within 800 ms1
PRF005performanceHTML response has Cache-Control1

PRF004 (response time) and SEC007 (certificate days left) depend on when the page is fetched and are excluded from checksSha256.

What it does not do

  • It does not crawl a site. It audits the URLs you give and, if you give a sitemap, up to maxPages same-host pages from it.
  • It does not render JavaScript, measure Core Web Vitals (LCP, CLS, INP) or take screenshots.
  • It does not log in, send cookies or fill forms; pages behind authentication are audited as an anonymous visitor sees them.
  • It does not report rankings, keywords, backlinks or traffic.
  • It does not change your site: every request is read-only (GET for the page and robots.txt; HEAD for links, or a one-byte ranged GET when a server refuses HEAD).

Limits

  • Server HTML only. Content added by JavaScript is not seen; neither are lab metrics such as LCP or CLS.
  • robots.txt is evaluated per RFC 9309 for Googlebot and * (wildcards, $, longest match, allow wins ties).
  • At most 100 pages per run, 5 MB of HTML per page, 5 redirects.
  • Requests to private, loopback, link-local and reserved addresses are refused, including after redirects.

Schemas and permissions

The input and every output item are described by JSON schemas that ship with the Actor (.actor/input_schema.json, .actor/dataset_schema.json). The Actor runs with Apify's limited permissions: it accesses only its own run's storage and the input you give it.