Skip to content
All docs

Site Audit: crawl a site and read Site Health

Crawl up to 10,000 pages for 1¢ per 10 pages and get Site Health, 9 theme scores and 173 checks, each with why it matters and how to fix it.

Updated View as Markdown
On this page· 15 sections

Steps

1. Start a crawl

Open a site's Technical tab from your sites and click Crawl site (or Re-crawl site). Pick how many pages to crawl, up to 10,000; the most it can cost is shown before you start. An agent can start the same crawl with crawl_site over MCP, and a script with POST /api/v1/crawl over the REST API.

2. Read Site Health and the themes

When the crawl finishes, the tab shows Site Health (0–100), the number of errors, warnings and notices, and a score for each of the 9 themes. Checks are listed worst first: each one says how many items failed out of how many were checked, why it matters and how to fix it. Core Web Vitals show as Pending for a few minutes after the crawl, while they're measured.

3. Open a check and fix it

Click View pages on a check to see every affected URL with its evidence (the status code, the duplicate title, the broken link and the pages that link to it). Checks AEBOT can help with have a Fix with AEBOT button. Agents read the same list with get_crawl_issue, free.

4. Schedule it

To keep watching the site, turn on Scheduled crawls on the same tab: weekly or monthly, with a summary email after each run. Setting it up is free; each run bills 1¢ per 10 pages when it runs.

5. Crawl again and compare

Re-crawl once your fixes are live. Each new crawl is compared with the one before it: the Site Health card shows the change ("+4 since Oct 5 · 12 new · 30 fixed"), each check shows how many issues are new and how many were fixed, and Compare lists every change. Reading and comparing past crawls is free.

A Site Audit crawls a whole site and grades it the way Semrush's Site Audit does: 173 checks (47 errors, 62 warnings and 64 notices) across 9 themes, a Site Health score and a score per theme. The checks cover 92 of Semrush's Site Audit issues, plus on-page, content and AI search checks Semrush doesn't have. For a single page with Core Web Vitals instead, use the free homepage technical audit on the same tab (or run_technical_audit).

How a crawl runs

  1. Seed and site checks. The crawl starts at the homepage, reads robots.txt and the sitemaps (up to 10,000 sitemap URLs), and queues them. At the same time it runs the site checks: whether HTTP redirects to HTTPS, whether www and non-www end up on one host, the TLS certificate (expiry, host name, trust) and HTTP/2, whether an unknown URL answers 404, llms.txt, and whether a firewall blocks AI fetchers.
  2. Pages. It fetches pages about 3–6 a second, follows every internal link (www and non-www count as one site) and obeys robots.txt's User-agent: * rules. Each page is checked as it's fetched: status, redirects, title, description, headings, canonical, hreflang, schema, images, links, speed and more.
  3. Links, images and scripts. It then checks up to 5,000 of the files and external links the pages point to (5 per page crawled, at least 500, at most 20 per external site): broken images, scripts and stylesheets, broken external links, images over 200 KB, and whether JS and CSS files are compressed, cached and minified.
  4. Scoring. Once that's done, the checks that compare pages run: duplicate titles, descriptions and content, broken internal links with the pages that link to them, orphan and single-link pages, canonical and hreflang targets, sitemap coverage, robots.txt and sitemap health. Then Site Health, the theme scores and each page's Internal LinkRank are worked out.
  5. Core Web Vitals. A few minutes after the crawl completes, Google PageSpeed Insights measures up to 10 pages on mobile: the homepage, then the page with the highest Internal LinkRank in each section of the site (one page per 10 crawled). Until then the Core Web Vitals theme shows Pending.

A small site finishes while you wait. A bigger one keeps crawling in the background and the tab shows its progress; over MCP or REST a big crawl answers status: "running" and you read it later. While a crawl is still running, its counts are provisional.

What it costs

1¢ per 10 pages fetched: $0.10 for 100 pages, $1.00 for 1,000 and $10.00 for 10,000. It's billed as the crawl runs, so a crawl that runs out of credit stops as partial and is still scored on the pages it reached. The checks, Site Health, the theme scores and the reports are included, and so are the link, image and script checks (up to 5,000 per crawl), the site checks and the Core Web Vitals measurements (up to 10 pages): only pages fetched are billed. Reading and comparing crawls is always free: the dashboard, get_latest_crawl, get_crawl_issue, compare_crawls and the REST endpoints. Over REST a crawl covers 25 pages unless you set max_pages (up to 10,000). See Credits, prices and top-ups.

Comparing crawls

When a crawl finishes it's compared with the site's previous scored crawl, and the comparison is saved with it. It shows:

  • Site Health and the theme scores, before and now.
  • New and fixed issues per check. For a page check, new counts the pages failing it now that didn't before, and fixed the pages that failed before and don't now (a page that now errors or redirects isn't checked, so its old issues count here; see became broken below). A page the new crawl didn't reach counts as removed, not fixed. A site-wide check counts 1 when it starts or stops failing. For links, images and scripts it's the change in the count, and only new ones are listed, because a file that passes isn't stored.
  • Pages added, removed, whose status code changed, that became broken, noindex or indexable, and whose title changed. When either crawl stopped at its page limit, pages added and removed aren't counted (the crawl didn't see the whole site), and new issues can include pages the other crawl didn't reach: the Technical tab leaves the new counts out then, and vs_previous and get_changes add incomplete_baseline.
  • robots.txt: whether it changed and which User-agent: * rules were added or removed; and the sitemap URL count.

Only crawls graded with the same version of the checks are diffed page by page. When the checks change between two crawls, the comparison shows the totals only, without new and fixed counts or a Site Health change, because the scores were worked out with different rules. Crawls made before Site Audit checks existed are never compared, and a site's first scored crawl is the baseline. Core Web Vitals are measured a few minutes after a crawl, so their theme change appears then.

On the Technical tab, Compare shows the comparison, and Crawl history lists the last 12 crawls with their Site Health and change; pick any earlier crawl there to compare with it. Comparing is free and fetches nothing.

Scheduled crawls

A crawl can repeat on its own, weekly on a day you pick or monthly on a day from 1 to 28. Turn it on in the Scheduled crawls card on the Technical tab (pick Repeat, the day, the most pages per run and whether to email you a summary), or ask an agent with schedule_crawl. Daily isn't offered: a 10,000-page site crawled every day would cost about $300 a month.

  • When it runs. Each site gets a fixed hour between 05:00 and 10:00 UTC (spread by site, so they don't all start at once). If a crawl of the site is already running then, the scheduled one waits an hour.
  • What each run does. It crawls up to its page limit like any crawl, is scored, and is compared with the crawl before it (see Comparing crawls above). With the email on, you get a summary afterwards: Site Health and its change, errors, warnings and notices with their change, up to 5 checks with new problems and 5 with fixes, the pages crawled and what the run cost, with a link straight to the comparison. A crawl you start from the dashboard that keeps running in the background after you leave sends the same summary.
  • What it costs. Setting up, changing and stopping a schedule is free. Each run bills 1¢ per 10 pages as it crawls, like any crawl. The card (and schedule_crawl) shows the most a run can cost and about what it comes to a month at your last whole-site crawl's size (a URL list's size for a list schedule). The default page limit is your last whole-site crawl's size plus 20%, rounded up to the hundred, so a growing site isn't cut short; a URL-list schedule defaults to the list's length plus the homepage. Changing one setting over the API, MCP or AEBOT keeps the others, and keeps the schedule's URL list unless you pass a new list or another source.
  • When it pauses. A run that finds your balance at zero pauses the schedule and you get a low-balance email; top up and press Resume. A schedule also pauses when its site is archived or the workspace is closed. Choose Off to stop it; past crawls stay.

Crawl settings

Open Advanced settings under Crawl site to change what a crawl covers and how it fetches. Tick Save as this site's default to keep them for every later crawl and scheduled run (a call's own settings always win). Agents pass the same settings to crawl_site and schedule_crawl, and scripts to POST /api/v1/crawl; GET and PUT /api/v1/crawl/settings read and set the site's defaults. Left alone, a crawl covers the whole site exactly as described above.

  • What to crawl. The whole site (links and sitemap, the default); sitemaps only (the robots.txt Sitemap: files, else /sitemap.xml); one sitemap (a file or index on the site); or a list of URLs (up to 10,000 over the API, 2,000 per MCP call, 5,000 from the dashboard's box or a .txt / .csv file, first column). The homepage is always fetched too, because the site-wide checks read it, and a list crawl's page limit is the list's length plus the homepage. URLs off the site, files and repeats are rejected and listed back (the dashboard shows how many, with a few examples). With any source but the whole site, links on the crawled pages count as inlinks but aren't followed.
  • Only crawl / skip paths. Up to 20 include and 50 exclude masks, in robots.txt syntax matched against the path and query: * matches anything, $ ends the path, anything else is a prefix. /shoes also matches /shoes-men; use /shoes/ for the folder only. Skip beats only-crawl. A skipped URL is never fetched or billed and counts in skipped by rules. The start page ignores include rules, but a crawl whose start page matches a skip rule is refused.
  • Ignore query parameters. Names to drop from URLs (sort, page_*), so /shop?sort=price and /shop are one page; * drops every query string. Tracking parameters (utm_*, gclid, fbclid …) are always dropped.
  • Subdomains. Off by default (sites are added by their host). On, links to any subdomain of the site's domain are crawled too, each obeying its own robots.txt, up to 25 subdomains; links to more count as skipped by rules.
  • robots.txt rules to obey. By default the crawl obeys User-agent: *. Pick Googlebot, Bingbot, OAI-SearchBot, ChatGPT-User, Claude-SearchBot or PerplexityBot to crawl the pages that bot's group allows (its own group, else *), to see the site as that bot may. The crawler still identifies as AuditAE-Bot; it never pretends to be another bot.
  • Device. Desktop (the default) or mobile: both are the AuditAE-Bot browser string.
  • Speed. Normal (3 pages at a time), polite (one page a second; a 10,000-page crawl then takes about 3 hours), or the robots.txt Crawl-delay (up to 10 seconds, else polite). The link and image checks also go one at a time to the site at the polite speeds.
  • Core Web Vitals pages. Up to 10 pages on the site to measure instead of the automatic sample.
  • Hide check. Each check card has Hide check: the check leaves Site Health and the theme scores of every crawl of the site at once (shown under Not checked as excluded, with Show again; a crawl that ran while the check was hidden, or with exclude_checks, keeps it excluded, and it is counted again from the next crawl). Agents and scripts pass exclude_checks.

What a narrowed crawl can't judge: with include or exclude rules, or any source but the whole site, orphan_sitemap_page, single_inlink, nofollow_only_inlinks, indexable_not_in_sitemap, deep_page need every link on the site, so they show as Not checked. A URL list also skips the sitemap joins (sitemap_bad_urls, sitemap_noindex, sitemap_non_canonical). The site checks, the link and image checks and Core Web Vitals run for every source.

Comparing: a crawl is compared with the previous crawl made with the same scope (source, URL list, rules, ignored parameters, subdomains and robots.txt group) when there is one. Two crawls of different scopes are still compared, but say the scope changed and leave out pages added and removed, because different settings reach different pages.

Site Health

Site Health starts at 100. Each error check that fails costs 2–4 points and each warning 0.5–1 point, more the larger the share of checked items failing it; notices and Core Web Vitals don't count. The score is rounded and never goes below 0.

So one broken page out of 800 costs an error a little over 2 points, while a DNS failure (a site-wide error) costs the full 4. Because AuditAE runs more checks than Semrush, with more site-level errors, the same site usually scores a few points lower here.

Theme scores

The 9 themes are Semrush's eight (Crawlability, HTTPS, International SEO, Core Web Vitals, Site Performance, Internal Linking, Markup and AI Search) plus On-page and content, an AuditAE extra for title, description, heading and content checks.

A theme's score is the weighted share of its checks that pass: errors weigh 4, warnings 1, notices ¼, and a failing check counts as half failed plus half the share of its items that fail. Checks that didn't run are left out, and a theme where nothing ran has no score. Two themes use Semrush's own rules: Markup is valid structured-data items ÷ all items, and Core Web Vitals is (good pages + ½ needs-improvement pages) ÷ pages measured.

Errors, warnings, notices and "not checked"

  • Errors stop pages being crawled, indexed or trusted (broken pages, DNS failures, redirect loops, pages blocked from search).
  • Warnings hurt rankings or AI citations but don't block them (missing meta descriptions, nofollow internal links, content that needs JavaScript).
  • Notices are worth knowing but often deliberate (deep pages, nofollow external links, no llms.txt). They move theme scores, never Site Health.
  • Not checked means the crawl didn't collect what a check needs, with the reason: for example, the crawl stopped at its page limit, so inlink counts are incomplete. Not-checked checks never count against you.
  • Links, images and scripts (11 checks). Each file or external link gets one light request (a HEAD, or a GET when the server refuses HEAD), following up to 5 redirects. It counts as broken only on a 404 or 410, a server error (except 503, 508 and 509, which mean an overloaded or rate-limiting server, and Cloudflare's 520–527), or a host that doesn't exist or refuses the connection. Other answers (401, 403, 429, other 4XX codes, a bot challenge page), timeouts, dropped connections, TLS errors and failed DNS lookups are left unverified, never broken; external links answering 403 get their own notice. Up to 200 of the site's own JS and CSS files are read in part to judge minification. Links past the per-crawl limit aren't checked.
  • Site checks. A few requests, made once per crawl: the HTTP homepage, the www or non-www twin, a made-up URL that should return 404, /llms.txt, a TLS handshake that reads the certificate and whether HTTP/2 is offered, and the homepage requested as ChatGPT-User (with an AuditAE-Probe suffix so site owners can tell it apart) to see whether a firewall blocks AI fetchers. check_llms_txt and check_ai_crawlers give more detail on the last two, free.
  • Core Web Vitals (5 checks). Lab LCP, CLS and Total Blocking Time from PageSpeed Insights on mobile; INP only when Google has field data for the page or the site. They move the Core Web Vitals theme only, never Site Health. A crawl with no page that answered (or a PageSpeed outage) shows them under Not checked. For one page on mobile and desktop, use the free homepage technical audit.

Crawls run before these checks existed list them under Not checked, which never affects a score.

How AuditAE differs from Semrush

  • User agent. The crawler identifies as AuditAE-Bot with a desktop browser string by default (Semrush defaults to mobile; pick mobile under Advanced settings), and page crawling obeys robots.txt's User-agent: * rules unless you pick another bot's group. The once-per-crawl site checks (the http:// and www/non-www homepage, a made-up 404 URL, /llms.txt and the TLS handshake) and the single light request to each file or outbound link don't consult robots.txt; an outbound link's own site's robots.txt is never read. The only request not sent as AuditAE-Bot is the AI-fetcher check: one homepage request as ChatGPT-User, skipped when robots.txt blocks ChatGPT-User or can't be read.
  • Subdomains aren't crawled by default (Semrush crawls them for a root domain), because a site is added by its host; turn them on under Advanced settings. www and non-www are treated as the same site.
  • Stricter severities. Blocking AI search bots site-wide (ai_search_bots_blocked) and blocking Googlebot or Bingbot site-wide (search_bots_blocked) are errors.
  • An extra theme, On-page and content, and AI search checks for llms.txt, AI bot access in robots.txt and Content-Signal.
  • No JavaScript rendering. Pages are read as the server sends them, as most AI crawlers read them; a page that only renders in the browser fails js_dependent_content.

How AuditAE differs from Screaming Frog

Screaming Frog's SEO Spider is a desktop app licensed per user per year, free up to 500 URLs. The Site Audit runs in the cloud and bills 1¢ per 10 pages crawled, with nothing to install.

  • Screaming Frog only: JavaScript rendering, crawls over 10,000 URLs, custom extraction and custom JavaScript, crawling behind a login or basic auth, private staging or localhost, ignoring robots.txt, log files, and Google Analytics and Search Console data joined to each URL.
  • Not on Screaming Frog's feature list: scheduled crawls that run with no computer left on, a hosted MCP server an agent uses to start, compare and schedule crawls (crawl_site, compare_crawls, schedule_crawl), Site Health with 9 theme scores, the AI search checks, and free team seats on one balance.

Prices, a cost table and when to keep Screaming Frog: Screaming Frog alternative.

Not built (yet)

Not offered: crawling pages robots.txt disallows, password-protected (basic-auth) sites and Web Bot Auth (sites aren't ownership-verified: anyone can add any domain), and JavaScript rendering. These Semrush checks aren't built yet:

  • tls_old_protocol (Semrush 28): Old TLS versions (1.0, 1.1). Needs a deliberately downgraded handshake our runtime can't make reliably yet.
  • tls_weak_cipher (Semrush 42): Weak TLS ciphers. Same reason: needs a deliberately weak handshake.
  • tls_no_sni (Semrush 127): TLS without SNI. A server that doesn't support SNI already shows up as a certificate name mismatch.
  • orphan_ga (Semrush 206): Orphan pages found in Google Analytics. Needs GA4 page paths joined per site; planned as a follow-up.
  • high_document_interactive (Semrush 208): Time to Interactive. Needs page rendering, and Lighthouse 10 dropped the metric.
  • external_resources_blocked (Semrush 210): Resources blocked by another host's robots.txt. Would mean fetching robots.txt from every external host a page loads from.
  • amp_invalid: AMP validation. Needs the AMP validator.
  • internal_link_rank: Internal LinkRank is shown as a page metric (0–100), not as a pass/fail check.

For agents and the API

  • crawl_site starts a crawl and returns Site Health, the theme scores and the failing checks (each with an id, severity, title and "n of m"). Its optional settings (source, urls, include, exclude, ignore_params, subdomains, robots_agent, device, speed, cwv_urls, exclude_checks, save_as_default) are described above; the answer adds settings, skipped_by_rules and, for a list, rejected. cwv_state: "pending" means Core Web Vitals are still being measured; read the crawl again a few minutes later.
  • get_latest_crawl reads the latest crawl, or an older one by run_id, free. Pass theme for that theme's report (load-time buckets, depth and inlink buckets, hreflang coverage, AI bot access and so on), severity to filter, or check to list the pages failing one check.
  • get_crawl_issue reads one check: its rule, why it matters, how to fix it, which tools fix it, and the affected URLs with evidence, 25 at a time. Free.
  • optimize_image fixes large_images: with site_id it takes the crawl's images over 200 KB, largest first, resizes them (1920 px wide by default, never enlarging), compresses them to WebP (keeping their format on WordPress, for /wp-content/uploads/ and next/image sources, or with format: "original") and steps them down toward 200 KB without visible loss. Each comes back with a private download link valid for 48 hours, the size before and after, and a paste-ready <img> tag. It also takes urls, for images on a CDN the crawl counts as external. AEBOT has it too (ask it to "shrink the large images"), and POST /api/v1/images/optimize returns the same answer over REST. 1¢ per 5 images optimized; an image that barely shrinks, a skipped or failed one and a repeat within 24 hours are free. It doesn't change the site: swap the files in (or upload them in your site builder), then submit_urls and crawl again to confirm the check clears. On a WordPress site paired with the AuditAE plugin (0.35.0+), wp_optimize_media does it in place instead: each Media Library file keeps its name and URL, its thumbnail sizes are compressed too and the originals are kept for wp_restore_media. On an unpaired WordPress site a Media Library upload gets a new file name, so the files keep their type and name; replace each one with a media-replace plugin that keeps the URL.
  • compare_crawls compares the latest crawl with the one before it, or any two by run_id and base_run_id: Site Health and theme changes, new and fixed issues per check, pages added or removed, robots.txt changes and the last 12 crawls' history. Free. get_crawl_issue with compare set to new or fixed lists the URLs behind one check's change, and get_latest_crawl carries the change in brief as vs_previous.
  • schedule_crawl turns weekly or monthly re-crawls on, changes them or stops them (cadence off); without a cadence, or with dry_run, it only quotes the most a run can cost and the monthly estimate. Free to set; each run bills 1¢ per 10 pages when it runs. get_latest_crawl shows the site's schedule.
  • REST: GET /api/v1/crawl/{id} returns the same fields plus the stored comparison, GET /api/v1/crawl/{id}/checks lists every check with its result, GET /api/v1/crawl/{id}/checks/{check_id} matches get_crawl_issue (including ?compare=), GET /api/v1/crawl/{id}/compare matches compare_crawls and GET /api/v1/crawl/history?site_id= lists a site's crawls, GET and DELETE /api/v1/crawl/schedule?site_id= read and stop the schedule, and PUT /api/v1/crawl/schedule with { site_id, cadence } in the body sets it. See REST API and API keys.

Check ids never change, so an agent can track a check across crawls. Crawls run before Site Audit checks existed keep their original issue list and say so; crawl again for Site Health.

Deprecated: the older issues_summary and top_problem_pages fields stay in crawl answers for agents that read them. On new crawls the MCP tools return issues_summary as counts only and top_problem_pages as the 5 worst pages with their failing checks; the REST API keeps the lists, each capped at 500 URLs. Read the checks instead; the old fields will be removed no earlier than December 1, 2026.

Every check

173 checks, grouped by their main theme. "Also in" lists the other themes a check counts toward; "Semrush" is the matching Semrush Site Audit issue id.

Crawlability

54 checks. Weighted share of crawlability checks passing (errors 4, warnings 1, notices ¼).

CheckTitleSeverityAlso inRuleSemrush
http_5xxPages returning 5XXError—Final HTTP status 500–599.1
http_4xxPages returning 4XXError—Final HTTP status 400–499, except 401, 403, 407 and 429 (those are http_access_denied).2
http_access_deniedPages refused the crawlerWarningAI SearchStatus 401, 403, 407, 429 or 999: usually a firewall, bot protection or a login, so kept out of 4XX.2
page_unreachablePages couldn't be crawledError—fetch_error is timeout, dns, conn_refused, conn_reset, tls:*, body_error, bad_redirect_location, unsafe_url or unknown.9
dns_failedDNS resolution issueError—The homepage fetch failed with fetch_error dns: the host didn't resolve.10
redirect_chainRedirect chains and loopsErrorSite Performance3 or more redirect hops, or fetch_error redirect_loop or redirect_too_many (more than 5 hops).33
redirect_temporaryTemporary redirectsWarning—A redirect hop answered 302, 303 or 307.109
redirect_permanentPermanent redirectsNotice—A redirect hop answered 301 or 308, with fewer than 3 hops.214
redirect_offsiteInternal URLs redirecting off-siteNotice—An internal URL redirected to another host (fetch_error redirect_offsite).—
meta_refreshMeta refresh usedError—The page has a <meta http-equiv="refresh">.40
blocked_by_robotsLinked URLs blocked by robots.txtNotice—An internal URL linked from crawled pages that robots.txt disallows for the crawl's user agent; of = pages crawled + blocked URLs.4
noindex_pageNoindex pagesNotice—Meta robots (or X-Robots-Tag) says noindex or none.4
noindex_headerX-Robots-Tag noindexNotice—The X-Robots-Tag response header says noindex or none.209
nofollow_pagePage-level nofollowNoticeInternal LinkingMeta robots or X-Robots-Tag says nofollow (or none).—
robots_txt_missingrobots.txt not foundNotice—/robots.txt returns 404 or 410.203
robots_txt_invalidInvalid robots.txt formatError—/robots.txt answers 200 with an HTML page, or with a non-empty body that has no recognised directive line (User-agent, Allow, Disallow, Sitemap, Crawl-delay …).16
robots_txt_unknown_linesrobots.txt has lines crawlers ignoreNotice—At least one non-comment line that isn't a known key: value, or an Allow/Disallow before the first User-agent.16
robots_txt_unreachablerobots.txt returns a server errorError—/robots.txt answers 5XX, or the request fails or times out.—
robots_txt_too_largerobots.txt over 500 KiBWarning—robots.txt is larger than 512,000 bytes (Google reads only the first 500 KiB).—
search_bots_blockedGooglebot or Bingbot blockedError—robots.txt blocks Googlebot or Bingbot from the whole site (the group that applies to it disallows /).—
sitemap_missingsitemap.xml not foundWarning—No Sitemap: line in robots.txt, and neither /sitemap.xml nor /sitemap_index.xml returns an XML sitemap.125
sitemap_not_in_robotsSitemap not referenced in robots.txtWarning—robots.txt returns 200 with no Sitemap: line, while a sitemap was found at a default path.124
sitemap_invalidInvalid sitemap formatError—A sitemap file that answers 200 but is HTML or has no <urlset>/<sitemapindex> root. Not run when a file couldn't be read (gzip failure, size cap).17
sitemap_too_largeSitemap file too largeError—A sitemap file with more than 50,000 <loc> entries or more than 50 MB uncompressed.43
sitemap_bad_urlsSitemap URLs that redirect or failError—A crawled URL listed in the sitemap whose status isn't 2XX, or that redirected (judged on the <loc> form).18
sitemap_noindexNoindex pages in sitemapError—A URL listed in the sitemap is noindex.18
sitemap_non_canonicalNon-canonical pages in sitemapError—A URL listed in the sitemap has a canonical pointing to another URL.18
sitemap_blockedSitemap lists robots-blocked URLsWarning—A same-site <loc> is disallowed by robots.txt for the crawl's user agent.—
sitemap_offsite_urlsSitemap lists other hostsWarning—A <loc> whose host isn't this site or its www/non-www twin.—
indexable_not_in_sitemapIndexable pages missing from sitemapNotice—An indexable 200 page that isn't in the sitemap. Not run with no sitemap, a truncated sitemap read, a capped crawl or a scoped crawl.—
orphan_sitemap_pageOrphaned sitemap pagesNoticeInternal LinkingA page in the sitemap that no crawled page links to (inlinks 0), the homepage excepted. Not run on a capped or scoped crawl.207
deep_pageCrawl depth over 3 clicksNoticeInternal LinkingReached in 4 or more clicks from the homepage (sitemap-only pages, depth 99, excluded).212
url_too_longURL over 200 charactersNotice—The URL is longer than 200 characters.201
url_underscoresUnderscores in URLWarning—The URL path contains an underscore.122
url_too_many_paramsToo many URL parametersWarning—More than 2 query parameters.113
url_uppercaseUppercase letters in URLNotice—The URL path contains uppercase letters.—
url_double_slashDouble slash in URL pathNotice—The URL path contains //.—
url_session_idSession ID in URLWarning—A query parameter named sid, sessionid, session_id, phpsessid, jsessionid, aspsessionid…, or sessid, or a ;jsessionid= path parameter.—
canonical_brokenBroken canonicalError—The canonical target was crawled and returned 4XX/5XX (except 401/403/407/429/999, which mean the crawler was refused) or couldn't be fetched.38
canonical_multipleMultiple canonical URLsError—More than one distinct target across all canonical tags and the Link header.39
canonical_to_redirectCanonical points to a redirectWarning—The canonical target was crawled and redirected.—
canonical_to_noindexCanonical points to a noindex pageWarning—The canonical target was crawled and is noindex.—
canonical_elsewhereCanonicalised to another URLNotice—The canonical points to a URL other than the page's final URL (and the target isn't broken).—
canonical_to_homepageCanonical points to the homepageWarning—A page other than the homepage has a canonical pointing at the homepage.—
canonical_missingNo canonical tagNotice—A page without noindex that has no canonical tag or Link header.—
canonical_relativeRelative canonical URLNotice—The canonical href isn't an absolute http(s):// URL.—
canonical_outside_headCanonical outside headWarning—A canonical <link> appears after </head> or <body.—
malformed_linksMalformed linksErrorInternal LinkingAt least one <a href> that fails URL parsing, contains a backslash or whitespace, or is written http:/x or https:x.44, 11
link_url_too_longLink URLs over 2,000 charactersWarning—At least one href longer than 2,000 characters.136
soft_404_siteMissing pages return 200Warning—A request for a random missing path (/auditae-404-<8 hex>) returns 2XX.—
soft_404_pagePage looks like an error pageWarning—A 2XX page under 300 words whose title or H1 says 404, page not found, not found or page doesn't exist.—
mixed_slash_linksLinked both with and without trailing slashNoticeInternal LinkingThe same page is linked both with and without a trailing slash.—
broken_internal_imageBroken internal imagesErrorSite PerformanceAn internal image that returns 404, 410 or a 5XX other than 503/508/509 (overload or rate limits) or Cloudflare's 520–527, or whose host doesn't exist or refuses connections.13
blocked_internal_resourcesInternal resources blocked in robots.txtWarning—An internal image, JS or CSS file disallowed by robots.txt for the crawl's user agent.130

HTTPS

17 checks. Weighted share of HTTPS checks passing (errors 4, warnings 1, notices ¼).

CheckTitleSeverityAlso inRuleSemrush
https_not_usedHomepage not on HTTPSWarning—The homepage's final URL is http:.126
http_not_redirectedHTTP homepage doesn't redirect to HTTPSError—http://host/ (redirects not followed) doesn't answer with a 3XX to an https: URL.32
http_redirect_temporaryHTTP→HTTPS redirect is temporaryWarning—The first redirect from http:// to https:// is a 302 or 307.32
www_not_consolidatedwww and non-www both serve the siteErrorCrawlabilityThe other host form (www or non-www) answers 2XX without redirecting to the main host and without a canonical to it.19
mixed_contentMixed contentError—An https page loads at least one http: subresource (image, script, stylesheet, iframe, media).30
links_to_httpLinks on HTTPS pages lead to HTTPWarning—At least one <a href="http:…"> on an https page.31
http_password_formPassword field on an HTTP pageError—An http: page has an <input type="password">.26
tls_cert_expiredCertificate expired or about toError—The certificate's valid_to is in the past or less than 7 days away; a certificate with a lifetime of 30 days or less is judged by the share of its lifetime left (less than 1 day).27
tls_cert_expiringCertificate expires within 30 daysWarning—The certificate expires in 7 to 29 days; a certificate with a lifetime of 30 days or less is judged by the share of its lifetime left (1 day up to a third of its lifetime).27
tls_name_mismatchCertificate name mismatchError—tls.checkServerIdentity(host, cert) fails: the certificate doesn't cover this host name.29
tls_untrustedUntrusted certificate chainError—The TLS handshake reports an authorization error other than expiry or name: self-signed, incomplete chain or unknown CA.—
hsts_missingNo HSTSNotice—The https homepage sends no Strict-Transport-Security header, or a max-age under 31,536,000.205
sitemap_http_urlsHTTP URLs in an HTTPS site's sitemapWarning—The homepage is https and the sitemap lists at least one same-site http: URL.128
canonical_httpCanonical from HTTPS to HTTPWarningCrawlabilityAn https page whose canonical is an http: URL.—
redirect_https_to_httpHTTPS page redirects to HTTPError—The redirect chain has a hop from https: to http:.—
security_headers_missingHomepage missing security headersNotice—The homepage lacks X-Content-Type-Options: nosniff, or lacks both X-Frame-Options and a CSP frame-ancestors directive.—
http_pagesPages served over HTTP on an HTTPS siteWarning—The homepage is https but the page's final URL is http:.—

International SEO

13 checks. Weighted share of hreflang and language checks passing (errors 4, warnings 1, notices ¼).

CheckTitleSeverityAlso inRuleSemrush
hreflang_invalid_codeInvalid hreflang valuesError—An hreflang value that isn't x-default or language[-Script][-REGION] (ISO 639-1, ISO 15924, ISO 3166-1 alpha-2 or 419); en-UK is invalid (it's en-GB).23
hreflang_no_selfHreflang without self-referenceError—The page has hreflang entries but none points at its own URL.24
hreflang_conflictingConflicting hreflang URLsError—One hreflang code maps to two or more different URLs.24
hreflang_canonical_conflictHreflang on a canonicalised pageError—The page has hreflang entries and its canonical points to another URL.24
hreflang_relativeRelative hreflang URLsError—An hreflang href isn't an absolute URL.25
hreflang_brokenHreflang links to broken pagesError—An hreflang target was crawled and returned 4XX/5XX.25
hreflang_redirectHreflang links to redirectsError—An hreflang target was crawled and redirected.25
hreflang_no_returnMissing return hreflangWarning—Page A lists B, B was crawled and parsed, and B's hreflang set has no URL equal to A.—
hreflang_no_x_defaultNo x-default hreflangNotice—Two or more hreflang entries and no x-default.—
no_langNo hreflang and no lang attributeWarning—No <html lang> and no hreflang entries.114
lang_invalidInvalid html langWarning—The <html lang> primary subtag isn't an ISO 639-1 or 3-letter language code, or the value isn't a well-formed BCP 47 tag (en_US, for one).—
hreflang_lang_mismatchHreflang language differs from html langNotice—The language of the page's own hreflang entry differs from its <html lang> (we compare the declarations; Semrush detects the text's language).204
content_language_mismatchContent-Language differs from html langNotice—The Content-Language header's language differs from <html lang>'s primary subtag.—

Core Web Vitals

5 checks. (good pages + ½ needs-improvement pages) ÷ pages measured, PageSpeed mobile on up to 10 pages; never part of Site Health.

CheckTitleSeverityAlso inRuleSemrush
cwv_lcp_poorPoor Largest Contentful PaintWarning—Lab LCP (PageSpeed, mobile) over 4.0 s on a sampled page (≤10 pages).—
cwv_cls_poorPoor Cumulative Layout ShiftWarning—Lab CLS over 0.25 on a sampled page.—
cwv_tbt_poorPoor Total Blocking TimeWarning—Lab Total Blocking Time over 600 ms on a sampled page (the lab stand-in for INP).—
cwv_inp_poorPoor Interaction to Next Paint (field)Warning—Field INP from the Chrome UX Report (via PageSpeed) over 500 ms, for the URL or else the origin.—
cwv_needs_improvementCore Web Vitals need improvementNotice—No metric poor, but LCP 2.5–4 s, CLS 0.1–0.25, TBT 200–600 ms or INP 200–500 ms on a sampled page.—

Site Performance

17 checks. Weighted share of performance checks passing (errors 4, warnings 1, notices ¼).

CheckTitleSeverityAlso inRuleSemrush
html_too_largeHTML over 2 MBError—The HTML response reached the 2,000,000-byte read cap.21
html_largeHTML over 1 MBWarning—HTML between 1,000,000 bytes and the 2 MB read cap.—
slow_page_loadSlow page (HTML) loadError—The final hop's response headers plus body took over 3,000 ms (measured from a Vercel region).111
slow_ttfbSlow server responseNotice—Time to first byte on the final hop over 800 ms.—
html_uncompressedUncompressed pagesWarning—HTML over 1 KiB sent with no Content-Encoding (gzip, br, zstd or deflate) although the request offered gzip and br.129
js_css_uncompressedUncompressed JS/CSSWarning—An internal JS or CSS file over 1 KiB served with no Content-Encoding.131
js_css_uncachedUncached JS/CSSWarning—An internal JS or CSS file with no Cache-Control max-age/s-maxage over 0 or immutable, and no future Expires.132
js_css_too_largePage JS+CSS over 2 MBWarning—The known sizes of a page's JS and CSS files add up to more than 2 MB; not judged for a page when over half its files have no known size.133
js_css_too_manyToo many JS/CSS filesWarning—More than 100 script src plus stylesheet links.134
js_css_unminifiedUnminified JS/CSSWarning—An internal file of 2 KB or more, without .min. in its name, whose first 64 KB is over 20% whitespace with lines averaging under 120 characters (≤200 files sampled).135
render_blocking_scriptsRender-blocking scriptsNoticeCore Web VitalsA <script src> in the head without async, defer or type=module (nomodule and non-JavaScript scripts are skipped: browsers never run them).—
images_no_dimensionsImages without width and heightNoticeCore Web VitalsAt least one <img> missing a width or height attribute.—
large_imagesImages over 200 KBNotice—An internal image whose size (Content-Length) is over 200 KB.—
http2_unsupportedNo HTTP/2Notice—The TLS handshake (ALPN) didn't negotiate h2.—
broken_external_imageBroken external imagesWarning—An external image that returns 404, 410 or a 5XX other than 503/508/509 (overload or rate limits) or Cloudflare's 520–527, or whose host doesn't exist or refuses connections.14
broken_internal_js_cssBroken internal JS/CSSErrorCrawlabilityAn internal JS or CSS file that returns 404, 410 or a 5XX other than 503/508/509 (overload or rate limits) or Cloudflare's 520–527, or whose host doesn't exist or refuses connections; every page that loads it is flagged.41
broken_external_js_cssBroken external JS/CSSNotice—An external JS or CSS file that returns 404, 410 or a 5XX other than 503/508/509 (overload or rate limits) or Cloudflare's 520–527, or whose host doesn't exist or refuses connections.211

Internal Linking

15 checks. Weighted share of internal-linking checks passing (errors 4, warnings 1, notices ¼).

CheckTitleSeverityAlso inRuleSemrush
broken_internal_linkBroken internal linksErrorCrawlabilityA crawled internal URL that other pages link to returned 4XX/5XX (except 401/403/407/429/999, which mean the crawler was refused) or couldn't be fetched; n and of count links (Σ inlinks of broken targets ÷ Σ inlinks).8
link_to_redirectInternal links to redirectsNotice—A crawled internal URL that redirected (judged on the linked form) and that other pages link to.—
link_to_blockedInternal links to robots-blocked pagesNotice—An internal URL disallowed by robots.txt that crawled pages link to.—
nofollow_internalNofollow internal linksWarning—At least one internal <a> whose rel includes nofollow.123
nofollow_externalNofollow external linksNotice—At least one external <a> whose rel includes nofollow.202
too_many_linksToo many on-page linksWarning—More than 3,000 <a href> on the page.108
single_inlinkOnly one incoming internal linkNoticeAI SearchA page that exactly one internal link points to (the homepage excepted). Not run on a capped or scoped crawl.213
nofollow_only_inlinksLinked only through nofollowNotice—Every internal link to the page is nofollow.—
no_outlinksNo outgoing internal linksNotice—A parsed page with no internal links to other pages.—
empty_anchorLinks with no anchor textNoticeAI SearchAt least one <a> with no text, no image alt, no aria-label and no title.216
generic_anchorNon-descriptive anchor textNoticeAI SearchAnchor text such as click here, read more, learn more, here or more info, a raw URL, or symbols only.217
resource_as_page_linkLinks to files formatted as page linksNotice—An <a href> to an image, script, stylesheet or document file (pdf, docx, zip …).215
javascript_linksjavascript: linksNoticeAI SearchAt least one href="javascript:…".—
broken_external_linkBroken external linksWarning—An external link that returns 404, 410 or a 5XX other than 503/508/509 (overload or rate limits) or Cloudflare's 520–527, or whose host doesn't exist or refuses connections.12
external_link_403External links returning 403Notice—An external link that answered 403 (often bot protection; counted as unverified, never broken).218

Markup

8 checks. Valid structured-data items ÷ all items (Semrush's rule); no score when the site has none.

CheckTitleSeverityAlso inRuleSemrush
schema_invalidInvalid structured data itemsError—validate_schema reports at least one error on a JSON-LD node of a type it has rules for (≤10 blocks, ≤100 KB a block and ≤30 nodes a page are checked).45
schema_parse_errorUnparseable JSON-LDError—JSON.parse fails on an application/ld+json block.—
schema_warningsStructured data with warningsNotice—At least one validation warning, or an error on a type without rules, and no counted errors.—
schema_missingNo structured dataNoticeAI SearchAn indexable page with no JSON-LD and no microdata or RDFa.—
schema_org_missingNo Organization or WebSite markup on the homepageNoticeAI SearchThe homepage's schema types include no Organization (or a subtype such as LocalBusiness) and no WebSite.—
og_missingOpen Graph tags missingNotice—An indexable page lacking og:title or og:image.—
twitter_card_missingTwitter card missingNotice—An indexable page with no twitter:card meta tag.—
amp_no_canonicalAMP page with no canonicalError—An <html amp> or <html ⚡> page without a canonical.22

18 checks. Weighted share of AI-search checks passing (errors 4, warnings 1, notices ¼).

CheckTitleSeverityAlso inRuleSemrush
llms_txt_missingllms.txt not foundNotice—/llms.txt isn't found.137
llms_txt_invalidllms.txt formatting issuesNotice—/llms.txt answers 200 but has a problem or formatting errors.219
content_too_longToo much contentNotice—More than 10,000 words.220
outdated_contentOutdated contentNotice—The Last-Modified header is more than 183 days old; pages without the header aren't counted.221
low_semantic_htmlLow semantic HTMLNotice—Semantic tags (main, article, section, nav, header, footer, aside, figure, h1–h6, p, lists, tables …) are under 15% of semantic + div + span tags.222
heading_hierarchySkipped heading levelNoticeOn-page and contentA heading level is skipped (e.g. an H4 straight after an H2).223
long_paragraphsParagraphs over 150 wordsNotice—At least one <p> over 150 words.223
low_readabilityHard-to-read textNotice—Flesch Reading Ease under 30, on English (or undeclared) pages of 200+ words.223
ai_search_bots_blockedAI search bots blocked in robots.txtError—robots.txt blocks OAI-SearchBot, Claude-SearchBot or PerplexityBot from the whole site (Semrush KB 1571).—
ai_user_fetchers_blockedAI user fetchers blockedWarning—robots.txt blocks ChatGPT-User, Claude-User or Perplexity-User from the whole site.—
page_blocked_for_aiPages blocked from AI searchNotice—A crawled page that robots.txt disallows for OAI-SearchBot, Claude-SearchBot, PerplexityBot, ChatGPT-User, Claude-User, Perplexity-User, Googlebot or Google-Extended.—
ai_training_bots_blockedAI training bots blockedNotice—robots.txt blocks GPTBot, ClaudeBot, Google-Extended, Applebot-Extended, CCBot or Meta-ExternalAgent site-wide (a policy choice; informational).—
ai_fetcher_firewallAI fetchers blocked by the firewallWarning—robots.txt allows ChatGPT-User and AuditAE-Bot got 2XX, but the homepage fetched with an AI agent's user-agent is refused (401/403/429/503…) or challenged.—
content_signal_restrictiveContent-Signal limits AI useNotice—robots.txt's Content-Signal sets search=no or ai-input=no.—
nosnippetSnippets blockedWarning—An indexable page with nosnippet or max-snippet:0 for all crawlers.—
js_dependent_contentContent needs JavaScriptWarning—A 2XX page with under 50 words, at least one script file and visible text under 2% of the HTML.—
article_no_dateArticles without a dateNotice—An article-like page (og:type article with an article:published_time/author/section/tag, or Article/BlogPosting/NewsArticle markup) with no datePublished, dateModified or article:*_time.—
article_no_authorArticles without an authorNoticeMarkupAn article-like page with no JSON-LD author, meta author or rel=author.—

On-page and content (AuditAE extra)

26 checks. Weighted share of title, description, heading and content checks passing (errors 4, warnings 1, notices ¼). An AuditAE extra; Semrush has no such theme.

CheckTitleSeverityAlso inRuleSemrush
title_missingTitle tag missing or emptyError—No <title>, or one with only whitespace.3
title_duplicateDuplicate title tagsError—The same title (trimmed, whitespace collapsed, case-insensitive) on 2 or more indexable pages.6
title_too_shortTitle too shortWarning—A title of 1–10 characters.101
title_too_longTitle too longWarning—A title over 70 characters.102
title_multipleMultiple title tagsWarning—More than one <title> in the head (SVG titles in the body are ignored).—
meta_description_missingMissing meta descriptionWarning—No meta description, or an empty one.106
meta_description_duplicateDuplicate meta descriptionsError—The same normalised meta description on 2 or more indexable pages.15
meta_description_multipleMultiple meta descriptionsWarning—More than one meta name="description" tag.—
meta_description_lengthMeta description too short or longNotice—A meta description under 70 or over 160 characters.—
h1_missingMissing H1Warning—No <h1> on the page.103
h1_multipleMore than one H1Notice—More than one <h1>.104
h1_same_as_titleH1 duplicates the titleWarning—The first H1 equals the title (trimmed, whitespace collapsed, case-insensitive).105
h1_emptyEmpty H1Notice—At least one <h1> with no text and no image alt.—
h1_duplicateSame H1 on several pagesNotice—The same normalised first H1 on 2 or more indexable pages.—
images_missing_altMissing ALT attributesWarning—At least one <img> with no alt attribute (alt="" passes, an unquoted alt counts); of = pages with images.110
low_word_countLow word countWarning—An indexable page with fewer than 200 words.117
low_text_html_ratioLow text to HTML ratioWarning—Visible text is 10% or less of the HTML.112
duplicate_contentDuplicate contentError—Indexable pages with 100+ words whose main-text hash is equal, or whose SimHash is ≤6 bits apart, unless one canonicalises to the other; groups say exact or near.7
no_viewportNo viewport tagError—No <meta name="viewport">.20
viewport_no_widthViewport width not setError—A viewport tag without width= or initial-scale=.46
doctype_missingDoctype not declaredWarning—No <!doctype html> in the first 2 KB (after a byte-order mark and comments).116
charset_missingEncoding not declaredWarning—No charset in the Content-Type header, a <meta charset> or an http-equiv Content-Type.115
frames_usedFrames usedWarning—The page uses <frameset> or <frame>.121
incompatible_pluginsFlash, Java or SilverlightWarning—An <applet>, or an <object>/<embed> with Flash, Java or Silverlight.120
lorem_ipsumPlaceholder textWarning—"lorem ipsum" in the main text.—
deprecated_htmlDeprecated HTML tagsNotice—<center>, <font>, <marquee> or <blink> tags.—

Try it in AuditAE

Crawl a site

Still stuck? Signed in, ask AEBOT in Documentation mode (free). Or email support@auditae.app.