Home Knowledge base The AEO scoring rubric, check by check
Rubric

The AEO scoring rubric, check by check

Every one of the 27 always-on checks and the 1 type-conditional check behind the 0–100 score: what each one measures, how many points it carries, why the weights are what they are, and how to read a result.

The AEO Site Checker score is a weighted sum of 27 always-on checks plus 1 type-conditional check, grouped into five categories, then normalized to 0–100. Fetchability carries 43 of the raw weight, Core SEO 21, Semantic HTML 13, Answer Engine signals 26, and Content quality 6. A page that shows business signals (a local business, a listing, a person) also gets a 5-point contact check added to both sides of the fraction.

This article is the full reference. If you only want the design decisions, skip to why the weights look like this.

How is the score computed?

Each check returns a weight (its maximum) and an earned value between 0 and that weight. The runner sums both across every check that ran and divides:

score = round(100 × Σ earned / Σ weight)

The denominator is not a fixed 100. For most pages it is 109 (all 27 checks plus the contact check) and for SaaS, article, and generic pages it is 104. Because the type-conditional check contributes to both sides only when it applies, a software landing page is neither penalized nor rewarded for lacking a phone number.

Letter grades are fixed thresholds on the normalized score: A ≥ 90, B ≥ 80, C ≥ 70, D ≥ 60, F below 60.

Fetchability — 43 points

The heaviest category by design. If an AI crawler cannot retrieve the page, none of the other 22 checks can help.

CheckWeightPasses when
fetch_direct18A plain HTTPS GET with a desktop browser user agent returns 2xx/3xx with no bot challenge. If the page is only reachable through the BrightData unlocker fallback, 16 of the 18 points are lost.
https4The final URL is HTTPS.
page_size3Decompressed HTML is under 4 MB. Larger bodies are truncated by most fetchers.
robots_ai_bots10robots.txt does not disallow the seven critical AI user agents: ChatGPT-User, OAI-SearchBot, Claude-User, Claude-SearchBot, PerplexityBot, Perplexity-User, Google-Extended. Roughly 1.43 points per bot allowed.
ssr_content8The server-rendered HTML already contains at least 200 words of readable content according to Mozilla Readability, without executing JavaScript.

fetch_direct alone is worth more than any other single check because it models the most common real-world failure: a WAF or bot-management rule returning a challenge page to anything that is not a logged-in human browser. A missing robots.txt counts as allowing every bot, which matches how crawlers treat it.

Core SEO — 21 points

Classic signals that AI retrieval pipelines still read, because most of them were built on top of conventional web indexes.

CheckWeightPasses when
seo_title4<title> is between 25 and 65 characters.
seo_meta_description4<meta name="description"> is between 80 and 175 characters.
seo_canonical3<link rel="canonical"> is present and resolves to a valid HTTPS URL.
seo_opengraph3og:title, og:description, og:url, og:image, and og:type are present.
seo_twitter_card2At least twitter:card and twitter:title.
seo_lang1<html lang="…"> is set.
sitemap4/sitemap.xml (or a sitemap index, or a sitemap declared in robots.txt) returns 200 with at least one valid URL. Index files are followed one level deep.

Title and description lengths are scored as ranges, not thresholds, because both extremes hurt: a nine-character title carries no information, and a 120-character one is truncated before the important words in most citation cards.

Semantic HTML — 13 points

The document outline is what a parser uses to decide which text is the answer and which is chrome.

CheckWeightPasses when
semantic_single_h13Exactly one <h1>.
semantic_heading_hierarchy3No skipped levels (h1 → h2 → h3, never h1 → h3).
semantic_landmarks4At least three of <header>, <nav>, <main>, <article>, <aside>, <footer>.
semantic_alt_text3At least 80% of <img> elements carry a non-empty alt.

Landmarks get the largest share here because they are what lets an extractor drop navigation and footers cleanly. A page with a single <div id="root"> wrapper gives the extractor nothing to hold on to.

Answer Engine signals — 26 points

The category that separates this audit from a conventional SEO checker.

CheckWeightPasses when
aeo_llms_txt5/llms.txt exists and follows the llmstxt.org shape: H1 first, a blockquote summary, at least one H2 section, at least one linked list item. Malformed files earn partial credit.
aeo_llms_full_txt1/llms-full.txt exists.
aeo_structured_data6JSON-LD is present with a recognized @type. Extra credit for FAQPage, Article, Organization, LocalBusiness, Person, Product, and RealEstateListing.
aeo_authority3An author or Organization object carries at least one sameAs link to a recognizable profile (LinkedIn, GitHub, ORCID, X).
aeo_freshness2dateModified is present and within the last 12 months.
aeo_readability5Mozilla Readability extracts an article with more than 100 words and a confidence above 50.
aeo_site_breadth4Sitemap URL count, presence of a /blog or /articles path, and at least one lastmod from 2024 or later. Scored in tiers.

aeo_readability is the closest thing the audit has to “would an extractor get the article text.” It runs the same library that Firefox Reader View uses, on the raw HTML, and reports whether a clean body came out. Pages that pass ssr_content but fail this check usually have content spread across many small containers with no article wrapper.

Content quality — 6 points

Four heuristics that encode the two largest effects in Aggarwal et al.’s GEO study: adding statistics and adding quotations lifted citation rate in their benchmark by a relative 41% and 28%. The paper summary covers what those numbers do and do not mean.

CheckWeightPasses when
content_front_loaded_answer2The first 200 words contain a declarative, answer-shaped sentence.
content_question_headings1At least one heading is phrased as a question.
content_statistics2At least three numeric facts appear in the extracted text.
content_quotations1At least one <blockquote> or attributed quotation.

The type-conditional check

CheckWeightApplies to
aeo_contact_signals5local_business, real_estate_listing, person, and generic pages with strong business signals. Looks for phone, address, hours, and service area in JSON-LD or visible text.

Site type is detected before scoring: JSON-LD @type values first (highest confidence), then visible signals such as tel: links, <address> elements, listing vocabulary (bedrooms, sqft, for sale), and bylines. The detected type and the reasons for it are shown on every scorecard.

Why the weights look like this

Three decisions explain most of the distribution.

Fetchability dominates because it is binary in practice. A page with perfect structured data that returns a Cloudflare challenge to OAI-SearchBot is cited exactly as often as a blank page. Weighting fetchability at 43 means a site that fails it cannot score above the mid-50s no matter how polished the content is, which matches what site owners see in the wild.

Content quality is small because the heuristics are weak proxies. Counting statistics in a page is not the same as measuring whether a page gets cited. The GEO effects were measured on a research benchmark against a retrieval-augmented model, not against production ChatGPT or AI Overviews. Six points is enough to surface the advice without letting a keyword-stuffed number salad outscore a clean, fetchable page.

Nothing is a gate. Every check contributes independently. That keeps the score continuous and lets two audits of the same page be compared after a single fix.

What the score does not measure

The audit reads one URL, once, as raw HTML. It does not:

  • Execute JavaScript. A client-rendered page fails ssr_content and aeo_readability on purpose, because most AI fetchers behave the same way.
  • Crawl internal links. Site breadth is inferred from the sitemap.
  • Measure off-site signals: brand mentions, Reddit or Wikipedia presence, backlinks, or whether any AI engine has actually cited the page.
  • Detect edge-level bot blocking that is not expressed in robots.txt. A WAF rule that returns 403 only to OAI-SearchBot will pass fetch_direct (the audit fetches with a browser user agent) and pass robots_ai_bots. Check your WAF logs for that case.

How to read a result

Fix in weight order. A typical F-to-B path is: unblock the direct fetch (18), allow the critical bots in robots.txt (10), make sure the article body is in the HTML (8 + 5), then add Article or Organization JSON-LD with sameAs and dateModified (6 + 3 + 2). That sequence alone is 52 points of raw weight.


Further reading

Ready to see the per-check breakdown for your own page? Run an audit →