CrawlCheck
A real report · denverpost.com · scanned 15 hours ago

What an agent is told, and the report behind it.

One record, two readers. A person reads the report below: every section, every finding, the evidence behind each. An agent never reads the report; it asks one endpoint and gets the signed answer in the card — a decision for read, cite, connect and transact, resting on the same measurements. Both regenerate from the same scan; neither is a mock-up.

Scan your own domain →The agent view, section by section →The signed JSON →

Your optionsWe fix it $100 once · Watch $29 / month
  1. The free scan$0

    Your grade, your score, and every problem we found.

  2. We fix it for you$100 once

    We fix every problem on your site, then scan it again to prove it. Thirty days of monitoring included.

    Get it fixed

    Card, then we start. One site per order.

  3. Watch$29 / month

    We check 3 websites twice a day and show every problem with its proof, how long it has been open and when it was fixed.

    You are here · C · 81/100

    Open your dashboard

Paying never changes your grade.

This sample is shown unlocked, so you can see what a licence includes. On your own domain the free scan gives you the grade, the score, which stage fails and every finding by name, with the top one in full; the detail, the fix and the bytes behind each one are what a licence buys.

Scan your own domain What a licence costs

Scan result

denverpost.com

2026-11-12 · 15 hours agowordpressid aasc46z1wvpublic

81
Cgrade

AI assistants like ChatGPT can read your site, but find little they can quote from your pages.

Fix first

robots.txt rules do not apply to named agents

This one is holding the grade down. Clear it and the grade lifts on its own.

Fix it for me Keep an eye on it, free for 30 days

AI visibility 81/100. An engine can reach and read this site. What is left is giving it something specific to say.

Held at C The score alone would grade higher; a medium-severity finding sets the letter. Clear it and the grade lifts on its own.

What this does not prove

This is what crawlers receive from the site today — reach, read, quote — measured from CrawlCheck’s own network. It does not show whether any engine cites the site, where it ranks, or what traffic or leads follow, and a crawler-identity probe is not a fetch from that operator’s verified addresses. What a number can and cannot say

11

findings

19/33

sections passing

+19

points available

63%

of 38 sites in the publisher reference set scored lower

24

scans on record

The short version

The website's robots.txt rules do not apply to all agents as intended, with 3 named User-agent groups not repeating certain Disallow rules. The site also has issues with its structured data, including an identity collision where two nodes share the same url. Additionally, the homepage depends on files that are disallowed by the site's own robots.txt, which could cause rendering issues.

Summary written from this scan’s findings, every sentence checked against one of them. How CrawlCheck reads

In plain English

  • 19 of 33 scored sections pass. 7 need work, 7 are failing. The other 8 of the 41 sections are measured for information and never scored.
  • Fix first: robots.txt rules do not apply to named agents 3 named User-agent groups (3 agents) do not repeat 8 of the Disallow rules the `*` group carries. A crawler obeys only its own most-specific group and ignores `*` entirely, so those rules do not… This one is holding the grade at C. See the fix list.
  • Fix the 41 failing measures in the fix list and the score reads 100. Now 81, a gain of 19 points.
  • Every named answer engine was served the page. OAI-SearchBot, Claude-SearchBot, PerplexityBot, ChatGPT-User, Claude-User, Perplexity-User, Googlebot, Googlebot Smartphone, Bingbot, Applebot. Disallowed by policy in robots.txt: Yahoo Slurp, ChatGPT search index, ChatGPT live fetch, Claude search index, Claude live fetch, Perplexity index, Perplexity live fetch, Le Chat live fetch (a choice, not a defect).
  • Down 2 points since the previous scan. Section average held at 80 for 1 scan since 2026-11-12. See what changed.

Start here

The three findings holding the grade down most. Open one for what was seen and how to fix it.

The three stages, in the order an engine hits a site

Each stage gates the next: an engine that cannot reach a page never reads it, and one that cannot read it never quotes it.

79

Stage 1 · 40% of the score

Reach

Can a named answer-engine crawler get your pages at all?

At least one answer engine was refused, challenged or served less than a browser.

83

Stage 2 · 30% of the score

Read

Once it has the bytes, can it find the words?

The content is buried in markup, or the files that guide a crawler are missing.

83

Stage 3 · 30% of the score

Quote

Is there a specific fact it can state and attribute?

An assistant would have to paraphrase your page instead of quoting a fact.

The stage to fix first is reach, the lowest of the three.

How this compares

Ranked against 36 sites in the same cohort (wordpress/publisher). This corpus is sites people chose to scan, not the web, so a rank here is a comparison, not a verdict.

AI visibility score (the grade shown)you 81 · median 80
56th
Section average (weighted)you 80 · median 81
41st
Content ratio (% visible text)you 4.4 · median 3.4
69th
Stable @id coverage (%)you 33.3 · median 84.6
8th
Render-blocking resourcesyou 27 · median 10.5
19th
Delivered page size (KB)you 306 · median 182
14th

Percentile: the share of comparable sites this one scores better than. Lower-is-better metrics (page size, render-blocking) are already inverted.

Section average over 22 scans on this score version · held at 81 since 2026-11-12
0501002026-10-23 00:17 · 83/100 · 10 findings2026-10-24 00:17 · 82/100 · 10 findings2026-10-25 00:17 · 82/100 · 10 findings2026-10-26 00:17 · 82/100 · 10 findings2026-10-27 00:17 · 83/100 · 10 findings2026-10-28 00:18 · 83/100 · 10 findings2026-10-29 00:18 · 82/100 · 10 findings2026-10-30 00:17 · 82/100 · 10 findings2026-10-31 00:17 · 82/100 · 10 findings2026-11-01 00:17 · 82/100 · 10 findings2026-11-02 00:17 · 81/100 · 10 findings2026-11-03 00:17 · 83/100 · 11 findings2026-11-04 00:17 · 83/100 · 11 findings2026-11-05 00:17 · 83/100 · 11 findings2026-11-06 00:17 · 83/100 · 11 findings2026-11-07 00:17 · 83/100 · 11 findings2026-11-07 01:02 · 83/100 · 11 findings2026-11-08 00:17 · 83/100 · 12 findings2026-11-09 00:17 · 83/100 · 11 findings2026-11-10 00:17 · 83/100 · 11 findings2026-11-11 00:17 · 83/100 · 11 findings2026-11-12 00:17 · 81/100 · 11 findings

What comes next

Each step builds on the same signed record. Start wherever you are.

  1. 01FixFix what holds the grade downSteps for your platform, checked by a re-scan.
  2. 02WatchWatch it every dayFree for 30 days. Changes and new findings reach your inbox.
  3. 03ClaimProve the domain is yoursOne DNS record or meta tag. Every signed answer about the site then says control is proven.
  4. 04Agent viewSee what agents are toldThe signed answer any agent gets before it reads, cites, connects or transacts.
  5. 05BuildAsk from your own codeOne call before your agent acts: npm, PyPI or plain HTTPS.

What to fix, in order

Findings first: each one holds the grade down until it is gone (the top one sets the letter). Then headroom: each one lifts the score by the points shown. Open a card for what we saw, why it matters and how to fix it.

Measured 48 times, the oldest finding here first seen 2026-08-20. 11 of them have been here on an earlier reading and 1 cleared and came back. A finding that cleared and returned is a regression, not a new fault.

Of 8 tagged findings, 4 are setting changes, 2 are content edits and 2 need a developer. 3 findings are not tagged. Setting changes are usually the same afternoon; nothing here is ranked by effort, only labelled.

Fix one thing: what it changes

FixClearsScoreLetterAlso needs
the homepage's code weight1 finding, 4 rows81 → 84C → C—
robots.txt1 finding, 1 row81 → 82C → C—
the machine-file chain1 finding, 1 row81 → 82C → C—
entitymap.json1 row81 → 82C → C—
XML sitemap1 finding81 → 81C → C—
llms.txt1 finding81 → 81C → C—

Each line is the grade formula rerun with that one fix in place; computed, not measured. The rescan after the fix is the measurement.

Sites like yours that fixed the same problem

Matched on WordPress. A fix counts once two readings confirm it; sites are not named. Read from the technology record of 2026-11-11.

serves no /llms.txt

12 sites on a stack like yours have made this fix (Published llms.txt); 12 still hold it. 102 on any stack.

  • similar site A (WordPress + Amazon CloudFront + WP Engine; shares platform): fixed 2026-11-10, still fixed today
  • similar site B (WordPress + Cloudflare + Cloudflare Bot Management; shares platform): fixed 2026-11-04, still fixed today
  • similar site C (WordPress + Fastly; shares platform): fixed 2026-10-31, still fixed today

serves no /agents.md (optional)

5 sites on a stack like yours have made this fix (Published agents.md); 4 still hold it. 21 on any stack.

  • similar site A (WordPress + Cloudflare; shares platform): fixed 2026-11-09, still fixed today
  • similar site B (WordPress + Cloudflare + Cloudflare Bot Management; shares platform): fixed 2026-11-04, still fixed today
  • similar site C (WordPress + Cloudflare + Cloudflare Bot Management; shares platform): fixed 2026-10-31, still fixed today

blocks PerplexityBot in robots.txt (optional: only a problem if the block is not deliberate)

4 sites on a stack like yours have made this fix (Unblocked PerplexityBot in robots.txt); 4 still hold it. 10 on any stack.

  • similar site A (WordPress + Amazon CloudFront + Netlify; shares platform): fixed 2026-11-06, still fixed today
  • similar site B (WordPress + Fastly + Pantheon; shares platform): fixed 2026-10-31, still fixed today
  • similar site C (WordPress + Cloudflare + SiteGround + Cloudflare Bot Management; shares platform): fixed 2026-10-31, still fixed today

blocks ChatGPT-User in robots.txt (optional: only a problem if the block is not deliberate)

2 sites on a stack like yours have made this fix (Unblocked ChatGPT-User in robots.txt); 2 still hold it. 7 on any stack.

  • similar site A (WordPress + Amazon CloudFront + Netlify; shares platform): fixed 2026-11-06, still fixed today
  • similar site B (WordPress + Fastly + Pantheon; shares platform): fixed 2026-10-31, still fixed today

The signed answer lists every match.

1robots.txt rules do not apply to named agents3 named User-agent groups (3 agents) do not repeat 8 of the Disallow rules the `*` group carries. A crawler obeys only its own most-specific group and ignores `MediumSettingConfirmed

first measured 2026-09-10 · 63 days ago · seen across 32 measured days. A one-off scan cannot produce this line; it comes from the record.

What we saw

3 named User-agent groups (3 agents) do not repeat 8 of the Disallow rules the `*` group carries. A crawler obeys only its own most-specific group and ignores `*` entirely, so those rules do not apply to any of the named agents. Worst group: `amazonadbot` bypasses /wp-admin/, /cgi-bin/, /wp-includes/, /xmlrpc.php, /wp-content/plugins/, /wp-content/cache/, /trackback/, /comments/. /robots.txt

Why it matters

A crawler reads only the User-agent group that matches it best and ignores every other group, including `*`. Naming an agent and giving it only `Allow: /` therefore deletes all of your `*` Disallow rules for that agent. The file still parses and the agent still reaches your homepage, so this is invisible on inspection — but the paths you meant to keep out of search are open, and search engines will crawl and may index them.

How to fix it

Every User-agent group that names a crawler must repeat the Disallow rules you want applied. A named group with no rules means 'allow everything' for that crawler.

Setting: a setting on the server, CDN, DNS or a plugin — no code and no writing

On WordPress (detected)

  1. WordPress serves a virtual robots.txt. Edit it in your SEO plugin: Yoast SEO → Tools → File editor; Rank Math → General Settings → Edit robots.txt; All in One SEO → Tools → Robots.txt Editor.
  2. A real robots.txt file in the site root (the folder with wp-config.php) overrides every plugin. If one exists, edit that file instead, through your host's file manager or SFTP.
  3. Keep one group per crawler: a crawler that has its own User-agent group ignores the * group entirely, so repeat any Disallow lines it still needs.

All WordPress fixes

Paste this

Each crawler obeys only its own group, so a named group must repeat the rules you want. The corrected file below copies them in for you.

The whole corrected robots.txt for www.denverpost.com · built from the live file, every change listed at the top.

Fix it with a coding agent

Paste into Claude Code, Cursor or Codex, opened on the code that serves this site.

Show prompt
You are working in the codebase (or server/CDN configuration) that serves denverpost.com. A crawler audit found the problem below. Fix it at the source, keep the change as small as possible, and do not change anything a visitor sees unless the fix requires it.

Finding: robots.txt rules do not apply to named agents (ROBOTS_RULES_SHADOWED, medium severity)
Page: https://denverpost.com/robots.txt
What was measured: 3 named User-agent groups (3 agents) do not repeat 8 of the Disallow rules the `*` group carries. A crawler obeys only its own most-specific group and ignores `*` entirely, so those rules do not apply to any of the named agents. Worst group: `amazonadbot` bypasses /wp-admin/, /cgi-bin/, /wp-includes/, /xmlrpc.php, /wp-content/plugins/, /wp-content/cache/, /trackback/, /comments/.
Why it matters: A crawler reads only the User-agent group that matches it best and ignores every other group, including `*`. Naming an agent and giving it only `Allow: /` therefore deletes all of your `*` Disallow rules for that agent. The file still parses and the agent still reaches your homepage, so this is invisible on inspection — but the paths you meant to keep out of search are open, and search engines will crawl and may index them.
How to fix it: Every User-agent group that names a crawler must repeat the Disallow rules you want applied. A named group with no rules means 'allow everything' for that crawler.
Detected platform: WordPress. Make the change where this platform controls it.
Rule and examples: https://crawlcheck.io/rules/ROBOTS_RULES_SHADOWED
Full report (markdown): https://crawlcheck.io/r/aasc46z1wv.md

When you are done:
1. Tell me which files or settings you changed and why.
2. If the fix is a server, CDN or cache setting you cannot change from the code, say exactly where it is set.
3. After deploying, re-scan at https://crawlcheck.io/?url=denverpost.com . The fix counts when ROBOTS_RULES_SHADOWED is gone from the new report.
Why this was decided
RuleROBOTS_RULES_SHADOWED · rule pack sv34 · scope core
Evaluated2026-11-12 00:17:42 UTC
Decisiond1:ab6db3d568fdb2282e23 · finding f1:cbfcabeaf2c8fae39c15 resolve either at /api/graph/<id> with a key
Observercrawlcheck-worker build be1e3120 · audit v4

What it rests on

IdentityStatusBytessha256Kept
read: /robots.txt2004,567ff800a4d427dalready_held

25 more in the manifest.

Artifacts: manifest:4098c6573755bdd21d4644c5f14f0df51d807dbfc2d86dd1a7ffd32afab1005b

Grade effect Caps the letter at C together with 3 other medium-severity findings; the letter rises only when all of them are gone. Moves no points.

Rule ROBOTS_RULES_SHADOWED under scoring rules v34 · fingerprint ROBOTS_RULES_SHADOWED|/robots.txt · persisting (seen in 47 of 48 readings)

Verify the fix Re-scan after the change. This finding is cleared when ROBOTS_RULES_SHADOWED is no longer reported at /robots.txt; if it comes back after clearing, it is marked a regression, not a new finding.

ROBOTS_RULES_SHADOWED · full transcript

2Two business records on this page claim the same identity1 identity collision in this page's structured data: two nodes share the same url.MediumDeveloperConfirmed

first measured 2026-08-20 · 84 days ago · seen across 33 measured days. A one-off scan cannot produce this line; it comes from the record.

What we saw

1 identity collision in this page's structured data: two nodes share the same url.

Why it matters

A system resolving which business this page is about has more than one candidate for one identity. Two LocalBusiness or Organization nodes sharing a phone number, an @id or a coordinate pair give a retrieval system no way to decide which record is the entity, so it may pick either or neither. This reads only what the page declares - it does not assert the business is duplicated or wrongly located.

How to fix it

Merge the duplicate business nodes into one, keep a single @id, and remove any plugin that emits a second empty LocalBusiness record.

Developer: a template, theme or application change — a developer touches it

On WordPress (detected)

  1. Keep one source of business markup: Rank Math → Titles & Meta → Local SEO, or Yoast Local SEO. Turn off the same block in your theme or any second plugin.
  2. Fill name, address, phone, geo coordinates and opening hours there, matching the Business Profile exactly.

All WordPress fixes

Fix it with a coding agent

Paste into Claude Code, Cursor or Codex, opened on the code that serves this site.

Show prompt
You are working in the codebase (or server/CDN configuration) that serves denverpost.com. A crawler audit found the problem below. Fix it at the source, keep the change as small as possible, and do not change anything a visitor sees unless the fix requires it.

Finding: Two business records on this page claim the same identity (ENTITY_COLLISION, medium severity)
Page: https://denverpost.com/
What was measured: 1 identity collision in this page's structured data: two nodes share the same url.
Why it matters: A system resolving which business this page is about has more than one candidate for one identity. Two LocalBusiness or Organization nodes sharing a phone number, an @id or a coordinate pair give a retrieval system no way to decide which record is the entity, so it may pick either or neither. This reads only what the page declares - it does not assert the business is duplicated or wrongly located.
How to fix it: Merge the duplicate business nodes into one, keep a single @id, and remove any plugin that emits a second empty LocalBusiness record.
Detected platform: WordPress. Make the change where this platform controls it.
Rule and examples: https://crawlcheck.io/rules/ENTITY_COLLISION
Full report (markdown): https://crawlcheck.io/r/aasc46z1wv.md

When you are done:
1. Tell me which files or settings you changed and why.
2. If the fix is a server, CDN or cache setting you cannot change from the code, say exactly where it is set.
3. After deploying, re-scan at https://crawlcheck.io/?url=denverpost.com . The fix counts when ENTITY_COLLISION is gone from the new report.
Why this was decided
RuleENTITY_COLLISION · rule pack sv34 · scope route
Evaluated2026-11-12 00:17:42 UTC
Decisiond1:fcd43e2660f9b58b8eb5 · finding f1:94cc84cf5ff4efe5d75b resolve either at /api/graph/<id> with a key
Observercrawlcheck-worker build be1e3120 · audit v4

What it rests on

IdentityStatusBytessha256Kept
read: /200314,053dc318faa4d8fkept

25 more in the manifest.

Artifacts: manifest:4098c6573755bdd21d4644c5f14f0df51d807dbfc2d86dd1a7ffd32afab1005b

Grade effect Caps the letter at C together with 3 other medium-severity findings; the letter rises only when all of them are gone. Moves no points.

Rule ENTITY_COLLISION under scoring rules v34 · fingerprint ENTITY_COLLISION|/ · persisting (seen in 47 of 48 readings)

Verify the fix Re-scan after the change. This finding is cleared when ENTITY_COLLISION is no longer reported at /; if it comes back after clearing, it is marked a regression, not a new finding.

ENTITY_COLLISION · full transcript

3The homepage depends on files this site's own robots.txt disallows15 render resources referenced by the homepage are disallowed to every crawler by this site's own robots.txt: /wp-content/plugins/dfm-trust-indicators/dist/css/MediumSettingConfirmed

first measured 2026-09-10 · 63 days ago · seen across 32 measured days. A one-off scan cannot produce this line; it comes from the record.

What we saw

15 render resources referenced by the homepage are disallowed to every crawler by this site's own robots.txt: /wp-content/plugins/dfm-trust-indicators/dist/css/style.min.css (/wp-content/plugins/), /wp-content/plugins/mng-digisubs/static/mng-digisubs.styles.css (/wp-content/plugins/), /wp-content/plugins/loader-wp/static/loader.min.js (/wp-content/plugins/), /wp-content/plugins/mng-digisubs/static/mng-digisubs.shared.bundle.js (/wp-content/plugins/). A crawler that obeys robots.txt will not fetch these, so it renders the page without them. /robots.txt

Why it matters

Googlebot renders pages, and a stylesheet or script it is forbidden to fetch is rendered without. Layout, visibility and any content a script inserts are then judged from a page the site never intended to show. Only rules in the * group count here - a rule aimed at one named crawler is a narrower question.

How to fix it

Allow crawlers to fetch the CSS and JavaScript the page depends on. Remove the Disallow rules covering those paths, or serve the content without them.

Setting: a setting on the server, CDN, DNS or a plugin — no code and no writing

On WordPress (detected)

  1. WordPress serves a virtual robots.txt. Edit it in your SEO plugin: Yoast SEO → Tools → File editor; Rank Math → General Settings → Edit robots.txt; All in One SEO → Tools → Robots.txt Editor.
  2. A real robots.txt file in the site root (the folder with wp-config.php) overrides every plugin. If one exists, edit that file instead, through your host's file manager or SFTP.
  3. Keep one group per crawler: a crawler that has its own User-agent group ignores the * group entirely, so repeat any Disallow lines it still needs.

All WordPress fixes

Fix it with a coding agent

Paste into Claude Code, Cursor or Codex, opened on the code that serves this site.

Show prompt
You are working in the codebase (or server/CDN configuration) that serves denverpost.com. A crawler audit found the problem below. Fix it at the source, keep the change as small as possible, and do not change anything a visitor sees unless the fix requires it.

Finding: The homepage depends on files this site's own robots.txt disallows (RENDER_RESOURCE_BLOCKED, medium severity)
Page: https://denverpost.com/robots.txt
What was measured: 15 render resources referenced by the homepage are disallowed to every crawler by this site's own robots.txt: /wp-content/plugins/dfm-trust-indicators/dist/css/style.min.css (/wp-content/plugins/), /wp-content/plugins/mng-digisubs/static/mng-digisubs.styles.css (/wp-content/plugins/), /wp-content/plugins/loader-wp/static/loader.min.js (/wp-content/plugins/), /wp-content/plugins/mng-digisubs/static/mng-digisubs.shared.bundle.js (/wp-content/plugins/). A crawler that obeys robots.txt will not fetch these, so it renders the page without them.
Why it matters: Googlebot renders pages, and a stylesheet or script it is forbidden to fetch is rendered without. Layout, visibility and any content a script inserts are then judged from a page the site never intended to show. Only rules in the * group count here - a rule aimed at one named crawler is a narrower question.
How to fix it: Allow crawlers to fetch the CSS and JavaScript the page depends on. Remove the Disallow rules covering those paths, or serve the content without them.
Detected platform: WordPress. Make the change where this platform controls it.
Rule and examples: https://crawlcheck.io/rules/RENDER_RESOURCE_BLOCKED
Full report (markdown): https://crawlcheck.io/r/aasc46z1wv.md

When you are done:
1. Tell me which files or settings you changed and why.
2. If the fix is a server, CDN or cache setting you cannot change from the code, say exactly where it is set.
3. After deploying, re-scan at https://crawlcheck.io/?url=denverpost.com . The fix counts when RENDER_RESOURCE_BLOCKED is gone from the new report.
Why this was decided
RuleRENDER_RESOURCE_BLOCKED · rule pack sv34 · scope route
Evaluated2026-11-12 00:17:42 UTC
Decisiond1:a374061f51f983af53cb · finding f1:2262efb943db36f97ff3 resolve either at /api/graph/<id> with a key
Observercrawlcheck-worker build be1e3120 · audit v4

What it rests on

IdentityStatusBytessha256Kept
read: /200314,053dc318faa4d8fkept
read: /robots.txt2004,567ff800a4d427dalready_held

24 more in the manifest.

Artifacts: manifest:4098c6573755bdd21d4644c5f14f0df51d807dbfc2d86dd1a7ffd32afab1005b

Grade effect Caps the letter at C together with 3 other medium-severity findings; the letter rises only when all of them are gone. Moves no points.

Rule RENDER_RESOURCE_BLOCKED under scoring rules v34 · fingerprint RENDER_RESOURCE_BLOCKED|/robots.txt · persisting (seen in 46 of 48 readings)

Verify the fix Re-scan after the change. This finding is cleared when RENDER_RESOURCE_BLOCKED is no longer reported at /robots.txt; if it comes back after clearing, it is marked a regression, not a new finding.

RENDER_RESOURCE_BLOCKED · full transcript

4Almost nothing a machine receives from this page is readable text4.4% of 313,548 decompressed bytes is visible text, and the largest single block is inline css at 44,440 bytesMediumDeveloperConfirmed

first measured 2026-08-20 · 84 days ago · seen across 33 measured days · returned 1 time after a close (last 2026-11-03). A one-off scan cannot produce this line; it comes from the record.

What we saw

4.4% of 313,548 decompressed bytes is visible text, and the largest single block is inline css at 44,440 bytes

Why it matters

A crawler pays for every byte it fetches and can only quote the text. Under 5% readable content means an answer engine downloads the whole page and comes away with almost nothing it can use — the difference between being quotable and being skipped. The content-ratio row above passes at 20%, so without this a page at 2% and a page at 19% were scored identically.

How to fix it

Move inline CSS and JavaScript into external files, drop unused page-builder styling, and make sure the words a visitor reads are in the HTML itself.

Developer: a template, theme or application change — a developer touches it

On WordPress (detected)

  1. Page builders add most of the code: in Elementor turn on the optimized DOM output and improved asset loading features; remove plugins that inject scripts on every page.
  2. Let a cache or optimization plugin defer JavaScript and remove unused CSS, then rescan to see the text share move.

All WordPress fixes

Fix it with a coding agent

Paste into Claude Code, Cursor or Codex, opened on the code that serves this site.

Show prompt
You are working in the codebase (or server/CDN configuration) that serves denverpost.com. A crawler audit found the problem below. Fix it at the source, keep the change as small as possible, and do not change anything a visitor sees unless the fix requires it.

Finding: Almost nothing a machine receives from this page is readable text (PAGE_IS_MOSTLY_CODE, medium severity)
Page: https://denverpost.com/
What was measured: 4.4% of 313,548 decompressed bytes is visible text, and the largest single block is inline css at 44,440 bytes
Why it matters: A crawler pays for every byte it fetches and can only quote the text. Under 5% readable content means an answer engine downloads the whole page and comes away with almost nothing it can use — the difference between being quotable and being skipped. The content-ratio row above passes at 20%, so without this a page at 2% and a page at 19% were scored identically.
How to fix it: Move inline CSS and JavaScript into external files, drop unused page-builder styling, and make sure the words a visitor reads are in the HTML itself.
Detected platform: WordPress. Make the change where this platform controls it.
Rule and examples: https://crawlcheck.io/rules/PAGE_IS_MOSTLY_CODE
Full report (markdown): https://crawlcheck.io/r/aasc46z1wv.md

When you are done:
1. Tell me which files or settings you changed and why.
2. If the fix is a server, CDN or cache setting you cannot change from the code, say exactly where it is set.
3. After deploying, re-scan at https://crawlcheck.io/?url=denverpost.com . The fix counts when PAGE_IS_MOSTLY_CODE is gone from the new report.
Why this was decided
RulePAGE_IS_MOSTLY_CODE · rule pack sv34 · scope route
Evaluated2026-11-12 00:17:42 UTC
Decisiond1:8806c4e2633d1bbbfa6d · finding f1:f4babb4a5f2416a1db5f resolve either at /api/graph/<id> with a key
Observercrawlcheck-worker build be1e3120 · audit v4

What it rests on

IdentityStatusBytessha256Kept
read: /200314,053dc318faa4d8fkept

25 more in the manifest.

Artifacts: manifest:4098c6573755bdd21d4644c5f14f0df51d807dbfc2d86dd1a7ffd32afab1005b

Grade effect Caps the letter at C together with 3 other medium-severity findings; the letter rises only when all of them are gone. Moves no points.

Rule PAGE_IS_MOSTLY_CODE under scoring rules v34 · fingerprint PAGE_IS_MOSTLY_CODE|/ · persisting (seen in 46 of 48 readings)

Verify the fix Re-scan after the change. This finding is cleared when PAGE_IS_MOSTLY_CODE is no longer reported at /; if it comes back after clearing, it is marked a regression, not a new finding.

PAGE_IS_MOSTLY_CODE · full transcript

5The sitemap does not say when anything changed9,068 child sitemaps listed, none carrying a lastmod date.LowContentConfirmed

first measured 2026-11-02 · 10 days ago · seen across 11 measured days. A one-off scan cannot produce this line; it comes from the record.

What we saw

9,068 child sitemaps listed, none carrying a lastmod date. /sitemap.xml

Why it matters

The sitemap lists URLs but carries no usable lastmod dates: either none at all, or one date copied onto every URL, which says everything changed at once and so says nothing. Either way it tells a crawler what exists and not what changed. A crawler with a budget uses lastmod to decide what to re-fetch; without it, the choice is made for you — usually by re-crawling little and late. This is the change signal every crawler already understands, and unlike a push protocol it needs no key, no account and no participation from the search engine.

How to fix it

Give each sitemap entry its own <lastmod>: the date that page last changed, not the date the sitemap was built. Then a crawler can prioritise the pages that changed.

Content: words, markup or images on a page — no deploy

On WordPress (detected)

  1. WordPress 5.5 and later serve /wp-sitemap.xml; Yoast and Rank Math replace it with /sitemap_index.xml. Keep exactly one turned on.
  2. Core's wp-sitemap.xml has no lastmod dates; Yoast and Rank Math sitemaps do. If the finding is missing lastmod, use the plugin sitemap.
  3. Add the sitemap's address to robots.txt as Sitemap: https://yourdomain/sitemap_index.xml.

All WordPress fixes

Fix it with a coding agent

Paste into Claude Code, Cursor or Codex, opened on the code that serves this site.

Show prompt
You are working in the codebase (or server/CDN configuration) that serves denverpost.com. A crawler audit found the problem below. Fix it at the source, keep the change as small as possible, and do not change anything a visitor sees unless the fix requires it.

Finding: The sitemap does not say when anything changed (SITEMAP_NO_LASTMOD, low severity)
Page: https://denverpost.com/sitemap.xml
What was measured: 9,068 child sitemaps listed, none carrying a lastmod date.
Why it matters: The sitemap lists URLs but carries no usable lastmod dates: either none at all, or one date copied onto every URL, which says everything changed at once and so says nothing. Either way it tells a crawler what exists and not what changed. A crawler with a budget uses lastmod to decide what to re-fetch; without it, the choice is made for you — usually by re-crawling little and late. This is the change signal every crawler already understands, and unlike a push protocol it needs no key, no account and no participation from the search engine.
How to fix it: Give each sitemap entry its own <lastmod>: the date that page last changed, not the date the sitemap was built. Then a crawler can prioritise the pages that changed.
Detected platform: WordPress. Make the change where this platform controls it.
Rule and examples: https://crawlcheck.io/rules/SITEMAP_NO_LASTMOD
Full report (markdown): https://crawlcheck.io/r/aasc46z1wv.md

When you are done:
1. Tell me which files or settings you changed and why.
2. If the fix is a server, CDN or cache setting you cannot change from the code, say exactly where it is set.
3. After deploying, re-scan at https://crawlcheck.io/?url=denverpost.com . The fix counts when SITEMAP_NO_LASTMOD is gone from the new report.
Why this was decided
RuleSITEMAP_NO_LASTMOD · rule pack sv34 · scope core
Evaluated2026-11-12 00:17:42 UTC
Decisiond1:420a831c2dd3a529022f · finding f1:5fd8b403c90bbad0b784 resolve either at /api/graph/<id> with a key
Observercrawlcheck-worker build be1e3120 · audit v4

What it rests on

IdentityStatusBytessha256Kept
read: /sitemap.xml200888,839493fa919e7c8kept
read: /sitemap_index.xml40495,255fa12fd3cc2a4kept
read: /wp-sitemap.xml200149,638a196f657db40kept

23 more in the manifest.

Artifacts: manifest:4098c6573755bdd21d4644c5f14f0df51d807dbfc2d86dd1a7ffd32afab1005b

Grade effect Does not cap the letter: only medium, high and critical findings do. Moves no points either; the score is built from the measured rows.

Rule SITEMAP_NO_LASTMOD under scoring rules v34 · fingerprint SITEMAP_NO_LASTMOD|/sitemap.xml · persisting (seen in 12 of 48 readings)

Verify the fix Re-scan after the change. This finding is cleared when SITEMAP_NO_LASTMOD is no longer reported at /sitemap.xml; if it comes back after clearing, it is marked a regression, not a new finding.

SITEMAP_NO_LASTMOD · full transcript

6The published coordinates are not in the country the address namesThis page declares latitude 39.7392, longitude 104.9903 beside an address in US (read from addressRegion). negating the longitude puts it inside US - a missing LowConfirmed

first measured 2026-09-10 · 63 days ago · seen across 32 measured days. A one-off scan cannot produce this line; it comes from the record.

What we saw

This page declares latitude 39.7392, longitude 104.9903 beside an address in US (read from addressRegion). negating the longitude puts it inside US - a missing minus sign.

Why it matters

Two facts in the same record disagree about where the business is. Anything that trusts the coordinate over the address is sent to the wrong place, and a range check cannot catch it because the value is a legal longitude. Nobody proofreads a number that never renders on the page.

How to fix it

Read the evidence below, then change what the server sends at that path. Re-scan to confirm: done is measured, not asserted.

On WordPress (detected)

  1. Keep one source of business markup: Rank Math → Titles & Meta → Local SEO, or Yoast Local SEO. Turn off the same block in your theme or any second plugin.
  2. Fill name, address, phone, geo coordinates and opening hours there, matching the Business Profile exactly.

All WordPress fixes

Fix it with a coding agent

Paste into Claude Code, Cursor or Codex, opened on the code that serves this site.

Show prompt
You are working in the codebase (or server/CDN configuration) that serves denverpost.com. A crawler audit found the problem below. Fix it at the source, keep the change as small as possible, and do not change anything a visitor sees unless the fix requires it.

Finding: The published coordinates are not in the country the address names (GEO_COUNTRY_MISMATCH, low severity)
Page: https://denverpost.com/
What was measured: This page declares latitude 39.7392, longitude 104.9903 beside an address in US (read from addressRegion). negating the longitude puts it inside US - a missing minus sign.
Why it matters: Two facts in the same record disagree about where the business is. Anything that trusts the coordinate over the address is sent to the wrong place, and a range check cannot catch it because the value is a legal longitude. Nobody proofreads a number that never renders on the page.
How to fix it: Change what the server sends at that path so the finding no longer applies.
Detected platform: WordPress. Make the change where this platform controls it.
Rule and examples: https://crawlcheck.io/rules/GEO_COUNTRY_MISMATCH
Full report (markdown): https://crawlcheck.io/r/aasc46z1wv.md

When you are done:
1. Tell me which files or settings you changed and why.
2. If the fix is a server, CDN or cache setting you cannot change from the code, say exactly where it is set.
3. After deploying, re-scan at https://crawlcheck.io/?url=denverpost.com . The fix counts when GEO_COUNTRY_MISMATCH is gone from the new report.
Why this was decided
RuleGEO_COUNTRY_MISMATCH · rule pack sv34 · scope route
Evaluated2026-11-12 00:17:42 UTC
Decisiond1:bc85be82189d9d5ab6cb · finding f1:b0dfa22e680744be8515 resolve either at /api/graph/<id> with a key
Observercrawlcheck-worker build be1e3120 · audit v4

What it rests on

IdentityStatusBytessha256Kept
read: /200314,053dc318faa4d8fkept

25 more in the manifest.

Artifacts: manifest:4098c6573755bdd21d4644c5f14f0df51d807dbfc2d86dd1a7ffd32afab1005b

Grade effect Does not cap the letter: only medium, high and critical findings do. Moves no points either; the score is built from the measured rows.

Rule GEO_COUNTRY_MISMATCH under scoring rules v34 · fingerprint GEO_COUNTRY_MISMATCH|/ · persisting (seen in 44 of 48 readings)

Verify the fix Re-scan after the change. This finding is cleared when GEO_COUNTRY_MISMATCH is no longer reported at /; if it comes back after clearing, it is marked a regression, not a new finding.

GEO_COUNTRY_MISMATCH · full transcript

7The homepage is reached through a chain of redirectshttp://denverpost.com/ takes 2 redirects to reach the page: 301 permanent (http→https) → 301 permanent (apex→www) → https://www.denverpost.com/ (200). Point theNoteSettingConfirmed

first measured 2026-10-17 · 26 days ago · seen across 25 measured days. A one-off scan cannot produce this line; it comes from the record.

What we saw

http://denverpost.com/ takes 2 redirects to reach the page: 301 permanent (http→https) → 301 permanent (apex→www) → https://www.denverpost.com/ (200). Point the first redirect straight at the final address.

Why it matters

Reaching the homepage takes more than one redirect, for example http to https and then the domain to www. Each hop is another request and round trip before a crawler or visitor gets the page, temporary hops (302, 307) tell search engines to keep the old address, and Google stops following after ten.

How to fix it

Send every old address straight to the final one in a single permanent (301 or 308) redirect: in the host, CDN or plugin rules, redirect http://domain and http://www straight to the final https address instead of chaining scheme, host and path fixes.

Setting: a setting on the server, CDN, DNS or a plugin — no code and no writing

Fix it with a coding agent

Paste into Claude Code, Cursor or Codex, opened on the code that serves this site.

Show prompt
You are working in the codebase (or server/CDN configuration) that serves denverpost.com. A crawler audit found the problem below. Fix it at the source, keep the change as small as possible, and do not change anything a visitor sees unless the fix requires it.

Finding: The homepage is reached through a chain of redirects (REDIRECT_CHAIN, note severity)
Page: https://denverpost.com/
What was measured: http://denverpost.com/ takes 2 redirects to reach the page: 301 permanent (http→https) → 301 permanent (apex→www) → https://www.denverpost.com/ (200). Point the first redirect straight at the final address.
Why it matters: Reaching the homepage takes more than one redirect, for example http to https and then the domain to www. Each hop is another request and round trip before a crawler or visitor gets the page, temporary hops (302, 307) tell search engines to keep the old address, and Google stops following after ten.
How to fix it: Send every old address straight to the final one in a single permanent (301 or 308) redirect: in the host, CDN or plugin rules, redirect http://domain and http://www straight to the final https address instead of chaining scheme, host and path fixes.
Detected platform: WordPress. Make the change where this platform controls it.
Rule and examples: https://crawlcheck.io/rules/REDIRECT_CHAIN
Full report (markdown): https://crawlcheck.io/r/aasc46z1wv.md

When you are done:
1. Tell me which files or settings you changed and why.
2. If the fix is a server, CDN or cache setting you cannot change from the code, say exactly where it is set.
3. After deploying, re-scan at https://crawlcheck.io/?url=denverpost.com . The fix counts when REDIRECT_CHAIN is gone from the new report.
Why this was decided
RuleREDIRECT_CHAIN · rule pack sv34 · scope core
Evaluated2026-11-12 00:17:42 UTC
Decisiond1:2f32d4adef799b7fec66 · finding f1:3abe957dbaa63d85090d resolve either at /api/graph/<id> with a key
Observercrawlcheck-worker build be1e3120 · audit v4

What it rests on

IdentityStatusBytessha256Kept
crawlcheck200314,053dc318faa4d8fkept
anon200314,05311ba378b340dkept
gptbot200314,05311ba378b340dkept
claudebot200314,053f767f94a20bbkept
oaisearch200314,053f767f94a20bbkept
claudesearch200314,05311ba378b340dkept
perplexity200314,053f767f94a20bbkept
chatgpt_user200314,053f767f94a20bbkept

18 more in the manifest.

Artifacts: manifest:4098c6573755bdd21d4644c5f14f0df51d807dbfc2d86dd1a7ffd32afab1005b

Grade effect Does not cap the letter: only medium, high and critical findings do. Moves no points either; the score is built from the measured rows.

Rule REDIRECT_CHAIN under scoring rules v34 · fingerprint REDIRECT_CHAIN|/ · persisting (seen in 32 of 48 readings)

Verify the fix Re-scan after the change. This finding is cleared when REDIRECT_CHAIN is no longer reported at /; if it comes back after clearing, it is marked a regression, not a new finding.

REDIRECT_CHAIN · full transcript

8No llms.txtNot present: /llms.txt answered HTTP 404.NoteContentConfirmed

first measured 2026-08-20 · 84 days ago · seen across 33 measured days. A one-off scan cannot produce this line; it comes from the record.

What we saw

Not present: /llms.txt answered HTTP 404. /llms.txt

Why it matters

Not a defect. llms.txt is an emerging convention for telling AI systems what a site is and which pages matter.

How to fix it

Publish /llms.txt: a short Markdown file naming the business, what it does, and the pages worth reading, served as text/plain or text/markdown.

Content: words, markup or images on a page — no deploy

On WordPress (detected)

  1. Upload llms.txt to the site root, the folder with wp-config.php, through your host's file manager or SFTP.
  2. Recent versions of Yoast SEO and Rank Math can generate llms.txt for you; use one source only.

All WordPress fixes

Fix it with a coding agent

Paste into Claude Code, Cursor or Codex, opened on the code that serves this site.

Show prompt
You are working in the codebase (or server/CDN configuration) that serves denverpost.com. A crawler audit found the problem below. Fix it at the source, keep the change as small as possible, and do not change anything a visitor sees unless the fix requires it.

Finding: No llms.txt (NO_LLMS_TXT, note severity)
Page: https://denverpost.com/llms.txt
What was measured: Not present: /llms.txt answered HTTP 404.
Why it matters: Not a defect. llms.txt is an emerging convention for telling AI systems what a site is and which pages matter.
How to fix it: Publish /llms.txt: a short Markdown file naming the business, what it does, and the pages worth reading, served as text/plain or text/markdown.
Detected platform: WordPress. Make the change where this platform controls it.
Rule and examples: https://crawlcheck.io/rules/NO_LLMS_TXT
Full report (markdown): https://crawlcheck.io/r/aasc46z1wv.md

When you are done:
1. Tell me which files or settings you changed and why.
2. If the fix is a server, CDN or cache setting you cannot change from the code, say exactly where it is set.
3. After deploying, re-scan at https://crawlcheck.io/?url=denverpost.com . The fix counts when NO_LLMS_TXT is gone from the new report.
Why this was decided
RuleNO_LLMS_TXT · rule pack sv34 · scope core
Evaluated2026-11-12 00:17:42 UTC
Decisiond1:96370b3cdefe4d1232ae · finding f1:02b589098746b639fa40 resolve either at /api/graph/<id> with a key
Observercrawlcheck-worker build be1e3120 · audit v4

What it rests on

IdentityStatusBytessha256Kept
read: /llms.txt40495,2303557f1559e46kept

25 more in the manifest.

Artifacts: manifest:4098c6573755bdd21d4644c5f14f0df51d807dbfc2d86dd1a7ffd32afab1005b

Grade effect Does not cap the letter: only medium, high and critical findings do. Moves no points either; the score is built from the measured rows.

Rule NO_LLMS_TXT under scoring rules v34 · fingerprint NO_LLMS_TXT|/llms.txt · persisting (seen in 48 of 48 readings)

Verify the fix Re-scan after the change. This finding is cleared when NO_LLMS_TXT is no longer reported at /llms.txt; if it comes back after clearing, it is marked a regression, not a new finding.

NO_LLMS_TXT · full transcript

9The machine files cost more than the pageThe machine files a crawler reads before the page total 893,406 bytes, 2.84x the homepage HTML (314,053 B); the heaviest are /sitemap.xml 888,839 B, /robots.txtNoteConfirmed

first measured 2026-09-16 · 57 days ago · seen across 31 measured days. A one-off scan cannot produce this line; it comes from the record.

What we saw

The machine files a crawler reads before the page total 893,406 bytes, 2.84x the homepage HTML (314,053 B); the heaviest are /sitemap.xml 888,839 B, /robots.txt 4,567 B. An absent agent file answers 404 with 95,281 bytes of HTML on average (/agents.md, /.well-known/agent-skills/index.json, /.well-known/mcp/server-card.json, /.well-known/api-catalog, /.well-known/media-kit.json) - a crawler probing for a file that is not there pays for a page each time; a short 404 body costs nothing to serve.

Why it matters

A crawler reads robots.txt, the sitemap, llms.txt and the agent files before the first page, and pays for every 404 that answers with a full page. Keep machine files as small as their job allows and serve absent paths with a short 404 body.

How to fix it

Read the evidence below, then change what the server sends at that path. Re-scan to confirm: done is measured, not asserted.

Fix it with a coding agent

Paste into Claude Code, Cursor or Codex, opened on the code that serves this site.

Show prompt
You are working in the codebase (or server/CDN configuration) that serves denverpost.com. A crawler audit found the problem below. Fix it at the source, keep the change as small as possible, and do not change anything a visitor sees unless the fix requires it.

Finding: The machine files cost more than the page (MACHINE_CHAIN_HEAVY, note severity)
Page: https://denverpost.com/
What was measured: The machine files a crawler reads before the page total 893,406 bytes, 2.84x the homepage HTML (314,053 B); the heaviest are /sitemap.xml 888,839 B, /robots.txt 4,567 B. An absent agent file answers 404 with 95,281 bytes of HTML on average (/agents.md, /.well-known/agent-skills/index.json, /.well-known/mcp/server-card.json, /.well-known/api-catalog, /.well-known/media-kit.json) - a crawler probing for a file that is not there pays for a page each time; a short 404 body costs nothing to serve.
Why it matters: A crawler reads robots.txt, the sitemap, llms.txt and the agent files before the first page, and pays for every 404 that answers with a full page. Keep machine files as small as their job allows and serve absent paths with a short 404 body.
How to fix it: Change what the server sends at that path so the finding no longer applies.
Detected platform: WordPress. Make the change where this platform controls it.
Rule and examples: https://crawlcheck.io/rules/MACHINE_CHAIN_HEAVY
Full report (markdown): https://crawlcheck.io/r/aasc46z1wv.md

When you are done:
1. Tell me which files or settings you changed and why.
2. If the fix is a server, CDN or cache setting you cannot change from the code, say exactly where it is set.
3. After deploying, re-scan at https://crawlcheck.io/?url=denverpost.com . The fix counts when MACHINE_CHAIN_HEAVY is gone from the new report.
Why this was decided
RuleMACHINE_CHAIN_HEAVY · rule pack sv34 · scope route
Evaluated2026-11-12 00:17:42 UTC
Decisiond1:4f4e7a2abd2e28f069d3 · finding f1:5f60febd53b8621e833e resolve either at /api/graph/<id> with a key
Observercrawlcheck-worker build be1e3120 · audit v4

What it rests on

IdentityStatusBytessha256Kept
read: /200314,053dc318faa4d8fkept
read: /robots.txt2004,567ff800a4d427dalready_held
read: /sitemap.xml200888,839493fa919e7c8kept
read: /sitemap_index.xml40495,255fa12fd3cc2a4kept
read: /wp-sitemap.xml200149,638a196f657db40kept
read: /llms.txt40495,2303557f1559e46kept

20 more in the manifest.

Artifacts: manifest:4098c6573755bdd21d4644c5f14f0df51d807dbfc2d86dd1a7ffd32afab1005b

Grade effect Does not cap the letter: only medium, high and critical findings do. Moves no points either; the score is built from the measured rows.

Rule MACHINE_CHAIN_HEAVY under scoring rules v34 · fingerprint MACHINE_CHAIN_HEAVY|/ · persisting (seen in 42 of 48 readings)

Verify the fix Re-scan after the change. This finding is cleared when MACHINE_CHAIN_HEAVY is no longer reported at /; if it comes back after clearing, it is marked a regression, not a new finding.

MACHINE_CHAIN_HEAVY · full transcript

10Private files or live keys are readable by anyone (advisory: not in the grade yet)Readable by anyone: Private key private key block in /wp-content/plugins/mng-digisubs/static/mng-digisubs.shared.bundle.js.NoteSettingConfirmed

first measured 2026-10-23 · 20 days ago · seen across 21 measured days. A one-off scan cannot produce this line; it comes from the record.

What we saw

Readable by anyone: Private key private key block in /wp-content/plugins/mng-digisubs/static/mng-digisubs.shared.bundle.js.

Why it matters

A file the site should never serve (a .git or .svn folder, a .env file, a config backup) answered with its own contents, or a live API key or private key is written into the homepage or the site's own scripts. Anyone who requests the same address gets the same bytes: database passwords, keys and source history are the first things an attacker tries. Each path was requested once and counts only when it answers with the file itself, never with a page.

How to fix it

Deny the listed paths at the server (or delete the files), then treat every password and key they contained as public: change the passwords and revoke and reissue each key shown. Remove keys from page code and scripts; a key a browser needs must be a publishable one.

Setting: a setting on the server, CDN, DNS or a plugin — no code and no writing

Fix it with a coding agent

Paste into Claude Code, Cursor or Codex, opened on the code that serves this site.

Show prompt
You are working in the codebase (or server/CDN configuration) that serves denverpost.com. A crawler audit found the problem below. Fix it at the source, keep the change as small as possible, and do not change anything a visitor sees unless the fix requires it.

Finding: Private files or live keys are readable by anyone (advisory: not in the grade yet) (SECRETS_EXPOSED, note severity)
Page: https://denverpost.com/
What was measured: Readable by anyone: Private key private key block in /wp-content/plugins/mng-digisubs/static/mng-digisubs.shared.bundle.js.
Why it matters: A file the site should never serve (a .git or .svn folder, a .env file, a config backup) answered with its own contents, or a live API key or private key is written into the homepage or the site's own scripts. Anyone who requests the same address gets the same bytes: database passwords, keys and source history are the first things an attacker tries. Each path was requested once and counts only when it answers with the file itself, never with a page.
How to fix it: Deny the listed paths at the server (or delete the files), then treat every password and key they contained as public: change the passwords and revoke and reissue each key shown. Remove keys from page code and scripts; a key a browser needs must be a publishable one.
Detected platform: WordPress. Make the change where this platform controls it.
Rule and examples: https://crawlcheck.io/rules/SECRETS_EXPOSED
Full report (markdown): https://crawlcheck.io/r/aasc46z1wv.md

When you are done:
1. Tell me which files or settings you changed and why.
2. If the fix is a server, CDN or cache setting you cannot change from the code, say exactly where it is set.
3. After deploying, re-scan at https://crawlcheck.io/?url=denverpost.com . The fix counts when SECRETS_EXPOSED is gone from the new report.
Why this was decided
RuleSECRETS_EXPOSED · rule pack sv34 · scope route
Evaluated2026-11-12 00:17:42 UTC
Decisiond1:9599a37e711454cc558e · finding f1:c0bbe1fe7368708f3f38 resolve either at /api/graph/<id> with a key
Observercrawlcheck-worker build be1e3120 · audit v4

What it rests on

IdentityStatusBytessha256Kept
read: /200314,053dc318faa4d8fkept

25 more in the manifest.

Artifacts: manifest:4098c6573755bdd21d4644c5f14f0df51d807dbfc2d86dd1a7ffd32afab1005b

Grade effect Does not cap the letter: only medium, high and critical findings do. Moves no points either; the score is built from the measured rows.

Rule SECRETS_EXPOSED under scoring rules v34 · fingerprint SECRETS_EXPOSED|/ · persisting (seen in 24 of 48 readings)

Verify the fix Re-scan after the change. This finding is cleared when SECRETS_EXPOSED is no longer reported at /; if it comes back after clearing, it is marked a regression, not a new finding.

SECRETS_EXPOSED · full transcript

114 off-site listings carry this phone number and the site never links themSearched YellowPages, DexKnows, BBB by (303) 954-1010. A listing the site does not declare is one an engine corroborates without you: whatever it prints becomesNoteConfirmed

first measured 2026-09-10 · 63 days ago · seen across 32 measured days. A one-off scan cannot produce this line; it comes from the record.

What we saw

Searched YellowPages, DexKnows, BBB by (303) 954-1010. A listing the site does not declare is one an engine corroborates without you: whatever it prints becomes your name, hours and category in the answer.

Why it matters

Declare the ones you own in sameAs so the entity graph and the directory agree, and correct or claim the ones you do not.

How to fix it

Read the evidence below, then change what the server sends at that path. Re-scan to confirm: done is measured, not asserted.

On WordPress (detected)

  1. Keep one source of business markup: Rank Math → Titles & Meta → Local SEO, or Yoast Local SEO. Turn off the same block in your theme or any second plugin.
  2. Fill name, address, phone, geo coordinates and opening hours there, matching the Business Profile exactly.

All WordPress fixes

Fix it with a coding agent

Paste into Claude Code, Cursor or Codex, opened on the code that serves this site.

Show prompt
You are working in the codebase (or server/CDN configuration) that serves denverpost.com. A crawler audit found the problem below. Fix it at the source, keep the change as small as possible, and do not change anything a visitor sees unless the fix requires it.

Finding: 4 off-site listings carry this phone number and the site never links them (NAP_UNDECLARED_LISTING, note severity)
Page: https://denverpost.com/
What was measured: Searched YellowPages, DexKnows, BBB by (303) 954-1010. A listing the site does not declare is one an engine corroborates without you: whatever it prints becomes your name, hours and category in the answer.
Why it matters: Declare the ones you own in sameAs so the entity graph and the directory agree, and correct or claim the ones you do not.
How to fix it: Change what the server sends at that path so the finding no longer applies.
Detected platform: WordPress. Make the change where this platform controls it.
Rule and examples: https://crawlcheck.io/rules/NAP_UNDECLARED_LISTING
Full report (markdown): https://crawlcheck.io/r/aasc46z1wv.md

When you are done:
1. Tell me which files or settings you changed and why.
2. If the fix is a server, CDN or cache setting you cannot change from the code, say exactly where it is set.
3. After deploying, re-scan at https://crawlcheck.io/?url=denverpost.com . The fix counts when NAP_UNDECLARED_LISTING is gone from the new report.
Why this was decided
RuleNAP_UNDECLARED_LISTING · rule pack sv34 · scope route
Evaluated2026-11-12 00:17:42 UTC
Decisiond1:32f4282bbaa449ec4fbb · finding f1:a3b71814478a0c1117bf resolve either at /api/graph/<id> with a key
Observercrawlcheck-worker build be1e3120 · audit v4

What it rests on

IdentityStatusBytessha256Kept
read: /200314,053dc318faa4d8fkept

25 more in the manifest.

Where each value was read

FieldValueRead from
nameThe Denver PostJSON-LD LocalBusiness
phone+13039541010JSON-LD LocalBusiness
address5990 Washington St., Denver, CO, 80216JSON-LD LocalBusiness
hoursMo 8AM-4PM; Tu 8AM-4PM; We 8AM-4PM; Th 8AM-4PM; Fr 8AM-4PMJSON-LD LocalBusiness

Artifacts: manifest:4098c6573755bdd21d4644c5f14f0df51d807dbfc2d86dd1a7ffd32afab1005b

Grade effect Does not cap the letter: only medium, high and critical findings do. Moves no points either; the score is built from the measured rows.

Rule NAP_UNDECLARED_LISTING under scoring rules v34 · fingerprint NAP_UNDECLARED_LISTING|/ · persisting (seen in 45 of 48 readings)

Verify the fix Re-scan after the change. This finding is cleared when NAP_UNDECLARED_LISTING is no longer reported at /; if it comes back after clearing, it is marked a regression, not a new finding.

NAP_UNDECLARED_LISTING · full transcript

Headroom +19 points if every row passes

Nothing here is broken. Each row is a measure that currently fails its optimal range, and what fixing it is worth to the score.

+2Answer engines allowednow 7 of 17 · Crawler permissions+2Search indexes allowednow 17 of 24 · Crawler permissions+2Lead paragraph defines the subjectnow does not name it, no defining verb · Quotable content+2Edge / CDNnow none detected · Server & hosting+1A named person is declarednow none · Authors & trust signals+1About page linked from the homepagenow no · Authors & trust signals+1Content rationow 4.4% · Page weight & text+1Cost of a missnow 3 missing file(s) return >20KB of HTML · Machine files+1Deferred vs blocking scriptsnow 2 deferred / 17 blocking · Page weight & text+1Inline JavaScriptnow 43,837B · Page weight & text+1Organization declares who runs itnow 0 of 2 · Authors & trust signals+1Render-blocking resourcesnow 27 · Page weight & text+1Stated robots policy matches actual behaviournow OAI-SearchBot: disallowed but served, Claude-SearchBot: disallowed but served, PerplexityBot: disallowed but served, ChatGPT-User: disallowed but served, Claude-User: disallowed but served, Perplexity-User: disallowed but served, Applebot: disallowed but served · What each crawler gets+1entitymap.jsonnow absent (404) · Machine files+1Credential edgesnow 0 · Structured data+1Cumulative Layout Shift (p75)now 0.13 · Speed+1Declared phone is written on the pagenow no · Local presence & NAP+1Found off-site, not declared in sameAsnow 4 — which ones, with a licence · Local presence & NAP+1H1 countnow 2 · Structured data+1Keys or secrets in page codenow Private key private key block in /wp-content/plugins/mng-digisubs/static/mng-digisubs.shared.bundle.js · Exposed files and secrets+1Lab Cumulative Layout Shiftnow 0.193 · Speed+1Lab LCP — synthetic, not field datanow 19.14s · Speed+1Lab Total Blocking Timenow 1.86s · Speed+1Largest Contentful Paint (p75)now 3.52s · Speed+1Stable @id coveragenow 33.3% · Structured data+1Title width in search resultsnow 765 px — shows as “The Denver Post – Colorado breaking news, sports, business, ...” · Structured data+1Trailing slashnow 1 target linked both with and without a slash (/contact-us) · URL naming+1Width and height declarednow 0 of 44 · Image signals+1sameAs pointing at a placenow 1 · Structured data+0Business phone on the pagenow none found · Trust and reputation+0CAA (who may issue certificates)now none · Site safety+0Clickjacking protection (framing)now not set · Site safety+0DNSSECnow not signed · Site safety+0Form controls have a namenow 1 of 2 (missing: checkbox) · Accessibility structure+0MIME-sniffing protection (nosniff)now not set · Site safety+0Outside files that hold the page until they loadnow 7: cmp.osano.com, ajax.googleapis.com, accounts.google.com, prodmg2.blob.core.windows.net, … · Third-party dependencies+0Outside services the page loadsnow 18 hosts: tracking 1, forms and widgets 1, fonts 1, code library (CDN) 2, consent 1, other 12 · Third-party dependencies+0Phone number in the textnow not in the text (+13039541010 is in a link or markup only) · What AI looks for+0Prices in the markupnow none · Price transparency+0Regression tests from this site's own fixesnow 3 fixed problems re-checked on every scan · 2 holding · 1 came back · Site safety+0Third-party scripts and stylesnow 18 from 17 outside hosts, 0 pinned with integrity= · Site safety

Watch this domain

Twice-daily scans, the date each finding first appeared, and a change receipt when something moves. Free for 30 days, no card.

Start watching denverpost.com

Get this fixed for you

Every finding above fixed on your site, then re-measured — done is measured, not asserted. One-time, $100 for one local-business site.

Get this fixed — $100

What that covers

More detail — headroom arithmetic, priorities and clusters

Optimisation headroom

81 now → 100 with the 41 failing measure(s) fixed — a gain of 19 points. Each number below is what the score would read with that one row passing, minus what it reads now: the same formula rerun, not a forecast. They do not add up, because the score is held at Reach + 15 and rounded. The LETTER is separately capped at C by finding severity, so clearing that finding lifts the grade independently of the score. 166 measure(s) could not be measured; they are excluded, not counted against the site, and are not headroom.

A short set that reaches B or better: clear ROBOTS_RULES_SHADOWED, ENTITY_COLLISION, RENDER_RESOURCE_BLOCKED, PAGE_IS_MOSTLY_CODE → B, score 81. Each step is the formula rerun after the previous one, not a sum.

Fix thisSectionCurrentlyPoints
Answer engines allowedAI and search agents7 of 17+2
Search indexes allowedAI and search agents17 of 24+2
Lead paragraph defines the subjectQuotable contentdoes not name it, no defining verb+2
Edge / CDNServer and hostingnone detected+2
A named person is declaredAuthorship and trust signals (E-E-A-T proxies)none+1
About page linked from the homepageAuthorship and trust signals (E-E-A-T proxies)no+1
Content ratioPayload and render path4.4%+1
Cost of a missMachine layer3 missing file(s) return >20KB of HTML+1
Deferred vs blocking scriptsPayload and render path2 deferred / 17 blocking+1
Inline JavaScriptPayload and render path43,837B+1
Organization declares who runs itAuthorship and trust signals (E-E-A-T proxies)0 of 2+1
Render-blocking resourcesPayload and render path27+1
Stated robots policy matches actual behaviourWhat each agent receivesOAI-SearchBot: disallowed but served, Claude-SearchBot: disallowed but served, PerplexityBot: disallowed but served, ChatGPT-User: disallowed but served, Claude-User: disallowed but served, Perplexity-User: disallowed but served, Applebot: disallowed but served+1
entitymap.jsonMachine layerabsent (404)+1
Credential edgesSchema and entity graph0+1
Cumulative Layout Shift (p75)Speed a crawler sees, and field data where it exists0.13+1
Declared phone is written on the pageLocal presence, citations and NAPno+1
Found off-site, not declared in sameAsLocal presence, citations and NAP4 — which ones, with a licence+1
H1 countSchema and entity graph2+1
Keys or secrets in page codeExposed files and secretsPrivate key private key block in /wp-content/plugins/mng-digisubs/static/mng-digisubs.shared.bundle.js+1
Lab Cumulative Layout ShiftSpeed a crawler sees, and field data where it exists0.193+1
Lab LCP — synthetic, not field dataSpeed a crawler sees, and field data where it exists19.14s+1
Lab Total Blocking TimeSpeed a crawler sees, and field data where it exists1.86s+1
Largest Contentful Paint (p75)Speed a crawler sees, and field data where it exists3.52s+1
Stable @id coverageSchema and entity graph33.3%+1
Title width in search resultsSchema and entity graph765 px — shows as “The Denver Post – Colorado breaking news, sports, business, ...”+1
Trailing slashNaming and case consistency1 target linked both with and without a slash (/contact-us)+1
Width and height declaredImage signals0 of 44+1
sameAs pointing at a placeSchema and entity graph1+1
Business phone on the page
measured, not in the grade
Trust and reputation (measured, not scored)none found+0
CAA (who may issue certificates)
measured, not in the grade
Site safety (measured, not scored)none+0
Clickjacking protection (framing)
measured, not in the grade
Site safety (measured, not scored)not set+0
DNSSEC
measured, not in the grade
Site safety (measured, not scored)not signed+0
Form controls have a name
too small to move the rounded score on its own
Accessibility structure (from the delivered HTML)1 of 2 (missing: checkbox)+0
MIME-sniffing protection (nosniff)
measured, not in the grade
Site safety (measured, not scored)not set+0
Outside files that hold the page until they load
measured, not in the grade
Third-party dependencies (measured, not scored)7: cmp.osano.com, ajax.googleapis.com, accounts.google.com, prodmg2.blob.core.windows.net, …+0
Outside services the page loads
measured, not in the grade
Third-party dependencies (measured, not scored)18 hosts: tracking 1, forms and widgets 1, fonts 1, code library (CDN) 2, consent 1, other 12+0
Phone number in the text
measured, not in the grade
What AI looks for vs what your page shows (measured, not scored)not in the text (+13039541010 is in a link or markup only)+0
Prices in the markup
measured, not in the grade
Price transparency (measured, not scored)none+0
Regression tests from this site's own fixes
measured, not in the grade
Site safety (measured, not scored)3 fixed problems re-checked on every scan · 2 holding · 1 came back+0
Third-party scripts and styles
measured, not in the grade
Site safety (measured, not scored)18 from 17 outside hosts, 0 pinned with integrity=+0

What to fix first

Ordered by contextual priority, not by severity alone. Two findings of the same severity are not equally urgent — one that breaks a file every agent reads before anything else outranks one on a single page. Every multiplier below is derived from this scan and shown with the reason it applied.

11.8

The homepage depends on files this site's own robots.txt disallows

/robots.txt · severity 3

Prerequisite impact×1.5/robots.txt is a discovery prerequisite - agents read it before anything else
Scope×1.52 of 16 named crawler identities affected
Persistence×1.75open for 63 days, first seen 2026-09-10
Confidence×1the bytes behind this finding are attached to it

7.9

robots.txt rules do not apply to named agents

/robots.txt · severity 3

Prerequisite impact×1.5/robots.txt is a discovery prerequisite - agents read it before anything else
Scope×1not an access-class finding - scope not multiplied
Persistence×1.75open for 63 days, first seen 2026-09-10
Confidence×1the bytes behind this finding are attached to it

5.8

Two business records on this page claim the same identity

/ · severity 3

Prerequisite impact×1.1affects the homepage
Scope×1not an access-class finding - scope not multiplied
Persistence×1.75open for 84 days, first seen 2026-08-20
Confidence×1the bytes behind this finding are attached to it

5.8

Almost nothing a machine receives from this page is readable text

/ · severity 3

Prerequisite impact×1.1affects the homepage
Scope×1not an access-class finding - scope not multiplied
Persistence×1.75fixed once and returned (1x) - this is a regression, not a new finding
Confidence×1the bytes behind this finding are attached to it

3.9

The published coordinates are not in the country the address names

/ · severity 2

Prerequisite impact×1.1affects the homepage
Scope×1not an access-class finding - scope not multiplied
Persistence×1.75open for 63 days, first seen 2026-09-10
Confidence×1the bytes behind this finding are attached to it

3.8

The sitemap does not say when anything changed

/sitemap.xml · severity 2

Prerequisite impact×1.5/sitemap.xml is a discovery prerequisite - agents read it before anything else
Scope×1not an access-class finding - scope not multiplied
Persistence×1.25confirmed on 12 scans of this domain since 2026-11-02
Confidence×1the bytes behind this finding are attached to it

2.6

No llms.txt

/llms.txt · severity 1

Prerequisite impact×1.5/llms.txt is a discovery prerequisite - agents read it before anything else
Scope×1not an access-class finding - scope not multiplied
Persistence×1.75open for 84 days, first seen 2026-08-20
Confidence×1the bytes behind this finding are attached to it

1.9

The machine files cost more than the page

/ · severity 1

Prerequisite impact×1.1affects the homepage
Scope×1not an access-class finding - scope not multiplied
Persistence×1.75open for 57 days, first seen 2026-09-16
Confidence×1the bytes behind this finding are attached to it

1.9

4 off-site listings carry this phone number and the site never links them

/ · severity 1

Prerequisite impact×1.1affects the homepage
Scope×1not an access-class finding - scope not multiplied
Persistence×1.75open for 63 days, first seen 2026-09-10
Confidence×1the bytes behind this finding are attached to it

1.4

The homepage is reached through a chain of redirects

/ · severity 1

Prerequisite impact×1.1affects the homepage
Scope×1not an access-class finding - scope not multiplied
Persistence×1.25confirmed on 32 scans of this domain since 2026-10-17
Confidence×1the bytes behind this finding are attached to it

1.4

Private files or live keys are readable by anyone (advisory: not in the grade yet)

/ · severity 1

Prerequisite impact×1.1affects the homepage
Scope×1not an access-class finding - scope not multiplied
Persistence×1.25confirmed on 24 scans of this domain since 2026-10-23
Confidence×1the bytes behind this finding are attached to it

Priority = severity × prerequisite impact × scope × persistence × confidence. A factor the record cannot support stays at ×1 rather than being guessed upward.

These findings share a cause

Findings are symptoms. Where two or more point at one underlying cause, they are grouped here — fixing the cause closes all of them. A single finding is never presented as a cluster, because one symptom does not establish a diagnosis.

The site's own robots.txt withholds what its pages need

ROBOTS_RULES_SHADOWED RENDER_RESOURCE_BLOCKED · highest priority in group 11.8

Disallow rules in the site's own robots.txt cover paths its pages depend on: a stylesheet or script a rendering crawler needs, or the images and product pages that image and shopping crawlers read. Each crawler obeys the rule for its group, so the page is drawn or indexed without them.

What to check: Allow the paths the pages reference (assets, image folders, product pages) in the group each crawler follows, or move them out of the disallowed directory.

Every finding also appears on its own below, with its full evidence. Grouping changes the order of work, not the record.

What each crawler was served

18 requests for the same URL, from one CrawlCheck address, at 2026-11-12 00:17 UTC: each named crawler, a mobile browser and an unnamed client. Robots.txt is what the site asks for; the status and word count are what its server actually sent.

Requested asRobots.txtServer sentWordsSame as browser
Unnamed client (control)—2002,099100%baseline
GPTBotdisallowed2002,099100%disallowed but served
ClaudeBotdisallowed2002,099100%disallowed but served
OAI-SearchBotdisallowed2002,099100%disallowed but served
Claude-SearchBotdisallowed2002,099100%disallowed but served
PerplexityBotdisallowed2002,099100%disallowed but served
ChatGPT-Userdisallowed2002,099100%disallowed but served
Claude-Userdisallowed2002,099100%disallowed but served
Perplexity-Userdisallowed2002,099100%disallowed but served
Googlebotallowed2002,099100%same page
Googlebot Smartphonenot listed2002,099100%same page
Mobile browser (control)—2002,099100%baseline
Bingbotallowed2002,099100%same page
Applebotdisallowed2002,099100%disallowed but served
Amazonbotdisallowed2002,099100%disallowed but served
Bytespiderdisallowed4299—blocked by the server
Meta-ExternalAgentdisallowed4035—blocked by the server
CCBotdisallowed2002,099100%disallowed but served

19

passing

7

need work

7

failing

8

information only

Sections, not individual checks: 41 in all, 33 scored. A scored section that could not be read is counted separately and never as a pass; information-only sections are measured and never scored.

Which crawlers are let in

74 of 115 named crawlers are allowed by robots.txt at /; 41 are disallowed. Robots.txt is a request; the edge decides. Where this scan also fetched the page as that crawler, the chip says what the edge did.

Answer engines 7/17 allowed

The crawlers behind ChatGPT, Claude, Perplexity and Google’s AI answers, and the fetchers that read a page live when a person asks (ChatGPT-User, Claude-User, Perplexity-User)

✗ChatGPT search indexA✗ChatGPT live fetchA✗Claude search index✗Claude live fetchA✗Perplexity indexD✗Perplexity live fetch✓Gemini research agent✗Le Chat live fetch✗DuckDuckGo AI assist✗You.com✓Phind✓Kagi✓Microsoft Copilot fetch✗Meta AI live fetch✓Amazon live fetch for Alexa questions✓Google user-triggered agent, acts on the webA✓Gemini Notebook user-supplied URL fetch

Search engines 17/24 allowed

Google, Bing, Apple and the rest of classic search

✓Google image crawler✓Google News✓Google video crawler✓Google Shopping✓Google AdSense✓Google push delivery✓Bing page preview✓Microsoft legacy crawler✗Yahoo Slurp✓Yandex (umbrella token)✓Coc Coc✓Google Search and AI OverviewsA✓Bing and Copilot indexD✗Apple and SiriD✗AmazonD✓DuckDuckGoB✗YandexA✗BaiduB✓SeznamA✓Neeva✗Huawei Petal✗Amazon search eligibility, separate from Amazonbot✓Mistral search index for Vibe✓Exa AI search index, Web Bot Auth signed

Training crawlers 22/46 allowed

Collect pages to train models. Blocking these while allowing answer engines is coherent policy, not a defect

Show all 46
✓Magpie AI✓img2dataset image corpus✓Awario RSS✓Awario smart✓Turnitin✗Internet Archive✓Internet Archive (legacy)✗Meta web index✗Webz.io omgili✗Cohere training corpus✗Huawei PanGu✗Allen Institute Dolma✓FriendlyCrawler ML✗Velen✓MyCentral AI✓DeepSeek✗NICT ICC✓Google non-search fetchA✓Vertex AI agent build✗OpenAI training and indexB✗Anthropic trainingD✗Anthropic legacy agent✗Anthropic legacy agent✗Gemini training and grounding✗Apple training✗Common CrawlA✗ByteDance✗Meta AI training✗Meta legacy✓Cohere✗Diffbot knowledge graph✗Webz.io✓Imagesift✗Timpi✗Allen Institute✓Generic scraper framework✓Semrush AI corpus✗Apple ads corpus✓TikTok✓QuillBot✗Webz.io extended✓ProRata✓Awario✓Mistral training crawl✓Google common crawler, public image URLs✓Google common crawler, public video URLs

Opt-out record: the date each crawler was closed or opened here, from every reading on record, each with sealed proof.

The letter beside a crawler is its conduct grade: how that crawler really behaved, from requests verified against its operator’s published addresses. A read the rules and obeyed them; F reached a path the rules forbid.

Some named groups declare no rules of their own, which means “allow everything” for that crawler regardless of the general rules. Those chips are marked.

Where the refusal happens

2 identities were refused from CrawlCheck’s network.

IdentityFrom CrawlCheck’s networkFrom a person’s own connectionWhere
Bytespiderthrottled (HTTP 429)not readnot named by the refusal
Meta-ExternalAgentrefused HTTP 403not readnot named by the refusal

The right-hand column is the one measurement this server cannot make: whether the same request is served from a home or office connection. The free CrawlCheck extension fills it: install it, open denverpost.com and press Two vantages; the next report shows the result for 14 days.

Site owner? One skip rule tells a refusal in front of the server from one on the server itself. Full comparison: Agent lens.

How crawlers move through this site

5 of 18 identities reach the page. 11 are turned away by the site’s own robots rules — a policy, not a fault. 2 are refused at the edge before any rule applies, for a request carrying the name from our address — an edge that admits crawlers by their published IP ranges may still let the real one through. Missing: entitymap.json, llms.txt. Of the 15 others that got through, 1 received exactly the browser’s bytes, 14 the same text in different bytes.

WHO ASKEDEDGEFILES FETCHEDDERIVEDPROCESSEDENGINEUnnamed client✓GPTBot⊘ClaudeBot⊘OAI-SearchBot⊘Claude-SearchBot⊘PerplexityBot⊘ChatGPT-User⊘Claude-User⊘Perplexity-User⊘Googlebot✓Googlebot Smartphone✓Mobile browser✓Bingbot✓Applebot⊘Amazonbot⊘Bytespider✗Meta-ExternalAgent✗CCBot⊘entitymap.json (JSON) — absentllms.txt (text) — absentpage HTML — openrobots.txt (text/plain) — opensitemap (XML) — openname, phone, address — openanswer text — unmeasureddeclared entities — absenttyped nodes — openenquiry — openidentity to corroborate — openembedded JSON-LD — openforms and call links — openvisible text — openquotable units — openrules per user-agent — openEdgedecision4 distinct response bodies served to the identities that were answered, by SHA-2564 versionsservedrobots.txt — present · 4.5 KB · sha256 ff800a4d427d901b5b4b8e6c08e0ec5132808d483171e0fa53d3c855b55f00e3 · keptrobots.txtpresent · 4.5 KBsitemap — present · 868 KB · sha256 493fa919e7c8a1490849b4693b6a56fdc01f5b923ac8b66c631fcddb6f97d215 · keptsitemappresent · 868 KBllms.txt — missing · 404 · sha256 3557f1559e468e7d4a4b649f985a9142c3bb90935cc46833e1b53c64e363f228 · keptllms.txtmissing · 404entitymap.json — missing · 404 · sha256 928fb366b5d8e4791552be46d9b3739f9a98ed3fc30897059d7e1ef3e3042871 · keptentitymap.jsonmissing · 404Page HTML — present · 306.7 KB · sha256 3a6447883d90b34647c5a10a041e3737e332c3baf40e5ee7fd8426504f505c3a · keptPage HTMLpresent · 306.7 KBJSON-LD — presentJSON-LDpresentDeclared identity (NAP) — presentIdentity (NAP)presentQuotable text — presentQuotable textpresentEnquiry path — presentEnquiry pathpresentrobots.txt resolutionrobots rulesParse and entity graphEntity graphName, address, phone corroborationNAP checkQuote extractionQuote extractionEnquiry (form or call)EnquiryAnswer engine output — not measuredEngineoutput notmeasuredEVIDENCEevery response above, kept by digest and sealedBytes kept — 13 distinct objects, 2.8 MB, each stored under its own SHA-256Bytes kept26 of 26 responsesManifest — sha256 4098c6573755bdd21d4644c5f14f0df51d807dbfc2d86dd1a7ffd32afab1005b: every response above, listed by digestManifest4098c6573755…Record digest — the manifest’s hash is part of this record’s digestRecord digestfixed at the sealDay root — the day is sealed after it closes (UTC); this digest is already recordedDay rootseals after 11-12Bitcoin — the root goes to the OpenTimestamps calendars at the seal; a Bitcoin block follows, usually within hoursBitcoinafter the seal

Who asked

  • Unnamed clientreaches the page · same text, different bytes
  • GPTBotturned away by the site's robots rules · same text, different bytes
  • ClaudeBotturned away by the site's robots rules · same text, different bytes
  • OAI-SearchBotturned away by the site's robots rules · same text, different bytes
  • Claude-SearchBotturned away by the site's robots rules · same text, different bytes
  • PerplexityBotturned away by the site's robots rules · same text, different bytes
  • ChatGPT-Userturned away by the site's robots rules · same text, different bytes
  • Claude-Userturned away by the site's robots rules · same text, different bytes
  • Perplexity-Userturned away by the site's robots rules · same text, different bytes
  • Googlebotreaches the page · same text, different bytes
  • Googlebot Smartphonereaches the page · identical bytes
  • Mobile browserreaches the page
  • Bingbotreaches the page · same text, different bytes
  • Applebotturned away by the site's robots rules · same text, different bytes
  • Amazonbotturned away by the site's robots rules · same text, different bytes
  • Bytespiderrefused at the edge (HTTP 429) to our request
  • Meta-ExternalAgentrefused at the edge (HTTP 403) to our request
  • CCBotturned away by the site's robots rules · same text, different bytes

Files fetched

  • robots.txtpresent · 4.5 KB
  • sitemappresent · 868 KB
  • llms.txtmissing
  • entitymap.jsonmissing
  • Page HTMLpresent · 306.7 KB

Derived

  • JSON-LDpresent
  • Quotable textpresent
  • Enquiry pathpresent
  • Declared identity (NAP)present

Answer engine output — not measured. No server can observe what an engine says.

Evidence

  • Bytes kept26 of 26 responses
  • Manifest4098c6573755…
  • Record digestfixed at the seal
  • Day rootseals after 11-12
  • Bitcoinafter the seal

✓ reached · ⊘ turned away by the site’s own rules · ✗ technical break · dashed box = missing or not measured. Drawn from this scan’s own fetches; nothing here is estimated. Fetched 2026-11-12 00:17 UTC by worker version be1e3120 under scoring rules v34. Each identity was sent by CrawlCheck from its own network: ✓ means our request under that name got through, not that the company’s own crawler did. The flow as JSON.

What each identity received — 26 responses captured, 26 kept as evidence
Who askedHTTPSizeCompared with a browserKept as evidence
Unnamed client200306.7 KBsame text, different byteskept · 11ba378b
GPTBot200306.7 KBsame text, different byteskept · 11ba378b
ClaudeBot200306.7 KBsame text, different byteskept · f767f94a
OAI-SearchBot200306.7 KBsame text, different byteskept · f767f94a
Claude-SearchBot200306.7 KBsame text, different byteskept · 11ba378b
PerplexityBot200306.7 KBsame text, different byteskept · f767f94a
ChatGPT-User200306.7 KBsame text, different byteskept · f767f94a
Claude-User200306.7 KBsame text, different byteskept · f767f94a
Perplexity-User200306.7 KBsame text, different byteskept · 11ba378b
Googlebot200306.7 KBsame text, different byteskept · 11ba378b
Googlebot Smartphone200306.7 KBidentical byteskept · 3a644788
Mobile browser200306.7 KBthe baselinekept · 3a644788
Mobile browser (control)200306.7 KBidentical byteskept · 3a644788
Bingbot200306.7 KBsame text, different byteskept · f767f94a
Applebot200306.7 KBsame text, different byteskept · 11ba378b
Amazonbot200306.7 KBsame text, different byteskept · 1378a569
Bytespider429162 Brefused (HTTP 429)kept · 413d294f
Meta-ExternalAgent403146 Brefused (HTTP 403)kept · 32f2fa94
CCBot200306.7 KBsame text, different byteskept · 11ba378b
CrawlCheck fetch (home page)200306.7 KB—kept · dc318faa
Files CrawlCheck fetched
/robots.txt2004.5 KB—kept · ff800a4d
/sitemap.xml200868 KB—kept · 493fa919
/sitemap_index.xml40493 KB—kept · fa12fd3c
/wp-sitemap.xml200146.1 KB—kept · a196f657
/llms.txt40493 KB—kept · 3557f155
/entitymap.json40493 KB—kept · 928fb366

Sizes are each response body as the fetch returned it: transfer compression removed, before any text decoding. A “kept” link re-hashes the stored copy inside our worker and says whether it still matches its digest; the bytes themselves are not republished.

Discovery chain breaks at llms.txt: everything after it is reachable only by guessing the conventional path. Rows behind this.

Where the bytes go

Of the 313,548 decompressed bytes the homepage delivers, 4.4% is text a reader or a model can actually use. Most of what a crawler downloads here is not words.

  • Readable text 4.4% · 13,731 B
  • Markup & attributes 65.1% · 204,197 B
  • Structured data (JSON-LD) 0.7% · 2,238 B
  • Inline CSS 14.8% · 46,455 B
  • Inline JavaScript 14% · 43,837 B
  • Inline SVG 0.1% · 372 B
  • HTML comments 0.9% · 2,718 B

The individual blocks that weigh the most, so the fix is a search rather than a hunt:

  • Inline CSS · 44,440 B (14.2%) — unnamedopens @import url(https://fonts.googleapis.com/css2?family=Inter:ital,opsz,w
  • Inline JavaScript · 14,517 B (4.6%) — #digisubs-social-login-js-afteropens (function () { var logPrefix = '[digisubs-social-login]'; var readyTim
  • Inline JavaScript · 4,739 B (1.5%) — #mng-ad-free-7day-js-afteropens ( function () { const config = window.mngAdFree7DayConfig; if ( ! conf

Every section

25 of 41 carry weight in the grade. Grey means measured and deliberately unweighted - it counts for nothing rather than zero, and each grey card says why. Open any section for the rows behind it: what was measured, what it is now, and the range that passes.

Machine files67robots.txt, llms.txt, sitemap and the entity graph: present, readable and served as the right type scoredAgent surfaces—Emerging standards (agents.md, API catalog, MCP card). Measured for information only not scored: these are published standards at very different stages of adoption, and several do not apply to every businessServer & hosting80What the edge and origin told us: cache state, compression, the software behind the page scoredStructured data55The JSON-LD entity graph: stable @ids, connected nodes, credentials and locations declared scoredLinked data100Whether the structured data parses as proper RDF and nothing dangles scoredAuthors & trust signals57Named people, dated articles, an organisation with contact details: the proxies an engine uses for trust scoredAccessibility structure96Language, alt text, labelled controls and one main landmark, read from the delivered HTML scoredEntity corroboration100Whether the identity links the site declares point back at it, and whether a Wikidata record names this domain scoredContent entities—Named things in the page text that a knowledge graph recognises. Measured, not scored not scored: the reading is sound but the scoring rule is not settled, and a rule that may move should not move a gradeQuotable content67Whether the sentences an answer engine would lift are on the page in a form it can take: a defining lead, short factual paragraphs, answered questions, few first-person openers scoredService area map—Every place the schema declares, placed on one map around the declared centre and radius: which have a page, which fall outside the circle. Measured, not scored not scored: a declared service area can be right or wrong only against facts this scan cannot seeWhole site—Up to 60 declared pages, read once a day after a scan: not-200s, thin and mostly-code pages, missing JSON-LD, canonical elsewhere, noindex, missing or duplicate h1, orphans, undeclared pages, duplicate titles, and the median words, text share and response time across them. Every count is free; Watch names which pages. Measured, not scored not scored: the grade stays anchored on the homepage so it is comparable across sites and daysFreshness—Every date the site publishes about itself: sitemap lastmod, Last-Modified, dateModified, dated elements, and where they disagree. Measured, not scored not scored: every date here is one the site published, so this reports what it claims rather than what is true. Calibrated 2026-09-16 on 114 records: the only row most sites carry (a sitemap that declares lastmod, 68%) is not a defect when absent, and the rows that would be defects (every lastmod stamped on one day, 8%; the sitemap and dateModified disagreeing by over a month, 2%) can be measured on too few sites to carry weightCrawl waste100Fetches that produce no new page: parameter and case variants, http links, redirecting or gone declared URLs, canonical-elsewhere and noindex pages scoredPage subject100Which business entity the page is about and how every other business entity on it is related: chain, subsidiary, department, or undeclared scoredLocal intents—Which Google Maps intent types the site names about itself, and which of those have a page the homepage links to. Measured, not scored not scored: the intent vocabulary is recovered names with no weights, and a claimed intent without a page is a content decision, not a defect; reported until the corpus says how it distributesConversion path—Phone link, form and call-to-action on the page, and whether they sit before the fold. Measured, not scored not scored: whether a visitor can act is a business judgement, and the grade is for what a machine receivesCrawler permissions33What robots.txt actually tells each named AI and search crawler it may do scoredSpeed44How fast the page answered our fetch, plus real-visitor field data where Google has it scoredPage weight & text20How many of the delivered bytes are readable words, and how much is markup, scripts and styling scoredMachine-file chain100robots.txt names the sitemap, llms.txt points onward, the entity graph points home: the chain a crawler follows scoredClaim consistency100Name, phone, city and years-in-business match between the structured data and the visible page scoredInstructions for agents100Text aimed at AI agents rather than people: present, visible, and not hidden scoredWhat each crawler gets88Each named crawler fetched the page; this is whether they all got the same thing scoredMobile100Viewport, zoom, icons and manifest: whether a phone gets a page it can use scoredLocal presence & NAP86Street address, coordinates, hours, phone, and the directory listings the site itself declares scoredWhat AI looks for—The facts an AI model weighs when it picks a business, ordered by how far each moved its ranking in CrawlCheck's tests, and whether the homepage shows each one. Measured, not scored not scored: the effects come from one model ranking fictional businesses, and a fact a business does not have should never be added to please a modelTrust and reputation—Red flags an agent should check before it cites or calls a business: the phone number in FTC unwanted-call complaints, malware or phishing listing, domain age and registration, parked or for-sale pages and redirects to another organisation. Measured, not scored. not scored: these are signals to check, not proof: a complaint can come from someone spoofing the number, and a young domain can be an honest new businessClaims and their evidence—Each fact the site states about itself beside every outside source that confirms or contradicts it. Measured, not scored. not scored: a source that cannot be read is not evidence against a claim, and a listing can lag a real change, so this reports what agrees rather than grading itSite safety—Malware or phishing listing, HTTPS and certificate, each security header graded, forms and where they send data, cookies, the http:// redirect, libraries with published advisories, sampled login, contact and checkout pages, changes since the last read, insecure resources, exposed versions, email forgery protection and domain registration. Measured, not scored. not scored: only a malware or phishing listing changes what AI systems do with a site, and the rest is protection rather than a property of what a machine is servedExposed files and secrets89Backups, environment files, repository folders, debug logs and keys reachable on the live host scoredAI rights and consent—What the site declares AI may do with its pages, per use, which signal decided it, and where signals disagree. Measured, not scored not scored: every row here is a reading rather than a pass or a fail, so nothing in it can move a gradePrice transparency—Whether the page states what the work costs, in text and in markup, and whether the two agree. Measured, not scored not scored: every row here is a reading rather than a pass or a fail, so nothing in it can move a gradeThird-party dependencies—Every outside host the page loads, grouped, and the ones that hold the page until they answer. Measured, not scored not scored: every row here is a reading rather than a pass or a fail, so nothing in it can move a gradeLanguage and region—Declared language, hreflang alternates and the region the page serves. Measured, not scored not scored: every row here is a reading rather than a pass or a fail, so nothing in it can move a gradeWhere AI already cites this site—Answer-engine arrivals and citations this site has already received. Measured, not scored not scored: every row here is a reading rather than a pass or a fail, so nothing in it can move a gradeError pages100A missing page answers 404 with a real page, not a 200 soft 404 or a blank; the error page is not a dead end scoredSitemap100A sitemap exists, resolves, and declares the pages the homepage links to scoredInternal links100Anchors carry words, targets resolve, and the link graph is not mostly repeats scoredURL naming80Lowercase hosts and paths, no case-only duplicates, machine files spelt correctly scoredImage signals80Alt text, declared dimensions, lazy-loading, modern formats, hero priority and the entity image in JSON-LD. scored

What the site states about itself

The facts an answer engine could repeat about this business, taken only from what this scan fetched, with where each was found. Anything absent is [not stated]: an engine asked for it would have to guess.

FactStated asFound inAgreementFirst seen
NameThe Denver Post2026-09-19
Phone(303) 954-1010structured data onlynot shown to readers2026-09-19
Address5990 Washington St., Denver, CO, 802162026-09-19
Map point39.7392, 104.9903structured datanegating the longitude puts it inside US - a missing minus sign2026-09-19
Opening hoursstatedstructured data2026-09-19
Business typeLocalBusinessstructured data2026-09-19
Profiles it links3 (Facebook, X, LinkedIn)links on the site3 of 3 point back

Everything else that was measured

Measured for information, not scored

Agent surfaces—Emerging standards (agents.md, API catalog, MCP card). Measured for information onlyContent entities—Named things in the page text that a knowledge graph recognises. Measured, not scoredService area map—Every place the schema declares, placed on one map around the declared centre and radius: which have a page, which fall outside the circle. Measured, not scoredWhole site—Up to 60 declared pages, read once a day after a scan: not-200s, thin and mostly-code pages, missing JSON-LD, canonical elsewhere, noindex, missing or duplicate h1, orphans, undeclared pages, duplicate titles, and the median words, text share and response time across them. Every count is free; Watch names which pages. Measured, not scoredFreshness—Every date the site publishes about itself: sitemap lastmod, Last-Modified, dateModified, dated elements, and where they disagree. Measured, not scoredLocal intents—Which Google Maps intent types the site names about itself, and which of those have a page the homepage links to. Measured, not scoredConversion path—Phone link, form and call-to-action on the page, and whether they sit before the fold. Measured, not scoredWhat AI looks for0The facts an AI model weighs when it picks a business, ordered by how far each moved its ranking in CrawlCheck's tests, and whether the homepage shows each one. Measured, not scoredTrust and reputation88Red flags an agent should check before it cites or calls a business: the phone number in FTC unwanted-call complaints, malware or phishing listing, domain age and registration, parked or for-sale pages and redirects to another organisation. Measured, not scored.Claims and their evidence100Each fact the site states about itself beside every outside source that confirms or contradicts it. Measured, not scored.Site safety79Malware or phishing listing, HTTPS and certificate, each security header graded, forms and where they send data, cookies, the http:// redirect, libraries with published advisories, sampled login, contact and checkout pages, changes since the last read, insecure resources, exposed versions, email forgery protection and domain registration. Measured, not scored.AI rights and consent100What the site declares AI may do with its pages, per use, which signal decided it, and where signals disagree. Measured, not scoredPrice transparency67Whether the page states what the work costs, in text and in markup, and whether the two agree. Measured, not scoredThird-party dependencies33Every outside host the page loads, grouped, and the ones that hold the page until they answer. Measured, not scoredLanguage and region100Declared language, hreflang alternates and the region the page serves. Measured, not scoredWhere AI already cites this site—Answer-engine arrivals and citations this site has already received. Measured, not scored

Section detail

Each row: the measure, what it is now, the range that passes, and whether this site is inside it. n/a means the input could not be measured and the row is excluded, not failed.

Machine layer — 67/100
Section score 67 / 100
MeasureCurrentlyOptimal
robots.txt
a crawler that cannot read robots.txt often treats that as disallow-everything
200 · 4567B200, text/plain, 100–4,000B✓ Passed
XML sitemap
without it a crawler enumerates the site by following links only
live200, valid XML, at a path robots.txt names✓ Passed
llms.txt
reported, not scored. Some agents fetch it and it costs nothing to publish, so the row stays. It is not graded because nothing we have measured, and nothing we have read, links its presence to a citation or a ranking — a study across roughly 300,000 domains found no correlation, and dropping the variable made the model more accurate, not less. Grading a file we cannot show works would price it for our customers on our say-so
absent (404)200, text/plain, 2,000–50,000BReported
security.txt
reported, not scored. Expires is required by RFC 9116; an expired file tells a researcher its contact may be stale
absent (404)a Contact and a future Expires, served as text/plain (RFC 9116)Reported
entitymap.json
machine-readable entity layer; optional, but it is the strongest identity signal available
absent (404)200, application/json✗ Failed
How rare is what this site publishes
adoption counts are third-party aggregates read in August 2026 and count sites in that index rather than the whole web; they are here to size the opportunity, not to score the site
llms.txt — roughly 70,200 sites publish one; this is not among them. entitymap.json — absent, and no third-party adoption figure exists for it. for scale, roughly 677,748 sites publish something built for agents at all, and about 107,200 now disallow GPTBot outright, so an AI policy is mainstream while a machine-readable map of the site is not.publish what almost nobody publishes, and keep it correctReported
Host agreement
a crawler resolving www must not get a different machine layer
hosts agree0 divergent files✓ Passed
Served whatever the Accept header
crawlers ask for machine files with Accept: */* or a text type, not text/html
same answer to Accept: */*every live file answers Accept: */*✓ Passed
Cost of a miss
every absent file bills the crawler for a full HTML 404
3 missing file(s) return >20KB of HTMLa missing machine file should 404 small, not ship a full page✗ Failed

Hosts and URLs

/robots.txtwww.denverpost.com: 200 · 4,567B live
denverpost.com: 301 → https://www.denverpost.com/robots.txt
/llms.txtwww.denverpost.com: 404 · 95,230B of HTML (not the file)
denverpost.com: 301 → https://www.denverpost.com/llms.txt
/entitymap.jsonwww.denverpost.com: 404 · 95,247B of HTML (not the file)
denverpost.com: 301 → https://www.denverpost.com/entitymap.json
/sitemap.xmlwww.denverpost.com: 200 · 888,839B live
denverpost.com: 200 · 888,839B live
/sitemap_index.xmlwww.denverpost.com: 404 · 95,255B of HTML (not the file)
denverpost.com: 301 → https://www.denverpost.com/sitemap_index.xml

Scanned on www.denverpost.com. denverpost.com 301s to www.denverpost.com, so that is the host a crawler ends up reading. Probed with redirects not followed, so a 200 here means the file is served at that exact URL — a followed redirect would report a file that lives somewhere else. The denverpost.com host serves its own machine layer. A crawler that resolves that hostname reads those files, not the ones on www.denverpost.com.

Server and hosting — 80/100
Section score 80 / 100
MeasureCurrentlyOptimal
Compression
our fetch decompresses the body and drops the content-encoding header before we can read it — this is our limitation, not a finding about the site. Check it in a browser’s network panel, or with curl --compressed -I
not visible from herebr preferred, gzip acceptableNot measured
Edge / CDN
absorbs crawler load and keeps machine files fast
none detecteda CDN in front of the origin✗ Failed
HTTP/3 advertised
HTTP/3 runs over QUIC (UDP datagrams) and recovers faster on lossy mobile networks; crawlers still fetch over HTTP/1.1 and HTTP/2, so this is not scored. Whether the QUIC handshake itself completes cannot be tested from a server fetch. An ech= key in the same DNS record is Encrypted Client Hello (RFC 9849, published in DNS per RFC 9848), which hides the site name from the network.
noh3 in the Alt-Svc header or the DNS HTTPS recordReported
Post-quantum key exchange
Hybrid key exchange protects today’s traffic against later decryption by a quantum computer (harvest now, decrypt later). Browsers offer it by default; most CDNs agree it. Measured weekly from outside by offering only that group; not scored. The share across measured sites is at /data/tls-posture.
not in the weekly probe sample (2026-11-09)X25519MLKEM768 agreed (RFC 10024)Reported
Cache state
DYNAMIC means every crawler hit reaches the origin. Shown, not scored: the speed rows below score what that costs, and scoring the mechanism too would count it twice
4 of 5 machine files DYNAMICHIT or MISS on machine files; DYNAMIC is Cloudflare's default for .txt and .xmlReported
Version disclosure
a public CMS version tells an attacker exactly which exploits to try
not disclosedno generator version in the HTML✓ Passed
Runtime disclosure
same reason as above
not disclosedno x-powered-by header✓ Passed
Vary
governs whether a cached copy is reused correctly
accept-encodingAccept-Encoding at minimum✓ Passed
Strict-Transport-Security
max-age 365 days, subdomains included · hstspreload.org: unknown. Shown, not scored: HSTS changes nothing about what crawlers receive
max-age=31536000;includeSubdomainsmax-age with includeSubDomains; preload only if you mean itReported
Webmaster verification tags
meta tags only — DNS and file verification leave nothing in the HTML, so a missing tag is not evidence of no registration. Shown, not scored
Google no tag visible · Bing tag present · Yandex no tag visibleBing at least: its index feeds ChatGPT search and CopilotReported
Client-side rendering
framework present, HTML delivered with text. Measured on the bytes the server sent, not on a rendered view
script bundle, no known framework · 2099 words deliveredtext present in the delivered HTML✓ Passed
ApplicationWordPress
detected from the delivered HTML, not from a header that can be removed
Varies onaccept-encoding
a response that varies can be cached differently per client
Schema and entity graph — 55/100
Section score 55 / 100
MeasureCurrentlyOptimal
Entity nodes
with no schema the site has no declared identity at all
3at least 3 typed nodes✓ Passed
Stable @id coverage
without an @id every page declares a brand-new unrelated entity
33.3%80–100%✗ Failed
Credential edges
the machine-readable form of why this business is qualified; a publisher, a shop or a SaaS is not held to it
0at least 1 (licence, membership or award) for a local or professional service✗ Failed
Locations missing a street
a service-area business legitimately omits this — not scored either way
00 for a premises business; expected for service-area✓ Passed
sameAs claims
sameAs asserts identity, so a WRONG target claims the business is something else. A large number of correct profiles is not a defect; a single target that does not lead back here is.
3 (3 corroborated, 0 not linking back, 0 dead)at least 2, none dead, at least one linking back✓ Passed
sameAs pointing at a place
a map link in sameAs claims the business IS that location
10✗ Failed
H1 count
common practice, not a Google rule: Google says a page with several h1 headings is fine. One h1 that names the subject still gives readers and answer engines the clearest outline, so it is kept as a practice check
21 (common practice)✗ Failed
Heading skips
a skipped level breaks the document outline a parser builds
00✓ Passed
Canonical
without it duplicates compete with each other
presentpresent on every page✓ Passed
Meta description
common practice, not a Google rule: Google sets no length limit and truncates snippets to fit the screen, often rewriting them. Past about 160 characters the end is usually cut off; under 50 it reads as a label, not a description. 95 chars is fine
157 chars50–160 chars (common practice)✓ Passed
Title width in search results
display, not ranking: Google measures a title by width, not characters, shows about 600 px of it on desktop and ends the rest with an ellipsis (it may also rewrite the title). Cut off: “weather, entertainment.”. Put the words that matter first.
765 px — shows as “The Denver Post – Colorado breaking news, sports, business, ...”up to about 600 px (Google desktop, 20 px Arial)✗ Failed
sameAs · 3 profilesdeclared relations · 0facebook.com/denverpostlinks backx.com/denverpostlinks backlinkedin.com/company/denver-post-…links backnone declared (owns, brand, founder, subOrganization …)LocalBusinessThe Denver Postrobots.txtpublishedsitemap.xmlpublishedsitemap_index.xmlHTTP 404wp-sitemap.xmlpublishedllms.txtHTTP 404machine files read on this scan
The entity graph as this site’s own structured data declares it: The Denver Post in the middle, 3 sameAs profiles (3 confirmed to link back), 0 declared relations. A profile that links back is evidence an assistant can check; one that does not is only a claim.
Entities declared3 nodes, 2 distinct types
Stable identity1 of 3 carry an @id (33.3%)
Without an @id a node cannot be referenced or merged — every page re-declares a new, unrelated entity.
Credential edges0
Licences, memberships and awards expressed as graph edges rather than prose.
Topic edges0
A high count with generic values usually means the graph is being used to store keywords.
Locations1 declared, 0 without a street address
sameAs claims3 total · 1 map links · 0 resolve to this entity · 1 resolve to a place
sameAs asserts identity. A map link pointing at a city claims the business is that city. No validator reports this — it only appears if the targets are resolved.
Document structure2 h1 · 129 headings · 0 level skips · canonical present · meta description 157 chars
RDF and linked-data surface — 100/100
Section score 100 / 100
MeasureCurrentlyOptimal
JSON-LD blocks that parse
a block that does not parse contributes no triples and looks, to a validator that counts tags, like structured data that is there
2 of 2every block✓ Passed
@context is schema.org
a graph in another vocabulary is valid RDF that no answer-engine resolver is built to read
2 of 2every block✓ Passed
Triples declared (approximate)
the size of what a linked-data reader actually receives; a single Organization with a name and a URL is three statements
68at least 20 on a homepage✓ Passed
Dangling @id references
a reference to an @id no node declares is a statement about nothing; the resolver drops the edge and the entity loses that relation
00✓ Passed
Top-level nodes carrying a subject IRI
a root or @graph node without an @id is a blank subject that no other page or site can reference; nested values (an address, an offer, a list item) are not held to this
0 of 2 (12 nodes in all)every entity the page declares — shown; the schema section scores @id coverageReported
RDFa and Microdata
Secondary serialisations are read by some parsers and are a second place for the facts to disagree. Not scored while JSON-LD is present; when a page declares no JSON-LD node, its schema.org Microdata and RDFa are read as its graph and every entity check runs on them
no RDFa, no Microdata, 23 Open Graph metaoptional; one serialisation kept accurate beats three that driftReported
RDF content negotiation
An RDF-aware client sent Accept: text/turtle. Almost no commercial site answers with a graph and absence is not a defect; a site that does is handing the machine the same facts in a tenth of the bytes. Not scored
text/html served (HTTP 200), Vary: Acceptoptional: text/turtle or application/ld+json to a client that asks for itReported
Alternate RDF representation linked
Tells a linked-data client where the graph lives without negotiating for it. Not scored
noneoptional: <link rel=alternate type=text/turtle> or a Link headerReported
Blank-node identifiers (_:)
A _: label is local to one document and changes between serialisations; nothing on another page or site can point at it. Shown, not scored
nonenone: every entity gets a persistent IRIReported
Business declared under two @ids
Two nodes with the same name and different @ids are two subjects to a graph reader; a plugin's #organization beside a theme's /#org splits one business into two. Shown, not scored
noneone @id per business, reused everywhereReported
Local @id convention
Hash and path identifiers are both valid; mixing them for the same kind of entity is how duplicate subjects appear. Shown, not scored
no local @idsone convention across the siteReported
Same address spelled two ways
/café/ and /caf%C3%A9/ are the same page to a browser and two different IRIs to a graph; percent-encoding drift splits the node. Shown, not scored
noneone byte-exact spelling per resourceReported
IRIs not in Unicode NFC
Composed and decomposed forms of the same character compare unequal byte for byte, so the same identifier written twice can fail to match itself. Shown, not scored
none of 6NFC everywhereReported
International domain names left unencoded
Parsers that expect an ASCII host may reject or re-encode a Unicode host differently from the canonical. Shown, not scored
nonethe xn-- (Punycode) form in structured dataReported
Wikidata identifier form
Both resolve to the same item. Mixing them is harmless to Wikidata and costs a string-matching reader one normalisation step. Shown, not scored
no Wikidata sameAseither; /entity/Q… is the concept IRI, /wiki/Q… the page about itReported
sameAs profiles that answer
Read from the entity corroboration fetches (up to six profiles per scan); a dead profile is an identity claim that points at nothing. Scored there, shown here
3 answered, 0 dead, 0 unverifiableevery declared profile answersReported

JSON-LD is an RDF serialisation, so every schema block above is already a graph of triples. This section reads it as one: 68 statements about 0 identified subjects, 1 reference between them, none dangling. The triple count is approximate: each property value is one statement and each @type one more; nested objects without an @id are counted as values, not expanded. Weight 0.8 in the overall, below the schema section it overlaps.

Authorship and trust signals (E-E-A-T proxies) — 57/100
Section score 57 / 100
MeasureCurrentlyOptimal
A named person is declared
an evaluator asking who is behind this finds a machine-readable answer or nothing; a site with no Person node is anonymous to a resolver
noneat least 1 Person node with a name✗ Failed
Person carries expertise properties
jobTitle, hasCredential, alumniOf, memberOf, knowsAbout or award: the statements that say WHY this person is qualified, in the form a reader can check
—every named personNot measured
Person is corroborated elsewhere (sameAs)
a person who exists only on this site is a claim; a person with profiles that link back is a fact someone else asserts too
—every named personNot measured
Person has a page of their own
the page an evaluator lands on to judge experience; without it the person is a name in a script tag
—a url or mainEntityOfPage on eachNot measured
Articles name a typed author
author as a string is a label; author as a Person or Organization object is an entity that can carry the expertise above
no Article nodes on this pageevery articleReported
Articles carry datePublished and dateModified
freshness is read from dateModified; an article with only a publish date reads as never maintained
—both on every articleNot measured
Organization declares who runs it
connects the business entity to the people entities; without the edge the two graphs never meet
0 of 2founder, employee or member on the organisation✗ Failed
Organization declares foundingDate
the one claim behind every 'years of experience' counter that a reader can check against a registry
1 of 2on the primary organisation✓ Passed
Contact route declared in schema
a business that cannot be reached by a stated channel is unverifiable by definition
1 of 2telephone, email or contactPoint✓ Passed
About page linked from the homepage
the page an evaluator opens first; if the homepage does not link it, most readers never find it
nolinked✗ Failed
Contact page or direct contact linked
a contact path in the delivered HTML, not only in a footer image or a widget that renders later
yeslinked✓ Passed
Privacy policy or terms linked
the cheapest trust signal on the list and the one small sites most often omit
yeslinked✓ Passed
Ratings carry a value and a count
a rating with no count is a number nobody can weigh; a count with no reviews behind it is the shape of a fabricated one
no aggregateRatingratingValue with reviewCount or ratingCountReported
Outbound references
Citations outward are part of how authority is read, and a count cannot say whether they are good ones. Not scored
19 external hosts linked (excluding social platforms): checkout.denverpost.com, accuweather.com, enewspaper.denverpost.comcite what the content relies on; there is no right numberReported

What this can and cannot say. E-E-A-T is a judgement an evaluator makes about experience, expertise, authoritativeness and trust; it is not on the wire and CrawlCheck does not pretend to score it. Each row above is one machine-readable statement a site makes that a reader could use as evidence toward that judgement, measured from the delivered homepage and its JSON-LD. A full row of passes does not create expertise, and a row of fails does not disprove it; what they decide is whether a machine reading this site can find the evidence at all. Weight 1.0 in the overall, the same as payload: what these rows measure is whether the evidence is findable by a machine, and that is the part CrawlCheck can stand behind.

Accessibility structure (from the delivered HTML) — 96/100
Section score 96 / 100
MeasureCurrentlyOptimal
Document language declared
a screen reader picks its voice and pronunciation from this; without it every word is read in the user's default language
lang=en-USa valid lang attribute on <html> (3.1.1)✓ Passed
Page has a title
the first thing announced when a page opens, and the label on every tab and bookmark
89 charsa non-empty <title> that names the page (2.4.2)✓ Passed
Images carry an alt attribute
a missing alt attribute makes the reader announce the file name; alt="" marks an image as decorative and is correct
44 of 44every image (alt="" for decoration)✓ Passed
Form controls have a name
a field with no name is announced as "edit text"; a placeholder is not a label, it disappears on the first keystroke
1 of 2 (missing: checkbox)a <label for>, wrapping label, aria-label or title on each✗ Failed
Buttons have an accessible name
an icon-only button with no name is announced as "button" and nothing else
3 of 3text, aria-label, or an image with alt inside each✓ Passed
Frames are titled
a frame with no title is a hole in the reading order the user cannot identify or skip on purpose
no framesa title on every iframeReported
One main landmark
the region a reader jumps to for the content; two of them is as unusable as none
oneexactly one <main> or role=main✓ Passed
A way past the navigation
without one, every page starts by tabbing through the whole menu
skip linka skip link, or nav and main landmarks✓ Passed
No duplicate ids
4.1.1 Parsing is obsolete (W3C errata, 2023), so a duplicate id alone is not a failure; one that a label or skip link resolves through sends it to the wrong element
0every id a label, description or #link resolves through is unique✓ Passed
1.1.1 Image buttons and map areas are named
an image used as a control is announced by its file name or not at all
none on the pagealt on every <input type=image> and linked <area>Reported
1.1.1 SVG images carry a name
role=img promises an image with a text alternative; without one the reader says "image" and nothing else. An icon inside a named button or link is not held to this
no svg with role=imga <title> or aria-label on each svg marked role=imgReported
1.1.1 Alt text is not a file name or placeholder
WCAG failure F30: an alt that is a file name or the word "image" is read aloud and tells the listener nothing
nonealt that describes the image, never "IMG_1234.jpg" or "image"✓ Passed
2.4.4 Links have an accessible name
an icon-only link with no name is announced as its URL or as "link"; the user cannot tell where it goes
357 of 357text, aria-label, or an image with alt inside every link✓ Passed
4.1.2 Custom controls have a name
a div made into a button by role=button is announced as "button" with no indication of what it does
2 of 2a name on every element given a widget role (role=button, tab, checkbox...)✓ Passed
2.5.3 Visible label is part of the name
a speech-input user says the words on screen; if aria-label replaces them with different words the command matches nothing
5 of 5every visible word of a link or button inside its aria-label✓ Passed
1.3.1 Headings are not empty
an empty heading is announced as "heading level 2" and breaks the outline readers navigate by
129 of 129text in every h1-h6✓ Passed
1.3.1 Data tables have header cells
without header cells a reader announces each value with no column name, so a price table becomes a list of numbers
no data tables<th> (or scope/headers) in every table of dataReported
1.3.1 Radio buttons are grouped
the question a set of options answers is lost when the options are not grouped; the reader hears "Yes, radio button" with no question
no radio groupsa <fieldset> or role=radiogroup around each setReported
1.3.5 Personal-data fields declare their purpose
the token lets browsers fill the field and lets assistive tools mark it with a familiar icon; an invalid token (failure F107) does neither
no name, email, phone or address fieldsa valid autocomplete token on each field asking for the visitor's own detailsReported
2.2.1 No timed refresh
a page that reloads or redirects on a timer takes the content away before a slow reader finishes (failures F40/F41)
noneno <meta http-equiv=refresh> with a delay✓ Passed
2.2.2 No moving content without a stop
text that scrolls on its own and cannot be paused is unreadable for many users and distracting for the rest
noneno marquee✓ Passed
1.4.2 No sound that plays on its own
sound that starts by itself talks over the screen reader the user is listening to
no autoplaying mediaautoplaying audio or video muted, or with controls✓ Passed
1.2.2 Watchable video has a caption track
deaf and hard-of-hearing visitors get nothing from the soundtrack without captions
no native video with controlsa captions or subtitles <track> (not scored: captions burned into the picture cannot be read from markup)Reported
2.1.1 Click targets reachable by keyboard
an onclick on a div cannot be reached with Tab or fired with Enter, so keyboard and switch users cannot use it
noneevery clickable element focusable✓ Passed
3.2.1/3.2.2 No change of context on focus or input
a select that navigates as soon as its value changes sends keyboard users away while they are still choosing (failure F37)
nonenavigation only on an explicit submit✓ Passed
4.1.2 Nothing focusable is hidden from readers
keyboard focus lands on something the screen reader says is not there, so the user hears silence
noneno aria-hidden on a link, button or field✓ Passed
4.1.2 ARIA roles are valid
an unknown role is ignored, so the element is announced as whatever it really is
noneevery role a WAI-ARIA 1.2 role✓ Passed
4.1.2 ARIA attributes exist
a misspelt attribute (aria-labeledby) does nothing; the name or state it was meant to set is never exposed
noneevery aria-* attribute defined in WAI-ARIA 1.2✓ Passed
1.3.1 Label and description references resolve
a label whose for points at no id labels nothing; the field it was written for stays unnamed
noneevery for, aria-labelledby, aria-describedby and headers id present✓ Passed
2.4.1 Skip link reaches its target
a skip link to a missing id moves focus nowhere, and the user tabs through the whole menu anyway
target presentthe #id a skip link names exists on the page✓ Passed
3.1.2 Language of parts is valid
an invalid tag is ignored, so a French quote on an English page is read with English pronunciation
noneBCP 47 tags (en, fr-CA) on every lang attribute✓ Passed
2.4.3 No positive tabindex
a positive tabindex pulls an element to the front of the tab order, usually ahead of the content it belongs to
nonetabindex 0 or -1 only (not scored: an order can still be meaningful)Reported

What this is. Read against the full WCAG 2.1 text: of its 78 success criteria, 21 can be decided, in part, from the document the server returns, and each is checked here. 4 more are measured in other sections (zoom, link wording, heading order, a sitemap). Contrast, reflow, focus visibility, keyboard traps and motion need a rendered page (27 criteria); captions’ accuracy, reading order and plain wording need a person (26). None of those is claimed. A page that passes every row here is not thereby conformant, and this is not a conformance claim. Each row counts a failure only where the markup settles it: an icon inside a named button is not a 1.1.1 failure, and a duplicate id fails only when something resolves through it. Weight 0.8 in the overall, in the Read stage.

All 78 WCAG 2.1 success criteria and where each stands
CriterionLevelCrawlCheck
1.1.1 Non-text ContentAMeasured in this section
1.2.1 Audio-only and Video-only (Prerecorded)ANeeds a person
1.2.2 Captions (Prerecorded)AMeasured in this section
1.2.3 Audio Description or Media Alternative (Prerecorded)ANeeds a person
1.2.4 Captions (Live)AANeeds a person
1.2.5 Audio Description (Prerecorded)AANeeds a person
1.2.6 Sign Language (Prerecorded)AAANeeds a person
1.2.7 Extended Audio Description (Prerecorded)AAANeeds a person
1.2.8 Media Alternative (Prerecorded)AAANeeds a person
1.2.9 Audio-only (Live)AAANeeds a person
1.3.1 Info and RelationshipsAMeasured in this section
1.3.2 Meaningful SequenceANeeds a person
1.3.3 Sensory CharacteristicsANeeds a person
1.3.4 OrientationAANeeds a rendered page
1.3.5 Identify Input PurposeAAMeasured in this section
1.3.6 Identify PurposeAAANeeds a person
1.4.1 Use of ColorANeeds a rendered page
1.4.2 Audio ControlAMeasured in this section
1.4.3 Contrast (Minimum)AANeeds a rendered page
1.4.4 Resize TextAAMeasured in another section of this report
1.4.5 Images of TextAANeeds a person
1.4.6 Contrast (Enhanced)AAANeeds a rendered page
1.4.7 Low or No Background AudioAAANeeds a person
1.4.8 Visual PresentationAAANeeds a rendered page
1.4.9 Images of Text (No Exception)AAANeeds a person
1.4.10 ReflowAANeeds a rendered page
1.4.11 Non-text ContrastAANeeds a rendered page
1.4.12 Text SpacingAANeeds a rendered page
1.4.13 Content on Hover or FocusAANeeds a rendered page
2.1.1 KeyboardAMeasured in this section
2.1.2 No Keyboard TrapANeeds a rendered page
2.1.3 Keyboard (No Exception)AAANeeds a rendered page
2.1.4 Character Key ShortcutsANeeds a rendered page
2.2.1 Timing AdjustableAMeasured in this section
2.2.2 Pause, Stop, HideAMeasured in this section
2.2.3 No TimingAAANeeds a person
2.2.4 InterruptionsAAANeeds a person
2.2.5 Re-authenticatingAAANeeds a person
2.2.6 TimeoutsAAANeeds a person
2.3.1 Three Flashes or Below ThresholdANeeds a rendered page
2.3.2 Three FlashesAAANeeds a rendered page
2.3.3 Animation from InteractionsAAANeeds a rendered page
2.4.1 Bypass BlocksAMeasured in this section
2.4.2 Page TitledAMeasured in this section
2.4.3 Focus OrderANeeds a rendered page
2.4.4 Link Purpose (In Context)AMeasured in this section
2.4.5 Multiple WaysAAMeasured in another section of this report
2.4.6 Headings and LabelsAAMeasured in this section
2.4.7 Focus VisibleAANeeds a rendered page
2.4.8 LocationAAANeeds a person
2.4.9 Link Purpose (Link Only)AAAMeasured in another section of this report
2.4.10 Section HeadingsAAAMeasured in another section of this report
2.5.1 Pointer GesturesANeeds a rendered page
2.5.2 Pointer CancellationANeeds a rendered page
2.5.3 Label in NameAMeasured in this section
2.5.4 Motion ActuationANeeds a rendered page
2.5.5 Target SizeAAANeeds a rendered page
2.5.6 Concurrent Input MechanismsAAANeeds a rendered page
3.1.1 Language of PageAMeasured in this section
3.1.2 Language of PartsAAMeasured in this section
3.1.3 Unusual WordsAAANeeds a person
3.1.4 AbbreviationsAAANeeds a person
3.1.5 Reading LevelAAANeeds a person
3.1.6 PronunciationAAANeeds a person
3.2.1 On FocusAMeasured in this section
3.2.2 On InputAMeasured in this section
3.2.3 Consistent NavigationAANeeds a rendered page
3.2.4 Consistent IdentificationAANeeds a rendered page
3.2.5 Change on RequestAAAMeasured in this section
3.3.1 Error IdentificationANeeds a rendered page
3.3.2 Labels or InstructionsAMeasured in this section
3.3.3 Error SuggestionAANeeds a rendered page
3.3.4 Error Prevention (Legal, Financial, Data)AANeeds a person
3.3.5 HelpAAANeeds a person
3.3.6 Error Prevention (All)AAANeeds a person
4.1.1 Parsing (obsolete, always satisfied for HTML per W3C errata)AMeasured in this section
4.1.2 Name, Role, ValueAMeasured in this section
4.1.3 Status MessagesAANeeds a rendered page
Entity corroboration — 100/100
Section score 100 / 100
MeasureCurrentlyOptimal
Identity claim — facebook.com
the target page references denverpost.com back
corroboratedcorroborated✓ Passed
Identity claim — x.com
the target page references denverpost.com back
corroboratedcorroborated✓ Passed
Identity claim — linkedin.com
the target page references denverpost.com back
corroboratedcorroborated✓ Passed
Wikidata Q2668654
the strongest third-party identity signal a machine can read
official website matches this domainP856 names this domainReported

3 corroborated · 0 unreciprocated · 0 unverifiable · 0 dead. A sameAs link is an identity CLAIM, and an identity claim can be reciprocated — the target either points back at this domain or it does not. Platforms that refuse datacentre readers are counted as unverifiable, never as failures: the claim can be neither confirmed nor accused from here, and pretending otherwise would manufacture findings. Corroborated claims pass, unreciprocated and dead claims fail, and unverifiable or declared-only claims are left out of the score — so a profile page that blocks readers can never cost a point, and a link that is dead or never mentions this site does.

Quotable content — 67/100
Section score 67 / 100
MeasureCurrentlyOptimal
Lead paragraph defines the subject
the first paragraph is the one most often lifted whole; if it is a slogan, the engine has to assemble the answer from fragments. Naming the subject is shown, not scored
does not name it, no defining verba first sentence that says what this is (corpus: 30% of homepages do)✗ Failed
Paragraphs an engine can quote whole
a self-contained paragraph of 15-70 words with a fact in it is the unit answer engines extract; a 200-word paragraph gets summarised instead, and the summary is theirs
8 of 12 (67%)at least 25% (corpus median 29%)✓ Passed
Question headings with an answer under them
the shape a query has when it arrives; a page that already carries the question and a short answer is quoted in that order. Having none is not scored
no question headingsat least half, where question headings existReported
FAQ markup matches the visible text
FAQ markup for text a visitor cannot see is a claim with nothing behind it; engines that compare the two drop the markup
no FAQPageevery declared question readable on the pageReported
Headings carry an id
a heading with an id is a stable address for one passage; without it a citation can only point at the whole page
0 of 29an id on each, so a passage can be cited by fragment (not scored: corpus median 0%)Reported
Sentence length
quotes are short; a 40-word sentence is paraphrased, and the paraphrase carries the engine's wording, not yours
median 15 words, 67% under 26a median of 22 words or fewer (corpus median 15)Reported
Sentences with a checkable fact
8-30 words with a number, date or name, in the third person: the sentence an engine can attribute to you without editing it
2 of 3 (67%)at least 15% (corpus median 20%)Reported
Paragraphs that open in the first person
"We offer" needs rewriting before it can be quoted about you; "Acme offers" does not
0 of 12 (0%)a third or fewer (corpus p90 24%)✓ Passed
Tables with a header row and at least two data rows
a table is the one structure every extractor reads the same way; the same facts in prose are re-assembled differently by each engine
0one per set of comparable facts (not scored: rare on homepages)Reported
A visible updated or published date
engines weigh freshness from the text as well as from schema; a date the reader can see is the one they trust
none founda dated line in the copy (not scored: 4% of homepages carry one)Reported

Sentences an engine could lift as they stand:

  • “Sign up for Newsletters and Alerts Sign Up Democrat Eileen Laubacher declares victory over Rep.”
  • “Lauren Boebert in Colorado's 4th Congressional District Democrat Eileen Laubacher declares victory over Rep.”

The lead, as delivered: “Sign up for Newsletters and Alerts Sign Up”

What this scores, and what it is not. These rows read the delivered HTML for the shape of quotable text: nothing here judges whether the copy is good, true or wanted. Counts come from body paragraphs and list items with the navigation, header, footer and forms removed; a page with fewer than five is not scored here. Thresholds were set from a 176-homepage corpus pass and each row states the corpus figure it was set against. Weight 0.8 in the overall and part of the Quote stage, from score version 15.

Crawl waste — 100/100
Section score 100 / 100
MeasureCurrentlyOptimal
Internal links carrying a query string
each parameter form is a separate URL to a crawler; tracking and sort parameters on internal links multiply the pages it thinks you have
1 of 309 - ntv_adpz0, unless the parameter changes the page✓ Passed
Internal links to http://
every one is a redirect before the page, and a redirect is a fetch that returned nothing
4 of 3090Reported
Declared URLs that redirect
a sitemap entry that redirects sends the crawler somewhere the sitemap should have named in the first place
0 of 6 sampled0✓ Passed
Declared URLs that do not answer 200
a declared page that is gone is a fetch spent on a page that will not be indexed
0 of 6 sampled0Reported
Apex and www both answer 200
two hosts serving the same site is every page twice, and the engine has to guess which copy is the real one
no, one redirectsone host, the other redirects✓ Passed

A crawler arrives with a budget. Every row here is a fetch that produced no new page: a redirect, a parameter variant, a case variant, a declared page that points elsewhere. Counted from the delivered homepage, the sitemap, the sampled declared URLs and the daily whole-site read where one exists. None of this moves the grade.

Page subject, the Webref question — 100/100
Section score 100 / 100
MeasureCurrentlyOptimal
Business entities declared on the page
Webref decides which entity a page is about and how much; a page that names several unrelated businesses splits its topicality between them
1one subject, others only by declared relationReported
The page's subject
mainEntity is the explicit declaration; a url on this host is the next best evidence; guessing from the first node is what this check refuses to do
The Denver Post - found by url on this hostdeclared as WebPage.mainEntityReported
Title and h1 name the subject
the two strongest on-page statements of what the document is about
title yes, h1 yesbothReported
Places named in the graph
areaServed is read as places the business serves; a locality the business is IN is a different relation, and both belong on the record
2 (Denver, Denver Metropolitan Area and the state of Colorado)the branch's own locality plus a declared service areaReported
Verdict
single: one entity. related: several, all connected. diluted: unrelated businesses share the page. ambiguous: no subject can be resolved
single - one business entity, and it is the subjectsingle or related✓ Passed

A document does not compete for a keyword alone; the index links it to entities by their Knowledge Graph identity and ranks documents against each other for that entity. This section reads the structured data on the delivered homepage and asks the question that layer asks: which business is this page about, and how is every other business on it related? Chain membership, subsidiary, department and containment are declared relations; a second business with no relation is a claim the engine must arbitrate. Measured, not scored, until the corpus shows how often each verdict occurs.

AI and search agents — 33/100
Section score 33 / 100
MeasureCurrentlyOptimal
Answer engines allowed
these fetch a page while composing a live reply
7 of 17all of them✗ Failed
Search indexes allowed
classic index coverage still drives most discovery
17 of 24all of them✗ Failed
Training crawlers allowed
blocking trainers while allowing answer engines is coherent, not a defect
22 of 46your policy choice — not scoredReported
Regional search engines allowed
Naver, Sogou, 360 and Yisou matter if you sell into those markets and are irrelevant if you do not; that is a business fact we cannot read off the page
7 of 7your policy choice — not scoredReported
Social link previews allowed
blocking these does not touch answer engines, it just makes your links render as bare URLs when anyone shares them
6 of 6your policy choice — not scoredReported
SEO and research crawlers allowed
blocking a link-index crawler costs you competitor visibility, not answer-engine visibility — a different trade from the one above
15 of 15your policy choice — not scoredReported
robots.txt groups
a second * group is invisible to parsers that stop at the first match
701 group per user-agent, no duplicate * group✓ Passed
Answer engines — fetch at question time — 7 of 17 allowed
OAI-SearchBotBLOCKED at / · ChatGPT search index · named rule · line 150: Disallow: /
ChatGPT-UserBLOCKED at / · ChatGPT live fetch · named rule · line 63: Disallow: /
Claude-SearchBotBLOCKED at / · Claude search index · named rule · line 69: Disallow: /
Claude-UserBLOCKED at / · Claude live fetch · named rule · line 72: Disallow: /
PerplexityBotBLOCKED at / · Perplexity index · named rule · line 159: Disallow: /
Perplexity-UserBLOCKED at / · Perplexity live fetch · named rule · line 162: Disallow: /
Gemini-Deep-Researchallowed · Gemini research agent · wildcard rule · group at line 9, no rule matches /
MistralAI-UserBLOCKED at / · Le Chat live fetch · named rule · line 144: Disallow: /
DuckAssistBotBLOCKED at / · DuckDuckGo AI assist · named rule · line 96: Disallow: /
YouBotBLOCKED at / · You.com · named rule · line 198: Disallow: /
PhindBotallowed · Phind · wildcard rule · group at line 9, no rule matches /
Kagibotallowed · Kagi · wildcard rule · group at line 9, no rule matches /
Copilot-Userallowed · Microsoft Copilot fetch · wildcard rule · group at line 9, no rule matches /
Meta-ExternalFetcherBLOCKED at / · Meta AI live fetch · named rule · line 138: Disallow: /
Amzn-Userallowed · Amazon live fetch for Alexa questions · wildcard rule · group at line 9, no rule matches /
Google-Agentallowed · Google user-triggered agent, acts on the web · wildcard rule · group at line 9, no rule matches /
Google-GeminiNotebookallowed · Gemini Notebook user-supplied URL fetch · wildcard rule · group at line 9, no rule matches /
Search indexes — 17 of 24 allowed
Googlebot-Imageallowed · Google image crawler · wildcard rule · group at line 9, no rule matches /
Googlebot-Newsallowed · Google News · wildcard rule · group at line 9, no rule matches /
Googlebot-Videoallowed · Google video crawler · wildcard rule · group at line 9, no rule matches /
Storebot-Googleallowed · Google Shopping · wildcard rule · group at line 9, no rule matches /
Mediapartners-Googleallowed · Google AdSense · wildcard rule · group at line 9, no rule matches /
APIs-Googleallowed · Google push delivery · wildcard rule · group at line 9, no rule matches /
BingPreviewallowed · Bing page preview · wildcard rule · group at line 9, no rule matches /
msnbotallowed · Microsoft legacy crawler · wildcard rule · group at line 9, no rule matches /
SlurpBLOCKED at / · Yahoo Slurp · named rule · line 177: Disallow: /
Yandexallowed · Yandex (umbrella token) · wildcard rule · group at line 9, no rule matches /
coccocbot-weballowed · Coc Coc · wildcard rule · group at line 9, no rule matches /
Googlebotallowed · Google Search and AI Overviews · wildcard rule · group at line 9, no rule matches /
bingbotallowed · Bing and Copilot index · wildcard rule · group at line 9, no rule matches /
ApplebotBLOCKED at / · Apple and Siri · named rule · line 36: Disallow: /
AmazonbotBLOCKED at / · Amazon · named rule · line 27: Disallow: /
DuckDuckBotallowed · DuckDuckGo · wildcard rule · group at line 9, no rule matches /
YandexBotBLOCKED at / · Yandex · named rule · line 195: Disallow: /
BaiduspiderBLOCKED at / · Baidu · named rule · line 45: Disallow: /
Seznambotallowed · Seznam · wildcard rule · group at line 9, no rule matches /
Neevabotallowed · Neeva · wildcard rule · group at line 9, no rule matches /
PetalBotBLOCKED at / · Huawei Petal · named rule · line 165: Disallow: /
Amzn-SearchBotBLOCKED at / · Amazon search eligibility, separate from Amazonbot · named rule · line 30: Disallow: /
MistralAI-Indexallowed · Mistral search index for Vibe · wildcard rule · group at line 9, no rule matches /
ExaSearchBotallowed · Exa AI search index, Web Bot Auth signed · wildcard rule · group at line 9, no rule matches /
Training / corpus crawlers — 22 of 46 allowed
Magpie-crawlerallowed · Magpie AI · wildcard rule · group at line 9, no rule matches /
img2datasetallowed · img2dataset image corpus · wildcard rule · group at line 9, no rule matches /
AwarioRssBotallowed · Awario RSS · wildcard rule · group at line 9, no rule matches /
AwarioSmartBotallowed · Awario smart · wildcard rule · group at line 9, no rule matches /
TurnitinBotallowed · Turnitin · wildcard rule · group at line 9, no rule matches /
archive.org_botBLOCKED at / · Internet Archive · named rule · line 42: Disallow: /
ia_archiverallowed · Internet Archive (legacy) · wildcard rule · group at line 9, no rule matches /
meta-webindexerBLOCKED at / · Meta web index · named rule · line 141: Disallow: /
omgiliBLOCKED at / · Webz.io omgili · named rule · line 153: Disallow: /
cohere-training-data-crawlerBLOCKED at / · Cohere training corpus · named rule · line 78: Disallow: /
PanguBotBLOCKED at / · Huawei PanGu · named rule · line 156: Disallow: /
Ai2Bot-DolmaBLOCKED at / · Allen Institute Dolma · named rule · line 24: Disallow: /
FriendlyCrawlerallowed · FriendlyCrawler ML · wildcard rule · group at line 9, no rule matches /
VelenPublicWebCrawlerBLOCKED at / · Velen · named rule · line 186: Disallow: /
MyCentralAIScraperBotallowed · MyCentral AI · wildcard rule · group at line 9, no rule matches /
DeepSeekBotallowed · DeepSeek · wildcard rule · group at line 9, no rule matches /
ICC-CrawlerBLOCKED at / · NICT ICC · named rule · line 117: Disallow: /
GoogleOtherallowed · Google non-search fetch · wildcard rule · group at line 9, no rule matches /
Google-CloudVertexBotallowed · Vertex AI agent build · wildcard rule · group at line 9, no rule matches /
GPTBotBLOCKED at / · OpenAI training and index · named rule · line 108: Disallow: /
ClaudeBotBLOCKED at / · Anthropic training · named rule · line 66: Disallow: /
anthropic-aiBLOCKED at / · Anthropic legacy agent · named rule · line 33: Disallow: /
Claude-WebBLOCKED at / · Anthropic legacy agent · named rule · line 75: Disallow: /
Google-ExtendedBLOCKED at / · Gemini training and grounding · named rule · line 105: Disallow: /
Applebot-ExtendedBLOCKED at / · Apple training · named rule · line 39: Disallow: /
CCBotBLOCKED at / · Common Crawl · named rule · line 57: Disallow: /
BytespiderBLOCKED at / · ByteDance · named rule · line 51: Disallow: /
meta-externalagentBLOCKED at / · Meta AI training · named rule · line 135: Disallow: /
FacebookBotBLOCKED at / · Meta legacy · named rule · line 99: Disallow: /
cohere-aiallowed · Cohere · wildcard rule · group at line 9, no rule matches /
DiffbotBLOCKED at / · Diffbot knowledge graph · named rule · line 90: Disallow: /
OmgilibotBLOCKED at / · Webz.io · named rule · line 153: Disallow: /
ImagesiftBotallowed · Imagesift · wildcard rule · group at line 9, no rule matches /
TimpibotBLOCKED at / · Timpi · named rule · line 183: Disallow: /
AI2BotBLOCKED at / · Allen Institute · named rule · line 21: Disallow: /
Scrapyallowed · Generic scraper framework · wildcard rule · group at line 9, no rule matches /
SemrushBot-OCOBallowed · Semrush AI corpus · wildcard rule · group at line 9, no rule matches /
Applebot-Extended-AdsBLOCKED at / · Apple ads corpus · named rule · line 39: Disallow: /
TikTokSpiderallowed · TikTok · wildcard rule · group at line 9, no rule matches /
QuillBotallowed · QuillBot · wildcard rule · group at line 9, no rule matches /
Webzio-ExtendedBLOCKED at / · Webz.io extended · named rule · line 192: Disallow: /
ProRataIncallowed · ProRata · wildcard rule · group at line 9, no rule matches /
AwarioBotallowed · Awario · wildcard rule · group at line 9, no rule matches /
MistralAI-Trainingallowed · Mistral training crawl · wildcard rule · group at line 9, no rule matches /
GoogleOther-Imageallowed · Google common crawler, public image URLs · wildcard rule · group at line 9, no rule matches /
GoogleOther-Videoallowed · Google common crawler, public video URLs · wildcard rule · group at line 9, no rule matches /
SEO and market-research crawlers — 15 of 15 allowed
KlaviyoAIBotallowed · Klaviyo Customer Agent knowledge-source crawler · wildcard rule · group at line 9, no rule matches /
AhrefsBotallowed · Ahrefs link index · wildcard rule · group at line 9, no rule matches /
SemrushBotallowed · Semrush crawler · wildcard rule · group at line 9, no rule matches /
MJ12botallowed · Majestic link index · wildcard rule · group at line 9, no rule matches /
DotBotallowed · Moz link index · wildcard rule · group at line 9, no rule matches /
rogerbotallowed · Moz site crawler · wildcard rule · group at line 9, no rule matches /
DataForSeoBotallowed · DataForSEO · wildcard rule · group at line 9, no rule matches /
BLEXBotallowed · WebMeUp link index · wildcard rule · group at line 9, no rule matches /
CloudflareBrowserRenderingCrawlerallowed · Cloudflare Browser Run /crawl · wildcard rule · group at line 9, no rule matches /
Cloudflare-AutoRAGallowed · Cloudflare AutoRAG · wildcard rule · group at line 9, no rule matches /
Peer39_Crawlerallowed · Peer39 ad context · wildcard rule · group at line 9, no rule matches /
AdsBot-Googleallowed · Google Ads quality · wildcard rule · group at line 9, no rule matches /
AmazonAdBotallowed · Amazon Ads · named rule · group at line 200, no rule matches /
AdIdxBotallowed · Microsoft Ads · wildcard rule · group at line 9, no rule matches /
OAI-AdsBotallowed · OpenAI ChatGPT ads page validation · wildcard rule · group at line 9, no rule matches /
Regional search engines — 7 of 7 allowed
Yetiallowed · Naver · wildcard rule · group at line 9, no rule matches /
YoudaoBotallowed · Youdao · wildcard rule · group at line 9, no rule matches /
Exabotallowed · Exalead · wildcard rule · group at line 9, no rule matches /
Sogou web spiderallowed · Sogou · wildcard rule · group at line 9, no rule matches /
YisouSpiderallowed · Shenma mobile search · wildcard rule · group at line 9, no rule matches /
360Spiderallowed · 360 Search · wildcard rule · group at line 9, no rule matches /
Sosospiderallowed · Soso · wildcard rule · group at line 9, no rule matches /
Social link previews — 6 of 6 allowed
Facebotallowed · Meta link crawler · wildcard rule · group at line 9, no rule matches /
Twitterbotallowed · X link preview · named rule · group at line 212, no rule matches /
LinkedInBotallowed · LinkedIn link preview · wildcard rule · group at line 9, no rule matches /
facebookexternalhitallowed · Facebook link preview · named rule · group at line 203, no rule matches /
Pinterestbotallowed · Pinterest · wildcard rule · group at line 9, no rule matches /
Slackbot-LinkExpandingallowed · Slack unfurl · wildcard rule · group at line 9, no rule matches /
153 more crawler names checked — 141 allowed; the ones this robots.txt names or blocks:
AI2Bot-DeepResearchEvalBLOCKED at / · Ai2 — AI assistant or agent · named rule · line 21: Disallow: /
ChatGLM-SpiderBLOCKED at / · AI data crawler · named rule · line 60: Disallow: /
CotoyogiBLOCKED at / · ROIS — AI data crawler · named rule · line 81: Disallow: /
Diffbot-UserBLOCKED at / · Diffbot — AI assistant or agent · named rule · line 90: Disallow: /
imageSpiderBLOCKED at / · AI data crawler · named rule · line 120: Disallow: /
laion-huggingface-processorBLOCKED at / · AI data crawler · named rule · line 126: Disallow: /
LCCBLOCKED at / · AI data crawler · named rule · line 129: Disallow: /
MistralAI-User/1.0BLOCKED at / · Mistral AI — AI assistant or agent · named rule · line 144: Disallow: /
Mozilla-Tabstackallowed · Mozilla that performs programmatic — AI data crawler · named rule · line 224: Allow: /
SBIntuitionsBotBLOCKED at / · SB Intuitions — AI data crawler · named rule · line 168: Disallow: /
SpiderBLOCKED at / · AI data crawler · named rule · line 177: Disallow: /
ThinkbotBLOCKED at / · Thinkbot — AI data crawler · named rule · line 180: Disallow: /
Baiduspider-imageBLOCKED at / · Baidu image search · named rule · line 45: Disallow: /

10 answer engine(s) are blocked. These are the agents that fetch a page while composing a reply, so this directly removes the site from live answers.

Speed a crawler sees, and field data where it exists — 44/100
Section score 44 / 100
MeasureCurrentlyOptimal
Largest Contentful Paint (p75)
how long a real visitor waits before the main thing on the page appears
3.52s2.5s or less✗ Failed
Interaction to Next Paint (p75)
how long the page takes to respond after a real visitor taps something
136ms200ms or less✓ Passed
Cumulative Layout Shift (p75)
how much the page moves under a reader mid-read
0.130.1 or less✗ Failed
Time to First Byte (p75)
the server half of every other number on this list
677ms800ms or less✓ Passed
Largest Contentful Paint trend
holding steady — +1.8% across 40 weekly readings (2026-02-07 to 2026-11-07), real Chrome visitors
3.45s → 3.51slower over timeReported
Interaction to Next Paint trend
getting faster — -7.5% across 40 weekly readings (2026-02-07 to 2026-11-07), real Chrome visitors
146ms → 135mslower over timeReported
Cumulative Layout Shift trend
holding steady — 0% across 40 weekly readings (2026-02-07 to 2026-11-07), real Chrome visitors
0.13 → 0.13lower over timeReported
Machine files answer quickly (measured here)
the median time CrawlCheck waited for your own robots, sitemap and entity files. A crawler that times out records nothing at all, so this is the speed number that decides whether you are read
338 ms median of 5under 500 ms✓ Passed
No slow outlier among them
one slow file is enough to lose a crawl. This is the worst single response of the same set, not an average that hides it
848 ms slowestunder 1500 ms✓ Passed
Lab LCP — synthetic, not field data
a simulated mobile run from Google’s servers. It is NOT what your visitors experienced — no field data exists for this origin
19.14s2.5s or less✗ Failed
Lab Total Blocking Time
main-thread work that would block interaction in the simulated run
1.86s200ms or less✗ Failed
Lab Cumulative Layout Shift
how much the simulated layout moved while loading
0.1930.1 or less✗ Failed

Measured on this exact URL. These are the 75th percentile of what real Chrome users experienced over the last 28 days, not a test run from here — the thresholds are Google’s published ones, the only ones that are.

Payload and render path — 20/100
Section score 20 / 100
MeasureCurrentlyOptimal
Content ratio
the rest is markup a model must read and discard
4.4%10–100% of decompressed bytes are visible text✗ Failed
Decompressed bytes
large pages are fetched less often and truncated more
313,548Bunder 500,000B✓ Passed
Tokens to read this page
estimated at about 4 characters per token. An agent that reads raw HTML pays for every byte of markup, scripts and styles; one that extracts the text pays for the words only. A markdown version served on request (Accept: text/markdown) lets agents take the cheap path.
~78.4k as HTML, ~3.4k as text (4%)an agent reading text pays a fraction of the HTML costReported
Inline JavaScript
inline JS is pure overhead to a text-extracting crawler
43,837Bunder 20,000B✗ Failed
Render-blocking resources
each one delays first paint and the crawler's render budget
270–5✗ Failed
Deferred vs blocking scripts
a blocking script stops HTML parsing dead
2 deferred / 17 blockingevery script deferred or async✗ Failed

Where the bytes go

Visible text13,731 B 4.4%
Inline CSS46,455 B 14.8%
Inline JavaScript43,837 B 14.0%
Structured data2,238 B 0.7%
Markup and attributes204,197 B 65.1%
Render-blocking resources27 10 stylesheets, 17 scripts
Entities with a stable @id1 / 3 33.3%
Credential edges0 none declared

1 of 1 map identity links point at places, not this business — 5990 Washington St, Denver, CO 80216. sameAs asserts that two URLs describe the same entity.

Machine-file trust chain — 100/100
Section score 100 / 100
MeasureCurrentlyOptimal
robots.txt was readable
every other file in the chain is normally discovered through robots.txt
yes200, text/plain✓ Passed
robots.txt names a sitemap
a crawler that has to guess the sitemap path often does not find it
2 Sitemap: line(s)at least one✓ Passed
robots.txt points at llms.txt
an llms.txt nothing links to is only reachable by guessing the conventional path
—named when the file existsNot measured
llms.txt links stay on this host
an off-host URL in your llms.txt sends the model to someone else's page as if it were yours
—most links on this hostNot measured
llms.txt points onward
the chain should keep going: llms.txt is a map, not a terminus
—names the sitemap or the entity graphNot measured
entitymap.json parses as JSON
a machine file that does not parse is worth less than one that is absent, because it looks present
—valid JSONNot measured
entity graph references this host
a graph that never names this site is describing something else
—yesNot measured
Canonical points at this host
a canonical on another host hands the page's standing to that host
same hostsame host as the one serving the page✓ Passed
Canonical uses https
an http canonical invites a redirect chain on every crawl
httpshttps✓ Passed

robots.txt ✓ → sitemap ✓ → llms.txt ✗ → entitymap.json ✗

A ✗ breaks the chain at that point: everything downstream is only reachable by a crawler guessing the conventional path.

Claim consistency — 100/100
Section score 100 / 100
MeasureCurrentlyOptimal
The schema declares an entity for this site
an entity graph that names only other companies gives an answer engine nothing to attach this site to
yes, an organisationone Organization, LocalBusiness or Person whose url is this host✓ Passed
Schema business name appears on the page
an answer engine ingests the assertion and never compares it to the page, so a stale one is repeated for months
—the name the schema asserts is the name a reader seesNot measured
Schema strings are not HTML-escaped
a JSON string is not an HTML context: the entity is read literally, so the business name contains the characters a-m-p
—no &amp; or &#39; inside a JSON-LD valueNot measured
Schema phone appears on the page
a phone number that exists only in the markup is the one an assistant will read out
—the same 10 digitsNot measured
Schema locality appears on the page
a locality nobody states on the page is a claim with no support behind it
—the declared town or city is named in the copyNot measured
Experience claim is backed by the schema
a datable claim in the copy that the structured data contradicts is the cheapest thing in an audit to disprove
—the copy and foundingDate agree within a yearNot measured

Checked against the page’s own visible text, with no extra request. Node type: NewsMediaOrganization.

Agent instruction surface — 100/100
Section score 100 / 100
MeasureCurrentlyOptimal
No agent-directed instructions in machine-only surfaces
hidden text, comments, alt attributes and llms.txt are read by a machine and proofread by nobody
41 surface(s) read, nothing matched0 matches✓ Passed
No hidden block over 50 words
an agent ingests hidden copy at full weight while a reader never sees it
none0 blocks✓ Passed
Agent-instruction file (agents.md)
the file agents are told to obey, as distinct from llms.txt which is the content map. Every Shopify store now ships one; adoption elsewhere is early, so its absence is not a defect — but if you publish one, everything in it is read as instruction
404your choice — not scoredReported

This reports EXPOSURE, not intent. Most hidden text is an old SEO habit or a collapsed menu, and a match here is a prompt to go and read it — not a finding that someone attacked the site.

What each agent receives — 88/100
Section score 88 / 100
MeasureCurrentlyOptimal
Every identity gets a response
a request that dies is indistinguishable from a site that is down, to the agent making it
all 18 answered0 silent✓ Passed
No answer engine is refused
a 403 to GPTBot is the whole answer to why a site is never cited
none refused0 refusals✓ Passed
No answer engine is handed an interstitial
a challenge at HTTP 200 looks fine to a status check and contains no content at all
none0 challenge pages✓ Passed
Crawlers get what an unnamed client gets
these fetches send a crawler's user-agent from OUR address, which is not in the range that operator publishes — so a split has two readings, cloaking or correct spoof-rejection, and only the operator can settle which
noneno identity split✓ Passed
No identity is sent to a different URL
a bot-only redirect quietly removes the page an answer engine was asked to read
none0 redirected✓ Passed
Same x-robots-tag for every identity
a bot-only noindex removes the page from search while the site looks perfectly fine in a browser, and nothing else checks it
consistentno identity-specific header✓ Passed
Answer engines get the same text as a browser
the page a browser renders is not evidence about the page an answer engine was given
100% of the browser's words90-100%✓ Passed
Training crawlers reaching the site
these collect pages for model training rather than answering questions, so refusing them is a policy decision and not a defect — it is reported because the edge may be doing it without anyone having decided, and a 403 here is not the same fact as a 429
Bytespider 429, Meta-ExternalAgent 403 of 6 turned awayyour choice — not scoredReported
Stated robots policy matches actual behaviour
robots.txt is a promise and the edge is the behaviour; neither one on its own can tell you they disagree
OAI-SearchBot: disallowed but served, Claude-SearchBot: disallowed but served, PerplexityBot: disallowed but served, ChatGPT-User: disallowed but served, Claude-User: disallowed but served, Perplexity-User: disallowed but served, Applebot: disallowed but served0 conflicts✗ Failed
Served the same content from every region tested
a site that serves different content by country is telling different engines different things about itself
—identical text worldwideNot measured

One URL, fetched as each named crawler and as a browser. The control fetches agreed (self-similarity 1), so text differences below are differences, not noise. A user-agent is a claim, including when we are the one making it.

IdentityStatusWordsSame textWhat happened
Unnamed client20020991
GPTBot20020991
ClaudeBot20020991
OAI-SearchBot20020991
Claude-SearchBot20020991
PerplexityBot20020991
ChatGPT-User20020991
Claude-User20020991
Perplexity-User20020991
Googlebot20020991
Googlebot Smartphone20020991
Mobile browser20020991
Bingbot20020991
Applebot20020991
Amazonbot20020991
Bytespider4299—rate-limited (HTTP 429) — throttled, not blocked — vendor unidentified; reproduced on a second request
Meta-ExternalAgent4035—refused HTTP 403 — vendor unidentified; reproduced on a second request
CCBot20020991
AgentConflictDetail
OAI-SearchBotdisallowed but servedHTTP 200 with 2099 words
Claude-SearchBotdisallowed but servedHTTP 200 with 2099 words
PerplexityBotdisallowed but servedHTTP 200 with 2099 words
ChatGPT-Userdisallowed but servedHTTP 200 with 2099 words
Claude-Userdisallowed but servedHTTP 200 with 2099 words
Perplexity-Userdisallowed but servedHTTP 200 with 2099 words
Applebotdisallowed but servedHTTP 200 with 2099 words

Which document each identity received

Against the Desktop browser's copy: 17 identities were handed the same document, 0 a different one on at least one field, 2 an error, challenge or redirect instead of the document.

IdentityDocumentDiffers onLooks like
BytespidererrorHTTP 429
Meta-ExternalAgenterrorHTTP 403

Compared on the copy each identity was served: title, H1, robots meta, canonical, word count, unique-token ratio (first screen and whole body), the dates the page states, its schema entities, author and salient terms. Reported, never scored. A difference is usually a device-segmented cache or a consent gate, and the last column says which it looks like.

Per-engine retrieval. Each answer engine reads through named crawlers with different jobs — one builds the index, one fetches live when a user asks, one collects training data. They are separate permissions and a site commonly grants one and refuses another. Nothing here is scored: these same facts are already scored once above, and this measures what an engine is permitted and given — never what a model has retained or would cite, which no CrawlCheck can see from outside.

EngineIndexLive fetchTrainingWhat the edge actually didAddressed by name
ChatGPT✗ blocked✗ blocked✗ blocked✓ served 2099 words— neither file
Claude✗ blocked✗ blocked✗ blocked✓ served 2099 words— neither file
Perplexity✗ blocked✗ blocked— —✓ served 2099 words— neither file
Google AI Overviews / Gemini✓ allowed✓ allowed✗ blocked✓ served 2099 words— neither file
Microsoft Copilot✓ allowed✓ allowed— —✓ served 2099 words— neither file
Apple Intelligence✗ blocked— —✗ blocked✓ served 2099 words— neither file
Meta AI✗ blocked✗ blocked✗ blocked✗ HTTP 403— neither file
Amazon✗ blocked— —— —✓ served 2099 words— neither file
DuckAssist✗ blocked— —— —— not probed— neither file
Mistral— —✗ blocked— —— not probed— neither file
Common Crawl (feeds many models)— —— —✗ blocked✓ served 2099 words— neither file

A blocked training column beside an allowed index column is coherent policy, not a defect: it says "answer with me, do not train on me." The last column is whether your llms.txt or agents.md addresses that engine by name — robots.txt is a permission, those two files are where an operator actually talks to an agent. Naming nobody is the norm and is not scored.

no vantage provider is configured and no extension reading exists for this site in the last 14 days, so this was not measured

Mobile surface — 100/100
Section score 100 / 100
MeasureCurrentlyOptimal
Images and embeds with dimensions declared
Media without width and height reserves no space, so everything below it moves when the image lands. This is read from the markup and is a risk indicator, not a measured CLS value — the real number needs a real page load.
1 of 4697.8% unsized — not scoredReported
Viewport meta
without it a phone renders the desktop layout scaled down, and that is what a mobile crawler records. Roughly 218 million live sites declare one (BuiltWith, August 2026), so its absence is the exception, not the norm.
width=device-widthwidth=device-width, initial-scale=1✓ Passed
Zoom is not locked
locking zoom is an accessibility failure and a one-line fix
readers can zoomno user-scalable=no, no maximum-scale under 1.5✓ Passed
Apple touch icon
what a saved-to-homescreen shortcut and several share surfaces use
declaredone apple-touch-icon link — not scoredDeclared only
Theme colour
sets the browser chrome on mobile; its absence is the cheapest visible gap on this list
absenta theme-color meta — not scoredReported
Beyond the basics
almost every site declares a viewport and almost none declare the rest, so this row is where a site separates itself rather than a place it loses points
none beyond viewportnot scored — these are differentiators, not defectsReported
Local presence, citations and NAP — 86/100
Section score 86 / 100
MeasureCurrentlyOptimal
Links to its Google Business Profile
the profile and the site are one entity to an answer engine; the website field on the profile ties them on the Google side, and this link ties them from the site
yesa g.page, maps.app.goo.gl or maps place URL✓ Passed
That profile link resolves
a dead profile link is worse than none: it asserts an identity that cannot be checked. A 429 or 403 here is Google throttling our check, not a fault on your site, and is left unscored
429 → www.google.com200 on a Google hostReported
Street address in the structured data
a service-area business legitimately omits this, so an absence is reported and not scored against you
declareddeclared for a premises business✓ Passed
Geo coordinates
coordinates are how a machine ties the entity to a place without parsing an address string
declaredlatitude and longitude✓ Passed
Opening hours
“are they open now” is one of the most common questions an assistant is asked about a local business
declaredopeningHours or openingHoursSpecification✓ Passed
Telephone in the structured data
engines read the number written on the page as well; the declared number must match it
declareddeclared✓ Passed
Phone numbers written on the page
Google local extraction keeps the phone numbers on a page only when there are 4 or fewer; a page listing more gives it none
01 to 4Reported
Street addresses written on the page
the same limit applies to addresses: more than 4 on one page and none are kept; a service-area business with none written is not marked down
14 or fewer✓ Passed
Declared phone is written on the page
Google reads phone numbers from the page text, not only from the markup; a number that exists only in structured data has nothing on the page to match
noyes✗ Failed
Coordinates are usable
two decimal places is about a kilometre — fine for a city, useless for a storefront someone is being driven to
1 pair(s), full precisionin range, not 0,0, at least 3 decimal places✓ Passed
Each location has its own coordinates
one centroid copied onto every branch tells an assistant they are all the same place
—no two locations share a pointNot measured
Coordinates agree with the declared country
negating the longitude puts it inside US - a missing minus sign
outside US — longitude signthe point falls inside the country the address names — reported, not scoredReported
Coordinates match the declared address
the address and the point are two independent claims about one place, and nothing else on the web compares them
—within 500mNot measured
Location entities declared
more location entities than real listings is the single most common way a local entity graph goes wrong
11 per real premises — not scoredReported
City on the page vs declared address
the place a page markets and the place it declares are the same, so an engine has nothing to reconcile
both say Denverreported, not scoredReported
Business name in structured data
two spellings of a legal name are two entities to a retrieval system, and it cannot tell which one you are
The Denver Postexactly one spelling✓ Passed
Schema and page agree on the phone number
with only one source there is nothing to compare, which is not the same as agreement
only structured data declares oneboth places state the same numberReported
Phone numbers a machine can read
an assistant dictating a number has to pick one; a second number is usually an old one that still rings somewhere
+13039541010exactly one number✓ Passed
Postal address in structured data
two addresses split the entity across two places
5990 Washington St., Denver, CO, 80216one address, or none for a service-area business✓ Passed
Profiles the site claims
sameAs is an identity claim: every link says this business IS the thing at that URL
3the profiles you actually own✓ Passed
Off-site listings found by your phone number
searched by the one key a service-area business cannot hide; Yelp, Angi, Thumbtack, Houzz, Facebook refuse an outside client and are recorded as our limit, not as an absence
4 on YellowPages, DexKnows, BBBevery one you own, declaredReported
Found off-site, not declared in sameAs
a listing you never linked is corroborated without you: whatever it prints becomes your name and category in the answer
4 — which ones, with a licence0✗ Failed
Listings printing a different business name
two names on one phone number are two entities to a retrieval system
00✓ Passed
Data Axle carries this phone number
Data Axle (formerly Infogroup / infoUSA) compiles business lists and sells them. Google licensed its data from 2005 to 2013; Google’s current business-listings notice names no US supplier. Reported, not scored, and not something to pay for: the next step is the free CrawlCheck registry (/registry).
refused (403) — our limit, not an absence—Reported
Directory listings declared
reported, not scored — how many citations a business needs is a marketing judgement, not a measurement
0the ones that matter for your tradeReported
Fact trace: business name
Carried through every layer: a machine that reads only the text gets it, and so does one that reads only the structured data. Reported, not scored
The Denver Post · HTML ✓ · text ✓ · schema ✓in the HTML, in the readable text and in the structured dataReported
Fact trace: phone
First missing at: readable text. It is only in the structured data, not in words on the page. Reported, not scored
(303) 954-1010 · HTML ✓ · text ✗ · schema ✓in the HTML, in the readable text and in the structured dataReported
Fact trace: email
First missing at: readable text. It is only in the structured data, not in words on the page. Reported, not scored
newsroom@denverpost.com · HTML ✓ · text ✗ · schema ✓in the HTML, in the readable text and in the structured dataReported
Fact trace: street address
First missing at: readable text. It is only in the structured data, not in words on the page. Reported, not scored
5990 Washington St. · HTML ✓ · text ✗ · schema ✓in the HTML, in the readable text and in the structured dataReported
Fact trace: service area
Named only in the structured data: Denver Metropolitan Area and the state of Colorado. A text reader does not learn you serve them. Reported, not scored
0 of 1 declared place in the readable textevery declared place also named on the pageDeclared only

Checked because this site declares a local business entity (LocalBusiness). This measures the site side of Google Business Profile alignment — whether the business points at its own profile and carries the fields a profile is matched on. It does not read the profile itself: that needs an API key, and inventing facts about a listing we cannot see would be worse than reporting nothing. Profile link found: https://maps.app.goo.gl/aK261HiEe923wgBV7.

Every profile below is one the site itself declares in sameAs. Nothing here was discovered by guessing at directories — undeclared listings need an index this scan does not have.

ProfileAnsweredYour phoneYour name
Facebook
https://www.facebook.com/denverpost
not checked——
X
https://x.com/denverpost
not checked——
LinkedIn
https://www.linkedin.com/company/denver-post-media/
not checked——

Directory coverage

Ten sources an answer engine is likely to reach for when asked about a local business, checked against what this site declares. Declared means the site names the profile in its own structured data — the only thing this scan can verify. A listing that exists but is not declared will read as missing here, and that is itself worth fixing: an engine reading your site has no way to find it either.

Yelp
the single most-cited local source in AI answers after Google itself
not declared
BBB
trust signal, and one of the few directories with a verification process an engine can lean on
not declared
Facebook
carries hours and phone, and is read by several engines as a primary source
declared
Nextdoor
hyperlocal, and disproportionately cited for home services
not declared
Thumbtack
category-specific lead surface for trades
not declared
Angi
category-specific, still heavily indexed
not declared
Bing Places
feeds Copilot and, historically, several ChatGPT retrievals
not declared
Apple Maps
the default map on every iPhone, and invisible to most SEO tooling
not declared
Trustpilot
review corpus that answer engines quote directly
not declared
Yellow Pages
low value alone, but a cheap consistency anchor
not declared

9 of 10 are not declared. Each one is a place a retrieval system could have found a second, independent statement of your name, address and phone — and the agreement between those statements is what makes any of them trustworthy.

Machine layer over time. Our own history of a site starts the first time we scanned it; the Internet Archive holds what came before. Nothing here is scored — a site’s past is not a defect, and the Archive’s coverage is uneven, so a missing snapshot says nothing about the site.

Archived robots.txt versions40 distinct, 2002-09-23 → 2004-04-12
Archived llms.txtnone archived
Exposed files and secrets — 89/100
Section score 89 / 100
MeasureCurrentlyOptimal
Version-control folder (.git) (/.git/HEAD)
a readable version-control folder lets anyone download the site's source code and its history, passwords included
not readable (HTTP 403)not readable✓ Passed
Git config file (/.git/config)
a readable version-control folder lets anyone download the site's source code and its history, passwords included
not readable (HTTP 403)not readable✓ Passed
Environment file (.env) (/.env)
environment files hold database passwords and API keys
not readable (HTTP 403)not readable✓ Passed
WordPress config backup (/wp-config.php.bak)
a config backup is served as plain text, with the database password inside
not readable (HTTP 403)not readable✓ Passed
Subversion folder (.svn) (/.svn/entries)
a readable version-control folder lets anyone download the site's source code and its history, passwords included
not readable (HTTP 403)not readable✓ Passed
Apache server-status page (/server-status)
shows every visitor's address and every URL being served, live
not readable (HTTP 404)not readable✓ Passed
Published source maps
a source map hands out the original, unminified source of the site's scripts, comments included
0 of 2 readablenone readable✓ Passed
Keys or secrets in page code
a live key in public code can be used by anyone who reads the page: to send mail, charge cards or read data as the site
Private key private key block in /wp-content/plugins/mng-digisubs/static/mng-digisubs.shared.bundle.jsnone✗ Failed
AI files (llms.txt and the documents it links)
nothing is published for AI agents to read
not applicable: no llms.txt or llms-full.txtnothing private: no keys, internal addresses or personal emailsNot applicable
Account names listed by the site's API (/wp-json/wp/v2/users)
the API does not hand out login names
not listed (HTTP 403)not listed to the public✓ Passed

Something here is readable that should not be. Lock it at the server (deny the path, remove the file, revoke and replace any key shown) before anything else on this report.

Read 2026-11-12 00:17 UTC. Six well-known paths were requested once each, the AI files (llms.txt, llms-full.txt and up to six documents they link) were read for keys, internal addresses and personal emails, and the WordPress account list (/wp-json/wp/v2/users) was requested once; a path counts as readable only when it answers directly with the file itself, so a site that answers every address with a page never reads as exposed. Keys are matched by their published formats and shown masked. Scored in Reach. A readable private file or live key is also raised as a finding, held as advisory (outside the grade) until its accuracy is measured; see /accuracy.

Error pages — 100/100
Section score 100 / 100
MeasureCurrentlyOptimal
A missing page answers 404
the right answer for a page that does not exist
HTTP 404404 or 410✓ Passed
The 404 page helps a visitor on
a 404 with no links is a dead end; one with the menu or a home link keeps the visitor
169 links, 389 wordsa way back (home link or menu)✓ Passed
A missing file answers 404
the right answer for a file that does not exist
HTTP 404404✓ Passed
Error pages reveal server details
server versions, PHP warnings and stack traces tell an attacker exactly which known flaws to try
nothing revealednothing revealed✓ Passed

Two addresses that cannot exist were requested once each (an invented page and an invented script file), with redirects not followed, so the answer is the server's own. Read 2026-11-12 00:17 UTC. Scored in Read: a missing page that answers 200 or redirects home is read as a real page by every crawler.

Sitemap coverage — 100/100
Section score 100 / 100
MeasureCurrentlyOptimal
A sitemap was readable
a sitemap is the only place a crawler learns about pages nothing links to
835 URLs declaredat least one sitemap resolves and parses✓ Passed
Sitemaps named in robots.txt resolve
a robots.txt pointing at a dead sitemap sends every crawler to a 404
2 of 2every named sitemap returns 200✓ Passed
Every sitemap read lists at least one URL
a sitemap that answers 200 with no <url> entries is a dead pointer: crawlers fetch it on every visit and learn nothing, and Search Console reports it as 0 discovered
every file read lists URLs0 empty✓ Passed
Homepage links are declared in the sitemap
a page missing from the sitemap is still findable by following links; a page missing from both is findable by nothing
not measured — only 20 of 6000 child sitemaps were read0 undeclaredReported
Sampled declared URLs resolve
a sitemap that lists dead URLs spends a crawler's budget on nothing
0 of 6 broken0 broken✓ Passed
Sampled declared URLs are final
declaring the pre-redirect URL makes every crawl pay an extra hop
0 of 6 redirect0 redirects✓ Passed
URLs declared in the sitemap835
20 of 6000 child sitemaps read — the count is a floor, not a total
Internal links on the homepage202
Linked but not declarednot measured
only 20 of 6000 child sitemaps were read, so a page missing from what we read may be declared in a part we did not read
Declared URLs sampled6 checked · 0 did not resolve · 0 redirected

This compares the sitemap against the links on the homepage only, so it finds pages the sitemap omits — it cannot prove a declared page is unreachable, because that needs a full crawl. The reverse gap (declared but linked from nowhere) is real and is not measured here. A page missing from the sitemap is still findable by following links; a page missing from both is findable by nothing.

Naming and case consistency — 80/100
Section score 80 / 100
MeasureCurrentlyOptimal
Hostname case
hostnames are case-insensitive but a mixed-case host splits logs and analytics
lowercasealways lowercase✓ Passed
Internal link paths
paths ARE case-sensitive on most origins: /About and /about are two URLs, two cache keys and two index entries
all 309 lowercase98–100% lowercase✓ Passed
Trailing slash
a page linked as /x and /x/ is two URLs to a crawler; both get fetched and both compete for the same canonical
1 target linked both with and without a slash (/contact-us)one form per URL, and the other form redirects to it✗ Failed
Host form in absolute links
links to both www and the bare domain send a crawler to two copies of the site whatever the canonical says
consistentone hostname in every self-link✓ Passed
Query strings in internal links
a query string makes a distinct URL; navigation that carries one produces near-duplicate pages
noneunder 2% of internal links (and fewer than 3)✓ Passed
Image signals — 80/100
Section score 80 / 100
MeasureCurrentlyOptimal
Images on the page
counted from <img> tags in the delivered HTML
44 (3 SVG)Reported
Missing alt text
alt is the text an engine reads for a picture, with the words around it; empty alt is correct for decoration, missing alt is a hole
0 missing, 1 empty (0% missing)0 missing; empty only on decorative images✓ Passed
Width and height declared
without both, the browser cannot reserve space and the page shifts as pictures load (the CLS score)
0 of 44all✗ Failed
Lazy-loaded
lazy-loading the hero image delays the largest paint; lazy-loading the rest speeds everything else
0 of 44below the fold only✓ Passed
Modern formats (WebP/AVIF)
smaller files, same picture
0 of 44mostReported
Hero image prioritised
the one image the browser should fetch first
5 fetchpriority=high, 5 preloadedone, when the largest paint is an imageReported
Entity image in structured data
what an engine shows next to the name; a URL in image or logo, ideally an ImageObject with dimensions
yesan image or logo on the organisation node✓ Passed
og:image
the picture a link preview uses when the page is shared
yespresent✓ Passed
Content Credentials and AI labels
read from each image file's own C2PA manifest and IPTC source-type label, the tags AI generators and editors write; most AI images carry no label, so no label does not mean a camera took it
8 of 8 photos read: 0 made by AI, 0 edited with AI, 0 camera, 0 with Content Credentials, 8 no labellabels that say how each image was madeReported

What an engine can learn from the pictures. Five rows score: missing alt, declared dimensions, nothing lazy-loaded above the fold, an entity image in JSON-LD and an og:image. Empty alt, file format and hero priority are reported and never scored — empty alt is correct on a decorative image, and format is a preference, not something an engine fails to read.

What this scan could not see 25 of 26 scored sections measured · 16 of 18 identities answered · 0 stage failures · 1 reading from 1 network (cloudflare) within 6 h · 5 not observed
SubjectStateAttemptedReason
nl_entitiesskippednothe deep entity read runs for domains under continuous record; this scan used the keyless resolver
vantageunmeasurednono vantage provider is configured and no extension reading exists for this site in the last 14 days, so this was not measured
identity:BytespiderrefusedyesHTTP 429
identity:Meta-ExternalAgentrefusedyesHTTP 403
section:commerceunmeasuredunknownno row of this section was produced for this page; it did not enter the grade

A non-observation is recorded, never scored: an unmeasured row is excluded from its section, not counted as a fail. Counts only; there is no composite confidence number.

Where each fact on this page comes from 16 facts · 21 statements · no disagreements
FactValue statedStated in
nameThe Denver PostJSON-LD LocalBusiness
meta og:site_name
agrees
telephone+13039541010JSON-LD LocalBusinessone source
emailnewsroom@denverpost.comJSON-LD LocalBusinessone source
address5990 Washington St., Denver, CO, 80216JSON-LD LocalBusinessone source
hoursMo 8AM-4PM; Tu 8AM-4PM; We 8AM-4PM; Th 8AM-4PM; Fr 8AM-4PMJSON-LD LocalBusinessone source
geo39.7392,104.9903JSON-LD LocalBusinessone source
urlhttps://www.denverpost.com/JSON-LD NewsMediaOrganization
JSON-LD LocalBusiness
agrees
logohttps://i0.wp.com/www.denverpost.com/wp-content/uploads/2020/11/denverpost.jpg?w=1200&crop=00px100630px&ssl=1JSON-LD LocalBusinessone source
foundingDate1892JSON-LD LocalBusinessone source
areaServed1 area: Denver Metropolitan Area and the state of ColoradoJSON-LD LocalBusinessone source
sameAs3 profilesJSON-LD LocalBusinessone source
titleThe Denver Post – Colorado breaking news, sports, business, weather, entertainment.<title>agrees
The Denver Postmeta og:title
descriptionColorado breaking news, sports, business, weather, entertainment.meta og:descriptionone source
canonicalhttps://www.denverpost.commeta og:urlone source
languageen-US<html lang>agrees
en_USmeta og:locale
imagehttps://www.denverpost.com/wp-content/uploads/2020/11/denverpost.jpgmeta og:image
meta twitter:image
agrees

Read from the page this scan received: its schema nodes, meta tags, link elements and page links, each value kept with the element that stated it. A fact stated in several places should say the same thing in each. Recorded, not scored.

If you would rather not do this yourself

Fix everything in this report
The 11 findings above, including 6 scored serious, corrected on your site and re-measured afterwards. You get a change receipt: the before and after, each sealed and independently verifiable on your own machine, so the fix is evidenced rather than asserted.
  • The machine layer, authored for the business. An entity map, an agents.md and an llms.txt written from the site’s own published facts rather than templated — the entity map being what lets a retrieval system tell this business apart from one with a similar name. Sold separately until now.
  • Thirty days of monitoring, included. The site is re-scanned twice a day and any crawler-visible change is posted to your webhook, so a regression is found by us rather than by you.
  • A second sealed receipt at day thirty. The first proves the fix landed; the second proves it held. Both verify on your own machine against a published root, with no need to trust us.
  • Done is defined by re-measurement, not by assertion. A finding that is still there on the re-scan is not finished work.
Get this fixed — $100
one local-business site · what that covers

The fix includes the machine layer: an entity map, an agents.md and an llms.txt authored for this business rather than templated — 7 of the 8 agent surfaces checked above are absent here. A bigger site, or several domains at once, is quoted against the report first: email hello@crawlcheck.io with this address.

Measured, not in the grade (16)

These are measured on every scan and shown in full. Each says why it carries no weight yet: most are waiting on enough sites to calibrate against, and some depend on an integration a site may not have, which must never decide a grade.

Agent surfaces (emerging, not scored) — 12 of 12 rows read

Not in the grade: these are published standards at very different stages of adoption, and several do not apply to every business.

Rows with a reading (not in the grade)12 / 12
MeasureCurrentlyOptimal
agents.md
The one surface here that pays off for an ordinary business today. Almost every agents.md on the web is a platform default its owner never wrote
absentAn authored file at /agents.md: what the business does, the area it serves, what an agent must collect before acting, and what it must not promiseReported
SKILL.md
The agent-skills convention. A 200 that carries HTML is a soft 404 and counts as absent - a naive check would call it present
absent (404)A markdown file at /SKILL.md with YAML frontmatter naming the skill, then what an agent can do here and howReported
Markdown for agents
Cuts what an agent must parse. A toggle on some edges rather than a build
absent (text/html; charset=utf-8)Accept: text/markdown returns a markdown body; HTML stays the default for browsersReported
DNS-AID records
An IETF draft (DNS for AI Discovery). Early: almost no site has these yet, so absence is not a defect
absentSVCB or TXT records at _index._agents (and _mcp._agents / _a2a._agents) pointing agents at your MCP server or agent cardReported
Link response headers
Useful where a relation is real. Inventing one to score a point is the cargo-culting these lists encourage
present: <https://www.denverpost.com/wp-json/>; rel="https://api.w.org/", <https://wp.me/7yQli>; rel=shortlinkRegistered relations only - canonical, alternate, describedby. Never an invented rel to satisfy a checkerReported
ARD manifest
The index agent registries crawl. Applies once the site has an agentic resource to list; a brochure site has nothing to put in it
absent/.well-known/ard.json (Agentic Resource Discovery v0.91): one entry per MCP server, agent card, skill or API this site offers, each with a urn:air:denverpost.com:<name> identifier, a media type, a url, and 2-5 representativeQueriesReported
Agent skills index
For sites that expose actions an agent can perform. A brochure site has no skills to declare
absent/.well-known/agent-skills/index.json listing each skill with a name, description, url and sha256Reported
API catalog
NOT APPLICABLE: no public API found. A catalog of nothing is not an improvement
absentNothing to publish - no API was discoverable on this siteReported
MCP server card
Applies once you run an MCP server. Publishing a card without one advertises an endpoint that does not answer
absent/.well-known/mcp/server-card.json with serverInfo, transport endpoint and capabilitiesReported
Agent payment protocols
NOT APPLICABLE: no Product, Offer or checkout found. A scanner that docks a service business for this is measuring the wrong site
not applicableNothing to publish - no commerce signals on this siteNot applicable
OAuth / protected-resource metadata
NOT APPLICABLE: nothing to authenticate against
not applicableNothing to publish - no protected API on this siteNot applicable
Web Bot Auth
Identifies you as a caller, not as a destination. Irrelevant to a site that only receives traffic
informationalA JWKS at /.well-known/http-message-signatures-directory - only if THIS site sends signed agent requests to othersReported

None of these affect the grade. They are published standards at very different stages of adoption, and several do not apply to every business — where that is true this table says so and why. A checklist that counts them all is measuring the wrong site.

Content entities (measured, not yet scored) — 4 of 4 rows read

Not in the grade: the reading is sound but the scoring rule is not settled, and a rule that may move should not move a grade.

Rows with a reading (not in the grade)4 / 4
MeasureCurrentlyOptimal
Entities read from the content
declared entities come from the page's own JSON-LD; the rest are a HEURISTIC read of the prose and are labelled as such
24the things this page is aboutReported
Resolve to a public entity record
resolution means Wikidata holds an item for this name. It is not a ranking signal and does not mean the page ranks for it
15 of 24a named thing the public record knowsReported
Sense is the primary one, not the page's
a bare name resolves to whatever the public record treats as its main sense — "Aurora" reads as the light display, not the Colorado city. The description is printed beside every resolution so you can see which sense you got. Resolving in CONTEXT needs a contextual model and is not measurable from a keyless lookup
not disambiguatedresolved in contextReported
Resolved and absent from the entity graph
a subject the prose is about, that the public record recognises, and that this site's own structured data never names — the writer's gap, not the machine's
140Reported

Entities are resolved against Wikidata — free, keyless, and it answers the question a writer actually has: does this thing exist as a public entity record, or is it just a phrase. Two evidence classes, kept apart: declared entities are read from the page's own JSON-LD; detected entities are a heuristic read of the prose and will contain some noise. Resolution is not a ranking signal.

Written about, recognised by the public record, absent from this site's structured data:

  • Denver Broncos — Q223507 · National Football League franchise in Denver, Colorado · 11 mentions
  • Colorado — Q1261 · state of the United States of America · 10 mentions
  • Broncos — Q60740406 · untrained horse or a horse that habitually bucks · 8 mentions
  • Daiyan Henley — Q114245319 · American football player (born 1999) · 6 mentions
  • Opinion — Q3962655 · judgement, viewpoint, or statement that is not conclusive · 5 mentions
  • BestReviews — Q7020906 · American media company · 3 mentions
  • Boulder — Q581776 · natural rock fragment larger than 25.6 cm in diameter (larger than 200 mm diameter according to ISO 14688) · 3 mentions
  • Thanksgiving — Q13959 · holiday in various countries · 3 mentions
  • Aurora — Q40609 · natural light display that occurs in the sky, primarily at high latitudes (near the Arctic and Antarctic on Earth) or even on other planets · 2 mentions
  • Carolina Panthers — Q330120 · National Football League franchise in Charlotte, North Carolina · 2 mentions
  • Congressional District — Q192611 · territorial division made or used for elections · 2 mentions
  • Kansas City Chiefs — Q223522 · National Football League franchise in Kansas City, Missouri · 2 mentions

2 more not listed.

Nothing in this section affects the grade — the corpus measures the distribution first.

Service area, as declared (measured, not scored) — 4 of 6 rows read

Not in the grade: a declared service area can be right or wrong only against facts this scan cannot see.

Rows with a reading (not in the grade)4 / 6
MeasureCurrentlyOptimal
Service areas declared in schema
the list an answer engine reads when asked "do they cover X"; a business that serves it but never declares it is invisible for that question
1every place the business actually serves, as City or Place nodesReported
Declared radius
the radius is the one claim that bounds all the others
no GeoCirclea GeoCircle around the real centreReported
Areas that could be placed on a map
a name that no gazetteer resolves is a name an engine cannot place either
0 of 1every declared name resolves to a placeReported
Areas with a page of their own
declaring an area and having a page for it are different claims; the page is what gets cited
0 of 1a location page per area that mattersReported
Declared areas outside the declared radius
the graph contradicts itself: the circle says no, the list says yes, and a reader has to guess which one is true
nonezeroReported
Farthest declared area
the distance the business is committing to on the record
—inside the radiusNot measured
declared centre

declared, has its own page · declared in schema only · outside the declared radius · ring = GeoCircle

Not placed (no gazetteer match near the centre): Denver Metropolitan Area and the state of Colorado

Not scored. Positions are OpenStreetMap place centroids resolved once per name; a page counts when a sitemap URL contains the place name. What this shows is what the site declares, laid out so the contradictions are visible; whether the business really works there is not on the wire.

The whole site, not just the front door (measured, not scored) — 1 of 1 rows read

Not in the grade: the grade stays anchored on the homepage so it is comparable across sites and days.

Rows with a reading (not in the grade)1 / 1
MeasureCurrentlyOptimal
Whole-site read
the homepage is graded now; the rest of the site is being read in the background. Re-scan in about a minute to see it
queued on this scanup to 60 declared pages, read once a dayReported
Freshness, as the site declares it (measured, not scored) — 9 of 10 rows read

Not in the grade: every date here is one the site published, so this reports what it claims rather than what is true. Calibrated 2026-09-16 on 114 records: the only row most sites carry (a sitemap that declares lastmod, 68%) is not a defect when absent, and the rows that would be defects (every lastmod stamped on one day, 8%; the sitemap and dateModified disagreeing by over a month, 2%) can be measured on too few sites to carry weight.

Rows with a reading (not in the grade)9 / 10
MeasureCurrentlyOptimal
Sitemap URLs with a change date
lastmod is the only change signal an engine can read without an account. A sitemap without dates tells a crawler nothing about what to re-fetch first
835 of 835every URL, with its real dateReported
Newest sitemap date
what the site says was touched most recently; the gap to today is a claim about activity, not a defect on its own
2026-11-11 (today)within the last month for a site that publishesReported
Spread of sitemap dates
a spread of dates is what a real edit history looks like
25 distinct days across 835 dated URLs (2026-10-15 to 2026-11-11)many days - real edit historyReported
Homepage Last-Modified header
the HTTP-level change date; a cache in front usually sets it, so it describes the copy served, not the edit
2026-11-12 (today)sent, and trueReported
Homepage dateModified in JSON-LD
the date the structured data asserts; an engine can quote it beside a fact, which is why a stale one is worse than none
nonepresent, and moved when the page changedReported
Dated elements on the page
a <time datetime> element is a date a machine can read without guessing at the prose
7 (newest 2026-11-11, today)every date a person can see also marked upReported
RSS or Atom feed
a refusal is a fact about the request, not the feed; the file may be fine for readers the shield allows
declared (www.denverpost.com/feed/), but the site refused CrawlCheck’s request for itdeclared, valid, recentDeclared only
Unchanged page answers 304 to a re-check
a crawler re-checking a page it already has sends If-None-Match or If-Modified-Since; a 304 costs it a few hundred bytes instead of the whole page, so it can afford to check more often
no ETag or Last-Modified, so a crawler cannot ask304 Not ModifiedReported
IndexNow (instant change pings to Bing and others)
IndexNow is sent by the site, so a scanner cannot see it; ChatGPT search draws on Bing's index, which IndexNow updates within minutes. CrawlCheck's guide shows how to set it up and confirm a 200
cannot be seen from outsidepinged on every publishReported
robots.txt history in the public archive
how long the site has been keeping a machine-readable front door; time depth is the one claim a new site cannot manufacture
first seen 2002-09-23, 40 versionsa long recordReported

Every date in this section is one the site published about itself. The section reports the claims and where they disagree; it does not decide whether a page is out of date, because only the business knows that. None of this moves the grade.

Local intents, the Maps vocabulary (measured, not scored) — 2 of 3 rows read

Not in the grade: the intent vocabulary is recovered names with no weights, and a claimed intent without a page is a content decision, not a defect; reported until the corpus says how it distributes.

Rows with a reading (not in the grade)2 / 3
MeasureCurrentlyOptimal
Local intents the site's own declarations name
a local query is resolved into one of 446 intent types before any place is retrieved; the site's business types, Service nodes, title and headings are what name them here
1 (post offices)every intent you serve, and none you do notReported
Claimed intents with a page linked from the homepage
an intent named only in a paragraph competes with every page on the web that names it; a page whose address carries the intent is what a query lands on
0 of 1 - no page for: post officesall of themReported
Intents searchers used to find the Business Profile
no Business Profile search terms on record for this domain
not measuredread from the profile's search termsNot measured
Conversion path on the page (measured, not scored) — 5 of 6 rows read

Not in the grade: whether a visitor can act is a business judgement, and the grade is for what a machine receives.

Rows with a reading (not in the grade)5 / 6
MeasureCurrentlyOptimal
Phone link on the page
on a phone, a tel: link is the shortest path from reading to calling; a printed number is not tappable
noneat least one tap-to-call linkReported
Phone link before the fold
the visitor who arrived from an answer engine has already decided; the number should be where they land
noin the first quarter of the pageReported
Quote or contact form
a form is the only path that works when the office is closed
1 found, one before the foldone form, reachable without scrollingReported
Calls to action
counted from link and button text: quote, estimate, call, book, schedule, contact
6 (first one before the fold)one clear ask, earlyReported
Contact or quote page linked
the page a visitor goes to when the hero did not convert
yeslinked from every pageReported
Sticky call button (mobile)
a fixed call bar keeps the number reachable at every scroll position on a phone
not detectedpresent on service sitesReported

The SXO layer: whether a visitor who arrived ready to act can act. Counted from the delivered HTML, so a form inside a third-party iframe shows as a form only if the iframe names one. None of this moves the grade.

What AI looks for vs what your page shows (measured, not scored) — 0 of 1 in range

Not in the grade: the effects come from one model ranking fictional businesses, and a fact a business does not have should never be added to please a model.

Rows in range (not in the grade)0 / 1
MeasureCurrentlyOptimal
Business name in the text
An agent reading this page through a fetch tool gets the text and often only its opening part; a name that lives only in markup or images is not in what it reads. Position is reported, not graded
word 1 of 2,099 (1% in)in the opening text, where a reader cut short still finds itReported
Phone number in the text
A number that exists only as a tel: link or in markup is invisible to an agent reading the text; written out, it can be quoted
not in the text (+13039541010 is in a link or markup only)written out in the opening text✗ Failed
Higher rating
changing “Rated 4.8 of 5” to “Rated 4.1 of 5” dropped the business in 176 of 177 paired tests, 3.87 places on average; 2 of 2 models tested punish it
not found on the homepageshown, if true of the businessReported
Many reviews
changing “212 Google reviews” to “9 Google reviews” dropped the business in 136 of 177 paired tests, 1.58 places on average; 2 of 2 models tested punish it
not found on the homepageshown, if true of the businessReported
Serves the asker's city
changing “Serves the asker’s city and nearby” to “Serves a town 40 miles from the asker’s city” dropped the business in 117 of 175 paired tests, 1.52 places on average; 2 of 2 models tested punish it
shown: service area in structured datashown, if true of the businessReported
Licence number shown
changing “State licence #48213, active” to “No licence information” dropped the business in 85 of 175 paired tests, 0.78 places on average; 1 of 2 models tested punish it
not found on the homepageshown, if true of the businessReported
Insurance stated
changing “Insured and bonded” to “No insurance information” dropped the business in 68 of 173 paired tests, 0.64 places on average; 0 of 2 models tested punish it
not found on the homepageshown, if true of the businessReported
Fast reply
changing “Replies to inquiries within 1 hour” to “Replies to inquiries within 3-5 days” dropped the business in 51 of 176 paired tests, 0.38 places on average; 0 of 2 models tested punish it
not found on the homepageshown, if true of the businessReported
Years in business
changing “In business since 2009” to “Founded in 2025” dropped the business in 45 of 172 paired tests, 0.36 places on average; 0 of 2 models tested punish it
shown: founded 1892 in structured datashown, if true of the businessReported
Emergency service
changing “24/7 emergency service” to “Weekday appointments only” dropped the business in 44 of 177 paired tests, 0.29 places on average; 0 of 2 models tested punish it
not found on the homepageshown, if true of the businessReported
Phone listed
changing “Phone (555) 010-4477” to “No phone listed (contact form only)” dropped the business in 32 of 178 paired tests, 0.19 places on average; 0 of 2 models tested punish it
shown: phone in structured datashown, if true of the businessReported
Hours stated
changing “Hours: Mon-Sat 7am-6pm” to “Hours: not listed” dropped the business in 28 of 175 paired tests, 0.13 places on average; 0 of 2 models tested punish it
shown: opening hours in structured datashown, if true of the businessReported
Prices published
changing “Prices published, free written estimates” to “Call for pricing” dropped the business in 11 of 173 paired tests, 0.03 places on average; 0 of 2 models tested punish it
shown: $60,000shown, if true of the businessReported

When an AI model picks a business, it weighs facts like these. CrawlCheck measures how much each one moves a model’s ranking (five businesses ranked with and without the fact, openai/gpt-oss-120b) and checks your homepage for it. The facts that cost the most when missing and are not on your homepage: higher rating, many reviews. Add only what is true of the business. Full method: the sensitivity census.

Trust and reputation (measured, not scored) — 7 of 8 in range

Not in the grade: these are signals to check, not proof: a complaint can come from someone spoofing the number, and a young domain can be an honest new business.

Rows in range (not in the grade)7 / 8
MeasureCurrentlyOptimal
Business phone on the page
with no number on the page, an agent cannot match the site to its listings or check the number's reputation
none founda phone number visitors and agents can check✗ Failed
Same phone on the page and in its markup
two different numbers for one business make every listing and answer less certain
consistentconsistent✓ Passed
Malware or phishing listing
a listed site is warned on or dropped by browsers and search, and refused by agents that check first
no match in the checked threat sourceno match✓ Passed
Domain age
most scam and copycat sites are weeks old; a new domain is not proof of anything, only a reason to check
1995-03-10 (31 years)older than 90 days✓ Passed
Registration
an expiring domain can lapse and be bought by someone else
renews by 2028-03-11more than 30 days left✓ Passed
Parked, for sale or placeholder
a parked or for-sale page is not a working business
nono✓ Passed
Redirects to another organisation
a site that forwards to a different organisation is not the business it names
nono✓ Passed
Homepage text copied on other domains
near-identical visible text on different domains, with each site's own name, numbers and links masked. Copycat sites clone a real business's page
none foundnone✓ Passed

Red flags: Business phone on the page. These are the checks an AI agent should run before it cites or calls a business: its phone number in public complaint data, its listing for malware or phishing, how old and how secure its domain is, and whether the site is really the business it names. Reported, not scored.

Claims and their evidence (measured, not scored) — 3 of 3 in range

Not in the grade: a source that cannot be read is not evidence against a claim, and a listing can lag a real change, so this reports what agrees rather than grading it.

Rows in range (not in the grade)3 / 3
MeasureCurrentlyOptimal
Profile link: facebook.com
an outside source agrees, so an assistant repeating this is on firm ground
✓ facebook.com (the profile links back to this site)confirmed by a source outside the site✓ Passed
Profile link: x.com
an outside source agrees, so an assistant repeating this is on firm ground
✓ x.com (the profile links back to this site)confirmed by a source outside the site✓ Passed
Profile link: linkedin.com
an outside source agrees, so an assistant repeating this is on firm ground
✓ linkedin.com (the profile links back to this site)confirmed by a source outside the site✓ Passed

3 confirmed outside the site · 0 contradicted · 0 where the markup and the page disagree · 0 stated only by the site · 0 with no readable source. Built from this scan’s own readings, no extra requests. As a graph (schema.org Claim and ClaimReview, signed): claims.json.

Site safety (measured, not scored) — 23 of 29 in range

Not in the grade: only a malware or phishing listing changes what AI systems do with a site, and the rest is protection rather than a property of what a machine is served.

Rows in range (not in the grade)23 / 29
MeasureCurrentlyOptimal
Malware or phishing listing
no match means none was found in that source, not that the site is proven clean
no match in Cloudflare security resolver (malware and phishing threat intelligence)no match✓ Passed
Homepage links to listed sites
a link to a malware or phishing domain sends visitors there, and injected outbound links are often the first sign a site has been hacked
none of 10 linked domainsnone✓ Passed
Content served only to crawlers
injected spam and cloaked redirects are usually shown to crawlers only, so the owner never sees them in a browser; a difference on the first read is re-read in paired rounds before it is reported
none: every named answer and search crawler got the outside scripts, links and redirects the unnamed client got (19 identities sent)none: crawlers get the scripts, links and redirects visitors get✓ Passed
HTTPS homepage
an agent or browser that cannot load the page securely shows a warning or nothing
loads over HTTPS (200)loads over HTTPS✓ Passed
Certificate
an expired certificate blocks every visitor and crawler with a security error
newest valid to 2027-02-04 (84 days)valid, renewed before expiry✓ Passed
HSTS (HTTPS on every return visit)
browsers that have seen the site refuse plain HTTP for the next year
max-age 31536000, includeSubDomainsmax-age of at least one year✓ Passed
Script-injection protection (Content Security Policy)
a wildcard source lets an injected script load from anywhere. Fix: list the hosts the site actually uses
enforced, but scripts are allowed from any source (*, https: or http:)an enforced policy that limits where scripts come fromWarning
Clickjacking protection (framing)
any site can load the page in a hidden frame and trick visitors into clicking. Fix: X-Frame-Options: SAMEORIGIN or frame-ancestors 'self'
not setDENY, SAMEORIGIN or frame-ancestors✗ Failed
MIME-sniffing protection (nosniff)
a browser may run an uploaded file as a script because it looks like one. Fix: X-Content-Type-Options: nosniff
not setset✗ Failed
Referrer-Policy
current browsers already pass other sites the origin only; setting it makes that hold in older browsers too
not set (current browsers default to strict-origin-when-cross-origin)strict-origin-when-cross-origin or stricterReported
Browser permission restrictions (camera, microphone, location)
an advisory, not a sign of misuse: with no policy, any script on the page, third-party ones included, may ask the visitor for camera, microphone or location. Fix: Permissions-Policy: camera=(), microphone=(), geolocation=()
no Permissions-Policyblocked with an empty list, e.g. camera=()Warning
Insecure resources on the HTTPS page
http:// scripts, images or frames on an HTTPS page can be swapped in transit; browsers block or flag them
00✓ Passed
Software version shown in headers
a visible version tells attackers which known flaws to try
none shownnone shown✓ Passed
Cookies without the Secure flag
a cookie without Secure can be sent over plain HTTP. Fix: add Secure where each is set
0 of 30✓ Passed
Session cookies readable by page scripts
analytics and preference cookies are not judged here; cookies set after signing in were not observed
not applicable: none of the 3 cookies observed is a session or login cookieHttpOnly on every session cookieNot applicable
Forms that send over plain HTTP
every form posts over HTTPS
none of 3 formsnone✓ Passed
Where forms send their data
nothing typed into these forms leaves the site's own host
only this sitethis site or a processor the owner chose✓ Passed
HTTP to HTTPS redirect
the first answer moves the visitor to HTTPS
http://www.denverpost.com (301) → https://www.denverpost.com (200)one redirect straight to HTTPS, never back to HTTP✓ Passed
jquery 3.5.1
no advisory in OSV.dev (npm advisories) lists this version (2026-11-12); a new one is picked up on a later read
no published advisoryno library with a published advisory✓ Passed
Script and form hosts in threat intelligence
checked against Cloudflare security resolver (malware and phishing threat intelligence); no match means none was found in that source, not that a host is safe
no match for 15 hostsno match✓ Passed
Same protections on login, contact and checkout pages
the pages that take visitors' details carry the homepage's protections
same as the homepage on the login page (/login), contact page (/contact-us), checkout page (/2026/11/10/colorado-buffaloes-basketball-ian-inman-san-diego/)every sampled page as protected as the homepage✓ Passed
Security changes since the last read
new form destinations, script providers and advisories are listed so the owner can confirm each was intended
since 2026-11-10: new script provider embed.sendtonews.comevery new script or form destination intendedWarning
Email forgery protection (DMARC)
without an enforcing policy, anyone can send email that appears to come from this domain
p=quarantinep=quarantine or p=reject✓ Passed
SPF
names the servers allowed to send this domain's mail
present, ends failpresent, ends fail or softfail✓ Passed
CAA (who may issue certificates)
limits which certificate authorities can issue a certificate for the domain
noneset✗ Failed
DNSSEC
protects visitors from forged DNS answers
not signedsigned✗ Failed
Domain registration
a lapsed registration takes the site and its email offline and can be bought by someone else
registered 1995-03-10, renews by 2028-03-11renewal more than 30 days away✓ Passed
Google Safe Browsing (Chrome, Firefox, Safari, Android)
check it by hand: transparencyreport.google.com/safe-browsing/search?url=www.denverpost.com
not read in this scanno unsafe contentReported
OpenPhish phishing feed
a live phishing feed, updated hourly, that mail filters and security tools import
not listednot listed✓ Passed
Registrar transfer lock
the domain cannot be moved to another registrar without unlocking it first
onon (client transfer prohibited)✓ Passed
HSTS preload list
a preloaded domain is HTTPS-only in every major browser from the very first visit, so no first request can be intercepted or downgraded
not preloaded: Subdomain; No preload directivepreloadedReported
Third-party scripts and styles
unpinned library files from ajax.googleapis.com, cdn.jsdelivr.net: if that CDN is compromised, the altered file runs here; add integrity= with the file's hash
18 from 17 outside hosts, 0 pinned with integrity=static library files pinned with integrity=✗ Failed
Scripts from CDNs taken over in 2024
polyfill.io and its sister CDNs (bootcss.com, bootcdn.net, staticfile.org) changed hands in 2024 and served malicious code to the sites loading them; remove the tag
nonenone✓ Passed
Hacked-site signatures
hidden spam links, cryptominers and obfuscated loaders are the usual traces of a hacked site
none foundnone✓ Passed
Subdomain takeover
a subdomain left pointing at a hosting account that was closed can be claimed by anyone and used to host phishing under this domain's name
none of 24 common subdomainsnone✓ Passed
Regression tests from this site's own fixes
each problem this domain had and fixed is re-run on every later scan; one that returns is marked as a regression, not as a new finding: Almost nothing a machine receives from this page is readable text
3 fixed problems re-checked on every scan · 2 holding · 1 came backevery fixed problem stays fixed✗ Failed

Read 2026-11-12 00:17 UTC and refreshed daily. The malware and phishing listing is the only row here that changes what AI systems do with a site. The rest is protection against the site being hacked or its email being forged, which is what gets sites listed; none of it is a ranking factor, so this section is not scored.

Security filters that do not publish their ratings for automated reading. Check each one and request a correction there: McAfee WebAdvisor (site lookup and re-rating request) · Norton Safe Web · Microsoft SmartScreen (Edge) · Google Safe Browsing. A new domain shows as unrated or “Unknown” in these filters until they first crawl it.

AI rights and consent (measured, not scored) — 5 of 5 in range

Not in the grade: every row here is a reading rather than a pass or a fail, so nothing in it can move a grade.

Rows in range (not in the grade)5 / 5
MeasureCurrentlyOptimal
AI training
collecting the page to train AI models. The signal and line named here are what a crawler reading the site's own declarations finds.
denied — decided by robots.txt line 21a stated answer either way: allow or deny✓ Passed
Grounding an answer
fetching the page while answering a person's question. The signal and line named here are what a crawler reading the site's own declarations finds.
denied — decided by robots.txt line 21a stated answer either way: allow or deny✓ Passed
Summaries and snippets
showing an excerpt of the page in an AI answer. The signal and line named here are what a crawler reading the site's own declarations finds.
denied — decided by robots.txt line 21a stated answer either way: allow or deny✓ Passed
Citation
listing the page as a search or answer source. Nothing on the site says, so each crawler falls back to its own default, and the defaults differ.
not declared · robots.txt closes it to OAI-SearchBot, Claude-SearchBot, PerplexityBot and not to the resta stated answer either way: allow or denyReported
Acting for a user
an agent acting or buying on the page for a person. The signal and line named here are what a crawler reading the site's own declarations finds.
denied — decided by robots.txt line 21a stated answer, once a standard signal for this use existsReported
Signals that disagree
two signals answering the same question differently leave each crawler to pick the one it honours; a denial anywhere is read here as a denial
nonenone✓ Passed
Where it is declared
robots.txt answers who may fetch; only a use signal answers what they may do with what they fetched
robots.txt, TDM-Rep metarobots.txt plus at least one use signal (Content-Signal, TDM-Rep, ai.txt or a robots meta directive)✓ Passed
Terms page
a crawler reads robots.txt, not the terms; a restriction that exists only in prose binds nothing that fetches
no terms link found on the pagemachine-readable signals that say what the terms sayReported

One answer per use, merged from everything the site publishes about what AI may do with its pages: robots.txt read for each agent’s own group, Content-Signal, ai.txt, TDM-Rep, robots meta and X-Robots-Tag, and the terms page. A denial anywhere denies; an explicit yes allows; a snippet limit limits; a clause in the terms restricts a use nothing machine-readable answers. The right answer is yours to choose; what is measured is whether you chose one and whether your signals agree. Not legal advice. The full answer: every signal, per path and per agent · the same answer travels in the Resolve record agents read before they fetch.

Price transparency (measured, not scored) — 2 of 3 in range

Not in the grade: every row here is a reading rather than a pass or a fail, so nothing in it can move a grade.

Rows in range (not in the grade)2 / 3
MeasureCurrentlyOptimal
Prices stated on the page
an assistant asked what the job costs can only quote a number the site states; with none it quotes a directory or a competitor
2 amounts ($60,000, $15)at least one figure or range✓ Passed
Link to a pricing or cost page
a crawler that lands on the homepage finds the cost page only through a link
/2026/11/11/denver-home-sellers-price-drops-colorado/, /2026/08/26/colorado-peaches-senior-womens-softball-35th-anniversary-photos/, /2026/11/10/inflation-consumer-prices-october/linked, or prices on this page✓ Passed
Prices in the markup
machines read prices from the markup first; a priceRange alone gives no figure to quote
noneOffer or price range declared✗ Failed

Read from the delivered homepage text and its structured data. Prices drawn only by a script after load are not in that copy, which is also what most AI crawlers see. Measured, not scored.

Third-party dependencies (measured, not scored) — 1 of 3 in range

Not in the grade: every row here is a reading rather than a pass or a fail, so nothing in it can move a grade.

Rows in range (not in the grade)1 / 3
MeasureCurrentlyOptimal
Outside services the page loads
each outside host is a service the site cannot fix when it is slow or down; every one adds a connection before the page is complete
18 hosts: tracking 1, forms and widgets 1, fonts 1, code library (CDN) 2, consent 1, other 1210 or fewer✗ Failed
Outside files that hold the page until they load
a script without async or defer, or a stylesheet, in the head from another host stops the page from drawing until that host answers; when it is down the page stays blank
7: cmp.osano.com, ajax.googleapis.com, accounts.google.com, prodmg2.blob.core.windows.net, …none✗ Failed
Trackers loaded
listed so the owner can confirm each is still wanted; every tracker is another script on every visit
1: stats.wp.comonly the ones you use✓ Passed
  • other: metrics.rapidedge.io, prodmg2.blob.core.windows.net, cdn.sophi.io, plugins.mngdigisubs.com, htlbid.com, ak.sail-horizon.com, cdn.parsely.com, applepay.cdn-apple.com, cdn.p-n.io, delivery.revcontent.com, cdn.cityspark.com, esm.sh
  • consent: cmp.osano.com
  • code library (CDN): ajax.googleapis.com, cdn.jsdelivr.net
  • forms and widgets: accounts.google.com
  • tracking: stats.wp.com
  • fonts: fonts.googleapis.com

Read from the delivered HTML: scripts, stylesheets, frames and media. Anything a script loads later is not counted here (the browser view in the extension lists those). Measured, not scored.

Language and region (measured, not scored) — 3 of 3 in range

Not in the grade: every row here is a reading rather than a pass or a fail, so nothing in it can move a grade.

Rows in range (not in the grade)3 / 3
MeasureCurrentlyOptimal
The page names its language
engines and screen readers read the page in the language it names; without one they guess from the text
lang="en-US" (English)a valid lang on <html>✓ Passed
The named language matches the words
a Spanish page marked English is indexed and quoted as English, and served to the wrong searchers
the text reads as English, the page says Englishthe same language✓ Passed
Language versions declared (hreflang)
hreflang tells an engine which version to show to which searcher
noneonly needed when the site has versions in other languages or regionsReported
The country signals agree
an engine places a local business by these signals; when they name different countries it has to pick one
page language en-US (US); og:locale en_US (US); phone prefix +1 (US/CA)one country✓ Passed

Read from the delivered homepage: its lang attribute, the Content-Language header, the words on the page (common words in 13 languages, or the writing system for 9 more), its hreflang links and the countries its domain, og:locale, address, phone prefix and currency name. Up to 6 language versions were requested once each to see whether they answer and point back. Measured, not scored.

Where AI already cites this site (measured, not scored) — 3 of 3 rows read

Not in the grade: every row here is a reading rather than a pass or a fail, so nothing in it can move a grade.

Rows with a reading (not in the grade)3 / 3
MeasureCurrentlyOptimal
Answers that cited this site
an engine that has already cited a site is the likeliest to cite it again; one engine alone is one point of failure
none of the answers CrawlCheck has run cited itcited by more than one engineReported
Pages the answers cited
these are the pages an engine quotes for you; keep them current, fast and in the sitemap before anything else
no page of it recorded in a cited answerthe pages that answer the questionReported
This site's own answer test
the watch plan runs the site's own prompts daily and records which answers cite it
not run for this domain yeta run of prompts with and without its nameReported

From the answers CrawlCheck itself has collected: the local trade-by-city prompts, the daily citation watch and manual runs, across Perplexity, Gemini, Google AI Overviews and ChatGPT where each was run. It is a sample, not every answer an engine has given, so "none" means none in that sample. Pages and prompts are recorded for answers given with web search on. Read 2026-11-12 00:17 UTC. Measured, not scored.

Common Crawl visibility — measured, not scored

CCBot is blocked by robots.txt, so future crawls will skip this site. Checked against October 2026 Index, from a stored result.

0 of 2 pages checked were captured, and 4 could not be checked — the index rate-limits, and that says nothing about the site.

PageIn the datasetCapturedStatus
/could not check—the index answered 521 (it rate-limits bursts; this says nothing about
/sitemap.xml?yyyy=2026&amp;mm=10&amp;dd=31not found——
/sitemap.xml?yyyy=2026&amp;mm=10&amp;dd=30could not check—the index answered 504 (it rate-limits bursts; this says nothing about
/sitemap.xml?yyyy=2026&amp;mm=10&amp;dd=29not found——
/sitemap.xml?yyyy=2026&amp;mm=10&amp;dd=28could not check—the index answered 504 (it rate-limits bursts; this says nothing about
/sitemap.xml?yyyy=2026&amp;mm=10&amp;dd=27could not check—the index answered 520 (it rate-limits bursts; this says nothing about

A capture means the page is in an open dataset. It does not establish that any model trained on it, and nothing here claims otherwise.

Deep entity read — measured, not scored

the deep entity read runs for domains under continuous record; this scan used the keyless resolver

Identity fingerprint — measured, not scored

The identity this site publishes is unchanged since 2026-11-11. Same name, same phone, same address, same declared profiles.

Fingerprint 8153bbf8989417ea971c5250c7185c50… · recorded 2026-11-12

Schema type newsmediaorganization. We hold no population figure for this type, so no rarity is claimed.

A fingerprint of the identity this site publishes, recomputed on every scan. A change here is a change the site made, not a judgement about it. Anyone can recompute this from the published page: the canonical form and the hash are both public at /api/entity-drift/latest.

How this compares — 36 wordpress/publisher sites, of 983 measured
MeasureThis siteCorpus medianRank
AI visibility score (the grade shown)818056th percentile
Section average (weighted)808141st percentile
Content ratio (% visible text)4.43.469th percentile
Stable @id coverage (%)33.384.68th percentile
Render-blocking resources2710.519th percentile
Delivered page size (KB)30618214th percentile

Percentiles come from sites CrawlCheck has measured itself, not from a published study — so they describe this corpus, not the web. The corpus is not a random sample and is weighted toward sites that were submitted or seeded, which is why the rank is shown next to the raw number rather than instead of it. A metric is left blank rather than ranked when fewer than 8 peers carry it. This rank is against the wordpress/publisher cohort (36 sites), not the whole corpus of 983, because a WordPress local-service site and a static personal site are not the same measurement problem.

Reach, read, quote — the three stages

An engine can reach and read this site. What is left is giving it something specific to say.

StageQuestionScore
Reach
40% of the score
Can a named answer-engine crawler get your pages at all?
At least one answer engine was refused, challenged or served less than a browser.
79
Read
30% of the score
Once it has the bytes, can it find the words?
The content is buried in markup, or the files that guide a crawler are missing.
83
Quote
30% of the score
Is there a specific fact it can state and attribute?
An assistant would have to paraphrase your page instead of quoting a fact.
83

Which engines, by name

From the probes in this scan — the same fetch each engine’s crawler makes, from our address.

Served the pageOAI-SearchBot · Claude-SearchBot · PerplexityBot · ChatGPT-User · Claude-User · Perplexity-User · Googlebot · Googlebot Smartphone · Bingbot · Applebot
Disallowed in robots.txtYahoo Slurp · ChatGPT search index · ChatGPT live fetch · Claude search index · Claude live fetch · Perplexity index · Perplexity live fetch · Le Chat live fetch
a policy refusal, which is a decision rather than a defect — it belongs here so it is visible, not because it is wrong

Fix the 30 items this report already lists and the same arithmetic reads 100. That is addition on the table below, not a forecast — every point has a named component behind it:

  • Answer engines allowed — now 7 of 17, worth 2 points
  • Search indexes allowed — now 17 of 24, worth 2 points
  • Lead paragraph defines the subject — now does not name it, no defining verb, worth 2 points
  • Edge / CDN — now none detected, worth 2 points

The stage to fix first is reach, the lowest of the three. The stages gate each other: an engine cannot read what it was refused, and it cannot quote what it could not read.

What this number covers. Everything above was measured on pages this scan fetched from your own domain. An answer engine also reads sources you do not control — directory listings, review corpora, and your Google Business Profile — and none of those are in this score. The profiles this site declares are listed below but were not fetched on this scan, so nothing here reflects what those listings actually say. A site can score well here and still be described wrongly by an engine reading a listing that disagrees with it.

What this number is not. It does not measure whether ChatGPT, Perplexity or Google’s AI answers actually cite you. No server can measure that, and a score that implied otherwise would be invented. This measures whether an engine can — reach, read, quote — which is the part you control and the part that has to be true first.

Section average over 22 scans on this score version · held at 81 since 2026-11-12
0501002026-10-23 00:17 · 83/100 · 10 findings2026-10-24 00:17 · 82/100 · 10 findings2026-10-25 00:17 · 82/100 · 10 findings2026-10-26 00:17 · 82/100 · 10 findings2026-10-27 00:17 · 83/100 · 10 findings2026-10-28 00:18 · 83/100 · 10 findings2026-10-29 00:18 · 82/100 · 10 findings2026-10-30 00:17 · 82/100 · 10 findings2026-10-31 00:17 · 82/100 · 10 findings2026-11-01 00:17 · 82/100 · 10 findings2026-11-02 00:17 · 81/100 · 10 findings2026-11-03 00:17 · 83/100 · 11 findings2026-11-04 00:17 · 83/100 · 11 findings2026-11-05 00:17 · 83/100 · 11 findings2026-11-06 00:17 · 83/100 · 11 findings2026-11-07 00:17 · 83/100 · 11 findings2026-11-07 01:02 · 83/100 · 11 findings2026-11-08 00:17 · 83/100 · 12 findings2026-11-09 00:17 · 83/100 · 11 findings2026-11-10 00:17 · 83/100 · 11 findings2026-11-11 00:17 · 83/100 · 11 findings2026-11-12 00:17 · 81/100 · 11 findings2026-10-232026-11-12

Since the last scan

Nothing. Every finding on this scan was present on the previous one at the same severity, and nothing that was open has cleared. Compared against 48 recorded scans of this domain.

Change since last scan — 24 distinct states across 26 scans

Comparing against the last reading that differed, taken 2026-11-11T00:17:41.462Z.

MeasureThenNowChange
Overall score81/10080/100-1/100 ✗
Content ratio4.6%4.4%-0.2% ✗
Stable @id coverage33.3%33.3%no change
Render-blocking resources2727no change
Page size310 KB306 KB-4 KB ✓
Findings1111no change

History keeps the last 24 changes on this domain — repeated identical readings collapse into one entry that records when the state began and how many scans confirmed it, so re-running a scan can never push real history out of the window. A finding that comes and goes is the pattern worth acting on: a permanent failure gets noticed, an intermittent one only shows up if something is looking at the right moment.

Three ways to re-read this record — site, rules and reader each checked apart

A grade can move for three reasons and this page keeps them apart: the site changed (seen only by a rescan), the rules changed (seen by reprocessing the stored measurements), or the code that reads the bytes changed (seen by replaying it on the stored bytes). Rules and code moving are never published as site changes.

OperationWhat it doesThis record
RescanA new fetch of the site, written as a new record. The only operation that can show a change on the site itself.Last measured 2026-11-12 00:17 UTCRe-scan
ReprocessThe measurements stored in this record, scored under today’s rule pack. Nothing is fetched; a difference is a rule change.Scored under the current rules (v34); recomputing them gives the same C 81.GET /api/reprocess?id=aasc46z1wv (key)
ReplayToday’s code run on the exact bytes this scan received, kept by SHA-256. Nothing is fetched; a difference is a code change.not run for this viewGET /api/replay?id=aasc46z1wv (key)

Since the first scan

Measured on 33 separate days between 2026-08-20 and 2026-11-12. 2 defects have stopped being measurable and 11 are still open.

What this does and does not say. Each row below is two dates: the day a defect was first measured here, and the first day it could no longer be measured. That is evidence the defect is gone. It is not evidence that we caused it to go, and nothing on this page claims otherwise — a site can be fixed for reasons that have nothing to do with a report. What is verifiable is the pair of measurements, and either date can be checked against the sealed record without asking us.

Headline measurements, first reading against latest

MeasureAt first scanNow
GradeFCworse
Overall score7381better
Section average (weighted)7780better
Visible text4.6%4.4%worse
Render-blocking resources2427worse
Page weight279 KB306 KBworse
Open findings411worse

Defects that stopped being measurable

FindingFirst measuredLast measuredDays
Images are not the format their file names say
IMAGE_FORMAT_MISMATCH · came back 1 time before this
2026-10-182026-11-0922
The sitemap returns HTML, not XML
SITEMAP_IS_HTML
2026-08-202026-09-1021

Median time from first measurement to no longer measurable: 22 days.

2 defects have closed and come back at least once. A failure that returns is easy to miss precisely because it looks fixed whenever anyone checks.

Still open

FindingFirst measuredDays open
Two different entities share the same identifying data
ENTITY_COLLISION
2026-08-2084
Almost nothing a machine receives from this page is readable text
PAGE_IS_MOSTLY_CODE
2026-08-2084
robots.txt rules do not apply to named agents
ROBOTS_RULES_SHADOWED
2026-09-1063
RENDER_RESOURCE_BLOCKED
RENDER_RESOURCE_BLOCKED
2026-09-1063
Published coordinates are not in the country the address names
GEO_COUNTRY_MISMATCH
2026-09-1063
The sitemap does not say when anything changed
SITEMAP_NO_LASTMOD
2026-11-0210
No llms.txt
NO_LLMS_TXT
2026-08-2084
NAP_UNDECLARED_LISTING
NAP_UNDECLARED_LISTING
2026-09-1063
The machine files cost more than the page
MACHINE_CHAIN_HEAVY
2026-09-1657
The homepage is reached through a chain of redirects
REDIRECT_CHAIN
2026-10-1726
Private files or live keys are readable by anyone
SECRETS_EXPOSED
2026-10-2320

This section is reported and never scored: a site that has improved a lot and a site that was always fine should get the same grade for the same measurements today.

Traffic, enquiries and sales

Not measured here, and not measurable here. Everything else in this report was produced by fetching your pages from outside. Clicks, enquiries and orders happen where no CrawlCheck can see them — in your Search Console, your inbox and your checkout. Connect one of those and this section fills in against the dates above. Until then it stays empty rather than showing an estimate, because an invented traffic figure on a report that measures honesty would be the whole product undone.

Cite this report

This report regenerates when it is opened, so both records carry the scan timestamp as the version and the access date as the retrieval. A citation that implied fixed content would be wrong.

BibTeX download

@techreport{crawlcheck_denverpost_com_aasc46z1wv,
  author      = {{CrawlCheck}},
  title       = {Machine-layer measurement of {denverpost.com}},
  institution = {CrawlCheck},
  type        = {Scan report},
  number      = {aasc46z1wv},
  year        = {2026},
  url         = {https://crawlcheck.io/r/aasc46z1wv},
  urldate     = {2026-11-12},
  note        = {Scanned 2026-11-12; report regenerates on access, figures are as of the access date}
}

RIS download

TY  - RPRT
TI  - Machine-layer measurement of denverpost.com
AU  - CrawlCheck
PB  - CrawlCheck
PY  - 2026
DA  - 2026/11/12
M1  - aasc46z1wv
UR  - https://crawlcheck.io/r/aasc46z1wv
Y2  - 2026/11/12
N1  - Report regenerates on access; figures are as of the access date
ER  - 

Type is RPRT — a dated report about one named site, not the aggregate dataset at /data. Note that /r/ is disallowed in our robots.txt, so this markup serves readers and reference managers, not search engines.

19

passing

7

needs work

7

failing

8

not measurable

Sections, not individual checks. Not measurable is counted separately and never as a pass — a section we could not read is not a section that passed.

Show this on your site

The badge renders the number as measured, whatever it is — it updates when this report is re-run. It is keyed on this report’s id, so only someone holding this link can produce it.

AI visibility 81 out of 100

Paste this where you want it:

<a href="https://crawlcheck.io/r/aasc46z1wv?via=badge"><img src="https://crawlcheck.io/badge/aasc46z1wv.svg" alt="AI visibility 81/100, measured by CrawlCheck" width="228" height="64"></a>

No landing has arrived from this badge yet. The link carries via=badge, so any that do are counted here.

Reading the transcript

CrawlCheck does not claim to predict rankings. It measures the inputs a crawler and a retrieval system must successfully receive before ranking, indexing or quoting is possible at all.

1

Observed

CrawlCheck received this exact status, header, body and rendered-text result. Everything in the sections below is at this level unless it says otherwise — it is a fact about a real response, with the bytes attached.

2

Protocol consequence

What that response necessarily means for a compliant crawler. A disallow rule, a non-text robots.txt or a JavaScript dependency can prevent or impair access by construction — not because we ranked anything, but because the protocol says so.

3

Search implication

Possible or unknown, and labelled as such. No finding here asserts a ranking effect, a citation formula, or a weighting. If a claim cannot be reduced to level 1 or 2, it is not made.

An important limit, stated plainly: the 19 identities above are sent from CrawlCheck’s own address wearing each crawler’s user-agent string. That is an edge-policy simulation — it shows what your edge does with a request that declares itself as that crawler. It is not a request from the real crawler, and it cannot be. A WAF may treat a verified Googlebot differently from anything merely claiming the name, which is exactly what Google recommends it do. Where a result says a crawler was refused, read it as a client declaring that name was refused — to prove what the real crawler received, check your own server logs against the operator’s published address ranges, which the free log verifier does line by line.

Transcript of the machine-file fetches

PathStatusContent typeBytesEdge
/robots.txt 200 text/plain 4,567 HIT ok
/sitemap.xml 200 application/xml 888,839 DYNAMIC ok
/sitemap_index.xml 404 text/html 95,255 DYNAMIC not present
/wp-sitemap.xml 200 text/html 149,638 DYNAMIC not present
/llms.txt 404 text/html 95,230 DYNAMIC not present

What this report cannot prove

  • The grade is not a ranking or a citation count. It says whether the bytes an engine receives can be fetched, read and attributed to www.denverpost.com. Whether any engine ranks, cites or recommends it is decided by that engine and is not measured here.
  • One URL, one moment, one vantage. Measured at 2026-11-12 00:17 UTC from CrawlCheck’s network for the homepage and the site’s machine files. The site can change after this, and a crawler from another network or country can be served differently.
  • Named crawlers were simulated, not observed. Requests carried each crawler’s name from CrawlCheck’s own address. A refusal shows what a client using that name gets; the real crawler, from its operator’s address, may be treated differently.
  • A pass is not an index entry. Passing every check here does not mean a search engine or an AI index has the page. Only that engine (for Google, Search Console) can say what it has stored.

What the scan does not measure at all is under Method.

What this scan attempted — read from its own record, not asserted

19 / 19

identity probe responses read

5

machine files fetched on both hosts

115

named agents resolved from robots.txt

33

of 41 sections scored

53

invariants checked on this report itself

11

findings

A randomised path that cannot exist was also requested — the control that distinguishes your website from a wall in front of it.

Every row on this report, by state (369 rows) — each state counts the same here

162

✓ Passed

inside the range that passes

41

✗ Failed

outside the range that passes

3

Warning

in place, but weaker than it should be; shown with its fix and excluded from the score like every state that is not passed or failed

20

Not measured

no reading was taken: the input was missing, unreachable or not fetched on this scan; excluded, not failed

0

Inconclusive

a reading was taken but could not be judged either way (an error, a timeout or an ambiguous answer)

3

Declared only

the site states it; nothing in this scan observed it working

0

Disagreement

two readings of the same thing do not agree (hosts, vantages or sources)

4

Not applicable

the measure does not apply to this site

136

Reported

a reading shown for information; it has no pass or fail

Only passed and failed rows move a section score. A row that was not measured, not applicable, inconclusive, declared only, in disagreement or reported for information is excluded from the score, and it is never shown as a pass.

Reading the scores
The two scores are not a grade
Crawl clarity is whether a machine can fetch, read and tell your pages apart. User clarity is whether a reader can tell what this is and who it belongs to. They fail independently, so read them separately rather than averaging them.
A dash means not measured, not zero
Components shown as — and excluded from the score. If a scan was rate-limited or the pages render with JavaScript, that measurement is withheld. A false clean bill of health is more dangerous than a false defect.
Unconfirmed findings are separated on purpose
Anything that could describe our access rather than your site — a refusal, a timeout — is listed apart and never counted toward the grade.
Content ratio is bytes, not tokens
The share of decompressed bytes that are visible text - the body as a parser reads it, not the smaller gzipped transfer. The deep audit measures tokens per KB with a real tokenizer; the two are named differently because they are different measurements.
What to do with it
Prefer fixes that are one setting over ones that need a sprint. Inline CSS is usually the largest cheap win, because it cannot be cached between pages — a crawler pays for it again on every URL.
What this scan does NOT measure

This is a machine-layer probe of one URL and the files that describe the whole site. Everything below is outside that scope by design, and no score on this page is adjusted for it.

Not a site-wide crawler
There is no full URL graph here, no broken-link inventory across every page, and no duplicate-content comparison. Sitemap coverage is checked against the homepage’s links only. For an exhaustive crawl of thousands of URLs, use a dedicated crawler — Screaming Frog, Sitebulb, or the site audit in Ahrefs or Semrush — and use this to check the machine layer they do not read.
Not a log analysis platform
Crawler behaviour is sampled in one tightly controlled interval, not tracked over weeks. Crawl budget, bot paths, and which pages a crawler actually spends its time on can only come from your own server logs. The free log verifier on this site reads those line by line against the operators’ published address ranges.
Not a replacement for Search Console
Index coverage, canonical selection, manual actions and Google-specific diagnostics come from Search Console and nowhere else. A page can be perfectly readable to every crawler measured here and still not be indexed, for reasons only Google can report.
Extractability, and arrivals - but not citation
This measures whether the bytes an engine receives can be fetched, parsed and attributed to you. Where the first-party beacon is installed it also counts arrivals: humans who clicked through from an AI assistant, recorded from your own site rather than guessed. What it still does not do is ask ChatGPT, Claude, Perplexity or Google whether they mention you when nobody clicks. A citation that produces no click is invisible here, and measuring that needs prompt monitoring, which is a different instrument.
Our vantage point is not the crawler’s
Every request here is honest and unauthenticated: it is sent from a datacentre address under our own name and never impersonates a verified crawler’s IP. A refusal therefore describes what a client declaring that name receives — which a WAF may treat differently from the real crawler, exactly as Google recommends it should.
Not a WCAG audit
The accessibility section reads whether the structure a screen reader depends on exists in the delivered document: a language, a title, names on images, inputs, buttons and frames, a main landmark, a way past the navigation, unique ids. Contrast, focus order, keyboard traps and motion need a rendered page and a person, and are not measured.
One rendering, no JavaScript execution
What is measured is the document the server returns. Content injected by client-side JavaScript is not executed here — which is deliberate, because most crawlers measured on this page do not execute it either, but it means a JavaScript-rendered site will read thinner here than it looks in a browser.
What we could not measure — 3

Every row in this report is either a measurement of your site or nothing at all. These lookups did not return a measurement, so they were left unscored rather than counted against you. They are listed because a silent absence is indistinguishable from a clean result, and that is the difference this tool exists to keep.

This covers the third-party and enrichment lookups only — CrUX, the Google profile link, the Internet Archive, the geocoder, and the two well-known files. Your own server’s refusals are never listed here: a 403 to GPTBot is the finding, not a gap in our instrument, and it is reported as a finding above.

LookupOutcomeWhose limitationWhy
Off-site presence (directories searched by phone number)reachedyoursYelp, Angi, Thumbtack, Houzz, Facebook refuse datacentre clients and are our limit, never an absence. Google Business Profile and review counts are still not read from here
Response compressionunreachedoursour fetch decompresses the body and drops the content-encoding header before we can read it — check it in a browser network panel or with curl --compressed -I
Google Business Profile linkrefusedtheirs, aimed at usGoogle throttled our check from a datacentre address

Every figure here was measured with no cookies and no session. That is deliberate: it is what an answer engine gets. If you open your own site while logged into its admin, you are looking at a different document — caching plugins, page builders and membership tools routinely skip their output filters for signed-in users, and admin bars and edit links are added on top.

To see what this report describes, open your site in a private window. If the two disagree, the private window is the one a crawler sees.

Crawl clarity — can a machine fetch, read and tell pages apart 44 / 100
componentstatus scoremeasured
Machine filesscored 67 robots.txt, llms.txt, sitemap and entitymap as scored above
Payload — content ratioscored 26 4.4% of decompressed bytes are visible text (byte-level; the deep audit scores tokens per KB separately)
Render pathscored 0 27 render-blocking resources
Document structurescored 80 0 heading skips, 2 h1
User clarity — can a reader tell what this is and who it belongs to 57 / 100
componentstatus scoremeasured
Entity identityscored 33 33.3% of 3 entities carry a stable @id
Declared standingscored 40 no credential edges declared
Location coherencescored 100 1/1 locations have a street address
Identity claimsscored 0 1 of 1 map links point at places, not the business
Page labellingscored 100 157-char description, canonical present

0 components not measured and excluded from the score — an unmeasured component is never counted as zero.

Score composition — The letter was set by the worst finding, not by the average — that is why a high score can carry a low grade.
SectionScoreWeight
Machine layer67/1001.5
Server and hosting80/1000.6
Schema and entity graph55/1001.2
RDF and linked-data surface100/1000.8
Authorship and trust signals (E-E-A-T proxies)57/1001
Accessibility structure (from the delivered HTML)96/1000.8
Entity corroboration100/1000.6
Quotable content67/1000.8
Crawl waste100/1000.6
Page subject, the Webref question100/1000.6
AI and search agents33/1001.2
Speed a crawler sees, and field data where it exists44/1001
Payload and render path20/1001
Machine-file trust chain100/1001.5
Claim consistency100/1001.3
Agent instruction surface100/1001
What each agent receives88/1001.5
Mobile surface100/1000.8
Local presence, citations and NAP86/1001.3
Exposed files and secrets89/1000.6
Error pages100/1000.4
Sitemap coverage100/1001.2
Internal linking100/1001
Naming and case consistency80/1000.4
Image signals80/1000.6

Not scored, and therefore excluded rather than counted as zero: Agent surfaces (emerging, not scored), Content entities (measured, not yet scored), Service area, as declared (measured, not scored), The whole site, not just the front door (measured, not scored), Freshness, as the site declares it (measured, not scored), Local intents, the Maps vocabulary (measured, not scored), Conversion path on the page (measured, not scored), Where AI already cites this site (measured, not scored), What AI looks for vs what your page shows (measured, not scored), Trust and reputation (measured, not scored), Claims and their evidence (measured, not scored), Site safety (measured, not scored), AI rights and consent (measured, not scored), Price transparency (measured, not scored), Third-party dependencies (measured, not scored), Language and region (measured, not scored).

Reach, then read, then quote

Reach, then read, then quote — each stage gates the next

REACH79adequateREAD83adequateQUOTE83adequate

Watch this site

These break silently. We re-check this site twice a day and send you one email when a result changes, nothing otherwise.

Change alerts only. Unsubscribe in one click.

Scan another domain

Export this result: JSON · CSV · PDF · Signed report card (image) Same stored record as this page, so an export can never disagree with the report.

For an AI agent: Markdown brief Paste it into ChatGPT, Claude or a coding agent and it has every finding, its evidence and its fix.