AI Quotes for Lawn and Cleaning: How Accurate Are They?

On this page
An instant quote over the phone looks simple. The caller gives a few facts and the agent reads out a number. For a lawn, cleaning or exterior business, that number is a promise. If it is low, the business eats the gap or argues with a customer at the door. If it is high, the caller hangs up and books someone else.
This post is for product teams at quoting and field service software companies whose agent quotes for many businesses. You own the agent. Each customer owns a different price book. You need to know your AI quote accuracy, why it slips, and how to test changes before they reach every tenant.
For the wider home services picture, start with our AI receptionist QA guide for home services. For the same problem in a different trade, see why moving estimates from AI agents go wrong.
Who quotes by phone, and what the agent must capture
This category already ships in lawn care software and cleaning tools. QuoteIQ's help center describes a "Virtual Call Team" that "answers calls 24/7, qualifies leads, takes messages, and can make outbound calls." The same QuoteIQ overview lists satellite measurement and AI measuring inside the quoting flow. On the lawn side, Turf Magazine reported that Service Autopilot by Xplor connected Deep Lawn's satellite measurement to operators' own pricing tables. Deep Lawn's CEO said quotes arrive "in about 60-90 seconds."
Speed is the selling point. AI quote accuracy is the risk. No public source we found reports a measured error rate for AI quotes for lawn care or cleaning.
Every phone quote is slot filling followed by a lookup. The agent fills a small set of typed fields. Then a pricing function turns those fields into a number. Here is what each trade needs:
| Trade | Size slots | Service slots | Modifiers | Where the price comes from |
|---|---|---|---|---|
| Lawn care | Lot size or acreage, mowable area | Mow, edge, trim, leaf cleanup | Frequency, first cut, slope | Tier table per lot size, per-acre rate above a cap |
| House cleaning | Bedrooms and bathrooms, square footage | Standard, deep clean, move-out | Frequency, pets, condition | Base by rooms, multipliers, add-on list |
| Pressure washing | Square footage per surface | Driveway, siding, deck | Stories, stain type | Rate per square foot, minimum |
| Gutter cleaning | Linear feet or house footprint | Clean, flush, guards | Stories, roof pitch | Per foot or per story tier |
| Window cleaning | Pane count | Exterior, interior, screens | Stories, access | Per pane, minimum |
The pricing function is boring on purpose. Given correct slots, it returns the same number every time. So AI quote accuracy is mostly a capture problem, not a math problem.
How speech errors compound into a wrong quote
A quote is only right if every slot is right. That makes errors multiply, not add.
Worked math (illustrative assumption): Suppose each slot is captured correctly 98% of the time, independently. A cleaning quote has six slots: bedrooms, bathrooms, frequency, condition, add-ons and price book version. The chance that all six are right is 0.98^6 = 0.886. About 11 in 100 quotes carry at least one wrong slot. At 99% per slot, it is still 0.99^6 = 0.941, or 6 in 100.
Real errors are not independent, either. A noisy line hurts every slot at once.
The research backs up why numbers and IDs are fragile. Peyser and colleagues at Google showed an end-to-end recognizer's WER on long numeric sequences reached 26%, against 7.6% on short ones, in their Interspeech 2019 paper. Long-tail numeric phrases hit 92.7% before their fixes. A NeurIPS 2026 workshop paper on cross-layer voice agent evaluation tested six ASR systems on 336 customer-service turns. It found 49% of downstream routing changes happened at zero normalized WER. Order-ID entity error rates ranged from 7.2% to 44.6%. Amazon's DSTC10 spoken dialogue study found slot value F1 fell from 0.486 on manual transcripts to 0.432 on ASR output.
The lesson: a low WER does not mean the agent stored the right acreage. Check the field, not the transcript. Our post on STT entity accuracy goes deeper on that measurement.

Five failures that change the price
1. "A quarter acre" stored as "four acres." A substitution or a fraction parse turns 0.25 into 4.0. With an illustrative tier table, the weekly mow moves from $50 to $440. That is an over-quote, and the caller hangs up. Flip it and you get the opposite. A caller with four acres quoted $50 is an under-quote of $390 per visit. Housecall Pro's 2026 lawn pricing guide puts weekly rates at $41–$65 under a quarter acre and $350–$600+ above three acres. A tier jump is a price cliff.
2. "Three bed, two bath" stored as "two bed, three bath." The numbers are the same words in a different order. In our illustrative book the quote moves from $205.00 to $213.50. That $8.50 gap looks harmless. But the crew time estimate, supply list and job record are now wrong.
3. Frequency misheard. "Biweekly" is ambiguous even to humans. It can mean every two weeks or twice a week. Each frequency carries its own recurring discount. Store "weekly" instead of "biweekly" and the per-visit price drops from $205 to $195. The schedule doubles from 26 to 52 visits a year. The customer gets charged for visits they never wanted.
4. Add-on dropped. The caller says "and the oven, please" mid-sentence, while the agent is still talking. A barge-in swallows it. The quote drops by $35. The crew arrives without time booked for the oven.
5. Wrong price book version. The business raised rates Monday. The agent still caches last month's rules. Every quote runs a little low, invisibly.
Where the errors come from, layer by layer
Each failure has a mechanism. Knowing which layer broke tells you what to fix.
Speech recognition and formatting
Spoken quantities arrive as words. Your formatter turns them into numbers. Deepgram's smart formatting docs note a streaming gotcha. If an entity looks incomplete, it waits for non-entity speech, or for 3 seconds of silence, before formatting. Setting `no_delay=true` returns results fast but "will result in skipping formatting altogether in many cases." Its separate numerals feature converts "nine hundred" to "900" and is off by default.
So one caller phrase can reach your LLM as "a quarter acre," "0.25 acre" or "1/4 acre." Fractions, ranges ("about half an acre, maybe more") and units ("four thousand square feet") all need explicit tests. A 2026 arXiv study found number normalization alone can shift WER by "more than 2 percentage points."
Turn-taking
Endpointing can cut a turn at a pause. "It's about a quarter..." ends. The agent asks a follow-up. The caller says "...acre, maybe a bit more." Now the agent has two half-slots to merge. Barge-in has the same effect on add-ons spoken over the agent.
LLM slot extraction
The model maps words to typed fields. It can swap bedrooms and bathrooms, guess a default frequency, or treat "pet hair" as a note instead of a billable add-on. These are tool argument errors. The tool call succeeds and the record is still wrong.
Lookups and the price book
Address lookups add their own trap. A parcel record gives the whole lot, including the house, driveway and beds. The mowable area is smaller. If the caller says "a quarter acre" and the parcel says 0.31, both may be right. Your agent needs a rule for which wins and when to ask. Then the price book itself must be the right version for the right tenant.
Write-back
Finally, the quote is written to the job record in your field service software. A quote spoken as $205 but saved as $170 is still a wrong quote. Always compare the spoken number with the stored one.
The quote oracle: compute the right answer first
Quote oracle: a function that takes the caller's true facts and the business's price book, and returns the price the agent should have quoted. It is your test's answer key.
Because pricing is deterministic, you don't need an LLM judge to grade the number. You need the expected value. Then grade three things separately: the slots, the spoken price and the stored price.
The script below is simplified and illustrative. We ran it as shown. The price book values are invented, though they sit inside Housecall Pro's published 2026 cleaning ranges.
# Simplified quote oracle: expected price from the price book, then compare.
# Illustrative price book. Swap in each business's real rules.
from dataclasses import dataclass, field
BOOK_V8 = {
"version": "clean-v8",
"base_by_bedrooms": {1: 100, 2: 130, 3: 160, 4: 190},
"extra_bath": 40, # each bathroom beyond the first
"freq_discount": {"one_time": 0.0, "monthly": 0.10,
"biweekly": 0.15, "weekly": 0.20},
"first_deep_multiplier": 1.5, # first visit only
"addons": {"fridge": 35, "oven": 35, "pet_hair": 25},
"minimum": 120,
}
@dataclass
class Slots:
bedrooms: int
bathrooms: int
frequency: str
first_deep: bool = False
addons: list = field(default_factory=list)
def expected_quote(s: Slots, book: dict) -> float:
base = book["base_by_bedrooms"][s.bedrooms]
base += book["extra_bath"] * max(0, s.bathrooms - 1)
visit = base * (1 - book["freq_discount"][s.frequency])
if s.first_deep:
visit = base * book["first_deep_multiplier"] # no discount on visit 1
visit += sum(book["addons"][a] for a in s.addons)
return round(max(visit, book["minimum"]), 2)
def check(said: Slots, captured: Slots, quoted: float, book: dict, band=15.0):
slot_diffs = {k: (v, getattr(captured, k)) for k, v in vars(said).items()
if getattr(captured, k) != v}
expected = expected_quote(said, book)
price_ok = abs(quoted - expected) <= band
verdict = "PASS" if (price_ok and not slot_diffs) else "FAIL"
return verdict, expected, quoted, slot_diffs
said = Slots(3, 2, "biweekly", addons=["oven"])
cases = {
"clean capture": (said, Slots(3, 2, "biweekly", addons=["oven"])),
"bed/bath swapped": (said, Slots(2, 3, "biweekly", addons=["oven"])),
"biweekly -> weekly": (said, Slots(3, 2, "weekly", addons=["oven"])),
"oven add-on dropped": (said, Slots(3, 2, "biweekly")),
}
for name, (s, c) in cases.items():
quoted = expected_quote(c, BOOK_V8) # agent priced what it captured
v, exp, q, diffs = check(s, c, quoted, BOOK_V8)
print(f"{name:20} {v} expected ${exp:.2f} quoted ${q:.2f} diffs={diffs}")Output:
clean capture PASS expected $205.00 quoted $205.00 diffs={}
bed/bath swapped FAIL expected $205.00 quoted $213.50 diffs={'bedrooms': (3, 2), 'bathrooms': (2, 3)}
biweekly -> weekly FAIL expected $205.00 quoted $195.00 diffs={'frequency': ('biweekly', 'weekly')}
oven add-on dropped FAIL expected $205.00 quoted $170.00 diffs={'addons': (['oven'], [])}Look at the second and third rows. Both quotes land inside a $15 tolerance band. A price-only check would pass them. Only the slot diff catches them. Price-only grading is the easiest blind spot to build into a quoting test.

Tolerance bands: where they belong
A tolerance band is the allowed gap between quoted and expected price. Use it narrowly.
| Quote type | Slot check | Price tolerance | Why |
|---|---|---|---|
| Fixed price book, all slots known | Exact | $0 | Deterministic math, no excuse for a gap |
| Rounded or "starting at" quotes | Exact | Rounding step only (e.g. nearest $5) | The rule defines the rounding |
| Range quotes ("$180–$220") | Exact | Expected must sit inside the spoken range | Range is the promise |
| Lookup-based size (parcel or satellite measurement) | Within a size band, e.g. ±15% | Price for the band's tier | Measurement noise, not agent error |
| On-site adjustment allowed (condition, overgrowth) | Exact for caller facts | Flag for review, don't fail | Final price is set at the door |
Never let a price band stand in for a slot check. A $10 band hides a doubled schedule.
Price book tests per business
You quote for many businesses. Each one has its own tiers, minimums, discounts and add-on list. A test suite written for one tenant says little about the next.
Generate tests from each price book instead. Boundary values matter most:
- Tier edges. If a tier ends at 0.25 acres, test 0.24, 0.25, 0.26 and "a quarter acre."
- Minimums. Test a quote that falls below the minimum, so the agent quotes the minimum.
- Stacked modifiers. First-time deep clean plus recurring discount plus two add-ons. Does visit one get the discount or not?
- Exclusions. Services the business doesn't offer. The agent should decline, not invent a price.
- Version change. Publish a new book, then run the suite. Every quote must reference the new version id.
Store the oracle's expected values and the book version with each test. When a tenant edits their book, values regenerate and the suite reruns. This is the same discipline as shipping prompt changes safely, applied to config.
For the scheduling version of this per-tenant problem, see why an HVAC AI books the wrong tech.
Caller profiles that break quotes
Slot errors cluster in certain callers. Build caller profiles that stress the slots that move price:
- The estimator. "Maybe half an acre? Could be more." Tests range handling and the confirm rule.
- The corrector. "Three bed, two... no, three bath." Tests self-repair.
- The bundler. Lists four add-ons in one breath while the agent talks. Tests barge-in capture.
- The fast talker on a noisy mobile line, outdoors. Tests numbers under noise.
- The ambiguous scheduler. "Every other week, or twice a month, whatever's cheaper." Tests frequency mapping.
- The non-native speaker. Accent and code-switching on numbers, such as Spanish "cuarto de acre."
Voice matters here. A text-only test would never hear "a quarter" blur into "four." Our post on synthetic callers covers how to build these. Evalgent's caller profiles set accent, speech pace, interruption level, response delay, background noise and language for each simulated call. That lets you run the same quote scenario under each profile over a real phone line.
Read-back and confirmation: the cheapest fix
A read-back repeats the price-moving slots before the quote. Do it in a different form from what the caller said. "That's 0.25 acres, about 11,000 square feet, mowed every week. Is that right?" One acre is 43,560 square feet, so a wrong value sounds wrong when restated.
Add a conflict rule for lookups. If the caller's size and the parcel or satellite figure differ by more than a set percentage, the agent asks. It should not silently pick one.
Then test the read-back itself. Does the agent read back every slot that changes price? Does it correct the slot when the caller says "no, four bedrooms"? Does the stored record change too? Judge this from the audio, not only the transcript. Our post on transcript vs audio evaluation explains why. Evalgent evaluates calls from the audio, with metrics like context retention and instruction adherence, plus custom metrics you define, such as "every price-moving slot was read back."
Monitoring quote vs final invoice drift
Tests catch known failures. The best production signal for AI quote accuracy is the gap between quote and final invoice.
Compute a drift ratio per job: invoice ÷ quote. Then track the median and the spread per business, per week.
- Median well above 1.0. The agent is under-quoting. Check size slots and add-ons.
- Median well below 1.0. The agent is over-quoting, or crews are discounting at the door.
- Spread widening. Capture is getting noisier. Check a recent prompt, model or STT change.
- Step change on one tenant. Look for a price book update the agent did not pick up.
Also track quote-to-booking conversion per tenant. A sudden drop with no drift change can mean over-quotes. Those jobs never reach an invoice, so the drift ratio cannot see them.
Worked example (illustrative assumption): A tenant books 200 recurring cleans from AI quotes in a month. If 6% carry a dropped $35 add-on, that's 12 jobs. Biweekly, that's 26 visits a year each. The unbilled work is 12 × 26 × $35 = $10,920 a year for one business. Multiply by your tenant count.

Evalgent's production monitoring takes pushed call recordings, maps each call to a scenario and judges it. It flags tool-call failures and policy failures with fix recommendations. Pair that with your own invoice join, and you can trace a drift spike back to the calls that caused it. For the metric side, see how to catch voice agent metric drift.
How to test an AI quoting agent before each release
1. Write the oracle per trade. Encode each price book as data, not prompt text. One function per trade returns the expected price from true slots.
2. List the price-moving slots. For each tenant, mark the slots that change the price: size, rooms, frequency, condition, add-ons and book version.
3. Generate boundary scenarios. Create tests at every tier edge, the minimum, stacked modifiers and exclusions. Include fractions, ranges and corrections.
4. Cross scenarios with caller profiles. Run each scenario under at least the estimator, corrector, bundler and noisy-line profiles, over the real phone path.
5. Grade three things. Check slots exactly, the spoken price against the oracle, and the stored price against the spoken one. Apply tolerance bands only where the table above allows.
6. Repeat runs. LLM agents vary run to run. Run each scenario several times and report pass rate, not a single pass.
7. Gate the release. Block a deploy if any price-moving slot regresses for any tenant. Use the go-live checklist for each new business you onboard.
8. Watch drift after launch. Track invoice ÷ quote and quote-to-booking per tenant. Alert on step changes and widening spread.
Evalgent works with teams to set this up for their first agent, generating scenarios from the prompt and flows and running them over PSTN, SIP or WebRTC.
Should an agent quote everything over the phone?
No. Some jobs should get a range, a "starting at" price, or a site visit.
- Good for instant quotes: recurring mowing on a measured lot, standard cleans with known rooms, window cleaning by pane count.
- Range or "starting at": first-time deep clean on an unknown condition, overgrown first cut, leaf cleanup by volume.
- Site visit or photo first: pressure washing on unknown surfaces or stains, gutter cleaning on steep roofs, anything above a tenant-set price cap.
Let each business set these limits in its price book, then test that the agent respects them. Declining to quote is correct when the book says so.
Frequently asked questions
How accurate are AI quotes for lawn care?
No public study reports a measured error rate for AI quotes for lawn care. AI quote accuracy depends on capturing lot size, frequency and services correctly. The pricing math is deterministic. A misheard size can cross a tier, moving a weekly quote from about $50 to over $400. Measure your own rate with an oracle and quote vs final invoice drift.
Can an AI receptionist give cleaning quotes?
An AI receptionist can give an AI cleaning quote when the business has a clear price book. It needs bedrooms and bathrooms, frequency, condition and add-ons. Quotes for standard recurring cleans work best. First-time deep cleans on unknown homes are safer as a range or "starting at" price, confirmed on site.
How do you test an AI quoting agent?
Build a quote oracle that computes the expected price from each scenario's true facts. Generate scenarios at price book tier edges and minimums. Run them under caller profiles over a real phone line. Grade the captured slots exactly, the spoken price against the oracle, and the stored price against the spoken one. Repeat runs to measure variance.
What is a quote oracle?
A quote oracle is a test function that takes a caller's true facts and a business's price book. It returns the price the agent should have quoted. Because price book math is deterministic, the oracle gives an exact answer key. Tests then compare captured slots and quoted prices against it, without needing an LLM to judge the number.
What tolerance should an AI quote have?
A fixed price book quote with all slots known should have zero price tolerance. Allow only the rounding step for rounded quotes. For lookup-based sizes, allow a size band such as ±15%, then require that band's tier price. Never use a price tolerance band in place of a slot check. Small gaps can hide doubled schedules.
Why does the AI agent quote the wrong lot size?
Wrong lot sizes come from several layers. Speech recognition can blur "a quarter" and "four." Formatters render fractions differently depending on timing and config. Endpointing can split "a quarter... acre" across turns. Parcel lookups include the house and driveway, not only mowable area. A read-back in square feet catches most of these.
How do you monitor quote vs invoice drift?
Join each AI quote to its final invoice and compute invoice divided by quote. Track the weekly median and spread per business. A median above 1.0 suggests under-quotes. A step change on one tenant often means a missed price book update. Also track quote-to-booking conversion, since over-quoted jobs never produce an invoice.
Should an AI agent quote pressure washing over the phone?
An AI agent can quote pressure washing over the phone when the surface type and square footage are known and the business prices per square foot. Unknown stains, delicate siding or multi-story work should get a range or a photo-based estimate first. Each business should set these limits in its price book, and tests should confirm the agent follows them.
The bottom line
AI quote accuracy is a slot capture problem, because a correct price book turns correct facts into the correct price every time. Test it with an oracle that checks every price-moving slot exactly, and watch quote vs final invoice drift per business after launch.
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