Crawl Check
Free AI-visibility audit

See what AI crawlers actually receive from your site — graded A–F, with a fix list.

Can ChatGPT, Claude, Perplexity and Google reach you, read you and safely quote you — and what to fix first.

No signup. Nothing installed. Nothing changed on your site. About 30 read-only requests in total.

{{ offlineLabel }}

{{ signinTitle }}

{{ signinBlurb }}

Licence key · from your receipt

The key is the account — there is no password. It is shown once on the page after checkout; the same key renders any report as yours on the web.

Email · the trial key is sent here

One trial per domain and per email. When it ends, monitoring stops; the record stays readable on every report for that domain.

Key sent to {{ email }} · paste it here
You cannot pay to improve a score. An account adds the lists behind the counts and the record over time — never a better grade.
{{ queueNote }}

{{ studioTitle }}

{{ planLine }}
Needs attention since last look
{{ b.label }} {{ b.count }} {{ b.range }}
domainmovedopen
{{ selCount }} selected
{{ footLine }}
Free AI-visibility audit

See what AI crawlers actually receive.

Domain
$

No signup. Nothing installed. Nothing changed on your site. About 30 read-only requests.

Recent scans · on this phone
Keep a record of 3 sites for $29/mo.
Twice-daily scans, the date each finding first appeared, and a receipt when something moves. Free for 30 days on one domain, no card.
Scan · about 30 read-only requests

Which domain?

$

{{ scanNote }}

Re-scan one under record
Scanning · one address, one second
{{ scanTarget }}
{{ reqCount }}
requests
answered
of about 30
ReachReadQuote
{{ i.name }} {{ i.meta }} {{ i.mark }}
Same second, same address — so a difference between them is your edge deciding, not the internet being busy.
On the wire

{{ scanTarget }}

{{ phaseLabel }}{{ reqCount }}/30
{{ l.text }}
▌
Scan did not complete

The scanner could not be reached.

POST {{ apiBase }}/api/scan
domain: {{ scanTarget }}
→ {{ apiErrorMsg }}
Nothing was measured, so nothing is reported — a failed request is never shown as a finding or a zero.
Under record · no reading yet

{{ domain }}

The first reading runs within the hour.
Twice a day after that. A record starts the day a domain is kept — the days you are not measuring are the days no tool can recover.
Scan result {{ sourceLabel }}

{{ domain }}

{{ rec.meta }}
{{ rec.scoreText }}
{{ rec.grade }}grade

{{ rec.verdict }}

AI visibility {{ rec.scoreText }}/100 · {{ rec.deltaWord }}.

{{ rec.capLabel }}{{ rec.capText }}

{{ rec.verdict }}

{{ s.n }}
{{ s.k }}
04 · Beyond the three stages · measured, not scored
{{ b.k }}{{ b.note }}{{ b.v }}
In plain English
{{ b.lead }} {{ b.rest }}
Score on record · {{ rec.histNote }}
{{ rec.histFrom }}now · {{ rec.score }}
Every section, scored
{{ g.k }}{{ g.note }}
Grey means measured but not scoreable, and counts for nothing rather than zero. Reach is 40% of the score and also a ceiling.
{{ sec.stage }} · weight {{ sec.weight }}

{{ sec.name }}

{{ sec.label }}
{{ sec.scoreNote }}

{{ sec.desc }}

MeasureCurrently
{{ r.note }}
optimal{{ r.opt }}
{{ r.ev }}
Evidence bytes · as received
n/a means the input could not be measured and the row is excluded, not failed. Tap a row for why it matters and the optimal range.

What to fix, in order

{{ domain }} · {{ rec.when }}
No reading yet.
A fix list is arithmetic on measurements. Scan the domain and it appears here, ranked.

Findings first: each one holds the grade down until it is gone. Then headroom: each row lifts the score by the points shown.

Findings · hold the grade
Headroom {{ rec.headroomNote }}
Marked fixed · awaiting re-scan
✓
{{ f.title }}
done is measured, not asserted
Clear
Nothing holds this grade.
The machine layer is clean as of the last reading. The record keeps measuring twice a day.
Get this fixed for you
Every finding above fixed on your site, then re-measured — done is measured, not asserted. One-time, from $750.
{{ fnd.sev }} · {{ fnd.holds }}{{ fnd.code }}

{{ fnd.title }}

{{ fnd.worth }}
Points
{{ fnd.first }}
First measured
{{ fnd.priority }}
Priority
Byte diff · last two readings
{{ d.when }}
{{ d.bytes }}
What we saw
{{ fnd.seen }}
What the fix must return
{{ fnd.expected }}
Deploy handshake
Ticket {{ fnd.ticket }}
The developer scans this when they ship. Re-measured within the minute; the verdict lands on both phones. Reopens itself on regression.
Evidence
{{ fnd.evidence }}
Why it matters

{{ fnd.why }}

How to fix it

{{ fnd.how }}

{{ fnd.snippet }}
Why this priority
{{ x.k }} {{ x.why }}{{ x.m }}
Priority = severity × prerequisite impact × scope × persistence × confidence. A factor the record cannot support stays at ×1.

What each crawler gets

15 identities · one address · inside one second
{{ engineNote }}
engineindexlive fetchtraining
{{ e.name }}{{ e.idx.t }}{{ e.live.t }}{{ e.train.t }}
{{ e.toks }}edge: {{ e.edge }} · {{ e.named }}
A blocked training column beside an allowed index column is coherent policy: “answer with me, do not train on me.” Naming nobody in llms.txt is the norm and is not scored.
{{ agentTotal }}
Tap any agent for how to verify it. “No published ranges” means a log line claiming that name can be neither confirmed nor accused — the verifier reports it as unverifiable, never as forged.
A browser and a mobile browser ran as controls, plus a randomised path that cannot exist — so “everyone gets this” and “only crawlers get this” are distinguishable.
{{ studioName }}{{ rec.date }}
AI visibility report · prepared for

{{ domain }}

{{ rec.grade }}
{{ rec.score }} /100
AI visibility score

{{ rec.verdict }}

{{ s.k }} — {{ s.q }}{{ s.s }}
What this means
{{ b.lead }} {{ b.rest }}
On the record from the field
{{ l.text }}
Talk track · internal
{{ t.line }}
What we are fixing
{{ f.title }}
{{ f.why }}
Internal: {{ f.how }}
Fix scope
{{ scopeLine }}{{ scopePrice }}
Done is measured, not asserted: each finding re-measured after the fix, and the ticket reopens itself if it returns.
{{ signedLine }}
Measured by CrawlCheck, an independent scanner. This report regenerates when opened, so it stays true. Verify at {{ rec.url }}
Internal notes, fix snippets and priority arithmetic stay off unless you turn them on. The studio name is set in Account.

Compare two sites

The same 35 sections, side by side, measured in the same second.
{{ h.grade }}
{{ h.score }}/100 · {{ h.finds }}
{{ r.name }} {{ r.a }} {{ r.b }}
Bold marks the section where the two differ by ten points or more. Useful for a pitch: the prospect on the left, the site you already look after on the right.
Cohort · {{ cohort.name }}
{{ cohort.head }}n = {{ cohort.n }}
{{ c.k }} {{ c.v }} · {{ c.med }}
{{ cohort.note }}
Trust · in plain terms

What we measure. What we never do.

{{ t.k }}
{{ r.t }}
This page is the source for the App Store privacy labels and every permission string. If a sentence here changes, those change with it.
App design v1.0 · frozen 5 Sep 2026 · tokens live from crawlcheck.io
Receipt · {{ receipt.at }}

{{ receipt.what }}

{{ receipt.domain }}
sha256 of the receipt
{{ receipt.hash }}
anchored
{{ receipt.anchor }}
what was hashed
The request line, the response headers, the first 64 KB of the body, the timestamp and the identity used — exactly as received, before any scoring.
Verify without trusting us
{{ v.n }}{{ v.t }}

The record

{{ recordSince }}
{{ syncLine }}
Nothing under record yet.
A record starts the day a domain is kept: dated receipts a third party can verify, hashes anchored to Bitcoin daily. The days you are not measuring are the days no tool can recover.
Nothing from the field or the studio yet. Enable an instrument in Tools → Field kit or Studio and its receipts land here beside the scans.
Hashes are anchored to Bitcoin daily. A receipt can be verified by someone who does not trust you.
Field kit · paid plans

What a phone can do that a server cannot.

Six ship at launch; the rest are the roadmap, in the order paying clients asked for them. Each one only works in a hand, on a street, or on a network the datacentre will never stand on — and each sends what it measured back to the record.

Studio · the business of fixing

From record to revenue.

Eight tools that turn receipts into retained clients, obligations the app meets for you, and numbers you put in your own renewal deck.

Record tools · proposed 16 Sep

What the site measures now, put to work.

Twenty tools built on sections and services crawlcheck.io already publishes — local intents, page subject, freshness, crawl waste, the lead form, YouTube channels, CI, the $1 pass — none of which the app used until now. Each says what it does and what flows back.

Google Business Profile · 20 instruments

What Google holds, against what the site declares.

The profile is the other half of a local identity. Connected read-only, it lets the app compare every field, hour, category, review question and service area with the schema and the page — and fix either side from the phone.

{{ gbpLine }}
Set up · once

What each instrument needs.

Four permissions, each named for the instruments that use it. Nothing leaves the phone until an instrument is enabled, and every one of these can be revoked in Settings. Tap a state to cycle allow · denied · not asked.

{{ p.name }}{{ p.uses }}
Why ask at all. A server can fetch a page. Only a phone can stand at the address, hear the assistant, or ride a carrier network. These permissions are the whole difference.
Push receipt · deep link

The moment a regression is felt.

A receipt arrives with a haptic pattern for its severity. One tap lands on the exact finding with the byte diff already open.

07:02
CCRegression · Highnow
{{ pushDomain }}
GPTBot is refused again — 403 after 6 days at 200. Tap for the bytes.
Critical: one long. High: two short. Medium: one short. Low waits for the morning digest. Quiet hours hold anything below High.
Share sheet · intake

Share anything to CrawlCheck. It knows where it goes.

A URL, a screenshot, a log file — each is routed to the instrument that can use it. Pick one to see the route.

Routed to
{{ shareRoute.to }}
{{ shareRoute.why }}
{{ feat.uses }}

{{ feat.name }}

{{ feat.how }}

{{ c.label }}
share of voice · round of 5 Sep {{ shareOfVoice }}
{{ c.label }}
Refused on 5 of 5 networks — the block is in the origin, not a carrier. Every row was fetched from this phone within the last week.
Live · 39.7392° N 104.9903° W · ±4 m
{{ p.k }} {{ p.v }} {{ p.mark }}
evidence bundle · sha256 3f9a…c21e · 4 photos · signed 5 Sep 2026 14:02 · attached to Local presence & NAP · hours mismatch filed as a finding
{{ r.sev }}{{ r.at }}
{{ r.what }}
{{ r.domain }}
{{ r.doneLabel }}
Quiet hours 22:00–07:00 hold anything below High. Haptics: one long for Critical, two short for High, one short for Medium.
{{ c.label }}
Denver · week 36 · from 1,240 anonymised phone readings · refusals are the origin’s, not the network’s
on the pagehumancrawler
{{ p.what }}sees{{ p.c }}
Photographed on the owner’s laptop 14:31 · 48,212 bytes received by the crawler · 3 human-only facts filed to Page weight & text
yesterday → this morning07:02
{{ d.q }}{{ d.mark }}
{{ d.was }}→{{ d.now }}
{{ diffNote }}
{{ v.who }}{{ v.verdict }}
{{ v.said }}
{{ printSrc }}
{{ p.k }} {{ p.v }}{{ p.note }}
Two mismatches filed as findings with the photograph attached. A printed URL that 404s is the one defect no crawler-side scan can see.
{{ w.grade }} {{ w.name }} {{ w.meta }}
Larimer St, 1400 block · 5 geofenced · ranked by grade · tap a pin for the pitch
Your site · measured by an independent scanner
{{ clientRec.grade }}
{{ domain }}
{{ clientRec.score }}/100 · {{ rec.deltaWord }} · looked after by {{ studioName }}
{{ c.at }}{{ c.what }}
{{ f.when }}{{ f.what }}{{ f.grade }}
{{ forecast.note }}
Summit Roofing · 150 locations{{ fleet.summary }}
Shared finding · SITEMAP_DECLARED_404 · {{ fleet.shared }} locations
One template, one deploy. Re-measured {{ fleet.shared }} times the minute it ships.
{{ k.n }}
{{ k.k }}
developertime to fixfixes
{{ d.who }}{{ d.ttf }}{{ d.n }}
August · 6 clients · every number traceable to a receipt on the record.
{{ noteStatus }}
“Owner says the hours sign has been wrong since March — they open at seven. The schema is right; the sign is wrong. Tell them before we show the report.”
0:19 · attached to Local presence & NAP · plays in Boardroom mode
Connect Google Business Profile first
Read-only scopes: business information, hours, reviews, performance. The instrument runs the moment the profile is connected.
fieldGoogleschemapage
{{ p.k }}{{ p.g }}{{ p.s }}{{ p.p }}
{{ p.mark }}
{{ parity.summary }}
{{ catmapNote }}
{{ reviewsNote }}
{{ terms.note }}
● both   ▢ Google only   ○ schema only
{{ gmap.note }}
{{ fleetsync.line }}
Google · 28 days · vs previous 28
{{ a.k }}{{ a.now }}{{ a.delta }}
The site’s own beacon · 28 days
{{ b.v }}
{{ b.k }}
{{ actions.note }}
{{ intents.summary }} · tap an unticked row to open a page task
{{ waste.pct }}
{{ waste.line }}
A crawler arrives with a budget. Every fetch here produced no new page.
{{ w.k }}{{ w.v }}
{{ waste.note }}
AI visibility · measured by an independent scanner
{{ percentile.grade }}
{{ domain }}
{{ percentile.score }}/100 · {{ percentile.date }}
{{ percentile.line }}
cohort · {{ percentile.cohortName }} · re-renders on every reading
{{ l.who }}{{ l.at }}
{{ l.src }}{{ l.page }}
{{ leadsNote }}
{{ yt.channel }}
{{ m.k }}{{ m.v }}
{{ yt.site }}
Bsummitroofing.cothe domain card, with the chip{{ ci.chip }}
{{ x.when }} · {{ x.what }}
{{ ci.rule }}
● has a page   ○ schema only   ◌ 10 mi ring
{{ map.note }}
Which pages · Watch and up
The free report counts 0 thin pages and 1 undeclared page on {{ feat.dayPassDomain }}. Watch names them.
One charge, nothing renews. The key is shown on the next page and is the account. What the week builds stays readable afterwards.
28 days{{ rec.grade }}
{{ engage.views }}
views · first-party
active {{ engage.active }}tel {{ engage.taps }} · {{ engage.pct }}
active time
median under 10 s · no cookie, no identifier
Licence key · the account
{{ keyQr.key }}
A second phone scans this and opens the same portfolio.
sha256 · receipt bytes
{{ anchor.hash }}
↓{{ p.t }}
{{ anchor.verdict }}
{{ asof.when }}
{{ asof.score }}/100
{{ asof.grade }}
{{ s.k }}{{ s.v }}
{{ asof.diff }}
{{ st.t }}
{{ stepResult }}
Flows back to the site
{{ feat.back }}
{{ feat.lockTitle }}
{{ feat.lockWhy }}
{{ feat.blockedNote }}
Lock screen · home screen

The first thing a paid user sees each day.

A scan runs on the lock screen; the grade lives on the home screen. Neither needs the app open.

Live Activity · during a scan
Friday 5 September
14:07
Crawl Check{{ glance.reqs }}
{{ domain }}
{{ v.label }}
Widgets · small and medium
{{ rec.grade }}{{ rec.score }}
{{ domain }}
{{ rec.deltaWord }} · {{ glance.next }}
{{ g.grade }}{{ g.domain }}{{ g.delta }}
Widgets refresh with each reading, twice a day. The medium widget lists the three domains that moved most.

Tools

One scanner, reachable from wherever you work.

Crawler log verifier

Paste access-log lines. Every crawler claim is checked against the operator’s published address ranges: verified, spoofed, or unverifiable — three verdicts, never two.

Forged rate
{{ forgedRate }}
of checkable
claims
{{ t.n }}
{{ t.k }}
{{ r.ip }}{{ r.verdict }}
claims {{ r.bot }}
{{ r.why }}
The rate divides by verified + spoofed only. Counting unverifiable hits as forged would inflate it; counting them as genuine would understate it.
Measured from everywhere · {{ globe.at }}
{{ globe.srcPill }}

Every light is a place someone ran a scan.

{{ globe.emptyNote }}
{{ l.g }}· ○ Denver · ◌ you
{{ globe.sel.grade }}
{{ globe.sel.name }}
{{ globe.sel.sub }}
{{ globe.sel.fail }}
{{ globe.sitesTotal }}
sites measured
{{ globe.today }}
today
{{ globe.countries }}
countries · 7 days
Your time zone puts you near {{ globe.near }}. Your site would light up here.
Each point is a city where at least one free scan was started, placed by the requesting network’s city, never by domain. Grades are medians for that city. Nothing here is named, and nothing a licence unlocks changes a light. One scanner, Denver.

Live badge

An SVG that shows the current score and links to the report. It moves when the measurement moves — a client can put it on their site and it can never flatter them.

AI visibility {{ rec.grade }} · {{ rec.score }}
Embed
{{ badgeSnippet }}

The scan is free. Keeping a record starts at $29 a month.

{{ paywallNote }}

or pay for the year — pay for ten months
One-time work, priced once
You cannot pay to improve a score.
The moment a payment can move a result, every result here is worth less — including the ones you would be paying for.

Account

{{ acctEmail }}
{{ acctPlanLine }}
Google Business Profile
{{ gbpCta }}
{{ gbpLine }}
OAuth on Google’s page, read-only scopes. Twenty instruments compare the profile with the schema; none writes to it without a tap on this phone.
Licence key · {{ keyQr.key }}
Another phone scans this to sign in. There is no password.
Studio name · on client reports
Not signed in.
Scanning needs no key. The record — twice-daily readings, receipts, client reports — opens with the licence key from your receipt.
Back to the record · crawlcheck.io
{{ k.n }}
{{ k.k }}
{{ sync.line }}
{{ x.kind }} · {{ x.domain }}{{ x.state }}
Every instrument, decision, consent and task on this phone is a receipt posted to POST /api/app/receipts under your licence key. Offline, it queues; back online, it sends. Nothing lives only here.
Billing
{{ billing.plan }}{{ billing.price }}
{{ billing.next }}
{{ i.at }}{{ i.what }}{{ i.amt }}
Design tokens
{{ tokensTitle }}
{{ tokensNote }}
{{ tokensPill }}
Connection · for the demo
{{ syncLine }}
Alert rules
{{ a.k }}
With these rules: {{ alertPreview }}
Alerts
Cadence
API
Data source{{ sourceLabel }}
Base URL
Key · licensed lane
{{ apiStatus }}
Paste one response
Paste a real /api/scan or /r/{id}.json body and the app maps it and renders the report.
Where each field came from
{{ m.field }}{{ m.from }}
CrawlCheck identifies itself honestly on every request and does not impersonate Googlebot, GPTBot or ClaudeBot. No scanned domain is ever named publicly.
{{ toast }}
Share · {{ domain }}
{{ sheet.ua }}{{ sheet.verdict }}
{{ sheet.operator }} · {{ sheet.role }} · verified by {{ sheet.verifyBy }}

{{ sheet.purpose }}

{{ sheet.head }}
Response head · as received