fixes for the AIR report's on-page checks
On-Page Signals for AI
Built from ReportScorer's own fix list 21 Aug 2026 · every claim badged by evidence tier
The AIR report grades a page on 14 checks, and eight of them are on-page: what is in your <head>, your heading structure, and whether you publish a markdown copy of the page at all. Together they are 56 of the report's 100 points. This page is the reference the report links to for each one — what the check actually looks for, what is VERIFIED about it versus still THEORY, and a copy-paste fix.
All eight, by how many points they carry
Ordered heaviest first — the same order the report itself sorts failed checks into, since that is the order most worth your time.
| # | Check | Points | What it requires |
|---|---|---|---|
| 01 | Content depth matches the pages the model cited | 18 pts | Bring the page up to roughly the length of the pages the model already cites for this phrase — a correlation, not a proven cause, but the pages it does cite for this phrase are consistently longer than yours. |
| 02 | Has a usable <title> | 11 pts | Give the page a title between 15 and 70 characters that names the thing the phrase is about. |
| 03 | Exactly one H1 | 7 pts | Use one H1 for the page subject and demote the rest to H2 — several H1s leave no single stated subject. |
| 04 | Sectioned with H2s | 7 pts | Break the content into at least two H2 sections so an assistant can quote one part of the page. |
| 05 | Declares a canonical URL | 5 pts | Add <link rel="canonical"> so duplicate URLs consolidate onto one address. |
| 06 | Page has a markdown version | 3 pts | Serve the same content at page.md (or page.html.md) so an assistant reads prose instead of unwrapping your HTML. |
| 07 | Has a meta description | 3 pts | Add a meta description summarising the page in one sentence. |
| 08 | Page points at its markdown / llms.txt | 2 pts | Add <link rel="alternate" type="text/markdown" href="…"> and <link rel="describedby" href="/llms.txt"> to the page head (or the equivalent HTTP Link: response header). |
How to read the badges
- VERIFIED
- a primary source confirms it: the spec, the vendor's own documentation, or our own measured logs.
- COMMUNITY-REPORTED
- practitioners observe it; no vendor confirmation.
- THEORY
- plausible, widely repeated, unproven — not a reason to skip the fix, a reason to know what you're buying.
01 Publish a markdown mirror #
Serve the same content at page.md (or page.html.md) so an assistant reads prose instead of unwrapping your HTML.
- Path
- page.md or page.html.md
- Worth
- 3 of 100 points
- Watch out for
- Serving the HTML page again under a
.mdURL is not a mirror
Evidence
- VERIFIED The convention is the spec's, not ours: append
.mdto a clean URL, or.html.mdto an extensioned one; a path with no filename getsindex.md. llmstxt.org — "Proposal" section - VERIFIED AI systems can't run your JavaScript (see server-side rendering), and even a server-rendered page still costs a crawler an HTML-strip pass to reach the prose. A markdown mirror removes that step entirely rather than asking a crawler to do it well.
- VERIFIED — our own logs We ate this one ourselves: reading our own server logs for AI-crawler traffic verified against Anthropic's published IP ranges (
claude.com/crawling/bots.json), ClaudeBot made 57 confirmed requests for.mdmirror paths in one window — against a single confirmed request for/llms.txtin the same window. The mirrors get fetched; the index file, on this domain, barely does. - THEORY That offering the mirror increases the odds an assistant names you for a given question. We can show it gets fetched; we have not run the controlled test that would show it changes what gets said.
Do this
- Pick the spelling that matches your URL shape and hold it site-wide — don't mix
page.mdandpage.html.mdacross the same site. - Serve it with
Content-Type: text/markdown; charset=utf-8, and make sure it is real prose — a script that just strips HTML tags at request time leaves boilerplate (nav, cookie banners) in the output, which defeats the point. - Verify with
curl, not a browser — a browser hides exactly the difference a crawler experiences.
# A markdown mirror only counts if it is actually there. Check the way a
# crawler would — no browser, no JavaScript:
curl -sI https://example.com/docs/pricing.md | grep -i content-type
# Content-Type: text/markdown; charset=utf-8
curl -s https://example.com/docs/pricing.md | head -5
# Should be prose. If it starts with <!DOCTYPE html>, you served the HTML page
# again with a .md extension, not a markdown mirror.02 Point the page at its markdown and its llms.txt #
Add <link rel="alternate" type="text/markdown" href="…"> and <link rel="describedby" href="/llms.txt"> to the page head (or the equivalent HTTP Link: response header).
- Path
- <head> or the Link: header
- Worth
- 2 of 100 points
- Watch out for
- The
typeattribute must literally contain "markdown", or it doesn't count
This is the check right above it (markdown mirrors) turned into a signpost. A mirror a crawler has to guess the URL of is worth less than one it is told about directly.
Evidence
- VERIFIED Both link relations and both delivery mechanisms are the spec's own recommendation, including the exact
Link:header syntax:rel="alternate" type="text/markdown"for the mirror,rel="describedby"for the llms.txt file that covers this page, either as an HTML<link>or an HTTPLink:response header — the header form works without touching origin markup, which matters if a CDN sits in front of you. llmstxt.org — "Proposal" section - THEORY That adding these links increases citation odds. Unmeasured — nobody, including us, has published a test isolating this signal from the content it points at.
Do this
- Point
rel="describedby"at your site's/llms.txt(or the nearest one covering this path) — not at the page's own markdown, that's whatrel="alternate"is for. - If you don't control page
<head>markup, set theLink:header at the edge instead — it covers non-HTML resources too, including the markdown file itself. - Check both are present the same way the report does: fetch the page and look for either the tag or the header — one is enough, you don't need both.
<!-- Clean URL (/docs/pricing) -> /docs/pricing.md -->
<!-- Extensioned URL (/docs/pricing.html) -> /docs/pricing.html.md -->
<!-- No filename at all (/docs/) -> /docs/index.md -->
<!-- HTML <link>, in <head> -->
<link rel="alternate" type="text/markdown" href="/docs/pricing.md">
<link rel="describedby" href="/llms.txt">
<!-- Or the HTTP header equivalent — works for the .md file too, and can be
set at the CDN/edge without touching origin markup -->
Link: </docs/pricing.md>; rel="alternate"; type="text/markdown",
</llms.txt>; rel="describedby"03 Match the depth of the pages the model already cites #
Bring the page up to roughly the length of the pages the model already cites for this phrase — a correlation, not a proven cause, but the pages it does cite for this phrase are consistently longer than yours.
- Bar
- half the median, floor 300 words
- Worth
- 18 of 100 points
- Watch out for
- Nav, menus and footers can inflate a naive word count on either side of the comparison
The report doesn't grade against a fixed word count — it grades your page against the pages currently cited for your phrase. And the bar it sets is deliberately half the median word count of that set, not the median itself: the median is, by construction, beaten by only half of what's ranking, so requiring it would fail pages that are already doing fine. This check asks whether you're in the same league, not whether you win the word count.
Evidence
- VERIFIED The comparison itself is real: your page's word count against half the median of the pages the report finds cited for this phrase, floored at 300 words so a very thin field can't set the bar to nothing.
- THEORY That closing the gap causes more citation. What's cited for a phrase is consistently longer than what isn't — that correlation is real and repeated — but "what ranks" and "what an assistant quotes" are different questions, and we have not run the test that would separate correlation from cause here.
Do this
- Find out what's actually cited for your target phrase — search it on AIR and read what's cited, or check yourself.
- Measure it the way a crawler does: strip the tags, count what's left. A word count read off the rendered page in a browser includes nav and footer boilerplate on both sides of the comparison and can mislead you either way.
- Write toward roughly half that page's length in substantive prose — padding with boilerplate doesn't move this number, only content does.
# What does the model actually cite for your phrase? Read one of those pages
# the way a crawler does, and count what a human reader would count:
curl -sL https://competitor.example/the-cited-page \
| sed 's/<script[^>]*>.*<\/script>//g; s/<[^>]*>//g' \
| tr -s '[:space:]' ' ' | wc -w
# Then your own page. The bar is HALF that number (floor 300 words), not the
# full number — you are being asked to be in the league, not to win it.04 Give the page a usable <title> #
Give the page a title between 15 and 70 characters that names the thing the phrase is about.
- Path
- <title> in <head>
- Range checked
- 15–70 characters
- Watch out for
- A title identical across many pages passes the length check and still says nothing
Evidence
- VERIFIED The 15–70 character range is exactly what the report checks — long enough to name a real subject, short enough that it isn't padding.
- THEORY That a title in range specifically improves an assistant's chance of citing you. This is decades-established practice for search results (Google's title-link documentation) and it is the cheapest, lowest-risk item on this page — but unmeasured for assistant answers specifically, which read pages rather than a results snippet.
Do this
- Name the actual subject in plain words a machine summarising you would reuse — not a slogan, not just your brand name.
- Keep every page's title different from every other page's.
- Land inside 15–70 characters; count it, don't eyeball it.
<!-- Names the thing, sits in range, could stand alone in a link list -->
<title>Wire Transfer Fees by Country — Example Payments</title>
<!-- Too short to be specific (8 chars) -->
<title>Pricing</title>
<!-- Truncates in almost every surface that shows it (past 70 chars) -->
<title>Complete and Definitive Guide to All of Example Payments' Wire Transfer Fees, Limits, and Processing Times by Country and Currency</title>05 Add a meta description #
Add a meta description summarising the page in one sentence.
- Path
- <meta name="description">
- Checked for
- presence only, no length rule
- Watch out for
- An empty
content=""attribute still passes a naive presence check — write an actual sentence
Evidence
- VERIFIED The report only checks that the tag exists with content — it does not grade length. Say what's actually true either way: a present-but-empty tag is a gap this page's own check can't see, not something to exploit.
- THEORY What it does for AI retrieval specifically: it is not confirmed as an input any assistant's answer pipeline reads. What it reliably does is control the snippet a human sees under a search result — a real, separate benefit, just not the one this report is measuring.
Do this
- Write one real sentence that summarises the page, not a keyword list.
- Make it unique per page — a description copy-pasted site-wide tells a reader (and a model) nothing about this specific page.
<meta name="description" content="Wire transfer fees, limits, and
processing times for Example Payments, by destination country and
currency.">06 Use exactly one H1 #
Use one H1 for the page subject and demote the rest to H2 — several H1s leave no single stated subject.
- Checked for
- count(<h1>) === 1
- Worth
- 7 of 100 points
- Watch out for
- Zero H1s fails this exactly the same as two does
Evidence
- VERIFIED The check is a literal count — pass requires exactly one, not "at least one." A page with zero H1s and a page with five both fail it.
- THEORY That this specifically changes an assistant's citation odds — grouped with title/meta/heading-structure/canonical as conventional page hygiene, established for search, unmeasured for assistant answers. Lowest-risk theory on this page: it was good practice before assistants existed and stays good regardless of whether the causal claim ever gets tested.
Do this
- Pick the one sentence that states what this page is about and make it your only
<h1>. - Demote everything else — including a second "related" heading at the top — to
<h2>or lower.
<!-- One subject, stated once -->
<h1>Wire Transfer Fees by Country</h1>
<h2>SWIFT fees</h2>
<h2>SEPA fees</h2>
<h2>Processing times</h2>
<!-- Not this: two H1s leave no single stated subject for either a reader
or a model to summarise the page around -->
<h1>Wire Transfer Fees</h1>
...
<h1>Related: Currency Conversion</h1>07 Section the page with H2s #
Break the content into at least two H2 sections so an assistant can quote one part of the page.
- Checked for
- count(<h2>) >= 2
- Worth
- 7 of 100 points
- Watch out for
- Headings that just say "Overview" and "More info" pass the count and help nobody
Evidence
- VERIFIED The check is a count, not a quality judgement — two or more
<h2>elements pass it regardless of what they say. Passing the check and writing a page an assistant can actually quote from are two different bars; only the second one is the point. - THEORY Same evidentiary position as one H1: plausible, unmeasured for assistant answers, real for a human scanning the page. The mechanism argument is a fair one — an assistant that can cite one
<h2>-bounded section can quote you narrowly instead of paraphrasing the whole page — but it is an argument, not a result.
Do this
- Break the page into at least two real sections, each answering one sub-question of the page's subject.
- Title each
<h2>with what's actually in it — a heading is what a reader, or a model, quotes back to identify the section.
08 Declare a canonical URL #
Add <link rel="canonical"> so duplicate URLs consolidate onto one address.
- Path
- <link rel="canonical">
- Worth
- 5 of 100 points
- Watch out for
- The check only looks for presence — a canonical tag pointing at the wrong URL still passes it
Evidence
- VERIFIED The check is presence-only: does a
<link rel="canonical">element exist. It does not verify thehrefpoints at the right page — that part is on you. - THEORY Grouped with the other conventional-hygiene checks on this page: well-established that a canonical consolidates duplicate URLs for search engines (Google's canonicalization documentation), unmeasured for whether it changes an assistant's citation odds.
Do this
- Add one canonical link to every URL variant of a page — including the tracking-parameter and trailing-slash versions — pointing at the single address you want treated as authoritative.
- Point it at itself on the canonical page, and at that page everywhere else the content is duplicated.
<!-- On every URL variant that renders the same content -->
<link rel="canonical" href="https://example.com/docs/pricing">
<!-- /docs/pricing?ref=nav, /docs/pricing/, /docs/pricing?utm_source=... —
all three should still declare the canonical above, not themselves -->Check all eight on your own page #
Run the AIR report and it checks all eight against your actual URLs and phrases, alongside the crawler-access, llms.txt and structured-data checks that make up the other six of the 14, covered further on LLM Web Indexing Files, the page this one is the companion to. Signing in is required — a single report run makes over 200 outbound requests, which is not something we can leave open to anonymous traffic.
Already have a report token? Its URL looks like airanks.net/report/<token> and needs no sign-in to view.