Methodology
How the checker scores a page
Checker version 2.0
Every rule, threshold and weight behind the 31 scored checks (29 different checks, since indexing directives and JavaScript-rendered content are scored in two groups), so a score can be traced to the reason for it.
What the checker does
The checker fetches one page and up to four site files (robots.txt, a sitemap, llms.txt and llms-full.txt), then applies fixed rules to the text it gets back. It is rule-based: no AI model decides a score, and the same page gives the same result every time it is scanned.
How a score is added up
The checks sit in three groups: AEO has 12, SEO has 11 and GEO has 8. Each group is worth 100 points, shared out by the weights in the Points column below. A check earns its full weight on a pass, part of it on a warning (the fraction is shown below), and usually nothing on a fail. A group score is the points earned out of the points possible on the checks that apply and could be read, so it always runs from 0 to 100. The overall score is the average of the three group scores, rounded.
Some things are left out of the score instead of counted against the site: a robots.txt, sitemap, llms.txt or llms-full.txt that could not be read (a timeout, a security error, or an HTTP 401, 403, 429 or 5xx answer); and a page that returns an error status or a bot-challenge page, where the scan stops and scores nothing. A real 404 or 410 for one of the files does count as "not found".
AEO (answer engine optimization)
12 checks, 100 points in total.
| Check | Points | What it reads | Pass | Warning | Fail |
|---|---|---|---|---|---|
| Structured data | 16 | JSON-LD blocks in the page | At least one JSON-LD item | Microdata found but no JSON-LD (half credit) | Neither found |
| AI crawler access | 14 | robots.txt, against the crawler list below | No robots.txt, or no listed crawler blocked | Some listed crawlers blocked (half credit) | Every listed crawler blocked |
| JavaScript-rendered content | 12 | The readable text in the raw HTML, and signs that JavaScript builds the page | Enough readable text, or no sign of a JavaScript-built page | Under 50 words (and under 400 characters) of text together with an app container, a "please enable JavaScript" notice or four or more script tags (half credit) | Not scored as a fail |
| Indexing directives | 12 | Meta robots, googlebot and bingbot tags, and the X-Robots-Tag header | No noindex, nosnippet or max-snippet:0 | noindex for some crawlers only, or nosnippet / max-snippet:0 (half credit) | noindex for all crawlers |
| Heading structure | 10 | H1 to H6 tags in the page content | One H1 and no skipped levels | More than one H1 (half credit), or a skipped level such as H2 straight to H4 (70% credit) | No headings, or no H1 |
| Meta tags and Open Graph | 8 | Title, meta description, og:title, og:description, og:image | All five present, with a title of 10 to 70 characters | Some missing (credit is the share present, out of five), or all present with a title outside 10 to 70 characters | None present |
| Freshness signals | 7 | Last-Modified header, then the article:modified_time or og:updated_time meta tag, then article:published_time, then the newest dateModified (else datePublished) in JSON-LD | A date found that is 365 days old or less | A date older than 365 days (60% credit), or one that cannot be read (half credit) | No date found |
| Question-style headings | 6 | H2 and H3 headings. Judged only when there are at least 3 | At least one heading ends in a question mark | None does (half credit) | Not scored as a fail |
| Lists and tables | 5 | The main content (menus, headers, footers and side panels removed). Judged only when the page has at least 300 words | A list of 3 or more items, or a table with 2 or more rows | Neither found (half credit) | Not scored as a fail |
| Readable text depth | 4 | The visible text in the raw HTML | 150 words or more, or 900 characters or more | Under 150 words and under 900 characters (half credit) | Not scored as a fail |
| Visible publication date | 3 | A time element with a valid datetime value. Judged on articles only | At least one valid date | None found (half credit) | Not scored as a fail |
| Sources cited | 3 | Links in the main content to other sites, not counting social networks. Judged on articles only | Links to at least one other site | None (half credit) | Not scored as a fail |
SEO
11 checks, 100 points in total.
| Check | Points | What it reads | Pass | Warning | Fail |
|---|---|---|---|---|---|
| Indexing directives | 15 | Meta robots, googlebot and bingbot tags, and the X-Robots-Tag header | No noindex, nosnippet or max-snippet:0 | noindex for some crawlers only, or nosnippet / max-snippet:0 (half credit) | noindex for all crawlers |
| Sitemap | 14 | A sitemap address declared in robots.txt, then /sitemap.xml, then /sitemap_index.xml | A valid XML sitemap | A file is there but is not a valid sitemap (half credit) | No sitemap found |
| Canonical URL | 13 | The canonical link tag | Present, on this site (with or without www) or a relative address | Points to a different host (half credit) | No canonical tag |
| Title tag length | 11 | The title, with entities such as & decoded | 50 to 60 characters | 30 to 49 or 61 to 70 characters (60% credit) | Under 30 or over 70 characters (20% credit), or no title (no credit) |
| Internal linking | 10 | Links on the page that stay on the scanned site (with or without www) | Three or more | One or two (half credit) | None |
| Image alt text | 8 | Every img tag in the page content | At least 90% of images are described or marked decorative (alt="") | 50% to 89% (credit equals the share) | Under 50% (credit equals the share). A page with no images passes |
| Meta description length | 8 | The meta description | 70 to 160 characters | Missing, shorter than 70 or longer than 160 characters (half credit) | Not scored as a fail |
| Mobile viewport tag | 7 | The viewport meta tag | Sets width=device-width and allows zooming | No width=device-width, or zooming blocked with user-scalable=no or maximum-scale=1 (half credit) | No viewport tag |
| Descriptive link text | 7 | Text links on the page. Judged only when there are at least 3 | Fewer than 2 generic links, or generic links are under a fifth of all links | 2 or more generic links (such as "click here" or "read more") making up at least a fifth of all links (half credit) | Not scored as a fail |
| Image width and height | 4 | Width and height attributes on every img tag. Judged only when the page has images | At least 90% of images set both | Fewer than 90% (half credit). Capped here because a stylesheet can do the same job and the checker cannot read stylesheets | Not scored as a fail |
| Page language | 3 | The lang attribute on the html tag | A valid language code such as en or en-GB | Missing, or not a valid language code (half credit) | Not scored as a fail |
GEO (generative engine optimization)
8 checks, 100 points in total. These are early signals, not guarantees.
| Check | Points | What it reads | Pass | Warning | Fail |
|---|---|---|---|---|---|
| llms.txt | 18 | /llms.txt | A plain-text file that starts with a # title heading | A text file with no title heading (half credit) | Missing, empty, or a web page served in its place |
| AI search bots vs training bots | 18 | robots.txt, against the two bot lists below | No robots.txt, or no AI search or assistant bot blocked. Blocking only training bots does not lower the score | Some of the AI search and assistant bots blocked (half credit) | All of the AI search and assistant bots blocked |
| JavaScript-rendered content | 14 | The readable text in the raw HTML, and signs that JavaScript builds the page | Enough readable text, or no sign of a JavaScript-built page | Under 50 words (and under 400 characters) of text together with an app container, a "please enable JavaScript" notice or four or more script tags (half credit) | Not scored as a fail |
| Organization or Person markup | 14 | JSON-LD for an Organization-type entity anywhere, or a Person at the top level | A named entity with a url, logo, sameAs or @id | Markup without those, or without a name, or no markup at all (half credit) | Not scored as a fail |
| FAQ schema | 12 | FAQPage markup, as JSON-LD or microdata | FAQPage with at least one question | FAQPage with no questions (half credit) | No FAQPage markup |
| sameAs profile links | 10 | The sameAs links on the entity markup. Judged only when the page has entity markup | At least one valid profile link | None (half credit) | Not scored as a fail |
| Named author | 8 | Author in the article JSON-LD, a meta author tag, a rel="author" link or a microdata author. Judged on articles only | A real author name | No author, or only a generic label such as admin or editor (half credit) | Not scored as a fail |
| llms-full.txt | 6 | /llms-full.txt | A plain-text file, or a file too large to read in full (counted as found) | Missing, empty, or a web page served in its place (half credit) | Not scored as a fail |
AI crawlers checked in robots.txt
A crawler counts as blocked when the robots.txt group that names it (or, if none does, the "*" group) disallows the whole site. A rule for one folder does not block a crawler. The list is: GPTBot, ChatGPT-User, PerplexityBot, ClaudeBot, Claude-Web, Google-Extended, CCBot, anthropic-ai, OAI-SearchBot, Claude-SearchBot, Claude-User, Perplexity-User, Applebot-Extended.
AI search bots and training bots
The GEO bot check uses the same blocking rule as above but splits the bots into two lists. Blocking the search and assistant bots keeps a site out of AI answers, so it lowers the score. Blocking only the training bots is a common deliberate choice and does not. Search and assistant bots: OAI-SearchBot, ChatGPT-User, PerplexityBot, Perplexity-User, Claude-SearchBot, Claude-User. Training bots: GPTBot, ClaudeBot, Claude-Web, anthropic-ai, CCBot, Google-Extended, Applebot-Extended.
Checks that do not apply
A check is left out, and the other weights in its group are scaled so the group still adds up to 100, when there is nothing for it to judge. A site never loses points for something it cannot have. Question-style headings need at least 3 H2 or H3 headings. Lists and tables need at least 300 words. Descriptive link text needs at least 3 text links. Image width and height need at least one image. The visible date, sources cited and named author checks apply to articles only (a page that marks itself as one with Article-type JSON-LD, an article Open Graph type or an article date tag). The sameAs check applies only when the page has Organization or Person markup. The AI bot check is left out when robots.txt is a web page rather than a text file.
What a scan cannot tell you
- The checker reads the raw HTML a server returns. It does not run JavaScript, so a page built in the browser is judged on what is in the first response. A warning says when that looks likely.
- It checks that a signal is present and well formed, not that it is correct. A canonical tag can point at the wrong page and still pass.
- It checks one page and a few site-wide files, not the whole site.
- It uses pattern matching, not a full HTML parser, so unusual markup can be misread.
- A pass is not a promise of better ranking or citation by any search engine or AI system. llms.txt, for example, is a proposed convention, not a standard every system follows.
Versions
Every result records the checker version and the scan date. When a rule, threshold or weight changes, the version changes and the change is written down, so two numbers are only compared when they come from the same version. The current version is 2.0.