How the SEO & GEO readiness score is calculated
Standard v2.1.2 — published 3 August 2026. Every check the AAJ readiness scorer runs, its weight, and what it measures. Published so the score can be audited rather than trusted. Measured signals score; assessed signals are shown with evidence and excluded from the total.
What is the scoring model?
100 points across a three-stage funnel: Reach (39), Read (25), Understand (36). Stages are ordered by dependency — a page an AI agent cannot fetch cannot be rescued by better structured data. When the Reach stage fails, the total is capped; when the Read stage scores below 50% of its configured maximum, the total is capped at 55. The report always shows the raw score alongside the cap, so a capped score is never mistaken for the underlying measurement.
Stage 1 — Reach (39 points)
- An AI agent can fetch the page — 20.5 points. The URL is fetched twice, once with a browser user-agent and once as ClaudeBot, and the responses are compared on status code and extractable word count. A different status, a challenge page, or materially less content fails. Parity alone is not enough: a response carrying fewer than 50 extractable words is a partial pass, as is two or more redirect hops or a scheme-and-host change. HTTP errors and noindex directives fail here.
- Retrieval bots allowed in robots.txt — 9.9 points. Whether robots.txt permits OAI-SearchBot, ChatGPT-User, PerplexityBot and ClaudeBot. Allowed-but-throttled (Crawl-delay above 1s) is a partial pass. Training crawlers are reported separately and never scored.
- Missing pages return a real 404 — 4 points. A guaranteed-nonsense path is requested. A 404 or 410 passes; a 200 fails, because every wrong URL then looks like a real page to an agent.
- Time to first byte — 3 points. Median of three requests: under 800ms passes, 800–2000ms partial, above 2000ms fails.
- Sitemap & robots hygiene — 1.6 points. robots.txt resolves, an XML sitemap resolves, and robots.txt references the sitemap.
Stage 2 — Read (25 points)
- Server-rendered content volume — 15 points. Extractable words in the initial HTML response, with script, style and noscript stripped, scored on a curve against a 600-word reference. No headless browser runs, so no render-coverage percentage is claimed. A response under 300 words that also carries a client-render fingerprint fails outright at 0 of 15.
- On-page fundamentals — 4 points. Four binary sub-signals at 1.0 point each: title present and 30–60 characters, meta description present and 70–160 characters, exactly one H1, and a canonical tag. Half credit for present-but-out-of-range.
- Token efficiency — markup tax — 3 points. Raw HTML bytes divided by extractable text bytes. At or under 10x passes, up to 30x partial, above that fails.
- Markdown content negotiation — 3 points. A request with Accept: text/markdown and no added query parameters returns a Markdown variant with Vary: Accept set. Markdown without Vary, or a discoverable .md twin, is a partial pass.
Stage 3 — Understand (36 points)
- Answer-shaped content — 12 points. Three sub-signals at 4.0 points each: a direct-answer block near the top, two or more question-phrased headings, and an on-page FAQ section.
- Structured data quality — 10 points. Four sub-signals at 2.5 points each: JSON-LD present, a page-type node (Article, Product, Service, FAQPage), at least one @id identifier, and at least one sameAs link. Presence alone is not enough — ungrounded schema says what a page is, not who publishes it.
- Citability signals — 10 points. Three sub-signals at 3.333 points each: external in-content citations to non-social domains, concrete statistics in the visible text, and at least one quotable blockquote passage.
- Freshness & authorship — 2 points. datePublished, dateModified, and a named author, in markup or schema.
- llms.txt — 2 points. A well-formed /llms.txt with sections and links. Weighted low deliberately: no major AI provider has committed to consuming it in production.
Which signals are assessed but not scored?
Content substance in the opening prose, Cloudflare AI-bot exposure, training-crawler policy, MCP discovery at /.well-known/mcp.json, AGENTS.md, and security headers. Each is a judgement call, an emerging convention with thin adoption, or a legitimate choice that should not cost a site points — so each is reported with evidence and excluded from the total.
Changelog
v2.1.2 — 3 August 2026
- Composite checks are decomposed into named binary sub-signals with the weight split evenly, and each sub-signal is reported as evidence. No partial-credit band is applied on top of a sub-signal total.
- The 30% partial-pass credit is reserved for genuinely single-signal checks; the Reach fetch check is the current example.
- The server-rendered content curve is applied to partial responses: 345 words against the 600-word reference scores 4.8 of 15 rather than zero. A fingerprinted JavaScript shell below 300 words still fails outright.
- The content-substance sample excludes interface text — buttons, navigation, video fallbacks and aria-hidden content are no longer read as prose.
- Displayed points are rounded to one decimal place, the priority list states that it is ordered by funnel stage, and a fix resolved by the same work as an earlier fix is marked dependent rather than presented as independent effort.
v2.1.1 — 3 August 2026
- One central scoring function. A partial pass is a flat 30% of a check's weight; an unmeasurable check scores zero and is never quietly upgraded.
- The render check no longer claims a coverage ratio it never measured, and fails outright when a JavaScript shell is fingerprinted.
- Only a scanner-side failure is marked not measurable; anything the target answered, including an HTTP error, is scored.
- Score caps are computed against the full configured stage maximum, and a Read stage below 50% caps the total at 55.
- The Markdown probe no longer appends a cache-busting query parameter, re-sends Accept on every redirect hop, waits up to 15 seconds, and retries once on a network error.
- Scores from v2.1.0 and earlier are not comparable to v2.1.1.
v2.0 — 2 August 2026
- The report was restructured as a Reach → Read → Understand funnel, dual-user-agent fetching was introduced, and measured signals were separated from assessed ones.
FAQ
Why is my score capped?
Because a stage the rest of the funnel depends on failed. If an AI agent cannot fetch the page, or the fetched response does not contain the page, downstream points describe markup no agent will ever read. The raw score is always shown next to the cap.
Why isn't llms.txt worth more?
No major AI provider has publicly committed to consuming llms.txt in production retrieval. It is cheap, honest hygiene — so it earns 2 points, not 20.
Why are training crawlers not scored?
Blocking GPTBot, CCBot or Google-Extended costs nothing in live citations. It is a legitimate business choice, so it is reported and never scored against a site.
Are scores comparable across versions?
Only within a major-minor line. Scores from v2.1.0 and earlier are not comparable to v2.1.1 or later; the changelog states what changed each time.
Run the scorer
Score any URL with the free SEO & GEO Readiness Scorer, then use the GEO/AEO Playbook to work the fix list. For hands-on delivery, see the AI Visibility Sprint.
Part of the AI Search & Agent Readiness hub - see the other 11 resources on this topic.