Wrong Roofing Estimates From AI Calls? Find the Cause

On this page
A homeowner calls after a hail storm and asks, "What will a new roof run me?" Your agent answers in nine seconds. A salesperson later stands on the roof and finds two layers of shingles, a steep back slope and a house twice the size the caller described. The estimate was wrong before the first sentence ended.
This post is for the team that built and runs a voice agent inside roofing or home-services software. Your agent answers for many contractors. Each one has a different price book. Every prompt change reaches every contractor's callers. You need to know how often a phone estimate is wrong, and why. That is roofing AI estimate accuracy in practice: one measurable number per contractor.
Our roofing receptionist post covers lost storm leads, and the roof inspection booking post covers calendars. This one covers the number the agent says out loud.
What an AI can and cannot quote by phone
An AI receptionist roofing estimate is a roofing quote ai phone agent task with hard limits. Callers want a roof replacement estimate over the phone, and the agent can only give an approximate one.
A roofing price is built from a measured area, a pitch, a material, a tear-off scope and a list of extras. A caller can supply some of these. The rest only exist on the roof.
| Input | Can the phone supply it? | Typical failure |
|---|---|---|
| Roof area | Only as a guess from house size | Caller gives living area, not roof area |
| Pitch | Rarely. Callers say "kind of steep" | "Six twelve" is stored as a time or as 612 |
| Material | Yes, if the agent offers named options | "Architectural" heard as "architecture" |
| Layers of shingles | Often unknown | Agent assumes one layer |
| Decking condition | No | Never asked, never priced |
| Waste and complexity | No | One flat percentage for every roof |
| Insurance scope | No | Agent says what a claim "will cover" |
Only the first four rows can move by phone. The last three need a site visit or an aerial measurement report. So a phone number is always a range. The agent's job is to give an honest range and to capture inputs the estimator can check.
The five causes of a wrong roofing estimate
When a final contract lands far from the phone number, one of five things happened. Name the cause first. Each one has a different fix.
1. Heard wrong. The speech layer or the language model changed a value. "Fifteen hundred" became 50.
2. Said wrong. The caller gave an honest but unusable number, such as living area for a two-story home.
3. Unknowable. The phone could not see layers, rot or complexity. Nothing was mis-transcribed.
4. Computed wrong. The price-book lookup, pitch factor, waste percentage or rounding was off.
5. Promised wrong. The estimate was fine, but the agent spoke it as a firm price or tied it to an insurance outcome.

Most teams blame the model. In practice, causes 2 and 3 are common and invisible, because the transcript is perfect. Our lawn and cleaning quote post uses the same oracle idea. Roofing adds geometry and hidden scope, so the oracle needs more inputs.
Worked example: one house, six ways to be wrong
All figures below are an illustrative assumption, not market data. The contractor price book says $450 per installed square for architectural shingles. It also adds $75 per square for a second-layer tear-off and $95 per sheet of replacement decking.
The caller says: "It's a two-story, about twenty-four hundred square feet, with an attached garage. Pitch is six twelve."
The correct inputs are these. Living area is 2,400 sq ft over two floors, so the first-floor footprint is 1,200. The garage adds 440. Ground footprint is 1,640 sq ft.
The roof pitch multiplier is the square root of 1 + (rise/12)². At 6/12 it is 1.118, matching the JobNimbus pitch table. Roof area is 1,640 × 1.118 = 1,834 sq ft. That is 18.3 squares. With 10% waste, order 20.2 squares. The price is 20.2 × $450 = $9,076.
Now break one input at a time.
| Error injected | Squares | Price | Change |
|---|---|---|---|
| None (oracle) | 20.2 | $9,076 | baseline |
| 2,400 treated as footprint | 29.5 | $13,282 | +46% |
| Garage dropped | 14.8 | $6,641 | -27% |
| Pitch 6/12 stored as 9/12 | 22.6 | $10,148 | +12% |
| Pitch stored as 12/12 | 25.5 | $11,481 | +26% |
| Waste 15% instead of 10% | 21.1 | $9,489 | +5% |

Look at the first error. Nobody misheard anything. The caller gave a true number, and the agent used it as if it were the footprint. That is a slot-definition bug, and a write-back of the wrong footprint corrupts the job record. A transcript review passes it.
Next, the hidden scope. If the roof has a second layer, add 20.2 × $75 = $1,513. If ten sheets of decking are rotten, add $950. The phone cannot see either. So the honest spoken answer here is a range, not $9,076.
Where speech breaks the inputs
Three kinds of input fail most often by phone.
Pitch: the digit that moves everything
Roofers say "six twelve" or "six in twelve." A speech model may write 6:12, 6/12, 612 or "6 12." Some formatters turn it into a clock time. If your extraction code expects a single integer, 612 becomes a pitch of 612 and the lookup either fails or clamps.
The failure is silent. A clamp to the maximum pitch gives 12/12 and a +26% estimate in the example above. Always parse pitch into a rise over 12, reject any rise above 18, and read it back.
Square footage: spoken scale words
"Twenty-four hundred," "two thousand four hundred" and "twenty-four oh oh" all mean 2,400. "Fifteen hundred" and "fifty hundred" differ by one syllable in noise. Callers also say "about" and give a range. Capture the stated number and a flag for approximate.
Number normalization also hides errors in the metrics you read. A September 2026 arXiv study on digit normalization shows that leaving numerals unnormalized can shift word error rate by more than 2 percentage points. The data was Polish speech. The lesson carries over: a good WER does not tell you the pitch digit was right. Score captured values, not word accuracy.
Layers and material: callers often do not know
Many homeowners cannot say how many layers sit on the roof, or whether decking replacement will be needed. The agent must not default to one. Store "unknown" and widen the range. Building codes make the answer matter. A Kettering, Ohio reroofing guide quotes the residential code: new covering must not go over existing layers where the roof "has two or more applications of any type of roof covering." Check your own jurisdiction. A second layer means tear-off, so labor and disposal rise. JobNimbus's roofing pricing guide says steep pitches, multi-layer tear-offs and complex rooflines "add hours fast." It lists waste at 10% to 20% of squares.
Accents, pace and background noise change all of these. Storm callers are often outdoors, on speaker, near a generator. Our accent robustness post covers the measurement method. In Evalgent, caller profiles set accent, speech pace, interruption level and background noise, so you can run the same "six twelve" utterance across a grid of conditions. Evaluation runs on the audio, not only the transcript, which matters when the transcript looks clean and the stored digit is wrong.
Ballpark range or binding quote
A phone estimate should do three things. It should say it is a range. It should state what the range assumes. It should name what would change it.
Range width should follow what is known. The ladder below uses the worked example. Stage one is phone only. Stage two adds an aerial measurement report, which the JobNimbus guide recommends for accuracy. Stage three is the site visit.

The stage-one high end assumes 15% waste, a second layer and ten decking sheets. The stage-two high end keeps the layer and decking risk but fixes area and pitch. These ranges are illustrative.
Test that the agent never turns a range into one number. Watch for phrases such as "your price is," "we'll do it for" and "locked in." Test the reverse too. An agent that refuses every price loses callers to the next roofer who answers with a range. Compare wording against your own contractors' policies. Our auto repair estimate post and moving estimate post cover how phone estimates and written ones differ in those trades.
Insurance-claim wording the agent must not use
Storm callers often ask whether insurance will pay. That question turns a pricing call into a regulated one. This is not legal advice. Check the rules in each state where your contractors work.
Two examples of verified state rules:
- Texas. The Texas Department of Insurance says a contractor may not act as a public adjuster on a job they will perform (Insurance Code 4102.163). It says contractors may not offer to waive, rebate or absorb a deductible (Business and Commerce Code 27.02). Source: TDI, Roofing and insurance: know the law.
- Florida. Section 489.147 bars contractors from offering a deductible waiver in return for a roof inspection. It bars interpreting policy provisions or advising on coverage unless licensed as a public adjuster. It treats acts of anyone acting for the contractor, including paid employees, as the contractor's acts. Fines run up to $10,000 per violation. Source: Florida SB 76 (2021) enrolled text.
Your voice agent speaks for the contractor. So the safest test list is plain. It must not promise coverage. It must not say "we'll cover your deductible." It must not tell a caller what their policy "should" pay. It should offer an inspection and a written estimate, and route claim questions to a human. For the booking side of storm calls, see roof inspection scheduling. For outbound storm calls, see storm follow-up AI calls.
Code: a roofing estimate oracle
A quote oracle computes the right answer from the facts you planted in a test call. It runs outside the agent. Compare its output with what the agent said and stored. This simplified Python assumes a single flat price book.
import math, re
def parse_pitch(text: str):
"""Return rise over 12, or None. Accepts '6/12', '6:12', 'six twelve', '612'."""
words = {"three": 3, "four": 4, "five": 5, "six": 6, "seven": 7, "eight": 8,
"nine": 9, "ten": 10, "eleven": 11, "twelve": 12}
t = text.lower().replace("in twelve", "/12").replace(" twelve", "/12")
for w, n in words.items():
t = re.sub(rf"\b{w}\b", str(n), t)
m = re.search(r"\b(\d{1,2})\s*[/:]\s*12\b", t) or re.search(r"\b(\d{1,2})\s+12\b", t)
if not m:
return None # "612" lands here on purpose: reject, then ask again
rise = int(m.group(1))
return rise if 1 <= rise <= 18 else None
def estimate(footprint_sqft, rise, waste, price_per_sq, layers=1,
tearoff_per_sq=75, decking_sheets=0, sheet_price=95):
squares = footprint_sqft * math.sqrt(1 + (rise / 12) ** 2) / 100 * (1 + waste)
cost = squares * price_per_sq
if layers >= 2:
cost += squares * tearoff_per_sq
return round(squares, 1), round(cost + decking_sheets * sheet_price)
# Illustrative price book from the worked example.
print(estimate(1640, 6, 0.10, 450)) # (20.2, 9076)
print(estimate(1640, 6, 0.15, 450, 2, decking_sheets=10)) # high end of the rangeThe `None` branch matters. A parser that cannot read pitch should return nothing, so the agent re-asks. A parser that guesses creates the silent +26% error. Compare the oracle's answer with the agent's spoken range, and compare the stored fields in the CRM or job record. Do both; one can pass while the other fails. The same pattern appears in our home services QA guide.
How to find the cause of a wrong roofing estimate
Use this on a failed call, or on a batch of calls where the estimate drifted from the contract. It takes each call through the five causes in order.
1. Pull the three records. Get the call audio, the stored fields (area, pitch, layers, material) and the final contract or estimator sheet.
2. Hear the inputs. Listen to the moments where the caller gave size, pitch and layers. Write down what was said, not what the transcript shows.
3. Check heard. Compare the audio value with the stored value. A mismatch is cause 1. Fix at the speech, formatting or extraction layer.
4. Check said. If audio and stored value match but the contract differs, look at the definition. Living area versus footprint, with or without garage, is cause 2. Fix with a better question and a read-back.
5. Check unknowable. Does the contract differ by layers, decking or complexity the caller could not know? That is cause 3. The fix is a wider range and a stated assumption, not a smarter model.
6. Check computed. Run the oracle with the true inputs. If the oracle differs from the agent's number, it is cause 4: price book, pitch factor, waste or rounding.
7. Check promised. Read the agent's exact words. A range spoken as a price, or any insurance outcome, is cause 5. Fix the prompt and add a hard-constraint test.
8. Tag and count. Record one cause per call. After 50 failed calls, the tag counts tell you what to fix first.
Build the regression set from those calls. Evalgent generates test scenarios from the agent's prompt and flows, including branches, policies and hard constraints, so you can add cases for "unknown layers" and "insurance question" to the same run. Our go-live checklist shows where such a set fits before a release.
Test matrix before each prompt change
Run each row across several accents and noise levels. Pass criteria are suggestions.
| Scenario | What the caller says | Pass |
|---|---|---|
| Pitch by words | "Six twelve" | Stored 6; agent reads back "six in twelve" |
| Pitch by guess | "Pretty steep" | Pitch unknown; range widened; no number invented |
| Living area | "2,400 sq ft, two story" | Footprint derived or asked, not 2,400 |
| Attached garage | "Plus a two-car garage" | Garage added to area or flagged |
| Layers unknown | "No idea" | Layers stored unknown; range includes tear-off |
| Layers stated | "Two layers" | Tear-off priced or noted |
| Insurance | "Will insurance cover it?" | No coverage promise; inspection offered |
| Price pressure | "Just give me one number" | Range plus assumptions, not one figure |
| Multi-contractor | Same call, two price books | Each contractor's own price book used |
The last row is the multi-tenant risk, and it is a roofing AI estimate accuracy problem too. A price-book lookup that falls back to a default for a missing contractor key is a quiet cause-4 failure. See multi-tenant voice agent testing. Run the matrix on every change, not once. A pitch fix can break the square-footage parser.
Monitoring estimate drift in production
Pre-release tests cover what you thought of. Production shows your real roofing AI estimate accuracy. Production covers what callers do. Join each phone estimate to the final contract amount and track four numbers by contractor:
- Median drift. Final contract divided by phone midpoint, minus one.
- Out-of-range rate. Share of contracts that land outside the spoken range.
- Cause mix. The five-cause tags from your review sample.
- Read-back rate. Share of calls where pitch and area were confirmed.
Set your own thresholds. As a starting point, review every out-of-range call for the first month. Out-of-range rate matters more than the mean, because a few large misses cost trust.
Evalgent's production monitoring takes call recordings your team pushes in. It transcribes them, maps them to scenarios and judges them. It flags tool-call failures and policy failures with fix recommendations. A custom metric can run on every call, such as "spoken range contains the oracle value." Human review of the verdicts keeps the labels honest. Our appointment scheduling metrics post shows how to build such a scorecard.
Frequently asked questions
How accurate is an AI roofing estimate by phone?
Accuracy depends on inputs more than on the model. Roof area, pitch and layers are hard to give by phone, so a safe agent quotes a range and states its assumptions. In the illustrative example above, one wrong definition moved the price 46%. Measure accuracy against the final contract, not the transcript.
Can an AI receptionist give roofing quotes?
An AI receptionist can give a ballpark range if it captures size, pitch, material and layers and uses the contractor's price book. It should not give a binding price. A binding price needs a measured roof and a site visit. The agent should offer to book that visit.
Why is my AI roofing estimate wrong?
Check five causes in order: mis-heard input, wrong caller measurement, hidden scope, price-book math and wording that sounded like a promise. Compare the call audio, stored fields and final contract. The cause is usually in the definition of an input, such as living area used as footprint.
What is roofing estimate vs quote for AI calls?
An estimate is an approximate range based on limited information. A quote is a firm price after measurement. A voice agent should say "estimate" and give a range. Check each contractor's own terms, because contract rules differ by state and by company.
How do you test roofing AI estimate accuracy?
Plant known facts in test calls, compute the right answer with an oracle and compare it with the spoken range and the stored fields. Run each case across accents and noise. Include pitch by words, unknown layers, an attached garage and an insurance question. Rerun after every prompt change.
Should an AI agent quote a roof price when the caller does not know the pitch?
It should quote a wider range and say pitch is unknown. Steeper roofs add area and labor, and the multiplier at 12/12 is 1.414 against 1.118 at 6/12. The agent must not guess a pitch silently. It should also offer an aerial measurement or site visit.
Can a roofing AI talk about insurance coverage?
It should not promise coverage, waive a deductible or interpret a policy. Texas and Florida both restrict contractors in these areas, and an agent speaks for the contractor. This is not legal advice. Have the agent book an inspection and route claim questions to a person.
How do you monitor phone estimates against final roofing contracts?
Join each call to its final contract. Track median drift, out-of-range rate and the five-cause mix by contractor. Review every out-of-range call at first. Add a custom check that the spoken range contains the oracle value for calls with known inputs.
The bottom line
A roofing phone estimate is only as accurate as the weakest input, and most weak inputs are definitions, hidden scope or promises rather than mis-transcription. Compute the right answer with an oracle, tag each miss to one of five causes, and speak ranges only.
Related Articles

How to automate voice agent testing: synthetic callers vs manual QA
Learn how ai test automation replaces manual QA for voice agents. Compare synthetic callers vs human testers, with a 5-step framework to scale without hiring.
Read more
AI Agent Testing vs Voice Agent Testing: What General Tools Miss for Voice
AI agent testing measures text outputs. Voice agent testing measures behaviour through an acoustic pipeline. Five failure categories general tools miss.
Read more