MilkHat Media round badge: a glass milk bottle wearing a red plaid trapper hat on a purple disc ringed in gold, with the words MilkHat Media, AI Automation

The 2026 Twin Cities HVAC Website Visibility Study

54 HVAC contractors. 52 data points. One question: can homeowners — and increasingly AI — actually find and understand your business online?

We pulled 54 HVAC contractor websites from Minneapolis down to Shakopee and checked every one of them by hand and by script on August 26, 2026. Three block AI crawlers. Three. If you've been told your site is invisible to ChatGPT because a robots file is shutting the door, that's not what we found. What we found is that 45 of the 50 readable sites have no structured answers on them at all, which means there's nothing on the page for an AI to pick up and repeat when a homeowner in Eagan asks it who to call.

The numbers, all in one place

  • 45 of 50 readable Twin Cities HVAC sites (90%) have no FAQ schema on the homepage. This was the most common failure in the study.
  • 44 of 50 (88%) have no Service schema, so a machine can't tell furnace repair from duct cleaning from a new install.
  • Only 3 of 54 sites (6%) explicitly disallow GPTBot, ClaudeBot, or Google-Extended, and all three of those blocks come from a Cloudflare-managed robots.txt file rather than anything the owner wrote.
  • 4 of 54 sites (7%) returned an empty page to every crawler we tested, including one identifying as Googlebot.
  • 18 of 54 sites (33%) show a phone number that doesn't match the number on their own Google Business Profile.
  • 21 of 50 (42%) publish no price or price range anywhere on the homepage.
  • Only 2 of 50 sites carry the full set of LocalBusiness, Service, FAQ, and Review schema together.

Sample: 54 independent HVAC contractor websites in the Twin Cities metro. Collected August 26, 2026. Download the raw data (CSV, 28 KB).

Do Twin Cities HVAC sites actually block AI crawlers?

Three out of 54. That's the whole answer, and it surprised me, because going in I half expected to find a pile of sites quietly shutting out ChatGPT and Claude without knowing it.

The three that do block are BWS, Quality Heating, and Elander Mechanical. All three run the same Cloudflare-managed robots.txt block, word for word, comment blocks and all. Nobody at those companies sat down and decided to keep AI off their site. Their host turned it on. And it's a narrower block than it looks: the same file says search=yes and use=reference, and PerplexityBot isn't in the disallow list at all. The block is aimed at model training, not at answering a homeowner's question.

The other 51 sites are wide open. Six have no robots.txt file whatsoever, which also leaves the door open.

Bar chart: 6% of Twin Cities HVAC contractor websites explicitly block GPTBot, ClaudeBot, or Google-Extended. 3 of 54 sites.
Only 6% of sites explicitly block major AI crawlers (3 of 54; n = 54 sites audited). All three blocks come from a host-managed robots.txt.

What to do instead: pull up yourcompany.com/robots.txt in a browser right now. If you see "User-agent: GPTBot" followed by "Disallow: /" and you didn't put it there, ask your host whether it came from a managed setting, and decide on purpose whether you want it. Blocking training while allowing search is a defensible choice. Not knowing which one you picked isn't. We keep a plain-English rundown of how AI search actually picks which businesses to name.

Then why doesn't my company come up in AI answers?

Because there's nothing on your page worth quoting. 45 of the 50 readable sites have no FAQ schema, and 44 have no Service schema. Take the two together and the picture gets stark: only 4 of 50 sites pair a LocalBusiness listing with FAQ markup and a published price.

Bar chart: 90% of readable Twin Cities HVAC contractor homepages have no FAQ schema. 45 of 50 readable sites.
90% of readable homepages lack FAQ schema, the most common failure in the study (45 of 50 readable sites; n = 54 sites audited).

Here's what that means in plain terms. When somebody types "what does it cost to replace a furnace in Bloomington" into an AI assistant, that assistant is looking for a page that states a question and answers it in a way it can lift cleanly. Your homepage probably says you've been family-owned since 1987 and that your techs are NATE-certified. Both of those are true and neither one answers the question.

Seventeen of the 50 sites do have LocalBusiness or HVACBusiness schema but nothing underneath it. They've told the machine they exist and stopped there. Two sites in the whole metro run the full stack, Brinks Heating & Air out of Plymouth and Bob Boldt HVAC in Eagan.

Bar chart: 88% of readable Twin Cities HVAC contractor homepages have no Service schema. 44 of 50 readable sites.
88% of readable homepages lack Service schema, so a machine cannot tell furnace repair from duct cleaning (44 of 50 readable sites; n = 54 sites audited).

I want to be careful here, because I only checked homepages. A shop could easily have FAQ markup buried on a service page I never opened. Read this as a homepage finding, not a whole-site verdict.

What to do instead: take the five questions your office manager answers on the phone every single day. What's your service call fee. Do you work weekends. How fast can you get here. Do you finance. How long does an install take. Put them on the page as questions with real answers, and have whoever built your site wrap them in FAQPage schema. That's an afternoon of work. It's the core of what we do on AI search and GEO.

Here's what that looks like from the other side. We asked ChatGPT for the best HVAC company near us in Shakopee and watched where its answer actually came from. Not one piece of it came from a company website.

Hover or tap the numbers to see why each part matters.

A ChatGPT answer to "best hvac company near me" showing a map result for Quality Heating & Air Conditioning in Shakopee, Minnesota, a Yelp rating, and a ranked top three list with review counts from Birdeye and other sources.

Everything in this card — the name, the star rating, the hours, the photo — comes from a free Google Business Profile. ChatGPT never visited this company’s website to build it.

Do this: Claim and fully complete your profile at google.com/business. It’s the highest-impact free thing you can do.

The rating here is credited to Yelp. AI tools lean on directories they already trust rather than on what a business says about itself.

Do this: Claim and complete Yelp, Angi, BBB, and Nextdoor. Six accurate listings beat fifty thin ones.

The winner shows 323 reviews. The runners-up show 48 and 58. Volume and recency are the clearest signals an AI tool has that a business is active and trusted.

Do this: Ask at the end of every job, by text, with a direct link. Never buy reviews — a suspension costs months.

4.0 from 6 reviews on the map. 4.8 from 323 on Birdeye. 5.0 from 87 somewhere else. When sources disagree, AI tools hedge — and hedging costs you the recommendation.

Do this: Write your name, address, phone, and hours down once. Make every listing match, character for character.

ChatGPT, August 2026. Results change over time.

Four sites wouldn't let us in at all. What's happening there?

Four sites returned an HTTP 202 with an empty body: Metro Heating & Cooling, Priority Heating & Cooling, Climate Masters, and Genesis Heating and Air Conditioning. Not a page. Not an error. 168 bytes of nothing.

We tested each of them five separate ways, using a normal Chrome user agent and then identifying as GPTBot, ClaudeBot, PerplexityBot, and Googlebot. Same empty response every time. Meanwhile Standard Heating served the same full 144KB page to all five.

Now, the honest caveat, and it matters. This kind of wall usually runs a JavaScript challenge, and a real person in a real browser sails right through it. Googlebot may also be waved through by IP verification rather than by its user agent, which our test can't replicate. So I can't tell you those four sites are invisible in Google. What I can tell you is that every automated reader we pointed at them got a blank page, and AI crawlers are automated readers. If you're not sure what your own host is doing, that's the kind of thing a technical review of your site build should catch.

What to do instead: ask your host to log which bots are getting challenged and which are getting through. If GPTBot and ClaudeBot are hitting the wall, get them allowlisted. A security setting nobody chose is a bad reason to disappear.

Does the phone number on your site match your Google listing?

For 18 of 54 shops, it doesn't. Two thirds matched cleanly, one site had no phone number we could find in the HTML, and four we couldn't check because of the wall.

Bar chart: 33% of Twin Cities HVAC contractor websites show a phone number that does not match their Google Business Profile. 18 of 54 sites.
33% of sites show a phone number that does not match their own Google Business Profile (18 of 54; n = 54 sites audited).

Before anybody panics, most of that gap is almost certainly call tracking. Swapping in a dedicated number so you can tell which marketing dollar produced which call is a normal, smart thing to do, and I'd never tell an owner to stop measuring. But there's a wrinkle that didn't exist five years ago. An AI assistant reading your website sees one number. The same assistant reading your Google listing sees another. When it has to pick one to hand a homeowner, you don't get a vote.

I'll flag this one as directional. I checked the homepage only, and I can't distinguish a tracking number from a stale number from the outside.

What to do instead: keep the tracking number in your header if it's earning its keep, and put your real, permanent office number in your LocalBusiness schema and in your footer. Machines read both. Give them the number that will still work in three years. We cover the same problem for other trades in our local SEO work.

Are all those Google reviews doing anything for your website?

They move together more than I expected. Across all 54 shops, the rank correlation between Google review count and referring domains came out at 0.64. Median review count was 323.5 and median referring domains was 143.

The straight-line correlation is only 0.29, and the gap between those two numbers tells you something: a handful of enormous outliers are pulling the average around. Hero has 19,386 reviews. Ries Heating in Shakopee has 19. Both are real businesses with real customers.

The mismatches are where it gets interesting. Comfort Matters has 3,242 Google reviews and 131 referring domains. Associated Mechanical in Shakopee has 45 reviews and 864 referring domains, the third-highest link count in the study. Those two are running on completely different engines. One has enormous local trust and a thin web footprint. The other is the reverse.

I'll say plainly that a sample of 54 is small for this kind of claim, and correlation here doesn't mean one causes the other. Shops that invest in reputation tend to invest in marketing generally. That's the more likely story.

What to do instead: pull your own two numbers and see which side you're light on. If you're heavy on reviews and thin on links, your next move is getting mentioned by name on Twin Cities websites that aren't yours. If it's the other way around, ask for reviews at the truck. Both sides of that are what local SEO is actually for.

Should you put prices on the site?

21 of 50 sites publish nothing that looks like a price. 29 publish something, even if it's a diagnostic fee or a financing figure.

I went in expecting the shops that publish pricing to also be the ones running lean, low-friction contact forms. That is not what the data says. Sites that publish a price had a median of 11 form fields. Sites that publish nothing had 10.5. There's no meaningful difference. Whatever makes a contractor comfortable posting a number, it isn't connected to how hard they make it to reach them.

That surprised me enough that I went back and re-ran it. Same result.

What to do instead: publish your service call fee and a realistic range for the three jobs you do most. You already say the number out loud forty times a week. A homeowner who leaves your site to go find that number somewhere else usually doesn't come back. We put numbers to that in the real cost of missed calls.

How long is your contact form, really?

Among the 27 sites with a working homepage form, the median is 11 fields. Seven of those forms run past 15. One asks for 74.

Twenty-three sites, nearly half, have no form on the homepage at all. For an emergency trade that's a defensible call. When somebody's furnace quits at eleven at night in February, they're calling, not typing. But it means your entire homepage conversion rests on one tel: link, and seven of the 50 sites don't even have that link in the header.

Bar chart: 46% of readable Twin Cities HVAC contractor homepages have no contact form. 23 of 50 readable sites.
46% of readable homepages have no contact form at all (23 of 50 readable sites; n = 54 sites audited).

The 74-field form is worth sitting with for a second. Nobody designed that. It's what happens when a form plugin gets updated four times over six years and nobody ever opens it on a phone to see what it's become. I've seen the same thing in half the trades I've worked with, and it's almost never the result of a decision.

What to do instead: open your own form on your own phone tonight. Count the fields. Name, phone, ZIP, and what's wrong is enough to dispatch a truck. Everything else you can ask when you call them back. That's the kind of thing we fix when we rebuild a site to convert.

All results by category

Twin Cities HVAC website audit, 54 sites, collected August 26, 2026. Content checks use the 50 sites that returned a readable page.
CategoryCheckFailingRate
Machine readabilityNo FAQPage schema45 of 5090%
No Service schema44 of 5088%
No Review or AggregateRating schema38 of 5076%
No LocalBusiness or HVACBusiness schema20 of 5040%
No single unique H119 of 5038%
JSON-LD present but invalid0 of 500%
AI crawler policyExplicitly disallows GPTBot / ClaudeBot / Google-Extended3 of 546%
No robots.txt file at all6 of 5411%
Empty response to all tested crawlers4 of 547%
Conversion and trustNo homepage contact form23 of 5046%
No price or price range published21 of 5042%
No 24/7 or emergency service stated15 of 5030%
No financing mentioned10 of 5020%
No click-to-call link in header7 of 5014%
FindabilitySite phone doesn't match Google listing phone18 of 5433%
Title tag names no city or service area9 of 5018%
Delivery (measured, not Core Web Vitals)Median server response time0.31 secrange 0.08–2.92
Median homepage HTML weight222 KBrange 14 KB–1.02 MB

How we did this

Sample definition. We searched Google Maps for HVAC and furnace repair across ten Twin Cities metro cities: Minneapolis, St. Paul, Bloomington, Eden Prairie, Maple Grove, Woodbury, Plymouth, Eagan, Burnsville, and Shakopee. From those results we kept every independent HVAC contractor with a verifiable website of its own. We excluded directories, marketplaces, and national franchises without a local site.

We also excluded 11 Google listings that appear to be lead-generation profiles rather than contractors. Each carried a generic city-plus-service name, and the reviews on each one referenced a completely different company by name. As one example, a listing called "Maple Grove Heating & Air Conditioning" carries reviews thanking "Dover Heating & Air Conditioning." We took that as evidence the listing isn't the business it claims to be. If you're a Twin Cities HVAC owner, that pattern is worth knowing about on its own.

Four more businesses were dropped because we couldn't verify they owned the domain search returned for them. In one case the domain belonged to an HVAC company in Watsonville, California. In another it was parked and for sale. In a third it belonged to an electrician. That left 54 sites in the study.

Collection date. All data was collected on August 26, 2026. Every figure here should be read as "as of that date."

Tools. Google Places for business profile data including review counts, ratings, and listed phone numbers. Direct HTTP requests for robots.txt, homepage HTML, JSON-LD parsing, form field counts, and phone extraction. SE Ranking for referring domains, backlink totals, and domain authority. Crawler behavior was tested by issuing the same request under five different user agents.

Unknown rates. Four of 54 sites (7%) returned an empty response, so every content-level field for those four is recorded as "unknown" rather than as a failure. They're excluded from all content percentages, which is why content checks report out of 50 and crawler policy reports out of 54. Backlink and Google Business Profile data was available for all 54.

What we could not measure. Core Web Vitals are missing entirely. The PageSpeed Insights API quota was exhausted at the time of collection, so mobile LCP and performance scores are unknown for all 54 sites, a 100% unknown rate on that field. We substituted server response time and HTML page weight, which we measured ourselves. Those are not Core Web Vitals and shouldn't be read as a substitute. We also did not measure indexed page counts or organic keyword totals.

Stated limitations. We checked homepages only, so schema present on interior pages wouldn't appear here. Form field counts come from raw HTML, which undercounts forms injected by JavaScript after load. Phone mismatches can't be distinguished from call tracking from the outside. And 54 is a small sample. Treat the cross-tabs as directional and the raw counts as solid.

Raw data. The full 54-row, 52-column dataset is published here:download the CSV (28 KB). Every number above traces to a row in it. If you find an error in your own row, tell us and we'll correct it and note the correction.

Common questions

If almost nobody blocks AI crawlers, is any of this urgent?

Urgent, no. Worth an afternoon, yes. The door is open on 51 of 54 sites, which means the advantage goes to whoever puts something quotable behind the door first. Right now that's a field of two in the entire metro.

My website guy says we already have schema. Is that enough?

Ask which types. Seventeen of the 50 sites we checked have LocalBusiness or HVACBusiness markup and nothing else, which tells a machine your company exists and stops there. Service, FAQ, and Review markup are what actually answer a homeowner's question.

How do I check my own robots.txt without calling anybody?

Type your domain followed by /robots.txt into any browser. It's a plain text file. Search it for GPTBot. If you see Disallow slash under it, something is blocking AI training crawlers, and it may have come from your host rather than from you.

Is a call tracking number actually hurting me?

Not for tracking, and I wouldn't give that up. The risk is that an AI assistant pulling your number from your website and one pulling it from Google get two different answers. Put your permanent number in your schema and footer and the problem goes away.

We get all our work from referrals. Does this matter for us?

Some of it does. Referral customers still search your name before they call, and what they find is your Google listing and your homepage sitting side by side. If those two disagree about your phone number or your hours, that's a small crack in a warm lead.

Why did you exclude those 11 Google listings?

Because the reviews on them credit other companies by name. A listing called "Woodbury Heating and Cooling" whose reviews thank "Huxley Heating and Cooling" isn't the business the listing claims to be. Including them would have polluted the sample.

Is 54 sites enough to trust?

For the raw counts, yes, because we opened every one. For the cross-tabs, treat them as a signal and not a settled fact. The review-to-links relationship in particular deserves a bigger sample before anybody plans around it.

Five things to check on your own site this week

Each of these takes under two minutes and none of them requires calling your web person first.

  1. Open yourdomain.com/robots.txt. Search the page for GPTBot. If it says Disallow slash and you didn't write it, your host did.
  2. Compare your phone numbers. Pull up your homepage and your Google listing side by side. If the numbers differ, know why.
  3. Open your contact form on your phone. Count the fields. Anything past six is costing you calls at eleven at night.
  4. Search your own homepage for a dollar sign. Hit Ctrl-F and type it. If nothing comes up, homeowners are leaving your site to find that number somewhere else.
  5. Read your title tag. It's the text in the browser tab. If it doesn't name a city or a service area, 9 of the 50 sites we checked have that same gap and it's the cheapest one to close.

None of this is glamorous work and none of it will change your week. But you built the trucks and the crew and the reputation already, and the website is the one part of the operation that's still running on whatever a contractor set up in 2019. Fix the phone number first. It's the one that's costing you calls today. If you'd rather hand the whole list to somebody, that's what we build for HVAC contractors.

For journalists and researchers

This study analyzed 54 independent Twin Cities HVAC contractor websites on August 26, 2026. The complete methodology and raw dataset are publicly available. Charts and statistics may be cited with attribution to MilkHat Media.

go@milkhatmedia.ai · Methodology · Raw data (CSV, 28 KB)