AI search · Roofing · Diagnostics

How Do You Optimize Your Roofing Website for AI Search? Diagnose Before You Build

A roofing site that gets no AI visibility is almost never "badly optimised" in the sense that phrase is sold. It is usually blocked somewhere nobody looked, or readable but not selectable, or selectable but unattributable. Those are four different failures with four different remediations and four different price tags, and applying the wrong one is how contractors end up on their third agency with nothing to show. This is the diagnostic sequence: how to establish which failure you actually have, in what order to test for it, and what the evidence can and cannot prove once you do.

The best diagnostic run we have published is in our AI SEO case study, and the first finding was not a content problem. This article is the method behind that run: what to measure, in what sequence, and how to tell a real failure from a seasonal artefact. It assumes a practitioner's tolerance for unflattering intermediate numbers. Sections four through ten are the instrumentation; section twelve is the triage order if you want to skip ahead.

The 60-second answer

Short answer

Test in the order the pipeline runs, and stop at the first failure. Fetch your priority pages as the crawler and confirm the body text arrives — if it does not, nothing else matters and no content budget will help. Then parse: check that the extracted text preserves your headings, claims and answer position. Then check attribution: does a passage naming your company also contain a fact worth quoting. Then check selection: does a passage answer a sub-question your buyers actually ask. Only then measure the panel, and only with a control cohort and intervals computed before you compare.

What makes this worth doing in this order is that the four failure modes are mutually exclusive in their fixes and wildly unequal in cost. Unreachable is a firewall rule. Unparseable is a rendering change. Unselectable is editorial. Unattributable is a brand and proof programme. Paying for the fourth while suffering from the first is the most common expensive mistake in this category, and it is invisible to anyone who starts with a content audit.

19.2% of sites returned no usable page to a live GPTBot fetch, against 3.8% that disallowed GPTBot in robots.txt Arobis scan · Oct 2026
18.2% of sites whose robots.txt allowed OpenAI's crawlers were still blocked at the fetch Same scan · 336 of 1,847
<10% of AI bot traffic is live search retrieval; the rest is training and discovery sweeps Cloudflare Radar data · 2026
41% same-day domain overlap between identical repeated questions — the floor under any measurement Axios · Oct 2026

The first two numbers are the reason this article exists. A contractor told that "AI search needs content" will buy content. A contractor whose CDN is returning a challenge page to OAI-SearchBot has a twenty-minute fix and a completely different problem, and the two situations look identical from the outside: no visibility, no obvious cause, an agency willing to explain it.

Why diagnosis has to precede the build

Optimisation advice is written for the median case, and the median case in this field is a site that is technically reachable. That assumption is doing enormous work. When 19.2% of a scanned sample fails a live GPTBot fetch — and 18.2% of the sites that explicitly allow those crawlers in robots.txt still fail — reachability is not a solved precondition. It is the first thing to test.

The economics of getting the order wrong are brutal for a contractor, because the false negative is silent. A firewall block produces no error a business owner will ever see. The site loads perfectly in Chrome, ranks in Google, passes a Lighthouse audit, and appears in no AI answer. Every signal available to a non-specialist says the site is fine, so the natural conclusion is that the site needs better content — which is a purchase that cannot work, because the content will never be read.

The asymmetry

A reachability failure causes total invisibility at near-zero cost to fix. A selectability failure causes partial invisibility at high cost to fix. Both present as "we do not show up in ChatGPT", and no vendor can distinguish them from a screenshot. The only way to know is to test, and the test takes an afternoon rather than a quarter. The build sequence that follows a clean diagnosis is set out in the on-page optimization guide; this article is the part that comes before it.

There is a second reason to diagnose before building, which is commercial rather than technical. Roofing companies arrive at this question with one of three histories: they have done nothing, they have done the standard local-SEO programme and it stopped working, or they have already bought an "AI SEO" package and cannot tell whether it did anything. Each history predicts a different most-likely failure, and none of them is answered by a proposal written before the first fetch.

The four failure modes and their signatures

Name the failure before you price the fix. The four below cover almost everything we find on roofing sites, and each has a signature you can confirm or eliminate in under an hour.

Failure modes, signatures and remediation
ModeSignatureConfirms itFix class
Unreachable
The crawler never gets a usable document
Zero or near-zero bot fetches in origin logs; a 200 to your browser and a 403, 429 or challenge to a bot user agentBot-UA fetch from an external network plus an origin-log comparison for the same timestampInfrastructure. Hours to days
Unparseable
A document arrives but not your content
Response full of navigation and script tags; body copy absent; word count near zeroThe extraction diff: bot-fetched HTML versus rendered DOM, compared as textRendering. Days to weeks
Unselectable
Text is present but loses the retrieval competition
Content arrives, yet a prompt panel shows directories cited and your domain absent for questions your pages should answerPassage diagnostics: pronoun density, answer offset, identifier uniqueness, section lengthEditorial. Weeks to a quarter
Unattributable
Cited but never named, or named without proof
Domain appears in citations; company name rarely appears in the answer text; no directory or third-party source corroborates youCitation-versus-mention logging in the panel, plus a source audit of your cited competitorsBrand, proof and off-page. Quarters

The four modes nest: a site can be unreachable and unattributable at once, and usually is. The order matters because each mode is a precondition for the next — fixing attribution on an unreachable site changes nothing observable.

Five points at which a roofing page disappears

Where a roofing page is lost between the crawl and the answer Five stages: fetch, parse, passage selection, assembly and naming. A failure at any stage produces the same outward symptom. 1 · FETCH WAF, robots, CDN rule — the failure nobody sees SILENT 2 · PARSE Client rendering, layout order, consent interstitial SHELL 3 · PASSAGE Chunk has no subject, no answer, no identifier LOSSY 4 · ASSEMBLY Passage used to support a claim, without the brand GHOST 5 · NAMING Three to six roofers named per city answer at most RARE
Stages one and two are infrastructure and produce no signal a business owner can see. Stages three to five are the editorial and off-page layer. Each stage gates the next.

Two diagnostics are worth running even when you are confident of the answer, because confidence in this field is usually wrong: the reachability test and the extraction diff. In our own audits, roughly a third of sites presented as "content problems" failed at the fetch or the parse. That is our sample rather than a published statistic, and it is the reason the tests below are ordered the way they are. The retrieval mechanics behind stages three to five are in the retrieval engineering brief.

What to instrument, and at which layer

Four data sources matter, and three of them are usually missing. None is a dashboard you can buy; all four are artefacts you have to keep.

The instrumentation stack
SourceWhat only it can tell youRetention
Origin access logsWhether a request reached your application at all, with status, bytes served and user agent — the only place an edge block becomes visible by its absenceRaw lines for 12 months minimum
Edge or CDN analyticsWhat was blocked or challenged before your application saw itAggregated per bot, per path
Search Console generative-AI report and Bing Webmaster Tools AI PerformanceImpressions and cited pages on surfaces you cannot query directlyMonthly exports; coverage varies by property and country
A frozen prompt panelWhat the answer actually said — the only observation of the output, as opposed to the inputEvery run, verbatim, with engine, date and location

The design decision that makes the whole stack work is to classify bot requests into four purposes rather than treating them as one population. This matters because the four classes have different causes and different meanings:

Training crawl
GPTBot, ClaudeBot, CCBot, Google-Extended. Evidence that you are in a corpus, not that you are in an answer. Blocking these is defensible and does not remove you from search answers.
Index crawl
OAI-SearchBot and equivalents. Populates the index that ChatGPT's search features draw on. This is the class that decides whether you are a candidate at all, and it is the one most often blocked by accident.
Answer-time fetch
ChatGPT-User, Claude-User, Perplexity-User. Triggered while a person is waiting for an answer. The closest observable proxy for citation, and usually present in logs in numbers far higher than referral traffic.
Impersonation
Any request claiming one of the above from an IP outside the operator's published range. Common, and the reason allowlists should be built on ranges rather than strings.

A minimal log classification, which runs in seconds over a month of lines and is the single most informative artefact in the whole audit:

# Classify bot requests by purpose, then by status
# (illustrative; adapt field positions to your log format)

awk '{ ua=$0 }
     /GPTBot|CCBot|Google-Extended|ClaudeBot/   { class="train" }
     /OAI-SearchBot|PerplexityBot|Claude-SearchBot/ { class="index" }
     /ChatGPT-User|Claude-User|Perplexity-User/ { class="fetch" }
     class!="" { print class, $9 }' access.log \
  | sort | uniq -c | sort -rn

# What you want to see:  index requests present, with 200s
# What indicts you:      index requests absent, or mostly 403/429
# What misleads you:     a large "train" count, which proves nothing
#                        about citation

One caveat on reading volume. Crawl frequency is a function of authority, site size and scheduling, not of quality, so a competitor with more GPTBot requests is not necessarily doing better — they may simply be larger. The diagnostic value of the logs is in the presence, class and status of requests, not in the count. The infrastructure work that follows a log finding sits with the roofing SEO team, because it is a hosting and development problem rather than an editorial one.

Test 1: the silent block

Run this first and never skip it. The mechanics are simple; the reason it is missed is that the three places a block can live are owned by three different people.

  • robots.txt. Read the file and look for a group that disallows OAI-SearchBot, PerplexityBot or Claude-SearchBot. A blanket "AI bots" group is the usual culprit, and it is usually inherited from a template or a plugin rather than chosen.
  • The edge. CDN bot-management, a WAF managed ruleset, or a hosting provider's default "block AI scrapers" toggle. This layer commonly returns a challenge page with a 200 status, which is why a naive check passes.
  • The application. Rate limits, geo rules, a WordPress security plugin, or a maintenance-mode cookie check that behaves differently for unfamiliar agents.

The published scan that motivates this test found 19.2% of 2,012 websites returned no usable page to a GPTBot user-agent fetch, against 3.8% that disallowed GPTBot in robots.txt. More telling: 18.2% of the sites whose robots.txt explicitly allowed OpenAI's crawlers — 336 of 1,847 — were still blocked at the point of fetch. The allowance was real and the content still did not arrive.

How to confirm, not infer

Fetch from a network that is not your office. Compare what you receive to what the origin logged for the same minute. If the edge blocked it, the origin has no record; if the application blocked it, the origin has a 403 or a challenge with the bot's user agent attached. Those two outcomes point at different owners, different tickets and different vendors, and guessing between them is how a two-hour fix becomes a three-week project.

Two related checks belong in the same pass. Confirm that a redirect chain resolves rather than loops, because a canonical pointing through a 404 is a reachability failure wearing an architecture costume. And confirm that the first screen of your HTML is not a consent notice — if the first two hundred words a crawler receives are a cookie banner, that is what gets indexed, regardless of how good the page is underneath. The access layer is covered in more detail in the visibility piece.

Test 2: is that really the bot you think it is

User agents are claims, not identities. Any client can send OAI-SearchBot and most will, because it is a token that gets past naive allowlists. This cuts both ways in an audit: a log full of "GPTBot" may contain no OpenAI traffic at all, and an allowlist built on the string is an open door for anyone who knows it.

Verification means checking the source address against the operator's published range file, per bot:

Verification sources and what to expect
BotPublished range fileNote
GPTBotopenai.com/gptbot.jsonTraining and general browsing
OAI-SearchBotopenai.com/searchbot.jsonThe index behind ChatGPT search answers
ChatGPT-Useropenai.com/chatgpt-user.jsonUser-triggered live fetches
PerplexityBot, Perplexity-UserPerplexity's published range filesSeparate files per agent

As reported on 6 October 2026, the three OpenAI files listed 18, 39 and 230 IPv4 prefixes respectively and no IPv6. The counts change; re-download rather than caching a snapshot in a wiki, and treat any traffic claiming these agents from outside the ranges as unverified.

# Verify a claimed bot by range, not by user-agent.
# Re-download the range file first; never trust a cached copy.

curl -s https://openai.com/searchbot.json | jq -r '.prefixes[].ipv4Prefix' \
  | sort > searchbot.cidrs

# Join against the IPs in your log that claimed to be OAI-SearchBot.
# Anything left unmatched is either a stale range file or an impostor;
# re-download before concluding which.

The practical consequence for a roofing site is narrow but important. If your allowlist was written on user-agent strings, you have two problems: the real bot may still be blocked by a rule you did not think of, and your analytics for "AI crawler traffic" contain unknown quantities of noise. Rebuild the rule on ranges, then re-baseline, because the numbers you had before were not measuring what you thought.

Test 3: the extraction diff

A curl against a bot user agent tells you whether content arrived. It does not tell you whether the page's meaningful content arrived, in the right order, with headings attached to their sections. That requires a diff.

The method: capture the raw HTML the bot receives, then capture the rendered DOM from a headless browser with JavaScript executed, reduce both to visible text, and compare. Three findings matter, and each points at a different fix.

What the diff tells you
ObservationDiagnosisFix owner
Bot HTML contains navigation and no body copyClient rendering; the content is painted after hydration and the assistant crawlers never run itDevelopment
Body copy present in both, but the bot version orders headings after their paragraphsReading order imposed by CSS layout rather than document structureFront-end
Body copy present, but your answer paragraph appears only in the rendered versionA component that renders conditionally — often a "read more" accordion or a sliderFront-end
Body copy present and ordered, but every project photo caption is missingCaptions are in the visual layer rather than the text layerContent
Both versions missing a section that exists in the CMSA template conditional, an unpublished block, or a tag-manager injectionDevelopment

The diagnostic discipline is to compare text rather than to look at the page. A page can look correct, pass every visual check, and still serialise into a document where a heading sits below the paragraph it introduces. Deleting the CSS and reading the source top to bottom is crude and effective; automating the diff is better if you are doing this across twenty URLs.

Two numbers bound the scale of this failure. Analysis of more than 500 million GPTBot fetches found no evidence of JavaScript execution, with JavaScript files requested in about 11.5% of GPTBot fetches and 23.8% of ClaudeBot's. And a single agency's February 2026 estimate put 42% of JavaScript-rendered content outside AI indexing — a figure worth citing only with the caveat that its methodology was not published in full. The direction is well supported; the precise share is not. Where the fix is a rebuild rather than a patch, it belongs with a team that does this on contractor sites routinely, which is why our roofing practice keeps that work in-house.

Test 4: passage diagnostics

If content arrives and is parseable, the next question is why it loses. Four measurements, all computable without a vendor tool, separate the plausible causes.

Four passage-level measurements
MeasureHowThreshold that warrants attention
Pronoun densityCount third-person and demonstrative pronouns per 100 words of body copy, excluding navigationAbove four is under-specified; above eight is a rewrite candidate
Answer offsetCharacter position at which the page's primary question is actually answeredLater than the first 600 characters means the answer is not in the opening passage
Identifier uniquenessTokens present on your page and absent from three competitors' equivalent pages — licence numbers, product systems, standards, programme namesAn empty set means you can only be retrieved by paraphrase
Section length distributionWords between consecutive headings across your top twenty commercial URLsA median above 500 words gives a splitter no good boundary

The mechanism behind each is the part worth understanding, because it tells you which measurement to trust when they disagree. A high pronoun density means a retrieved chunk loses its subject and drops out at the rerank. A late answer offset means the answer sits in the middle of the passage — the position where model accuracy is documented to degrade. An empty identifier set means the lexical half of hybrid retrieval has nothing rare to match. Long undifferentiated sections mean the splitter cuts mid-argument and produces chunks that begin with "this is why".

The cheapest of the four

Answer offset. One look at where the page actually answers its own question usually settles whether the problem is retrieval mechanics or editorial discipline, and it takes a single scroll. Roofing pages disproportionately answer late, because the template opens with a hero, a trust strip and three sentences about the founding year before saying anything a reader came for.

A fifth check belongs here even though it is not a passage measurement: whether the company is named inside the passage that carries the claim. One 2026 analysis found 61.7% of citations came from domains whose brand was never named, and a panel found ChatGPT citing sources in 87% of appearances while naming a brand in 20.7%. Those are aggregate consequences of writing "we" for nine hundred words, and they are the bridge to the fourth failure mode in section three, which the recommendation article treats as its own campaign.

Test 5: entity consistency

Entity confusion is the failure most likely to be misdiagnosed as a content problem, because the symptom — appearing for the wrong city, or not appearing for the right one — looks editorial and is actually a records problem.

Build the comparison table before changing anything. For a single roofing business there should be one row per external record, and the job is to find every field that differs.

Fields that must agree, and where they drift
FieldSources to compareTypical drift
Legal nameSite, Google Business Profile, licence registry, invoices, directory listingsTrading name on the site, legal name on the registry, both used interchangeably in prose
AddressGBP, site footer, BBB, manufacturer locatorSuite number dropped on three of five records
TelephoneSite, GBP, directoriesCall-tracking numbers placed on listings, splitting the entity into two
CategoriesGBP primary and secondary, site service pages, directions listingsPrimary category set to a general contractor when the work is roofing
Service areaSite copy, schema areaServed, GBP service areaThree different lists, one of which includes cities you do not serve
Programme listingsManufacturer contractor locator, trade association directoryListed under a lapsed certification tier
HoursGBP, site, directoriesEmergency availability claimed in one place and contradicted in another

Two findings from the wider research make this worth the tedium. In one five-engine panel, 56.3% of Gemini's roofing answers involved a manufacturer programme, which means a lapsed or missing locator entry is a distribution loss rather than a branding detail. And in a Florida study of 745 queries, BBB was the single most-cited source on Perplexity — at 59.6% of answers — so the records that matter most are engine-specific and cannot be guessed. Citation and mention are different events, and the citing playbook covers the half this test cannot reach.

The test itself is an interrogation: ask an assistant what it knows about the business, in the plainest possible phrasing, and read the answer for inaccuracies rather than for praise. Confusion with a similarly named contractor, a city in the service area you have never worked in, a licence number belonging to someone else — each of those is a diagnostic result with a specific repair, and each is invisible on the website itself.

Test 6: coverage against the question set

The previous four tests ask whether your pages can win. This one asks whether you are in the right competition at all, and it is the test most likely to reveal a strategic error rather than a technical one.

Build the matrix from demand, not from your sitemap. One head question — "how much does a roof replacement cost in [city]" — fans out into sub-questions the engine generates and you never see: the price basis, what changes it, the material comparison, the permit and disposal line items, the insurance case, the financing case, the seasonal effect, and the regional difference. Google documents the fan-out technique and exposes no sub-queries to publishers, so the matrix is your reconstruction rather than a readout.

A coverage matrix for one roofing question
Sub-questionDo you have a section?Is the answer in its first sentence?Does it name you and a number?
What is the price basis?YesNo — three paragraphs of preambleNo
What does extra tear-off cost?Partial — one clauseNoNo
How do materials compare?No——
Is the permit included?No——
Does insurance cover it?Separate pageYesYes
Can it be financed?No——
Does season change the price?No——
Does region change the price?PartialNoNo

Illustrative row values. The point is the shape of the result: two of eight sub-questions answered well, one page carrying the load, six gaps, and no row where the company name and a number appear in the same sentence as the answer.

Score the matrix by counting rows that are fully answered rather than by counting words. A roofing cost page with eight sections in which two are complete will lose to a competitor with four sections in which four are complete, because the retrieval competition is passage against passage, not document against document. Coverage breadth without depth produces a page that looks comprehensive and wins nothing.

One caution about interpretation. A gap in the matrix is not automatically a page to commission. The question is whether the sub-question is asked in your market with commercial intent, and the fastest source of evidence is your own call log and your paid search query report rather than an AI tool's suggestion list. For the wider tactic inventory, the 50-strategy set is the reference we work from.

Test 7: the panel, and what it can prove

The panel is the only observation of the output. It is also the most abused instrument in this field, so the design matters more than the tool.

Minimum viable design: sixty prompts per market, per engine, frozen in writing before the first run; city-modified and intent-weighted toward selection and emergency questions; each prompt run at the same cadence, from the same location, with the full answer text logged verbatim, including which domains were cited and whether the business name appeared in the prose.

Then do the arithmetic before anyone sees a chart. At a 45% hit rate, twenty prompts with one run each gives a 95% interval of roughly 23% to 68%. Sixty prompts narrows it to roughly 32% to 58%. Because identical questions repeated the same day overlap by only about 41% in the domains cited, a single-run comparison across months is measuring noise as much as effect.

What the panel can and cannot establish
QuestionAnswerable?How
Is my domain cited at all for this market?YesPresence count over a frozen set, stated as a range
Is my brand named when my domain is cited?YesManual tagging of answer text; the ghost-citation rate
Which competitors occupy the slots?YesNamed-entity extraction per prompt, with occupancy share
Did my change cause the movement?Only with controlsTreated versus untreated cohort, four weekly observations minimum
Why did the engine choose them?NoSelection is unobservable; only the outcome is visible
Will this produce more booked jobs?Not from the panelRequires a separate call-and-close measurement in the CRM

The row that matters most is the fourth. Without a control cohort, every result is a story about the weather. The companion article on retrieval mechanics sets out the experiment design and the interval arithmetic in more detail; for diagnostic purposes the requirement is simply that a treated cohort and an untreated cohort are observed over the same weeks, and that the report shows both.

The triage order

Diagnosis produces a list. Triage produces a sequence, and the sequence is not negotiable because each step changes whether the next one is measurable.

Step 1

Reachability — hours

Fix the block, the redirect chain and the consent interstitial. Until a bot receives your body copy, every other measurement is measuring nothing, and every other spend is unverifiable.

Step 2

Parse fidelity — days to weeks

Render the primary copy on the server, restore document order, and move conditional components out of the way of the answer. Re-run the extraction diff on the same twenty URLs and keep both artefacts.

Step 3

Entity consistency — days, mostly admin

One legal name, one address, one telephone scheme, one service area, and programme listings that reflect current status. This work is unglamorous and it is the cheapest available improvement to attribution.

Step 4

Passage and coverage — the quarter's editorial work

Answer offset, pronoun density, identifiers, section geometry, and the matrix rows that are worth completing. Four sections done properly beat eight done thinly.

Step 5

Attribution and corroboration — the following two quarters

Named mentions in third-party prose, supplier and association records, and the review and proof layer. This is the slowest and the only step that competes on the axis your competitors are also working.

Two rules govern the sequence. Do not start a step before the previous one has been verified rather than assumed — the verification artefact matters as much as the fix. And do not run steps four and five in parallel on the same pages, because you will be unable to attribute movement to either, which means you will not know which one to fund next year.

Crawl is not citation: the economics of the ledger

Contractors are routinely sold crawler visibility — "GPTBot visited your site 4,000 times last month" — as though it were an outcome. It is a supply-side observation, and the published ratios make the gap plain. Cloudflare's measurements of crawl-to-referral ratios have been reported in the hundreds or thousands to one depending on the operator and the window: around 900 to 1 for OpenAI's crawler and over 10,000 to 1 for Anthropic's in one May 2026 snapshot, with different figures published as the methodology and period changed in July 2026.

The absolute numbers should not be quoted as facts, and the reason is instructive: they depend on what counts as a crawl, what counts as a referral, and which properties are in the panel. What is robust across every version is the shape of the finding. Requests vastly outnumber referrals, and — per the same body of work — more than 90% of AI bot traffic is training or broad discovery rather than live retrieval, with one analysis putting live search at under 10% and search-related traffic at roughly 8%.

The one ledger worth keeping

Classify by purpose, then report the classes separately. Training crawls are a commercial decision about your content. Index crawls are a precondition. Answer-time fetches are the closest proxy for citation. Referrals are the only visitor-adjacent number, and they will be small for a local contractor regardless of visibility, because most people who see a recommendation call rather than click. A report that blends all four into "AI visibility is up" has told you nothing you can act on.

One worked illustration of what an honest ledger looks like, from a published site diary covering 20 days in mid-2026: 5,227 AI crawler requests, 1,041 answer-time fetches across 14 posts, and seven visits referred by AI answers — a ratio of roughly 747 crawls per referred visit. The same diary noted that a single weekly pricing table absorbed 503 of those answer-time fetches, which is the most useful line in it: the page being fetched at answer time is the page the engine needs, and it is rarely the page the business considers its flagship.

For a roofing contractor, the practical implication is to instrument ChatGPT-User, Claude-User and Perplexity-User requests by path, and to look at which pages appear. Those paths are your actual AI-facing inventory. If they are all directory-style pages and never your service pages, the diagnosis is coverage, not visibility, and the fix is editorial. Which of those service pages convert is a separate question, covered in the high-intent leads breakdown.

What to fix when the budget is zero

Most roofing companies asking this question have a website and no budget for a programme. The good news is that the highest-leverage diagnostics are free, and the first three fixes usually are too.

Zero-budget sequence
ActionCostTimeWhat it potentially unlocks
Fetch three priority pages with a bot user agent and read the outputNone20 minutesRules the entire content question in or out
Read robots.txt and the hosting control panel for AI bot togglesNone30 minutesRemoves the most common accidental exclusion
Rewrite the first paragraph of your top five pages so the answer comes first and the company is named inside itNone2 hoursMoves the answer into the opening passage and reduces ghost citation
Fix name, address, phone and service area so every listing agreesNone3 hoursEntity consistency, the cheapest attribution gain available
Add licence number, insurance limits and warranty terms as visible textNone2 hoursIdentifier uniqueness and a quotable fact in one edit
Caption ten completed projects with municipality, material, size and durationNone2 hoursFirst-hand, local, unfakeable claims no directory can replicate

What not to buy first, on any budget: a schema package, an llms.txt service, a semantic-chunking tool, or a monthly report that quotes a single percentage movement without an interval. Each of those is either unproven, ineffective, or uninterpretable at the sample sizes a local contractor can afford.

Reporting, and what can be promised in a contract

The reporting question and the contracting question are the same question asked at different times: what is observable, and who bears the risk of the unobservable part.

Observable and defensible, month over month: bot requests by class and status; response bytes and word counts from a bot fetch; extractable content diff results; entity field consistency across a fixed list of records; the count of pages answering a question in their first sentence; branded mentions earned in third-party prose; citation presence as a range over a frozen prompt set; and answer-time fetch counts by path.

Not observable, and therefore not contractible: a guaranteed citation, a guaranteed mention, a position inside an answer, a percentage lift attributable to a specific edit without a control cohort, or any forecast of booked jobs. The shortlist is regenerated per prompt and identical questions overlap about 41% day to day; nobody can guarantee an outcome they cannot see.

Fair to include
A defined prompt set, published in the contract, run at a stated cadence. A named control cohort. The technical artefacts — fetch logs, diffs, entity tables — delivered as deliverables rather than as slides.
Fair to refuse
Outcome guarantees of any kind, and any target expressed as a percentage of answers in which the company appears, unless the contract also fixes the sample size and the confidence interval.
Worth insisting on
A written diagnosis before a proposal. If an agency cannot tell you which of the four failure modes you have, and cannot show the artefact that proves it, the proposal is about their product rather than your site.

There is a version of this that is uncomfortable for agencies, so it is worth stating plainly. The best diagnostic outcome for a contractor is sometimes "you are blocked by a firewall rule, here is the ticket, this should take a fortnight and we should not charge you a programme for it." The second best is "your site is fine and your market is served by directories, so the constraint is off-page and here is what that costs." Both are more useful than a retainer, and both are what an honest diagnosis occasionally produces.

What these diagnostics cannot tell you

  • Why an engine chose a competitor. Selection is unobservable. You can see the outcome, infer the sub-questions, and test hypotheses, but the mechanism is not exposed to publishers.
  • Whether your fix caused the change. Not without a control cohort observed over the same weeks, and not without intervals computed before comparison.
  • Whether any of it produces booked jobs. No published study connects on-page AI visibility to signed roofing contracts. The chain from citation to contract requires CRM data and a different method.
  • What a benchmark says about your site. Published block rates for a single bot range from about 4% to 25% depending on the sample, and directory reliance from 9.6% to 82%. Benchmarks describe other people's populations.
  • Whether an AI-visibility tool's score means anything. A composite score can rank two sites without describing either. Ask what is being counted, at which layer, and with what sample.
  • How the retrieval stack actually works. The major vendors have not published their architectures. The pipeline model is well supported and it is still a model.

What the diagnostics can do is narrower and more valuable: they can eliminate. Ruling out a reachability failure in twenty minutes is worth more than a quarter of content work aimed at a site the crawler never read, and ruling out a market where directories dominate is worth more than an annual retainer aimed at a battle the site cannot win alone.

Source register and confidence

Every figure used above, with its provenance and its weakness. Several of the crawler statistics contradict each other, which is itself one of the article's arguments.

Source register
Figure usedSource, date, sampleConfidence
19.2% of sites returned no usable page to a live GPTBot fetch; 3.8% disallowed GPTBot in robots.txt; 18.2% of allowing sites (336 of 1,847) still blockedArobis website AI readiness scans, 2,012 scans, Oct 2026Vendor scan
14.3% of 4,962 top-10,000 robots.txt files block GPTBot; 20.8% in the top 1,000; 10.8% block at least one AI search crawlerAI Crawler Check study, Oct 2026Independent study
8.9% of 894 tested sites block at least one AI search bot; 45% of GPTBot blockers also block OAI-SearchBot; 2.3% block in the firewall onlyPublished site test, Oct 2026Small sample
~25% of top-1,000 sites block GPTBot; ~5% block OAI-SearchBot; ~30% use the training-block/search-allow middle pathPresenc tracker, May 2026Vendor tracker
19.1% of 54,771 parseable domains block at least one AI crawler; GPTBot 15.4%; 23.6% publish llms.txtUSTA Closing Web Index, Jul 2026Vendor index
Under 10% of AI bot traffic is live search retrieval; ~89% training or mixed; ~8% search-related; ~2.2% user queriesCloudflare Radar data as reported, 2026Secondary reporting
Crawl-to-referral ratios in the hundreds or thousands to one; figures vary by period and methodCloudflare, May and July 2026, as reportedContested magnitude
5,227 crawler requests, 1,041 answer-time fetches across 14 posts, 7 referred visits over 20 daysSingle-site published diary, Jul–Aug 2026One property
No evidence of JavaScript execution in 500M+ GPTBot fetches; JS fetched in 11.5% (GPTBot) and 23.8% (ClaudeBot) of requestsVercel with MERJLarge-scale measurement
42% of JavaScript-rendered content never indexed by AI systemsSingle agency analysis, Feb 2026Unpublished method
Per-bot IP range files; 18 / 39 / 230 IPv4 prefixes as reportedOpenAI published ranges, 6 Oct 2026Primary, changing
~41% same-day domain overlap for repeated identical questionsAxios, Oct 2026Journalism
61.7% ghost citations; ChatGPT named a brand in 20.7% of appearances while citing in 87%Semrush, 2026Vendor
Manufacturer programmes in 56.3% of Gemini roofing answers; own-site citation share 17.8% ChatGPT / 87.2% AI ModeCheers Market Baseline, 2,176 answers, Sep 2026Vendor panel
BBB most-cited source on Perplexity at 59.6%; 745 queries, 10 metros, 5 platformsLocal Vitals Florida study, Apr 2026Vendor study
Query fan-out documented; no special optimisations required for AI Overviews or AI ModeGoogle Search Central, updated 31 Dec 2025Vendor documentation
Adding JSON-LD to 1,885 pages produced no significant citation movementAhrefs controlled study, May 2026Controlled

The disagreement worth naming rather than smoothing: published GPTBot block rates range from roughly 4% to 25% across samples, because a top-1,000 publisher population behaves nothing like a population of small business sites. Neither number describes a roofing contractor. The same applies to the crawl-to-referral ratios, which moved by an order of magnitude between published snapshots of the same operator. Any figure quoted without its population is decoration.

Questions we get asked

How do you optimize your roofing website for AI search?

Diagnose before building. Fetch priority pages with a crawler user agent and confirm the body copy arrives; if it does not, fix the block or the rendering and stop. Then check that a self-contained passage names the company and answers a question in its first sentence, that listings agree on name, address and service area, and that each commercial question has a section of its own. Measure on a frozen prompt set against an untreated cohort, and report ranges rather than points.

How do you know whether AI crawlers are blocked?

Three layers, checked separately: robots.txt for a group disallowing OAI-SearchBot or PerplexityBot; the CDN or WAF for bot-management rules that challenge or 403 the agent; and the application for rate limits and security plugins. Then confirm by fetching from an external network and comparing to origin logs for the same timestamp — an edge block leaves no origin record, while an application block does. In one scan, 19.2% of sites failed a live GPTBot fetch against 3.8% that said so in robots.txt.

Does a lot of GPTBot traffic mean you are visible in AI search?

No. GPTBot is primarily a training crawler, and under 10% of AI bot traffic is live search retrieval by one 2026 analysis. Crawl-to-referral ratios have been reported in the hundreds or thousands to one. The signal worth counting is answer-time fetches from ChatGPT-User, Claude-User and Perplexity-User, classified by path, because those occur while an answer is being written.

Why do published statistics on AI crawler blocking disagree so much?

Because the populations differ. Studies of the top 1,000 sites find GPTBot block rates around 20 to 25%, studies of ten thousand mixed sites around 14%, and scans of small-business websites around 4%. Publisher populations block more aggressively than businesses that want to be found. Any benchmark quoted without its sample is a rhetorical device, and none of them describes your site.

What is the fastest diagnostic you can run yourself?

Fetch one commercial page with a bot user agent and look at the first 1,200 characters of stripped text. That single observation tells you whether content arrived, whether the answer is at the top, and whether your company name appears beside a fact. It takes twenty minutes and it rules out the two most expensive misdiagnoses: paying for content on a blocked site, and paying for visibility on a site whose answer sits in paragraph four.

How many prompts does an AI visibility audit need?

Sixty per market per engine is the practical minimum for monthly reporting, and twenty is a smoke test only. At a 45% hit rate, twenty prompts with one run each gives a 95% interval of roughly 23% to 68%; sixty narrows it to roughly 32% to 58%. Prompts should be frozen before the first run and reported per engine, because own-site citation shares differ by a factor of five between engines.

Your competitor is named in AI answers and you are not. What is the diagnosis?

One of two, and they are distinguished by whether your domain appears in the citations at all. If it does and the name does not, you have an attribution failure: ghost citation, caused by writing in the first person and by thin third-party corroboration. If the domain never appears, you have a selectability or reachability failure. Run the fetch test to separate the last two, then look at coverage and passage quality.

Should you block training crawlers but allow search crawlers?

That is a defensible and increasingly common configuration — roughly 30% of top-1,000 sites by one tracker. The mistake is blocking both together: 45% of sites that block GPTBot also block OAI-SearchBot in one 2026 test, which removes them from ChatGPT search answers as well as from training. Make the decision per agent, deliberately, and record it, because a default inherited from a hosting panel is not a decision.

What should you ask an agency before hiring them for this?

Ask which of the four failure modes they believe you have, and ask to see the artefact that proves it: the fetch log, the extraction diff, the entity table, or the panel with its interval. A proposal that arrives before a diagnosis is a product being sold rather than a problem being solved. Also ask what they will refuse to guarantee, because anyone guaranteeing a citation is guessing.

How long before a fix shows up?

Reachability fixes change what is fetchable within a crawl cycle, usually days to weeks. Rendering changes take effect at the next successful crawl of each URL. Editorial changes move on a one-to-two-month horizon. Attribution work moves over quarters. Because identical questions repeated the same day overlap only about 41% in the domains cited, nothing should be judged on a single measurement or a single week.

Glossary

Failure mode
One of the four mutually exclusive reasons a page can be invisible in AI answers: unreachable, unparseable, unselectable, unattributable.
Silent block
An exclusion applied at the CDN, firewall or application layer that returns a challenge or error to a crawler while the site works normally in a browser.
Index crawl
Collection by the agent that populates a search index used in answers, such as OAI-SearchBot. Distinct from training collection.
Answer-time fetch
A request from an agent such as ChatGPT-User or Perplexity-User triggered while an answer is being generated. The closest observable proxy for citation.
Extraction diff
Comparing the text a crawler receives against the rendered DOM to detect client rendering, layout-imposed reading order and conditionally hidden content.
Answer offset
The character position at which a page actually answers its own primary question. Late offsets place the answer in the middle of a retrieved passage.
Pronoun density
Pronouns per hundred words of body copy. A proxy for how badly a passage will degrade when retrieved outside its original context.
Identifier uniqueness
The set of strings on your page that do not appear on competitors' equivalent pages — licence numbers, product systems, standards, programme names.
Entity consistency
Agreement across every external record on legal name, address, telephone, categories and service area.
Coverage matrix
A reconstruction of the sub-questions inside one head question, scored by whether each is fully answered rather than by word count.
Control cohort
A set of comparable URLs left untreated so that change can be attributed to work rather than to season or index drift.
Ghost citation
A citation in which the domain is used as a source while the brand is never named in the answer.
Crawl-to-referral ratio
The number of crawler requests per visit referred back. Reported in the hundreds or thousands to one for AI crawlers, with wide variation between snapshots.
Triage order
The sequence in which failure modes are fixed, gated by verification, because a later fix is unmeasurable until an earlier one is confirmed.