The GEO audit checklist: what generative engines actually read on your pages

A GEO audit checks whether generative engines can fetch, read, and reuse your pages. Generative engine optimization is not a ranking trick. It is page QA: the engine either gets clean text, clear structure, and permission to crawl, or it moves on to a site that provides them.

This checklist is written for operators. Every check names what to verify, why a generative engine cares, and how to confirm it in one command or one view. Run it against https://yoursite.com top to bottom. Most checks take under a minute.

1. Rendered-page legibility

Verify: the raw HTML response contains your actual copy, not an empty shell.

Why it matters: generative engines work from fetched text. If the response is a loading spinner and a script tag, there is nothing to read, quote, or cite.

Check it:

curl -s https://yoursite.com/ | sed -e 's/<[^>]*>//g' | tr -s ' \n' ' ' | head -c 600

You should recognize your headline and first paragraphs in that output. If you see mostly whitespace or boilerplate, the page is not legible to a text-first fetcher.

2. Server-rendered content, not client-only

Verify: the content that matters exists in the HTML before any JavaScript runs.

Why it matters: some AI crawlers execute little or no JavaScript, and even the ones that render pages give hydrated content less reliable treatment. Client-only rendering makes your most important pages invisible to the least patient readers.

Check it:

curl -s https://yoursite.com/pricing | grep -c "the exact plan name you show on screen"

A count of zero means that copy only exists after client-side rendering. Move it into the server-rendered response.

3. robots.txt allows AI crawlers

Verify: robots.txt does not block GPTBot, ClaudeBot, or PerplexityBot from the pages you want cited.

Why it matters: a disallow rule is a hard stop. No amount of content quality recovers a page the crawler is forbidden to fetch. Blanket-blocking AI crawlers quietly removes you from generative answers.

Check it:

curl -s https://yoursite.com/robots.txt

Read the rules for GPTBot, ClaudeBot, and PerplexityBot by name, then the User-agent: * fallback. index365.co allows AI crawlers on every public route and disallows only authenticated dashboard paths, and the policy is generated from application code rather than a hand-edited file. Auth should protect private data. robots rules should invite readers.

4. llms.txt presence and freshness

Verify: https://yoursite.com/llms.txt exists, returns 200, and describes the site you run today.

Why it matters: llms.txt is a curated inventory for AI readers: what the site is, which pages matter, and where an agent should start. A missing file wastes the one surface built for this audience. A stale one is worse, because engines act on wrong information confidently.

Check it:

curl -s https://yoursite.com/llms.txt | head -20

Confirm the product names, links, and claims match the live site. index365.co generates its llms.txt from application code, so the inventory updates when routes and products change instead of rotting in a static folder. If yours is a static file, put a review date on it and treat drift as a bug.

5. Canonical URLs

Verify: every key template emits one self-consistent canonical URL.

Why it matters: engines consolidate signals per canonical URL. Conflicting or missing canonicals split your identity across www, trailing-slash, and query-string variants, and the engine may cite the version you least want.

Check it:

curl -s https://yoursite.com/ | grep -o '<link rel="canonical"[^>]*>'

The canonical should be absolute, HTTPS, and identical to the URL you promote. Repeat on one product page and one article.

6. Structured data on key templates

Verify: your home, product, and article templates emit valid JSON-LD.

Why it matters: structured data gives engines typed facts instead of inferred ones. An Article with dates, an Organization with a name and logo, a Product with real attributes: these are the fields engines can trust without guessing.

Check it:

curl -s https://yoursite.com/ | grep -c 'application/ld+json'

Then paste the page URL into a schema validator view and read the parsed output. Zero blocks on a key template is a finding. Invalid JSON in a block is a worse one.

7. Heading semantics

Verify: one H1 per page, and H2s that describe the sections under them.

Why it matters: headings are the outline an engine uses to segment your page into answerable chunks. A page with four H1s, or with styled divs instead of headings, reads as one undifferentiated blob.

Check it:

curl -s https://yoursite.com/ | grep -o '<h[123][^>]*>' | sort | uniq -c

Expect exactly one H1 and a sensible count of H2s. Then read the H2 texts alone and ask whether they summarize the page. That is exactly how a machine will read them.

8. Answerable page sections

Verify: each major section opens with a sentence that could stand alone as an answer.

Why it matters: generative engines lift spans of text, not whole pages. A section that starts with a direct, complete statement is quotable. A section that starts with three sentences of wind-up gives the engine nothing to extract.

Check it: open your top three pages and read only the first sentence under each H2. If that sentence does not answer the heading, rewrite it so it does. This is a view check, not a command, and it is the highest-leverage edit on this list.

9. Sitemap lastmod accuracy

Verify: sitemap.xml lists your real URLs and the lastmod dates reflect actual changes.

Why it matters: crawlers use lastmod to budget refetches. Dates that never change tell engines your content is frozen. Dates that update on every deploy without content changes teach engines to ignore your signal entirely.

Check it:

curl -s https://yoursite.com/sitemap.xml | grep -A1 '<loc>' | head -20

Pick one URL you know changed recently and one that did not. Both lastmod values should match reality.

10. Status codes and redirect hygiene

Verify: promoted URLs return a clean 200 without redirect chains.

Why it matters: every redirect hop spends crawl budget and adds a failure point. Chains of two or more hops, or a 200 page whose canonical points somewhere else, dilute the URL identity an engine builds.

Check it:

curl -sIL -o /dev/null -w "%{http_code} %{num_redirects} %{url_effective}\n" https://yoursite.com

You want 200, zero or one redirect, and a final URL that matches your canonical.

11. OG and meta completeness

Verify: every public template has a title, meta description, and Open Graph tags that describe the page truthfully.

Why it matters: titles and descriptions are the densest summary an engine reads, and OG data is reused in previews wherever your page gets cited. Empty or duplicated descriptions across templates flatten your pages into one indistinct entry.

Check it:

curl -s https://yoursite.com/ | grep -Eo '<meta (property|name)="(og:[a-z:]+|description|twitter:[a-z]+)"[^>]*>'

Repeat across templates and compare: each page should describe itself, not repeat the homepage.

12. Fact parity across surfaces

Verify: the facts on your rendered page, your structured data, and your llms.txt agree.

Why it matters: engines cross-check. A plan priced one way in visible copy and another way in JSON-LD is a contradiction, and engines resolve contradictions by trusting your site less. Parity is a trust signal that costs nothing but discipline.

Check it: pick your three most-cited facts, such as product names and prices, and grep each surface for them. Any mismatch is a finding with a one-line fix.

Run the checklist on request

The twelve checks above are deterministic, which means they can run as page QA instead of a quarterly project. The AI-Readiness scan runs this class of checks on request and returns trusted Findings your coding agent can use, so verification becomes a command instead of an afternoon.

Auditing for answer engines is a related but different pass with its own checks. That one is covered in the AEO audit checklist. For a worked example of this checklist against a live site, read how we audited index365 for AI legibility.

Sources