Evalgent
Back to Blog
Voice AI Testing

Testing Roof Inspection Booking Before Storm Season

Deepesh Jayal
15 min read
Testing Roof Inspection Booking Before Storm Season
On this page

A roofer near Springfield, Missouri, described the week after an April 2026 hailstorm. "It seems like hundreds of phone calls a day," owner Phil Schroff told KY3. Before the storm he got "a handful of calls each day." His lead time for inspections alone grew to two to three weeks. In Wisconsin, another roofing crew told WMTV it was working 14-hour days to keep up with inspections.

This post is for the product team behind storm restoration and roofing CRM software with a built-in AI voice agent for roofing contractors. Your agent books inspections for many contractors at once. A storm turns a quiet Tuesday into the busiest day of their year. And every contractor in the hail swath spikes at the same moment. Here is what breaks, why, and how to test it before the next storm season.

2–3 weeks
Inspection lead time one Missouri roofer reported after an April 2026 hailstorm (KY3)
44%
Average street-name transcription error rate across 15 speech models (Zhou et al., arXiv 2026)
1 inch
Hail diameter that makes a thunderstorm severe (National Weather Service)
$10,000
Maximum Florida fine per violation of the contractor solicitation statute (Fla. Stat. 489.147)

What a roof inspection booking call has to capture

Roof inspection scheduling looks simple. It is really a data-entry job done by voice. The agent has to fill a record that a dispatcher, an inspector and an insurance file all depend on.

Roof inspection AI scheduling: a voice agent that takes storm-damage calls, collects the property and claim details, picks an inspector slot inside the right territory, confirms it with the caller and writes the job to the CRM.

The table below is the minimum record. Each field has a typical failure.

FieldWhy the contractor needs itHow it fails by voice
Property addressInspector routing, territory, permit lookupsStreet name misheard; new subdivision not in the geocoder
Service area checkContractor only works certain counties or ZIPsOut-of-area job booked, inspector drives 70 miles
Storm date and typeHail damage vs wind damage, claim timing"Last Thursday" resolved to the wrong date
Leak statusActive leak needs an emergency tarp firstCaller says "a little water" and it lands as routine
Roof type and storiesLadder, crew size, steep or tile roof gear"Two-story" stored as one; metal stored as shingle
Insurance claim statusFiled or not, claim number, adjuster meetingClaim number digits swapped; adjuster date dropped
Callback number and consentReschedules and follow-upsWrong digits; no record of consent for automated calls

Every one of these fields can be wrong while the call sounds fine. The caller hears "You're all set for Tuesday at nine." The dispatcher finds out on Tuesday. This is the same capture-to-write-back chain we describe in the home services QA guide. Roofing adds two things: insurance and surge.

Why storm surge breaks an agent that passed in March

Your agent probably passed testing. Someone called it twenty times on a calm afternoon. Each call ran alone. Storm day is different in three mechanical ways.

Calls overlap on the same calendar

On a quiet day, two callers rarely want the same inspector slot within the same minute. After hail, dozens do. Most booking flows read availability, talk to the caller, then write the booking. That gap between the read and the write is the bug. Two calls both read "Tuesday 9:00 open." Both callers say yes. Both writes land. One inspector now has two roofs at 9:00.

Timeline of two overlapping storm-day calls that both read Tuesday 9:00 as open and both write, double-booking one inspector, while a conditional write lets only one succeed

This is a classic race condition. It hides in testing because test calls run one at a time. We cover the broader pattern in our post on concurrency failure in voice agents.

Every tenant spikes together

A CRM platform usually sizes for the sum of its customers' normal traffic. That works when customers are independent. Storms break the independence. A hail swath across one metro can hit forty of your contractors in the same hour. Your shared tool backends feel all forty peaks at once: the calendar API, the geocoder, the CRM write path and your LLM rate limits.

Latency climbs when callers are most anxious

Under load, each hop slows down. Tool calls queue. Model calls wait on rate limits. A two-second pause after "let me check the calendar" becomes six. Callers repeat themselves or talk over the agent. Now the transcript has barge-ins, and the agent may act on a half-heard answer. Our breakdown of what each 100 ms costs applies with extra force here. A homeowner with water coming through the ceiling does not wait politely.

Worked math: sizing for 412 calls in 6 hours

Here is an illustrative example. The numbers are assumptions for one mid-size contractor, not measured data. Swap in your own.

Inputs (assumed): 412 calls in the 6 hours after a hail warning. 45% arrive in the first 2 hours. A full intake with claim fields takes 6 minutes on average.

Peak arrival rate: 412 × 0.45 / 2 h = 92.7 calls per hour.

Average concurrent calls (Little's law, L = λW): 92.7 calls/h × 0.1 h = 9.3 calls in progress. In call-center terms, that is an offered load of 9.3 Erlang.

Plan for the tail, not the mean: arrivals bunch up. A rough Poisson 99th percentile is mean + 2.33 × √mean = 9.3 + 7.1 ≈ 17 concurrent calls. That is one contractor.

Now multiply by correlation: if 40 contractors sit inside the same swath, plan for roughly 40 × 9.3 ≈ 370 concurrent calls on shared backends.

Then check inspector capacity: say the contractor has 6 inspectors doing 7 inspections a day, or 42 per day. Assume 60% of the 412 calls want an inspection: 247 new requests. With 120 inspections already booked, the next open routine slot is (120 + 247) / 42 ≈ 8.7 days out. Day 9.

That last number is the dangerous one. A routine slot nine days out is fine for a missing shingle. It is a disaster for an active leak. If the agent never asks about water inside the house, it books the leak on day 9 too.

Five failures to test in storm-season roofing calls

Each of these costs a contractor money or invites a complaint.

Grid of five storm-season roof inspection call failures showing what the caller said, what the system stored, and the test check that catches each one

1. Double-booked inspectors

The race above is the main cause of double booking. A second cause is stale availability caching. Some teams cache the calendar for 60 seconds to protect the API. Under surge, 60 seconds is many bookings. Test both. Fire parallel calls at one slot and assert exactly one booking succeeds. Then check the agent's words: it should only say "you're booked" after the write succeeds.

2. Wrong address in storm areas with new subdivisions

Address capture is harder than it sounds. A February 2026 paper, "Sorry, I Didn't Catch That", tested 15 speech models from OpenAI, Deepgram, Google and Microsoft on US street names. The authors report an average transcription error rate of 44%. Routing distance errors were twice as large for speakers whose primary language was not English. Fine-tuning on under 1,000 synthetic samples improved accuracy for those speakers by nearly 60%.

Storm areas add a second layer. Fast-growing suburbs have new streets that geocoding services may not know yet. A misheard "Briarwood Court" can snap to a real "Briarwood Drive" two miles away. The record looks valid, so nobody flags it.

Test with real street names from each contractor's service area, including new streets. Spoken read-back should spell or confirm the street. The stored address must match the confirmed one. A geocoder confidence below your threshold should trigger a clarifying question, not a silent best guess.

3. Active leak booked as a routine inspection

Callers understate. "There's a bit of a stain on the ceiling" can mean active water. The agent should ask one direct question on every storm call: is water coming inside right now? A yes should route to the emergency path. That might be a same-day tarp crew, an on-call transfer or a priority flag. Which path depends on the contractor's config. The failure is when that branch never fires because the caller never used the word "leak."

4. Promising insurance outcomes

Insurance claim intake is the compliance trap. A caller asks, "Will insurance cover a new roof?" A helpful model wants to say yes. It must not. Some states restrict what contractors can say about claims.

Florida's section 489.147 bars contractors from "interpreting policy provisions or advising an insured regarding coverages or duties" unless they hold a public adjuster license. It also bars offering a waiver of any insurance deductible in exchange for a roof inspection or a claim. Fines reach $10,000 per violation. Texas Insurance Code section 4102.163 says a contractor may not act as a public adjuster, or advertise to adjust claims, for any property where it provides or may provide contracting services.

Your agent speaks for the contractor. So test it like a contractor's employee who has had compliance training. Probe for coverage promises, deductible talk and "we'll handle the adjuster for you." The safe pattern is neutral: the inspector documents damage; the insurer decides coverage. This is not legal advice. Each contractor should confirm the rules for their states with counsel. We see similar coverage-promise risk in home warranty claims calls.

Many platforms also run outbound calls after a storm. Examples include "your inspection is tomorrow" or "we have openings in your area." The FCC's 2024 declaratory ruling confirms that AI-generated voices count as "artificial or prerecorded voice" under the TCPA. Those calls need prior express consent.

Consent revocation rules are also moving. The FCC delayed the 2024 "revoke-all" requirement to January 31, 2027 in DA 26-12. On September 30, 2026, it adopted FCC 26-67, described in its September fact sheet. It lets an opt-out from one informational call category stay scoped to that category. It also lets callers name exclusive opt-out methods. The changes take effect 30 days after Federal Register publication. As of October 18, 2026, we could not confirm a publication date, so check the Federal Register. This is not legal advice.

Test that an informational reminder never turns into a sales pitch. Test that "stop calling me" is logged and honored. See our outbound voice agent testing plan and the TCPA checks for speed-to-lead calls.

Roof inspection AI scheduling across many contractor configs

You do not ship one agent. You ship one agent with hundreds of configs. Each contractor sets its own service area, inspector territories, emergency policy and claim fields. A storm tests every config at once.

Config itemExampleWhat to test
Service area14 ZIP codes in two countiesOut-of-area caller gets a polite decline, not a booking
Inspector territoriesNorth and south of a highwayEach inspector territory gets only its own bookings
Emergency policyTarp crew same day, or transfer to on-callLeak = yes always reaches that path
Claim fieldsClaim number required before booking, or optionalMissing claim number never blocks a leak
Storm modeLonger slots, extra inspectors added for a weekNew capacity shows up in the agent's options

Storm mode deserves its own tests. Contractors add temporary inspectors or open Saturdays after a big hail event. If the agent's availability tool does not see them, it books day 9 while day 3 sits empty. Our post on testing one agent across 500 customer setups covers sampling configs so you do not need 500 full test runs.

Territory logic fails the same way it does in HVAC. A tech gets booked outside their area or skills, as in HVAC agents that book the wrong tech. Weather also cancels work. Hail weeks bring rain days, and rain-day reschedules collide with new bookings in the same calendar.

Code: prove one slot can only be booked once

Here is a simplified, self-contained Python test. It fires 50 concurrent "agents" at one inspector slot. The store stands in for your calendar API. The point is the pattern: read a version, let the caller confirm, then write only if the version has not changed.

# Simplified: an in-memory stand-in for the CRM calendar API.
import asyncio
import random


class SlotStore:
    def __init__(self):
        self.bookings = {}   # (inspector_id, start) -> job_id
        self.version = {}    # (inspector_id, start) -> int
        self._lock = asyncio.Lock()

    async def read(self, key):
        await asyncio.sleep(random.uniform(0.01, 0.05))  # API latency
        return self.bookings.get(key), self.version.get(key, 0)

    async def write_if_version(self, key, job_id, expected):
        async with self._lock:  # stands in for an atomic compare-and-set
            if self.version.get(key, 0) != expected:
                return False
            self.bookings[key] = job_id
            self.version[key] = expected + 1
            return True


async def agent_books(store, key, job_id):
    holder, ver = await store.read(key)            # "Tuesday 9:00 is open"
    if holder:
        return False
    await asyncio.sleep(random.uniform(0.2, 1.5))  # caller says "yes"
    return await store.write_if_version(key, job_id, ver)


async def main():
    store = SlotStore()
    key = ("insp-07", "2026-10-21T09:00")
    results = await asyncio.gather(
        *(agent_books(store, key, f"job-{i}") for i in range(50))
    )
    booked = sum(results)
    assert booked == 1, f"{booked} bookings for one slot"
    print("PASS: 1 booking, 49 callers offered another slot")


asyncio.run(main())

Expected output: `PASS: 1 booking, 49 callers offered another slot`. Replace `write_if_version` with a plain write and the assert fails with many bookings. Run the same idea against your staging calendar API, not just a mock.

The code test proves the backend. It does not prove the agent's words. A second check is needed: on the 49 failed writes, did the agent apologize and offer the next slot? Or did it still say "you're all set"? That check needs the call audio or transcript, not the database.

A storm-day test matrix you can copy

We call this the hail-day matrix. Rows are scenarios. Columns are conditions. Each cell is a set of calls with a pass threshold.

Hail-day test matrix heatmap with storm scenarios as rows and call conditions as columns, where an illustrative run shows two failing cells under storm noise

Scenarios (rows):

1. Hail damage, no leak, claim not filed yet

2. Wind damage, missing shingles, claim filed with claim number

3. Active leak, caller understates it

4. Adjuster meeting already set; caller wants the inspector there too

5. Out-of-area address on a new street

6. Caller asks whether insurance will pay for a new roof

7. Caller asks to stop all follow-up calls

Conditions (columns):

  • Single call, quiet line
  • 50 concurrent calls on one tenant's calendar
  • Background noise: wind, rain on a window, a generator
  • Degraded tools: calendar API at 3 seconds, geocoder timing out
  • Caller interrupts during read-back

Pass thresholds (starting points, tune to your risk):

CheckThreshold
Double bookings under 50 concurrent calls0
Active leak routed to emergency path100% of runs
Coverage or deductible promises0
Stored address matches confirmed address98% or better
Claim number stored exactly when given98% or better
Agent says "booked" only after a successful write100% of runs
p95 pause after caller finishes speaking, under loadYour quiet-day p95 plus a set margin

Run each cell at least 20 times. Model output varies run to run. One pass proves little. A cell at 19 of 20 for leak routing is a fail, because the threshold is 100%.

How to test roof inspection AI scheduling before storm season

1. Write down the record. List every CRM field the booking must fill, per contractor config. Mark which fields block booking and which are optional.

2. Build scenario sets per storm type. Cover hail, wind and post-storm leaks. Include understated leaks, claim numbers with repeated digits and adjuster meetings. The National Weather Service calls a storm severe at 1-inch hail or 58 mph winds, so tag scenarios by those thresholds. Evalgent generates scenarios from the agent's prompt and flows, including branches and hard constraints like "never discuss coverage," which surfaces gaps a hand-written list misses.

3. Use real addresses. Pull street names from each test tenant's service area. Add new-subdivision streets and out-of-area addresses near the border.

4. Add caller conditions. Vary accent, pace, interruptions and background noise. Evalgent's caller profiles set accent, speech pace, interruption level, response delay and background noise per test call.

5. Run the surge as a load test. Fire overlapping calls at one tenant's calendar, then at many tenants at once. Assert zero double bookings and stable latency.

6. Degrade the tools. Slow the calendar API and time out the geocoder. Check that the agent says it is still checking, rather than inventing a slot.

7. Judge from the audio and the record. Compare what the caller said, what the agent confirmed and what the CRM stored. A clean transcript with a wrong record is still a fail.

8. Gate releases. Re-run the matrix on every prompt or flow change. Block a release that drops any 100% check. Our go-live checklist covers per-customer launch gates.

Evalgent's call simulator reaches the agent over PSTN, SIP or WebRTC, so these calls take the same path as real storm-day callers. It judges from the audio, not only the transcript. That matters when a caller's "nine" is drowned out by rain on the window.

Monitoring when the storm actually hits

Testing roof inspection AI scheduling lowers risk. It does not remove it. During a real storm event, watch these signals per tenant and across the platform:

  • Double-booking count from the calendar, checked every few minutes.
  • Leak-yes calls not on the emergency path. Any count above zero pages someone.
  • Geocoder low-confidence rate. A spike points to new streets or a struggling speech model.
  • Tool-call failures and timeouts on the calendar and CRM write.
  • p95 response latency against the quiet-day baseline.
  • Policy flags for coverage, deductible or adjuster language.

Evalgent's production monitoring takes pushed call recordings, transcribes them, maps them to scenarios and judges them. It flags tool-call failures, latency spikes, PII leakage and policy failures with fix recommendations. For a general setup, see how to monitor voice agents in production.

Frequently asked questions

How do you test an AI receptionist for a roofing company?

Test a roofing AI receptionist with scenario sets per storm type: hail, wind and active leaks. Run them alone, then as overlapping calls on one calendar. Add background noise, real local street names and slow tools. Compare what the caller said, what the agent confirmed and what the CRM stored. Re-run the full set after every prompt or flow change.

Can an AI receptionist talk about insurance claims for roof damage?

A roofing AI receptionist can collect claim facts: whether a claim is filed, the claim number and the adjuster meeting date. It should not interpret coverage, promise a new roof or offer deductible help. Florida section 489.147 and Texas Insurance Code 4102.163 restrict contractors here. Contractors should confirm their own state rules with counsel.

How many concurrent calls does a roofing AI need after a hail storm?

Concurrent calls equal arrival rate times average call length. In an illustrative case, 92.7 calls per hour at 6 minutes each averages 9.3 calls at once. Plan for the tail, around 17 for that contractor. A platform must also add up every contractor inside the same hail swath, because they all spike together.

How do you prevent double booked roof inspections?

Prevent double-booked roof inspections with a conditional write. The agent reads the slot with a version, lets the caller confirm, then books only if the version has not changed. If the write fails, the agent offers the next slot. Test it by firing many parallel calls at one slot and asserting exactly one booking.

What should a roofing AI do with an active roof leak?

A roofing AI should ask every storm caller whether water is coming inside right now. A yes routes to the contractor's emergency path: a same-day tarp crew, an on-call transfer or a priority flag. It should never land in the routine queue, which can sit many days out after a big storm.

Can a roofing AI make storm follow-up calls?

A roofing AI can make storm follow-up calls only with the right consent. The FCC confirmed in 2024 that AI-generated voices count as artificial voice under the TCPA. Keep reminders informational, log opt-outs and honor them. Revocation rules changed in FCC 26-67, effective 30 days after Federal Register publication. This is not legal advice.

How do you test address capture for storm damage calls?

Test address capture with real street names from each contractor's service area, including new subdivision streets. Add accents and background noise. Check that the agent reads the address back and that the stored address matches the confirmed one. Low geocoder confidence should trigger a clarifying question, never a silent nearest match.

What should a roof inspection booking write to the CRM?

A roof inspection booking should write the confirmed address, territory and inspector, slot, storm date and type, and leak status. It should also store roof type and stories, claim status, claim number, adjuster meeting date, callback number and consent. Each field should match what the caller confirmed on the call, not the agent's first guess.

The bottom line

Roof inspection AI scheduling is tested by storms, not by quiet afternoons. Test overlapping calls, real addresses, leak triage, insurance language and CRM write-back before hail season, then monitor every one of them while the storm is happening.

Related Articles