Wrong Moving Estimates From Your AI Agent? Find the Cause

On this page
A mover calls your support line. Your AI agent quoted their customer $1,850. The final invoice says $3,420. Which part of the agent broke?
This post is for product teams at moving software companies whose agent gives phone estimates for many movers. It covers a root-cause taxonomy for AI moving estimate accuracy, a triage order for disputed jobs, and the federal rules on who pays. For the full program view, see the moving companies QA playbook.
Why AI moving estimate accuracy is a chain problem
A phone estimate is a chain of six small decisions. Each can fail alone, and every failure looks the same on the invoice: a bigger number.
1. Inventory capture. Rooms, large items (piano, sectional, safe, gym equipment) and a box count.
2. Access. Stairs and floor number, elevator and reservation windows, long carry from truck to door, parking.
3. Distance. Origin and destination zip codes, plus any stops.
4. Services. Full packing, partial packing, crating, disassembly, storage.
5. Date. Peak season, weekends, month-end. Many movers price these differently.
6. Conversion and pricing. Inventory becomes cubic feet, cubic feet become weight or hours, and hours become crew size, truck count and dollars.
The voice call is only the front door. The agent writes a CRM record, the pricing engine reads it, and the crew shows up with what it says. The final invoice reflects what the crew found. A speech error never throws an exception. It produces a clean, wrong record that every downstream system trusts.
SmartMoving, for example, publicly describes its Smart Scout phone agent capturing "dates, zip codes, and job type" and flagging tight parking or oversized furniture, then logging the job in the CRM (SmartMoving, November 2025). SmartMoving's July 2026 release says the platform powers "more than 2,200 moving operations" (Business Wire). Those captured fields are the ones that drive the price, across thousands of movers.

The six root causes of a wrong moving estimate
This is the taxonomy. Call it the estimate gap ledger. Every dollar of difference between estimate and final invoice gets one label from this list, or a seventh label for genuine customer changes.
| Cause | What happened | Call audio shows | CRM record shows | Final invoice shows |
|---|---|---|---|---|
| 1. Speech capture error | Agent misheard a value | Caller said "40 boxes" or "third floor" | "14 boxes", "first floor" | Extra labor, stair charge |
| 2. Slot omission | Agent never asked | No question about piano or stairs | Field empty or default | New line item |
| 3. Conversion or tariff config | Right inputs, wrong math | Correct details | Correct details | Cubic feet, weight or hours off by a ratio |
| 4. Stale price table | Right math, old prices | Correct details | Correct details | Same items, different rates |
| 5. Agent improvised a number | LLM said a price the engine never produced | A dollar amount spoken | Engine output differs or is missing | Any value |
| 6. Wrong regulatory wording | Price was right, label was wrong | "Guaranteed" or "binding" said | Non-binding estimate type | Dispute, not a pricing gap |
| 7. Customer change (not a fault) | Caller added items later | Details matched at the time | Matched | Later change logged |
Causes 1 and 2 are capture failures. Causes 3 and 4 live in the tenant's config, not the model. Cause 5 is a generation failure, and cause 6 is a compliance failure. Each leaves a different fingerprint across the three records, so you don't need to guess.
Cause 1: speech capture errors
Numbers and quantities are the weakest part of phone speech recognition. Peyser and colleagues at Google showed that end-to-end ASR struggles with numeric sequences, especially numbers unseen in training. Their fixes cut word error rate on the longest numeric sequences by up to 8x (Peyser et al., 2019). On an 8 kHz phone line, "forty" and "fourteen" sound alike. So do "third" and "first" when a dog barks.
The fingerprint: the audio has the right value, the transcript or CRM has the wrong one. A transcript-only evaluator agrees with the wrong record. Our guide to entity accuracy in speech-to-text covers how to score quantities and addresses separately from overall WER.
Cause 2: slot omissions
A slot omission is a question the agent should have asked and didn't. Slot filling across a long phone call is hard. The SpokenWOZ benchmark has 5.7k spoken dialogues and 249 hours of audio. Its best dialogue state tracker reached only 25.65% joint goal accuracy (Si et al., SpokenWOZ). The authors flag cross-turn slots as a core challenge. Moving calls are full of them. A caller mentions the piano in minute one, then talks about dates for five minutes. The agent forgets to price it.
The fingerprint: the agent never asked, or the caller volunteered the item and it was never written down. The CRM field is empty or holds a default like `floor: 1`. An empty field looks unknown. A default looks like an answer.
Cause 3: conversion and tariff config errors
Here the inputs are right and the math is wrong. Every mover converts moving inventory differently. One tenant prices local jobs at an hourly rate with a crew-size table. Another prices interstate jobs by weight, using a density factor to turn cubic feet into pounds. Box sizes, cube sheets and minimum hours are per-tenant settings. One wrong number skews every estimate for that mover.
The fingerprint: audio and CRM agree, but the invoice differs by a consistent ratio for one tenant. Check that tenant's density factor before the model.
Cause 4: stale price tables
Stale prices look like config errors, but the gap appears on a date. The mover raised rates on the first of the month, or added a peak season surcharge. The engine still reads last quarter's table.
The fingerprint: correct inputs, correct conversion, wrong rate. Estimates made before a rate change are fine. Estimates after it are low, and only for that tenant.
Cause 5: the agent improvised a number
Here the LLM speaks a dollar figure the pricing engine never produced. Maybe the tool call timed out and the model filled the silence. Maybe the caller pushed ("just ballpark it") and the prompt didn't hold. This is the AI moving quote failure product teams fear most.
The fingerprint: the spoken amount in the audio doesn't match any tool response in the call log. Check the tool trace first. A silent tool failure followed by a confident price is a classic pattern. Our post on hallucination rate for voice agents shows how to score it per call.
Cause 6: wrong regulatory wording
The price may be fine. The words around it are not. If the agent calls a non-binding estimate "guaranteed", or says "binding" when no binding estimate exists, the dispute is about the label. This cause needs the audio, because the transcript may smooth over a single word.
What 49 CFR 375 says about estimates
For interstate household goods moves, federal rules decide who absorbs the gap. Intrastate moves follow state rules, so check those separately. This section summarizes the federal text as of October 2026. It is not legal advice.
Non-binding estimate: a written estimate that is not a guarantee. Under 49 CFR 375.405, it must be "reasonably accurate" and based on "the estimated weight or volume of the shipment." It must describe "the entire shipment and all services." The mover may not collect more than 110 percent of the original non-binding estimate at destination.
Binding estimate: a written price that binds both mover and shipper. FMCSA says it "guarantees that you do not have to pay more than the estimated amount at the time of delivery" (FMCSA).
Three details matter for an AI agent:
- The survey rule. 49 CFR 375.401 requires a physical survey unless the shipper waives it in writing before loading. FMCSA's consumer guidance says the estimate should be based on an "actual or virtual inspection" (FMCSA). A phone call alone is neither.
- Added items on a binding estimate. Under 49 CFR 375.403(a)(6), if the shipper adds goods or services, the mover must reaffirm, rewrite, or convert the estimate before loading. If the mover loads without doing so, the original estimate counts as reaffirmed.
- Billing timing. Charges for added services the shipper did not agree to at the time are billed after 30 days from delivery under § 375.405(b)(9).
So the same AI error lands differently. On a binding estimate, a missed piano is the mover's loss if the paperwork isn't redone before the bill of lading is issued. On a non-binding estimate, it becomes a delivery-day cap and a delayed bill.

A worked example: the $1,850 job that became $3,420
All figures here are illustrative assumptions, not data from any mover.
The estimate. A two-bedroom local move. The agent captured 60 boxes, ground-floor pickup, no special items. The tenant's table priced it at 3 movers and one truck at $175 per hour. It estimated 9.5 hours including travel. That's 9.5 × $175 = $1,662.50, plus $187.50 for materials and fuel. Total: $1,850.
The final invoice: $3,420. The gap is $1,570, or 85% over the estimate. Here is the ledger:
| Invoice delta | Amount | Audio | CRM | Cause |
|---|---|---|---|---|
| Piano handling | $450 | Caller said "and the upright piano" at 0:52 | No piano field | 2, slot omission (cross-turn) |
| 3rd-floor walk-up | $520 | "Third floor, no elevator" at 2:10 | `floor: 1` | 1, speech capture error |
| Extra 40 boxes | $600 | "About a hundred boxes" at 3:05 | `boxes: 60` | 1 or 5, check the trace |
Now the conversion math for the boxes. Assume this tenant uses 3 cubic feet per medium box. Forty extra boxes is 120 cubic feet. At a tenant-configured 7 lb per cubic foot, that's 840 lb more weight on an interstate tariff. On this hourly local job it meant about 3 more labor hours ($525) and $75 of extra materials. That's the $600.
The 3rd-floor line: 2 extra hours at $175 is $350, plus a $170 stair fee from the tenant's tariff. That's the $520.
The boxes line needs one more check: the tool trace. If the pricing tool received `boxes: 100` and the CRM says 60, you have a write-back bug, not a speech bug.
If this had been an interstate non-binding estimate, the 110% cap applies. The mover could require at most $1,850 × 1.10 = $2,035 at delivery. The other $1,385 waits for a later bill. Three misses in one call became a collections problem.
How to diagnose a wrong AI moving estimate
Run these steps on every disputed job.
1. Pull the three records. Get the call recording, the CRM record written by the agent, and the final invoice with line items. Add the tool-call log if you have one.
2. List every invoice delta. Each line on the final invoice that differs from the estimate becomes one row. Use the ledger table above.
3. Check the audio first. For each delta, search the recording for the item. Did the caller mention it? Did the agent ask about it? Note the timestamp.
4. Compare audio to the CRM. If the caller said it and the CRM differs, it is cause 1. If the caller said it and the CRM has nothing, it is cause 2. If nobody mentioned it and the agent never asked, it is also cause 2.
5. Compare CRM to the tool input and output. If the CRM is right and the price is wrong, rerun the tenant's pricing with the same inputs. A wrong ratio points to cause 3. A rate that changed by date points to cause 4.
6. Match the spoken price to the engine. If the agent said a number that no tool returned, label it cause 5.
7. Listen to the estimate wording. Check the words "binding", "non-binding", "guaranteed" and "estimate" in the audio. A mismatch with the estimate type on file is cause 6.
8. Label the rest as customer changes. If the details matched at the time and the customer added items later, it is not an agent fault. Log it anyway.

A simplified triage function
This is simplified Python. It assumes you've extracted facts from the audio, the CRM stores which price table version priced the job, and you can rerun the tenant's pricing.
# Simplified. Labels one invoice delta with a root cause.
def triage_delta(item, audio_facts, crm, tool_log, tables, rerun_price):
heard = audio_facts.get(item) # value caller said, or None
asked = audio_facts.get(f"asked:{item}", False)
stored = crm.get(item) # value agent wrote, or None
if heard is not None and stored is None:
return "2_slot_omission" # said, never written
if heard is not None and stored != heard:
return "1_speech_capture" # said, written wrong
if heard is None and not asked:
return "2_slot_omission" # never asked
spoken = audio_facts.get("spoken_total")
engine = [t["total"] for t in tool_log if t["name"] == "price_estimate"]
if spoken is not None and spoken not in engine:
return "5_improvised_number" # no tool returned that figure
if crm["price_table_version"] != tables.version_on(crm["estimate_date"]):
return "4_stale_price_table" # priced from an outdated table
correct = rerun_price(crm, tables.version_on(crm["estimate_date"]))
if engine and engine[-1] != correct:
return "3_conversion_or_tariff_config"
return "7_customer_change"
# Example output for the piano row:
# triage_delta("piano", {"piano": "upright"}, crm, log, tables, f)
# -> "2_slot_omission"Wording checks (cause 6) run on the whole call as a separate rule.
Measuring AI moving estimate accuracy across tenants
One disputed job tells a story. A sample tells you the rate. Here is the protocol for AI moving estimate accuracy at scale.
Estimate error: (final invoice − estimate) ÷ estimate, per job. Track the median and the share of jobs above +10%. The +10% line matters because it matches the federal 110 percent cap on non-binding estimates.
Per-cause share: the percentage of total gap dollars assigned to each cause. Report it per tenant. Causes 3 and 4 cluster by tenant. Causes 1, 2 and 5 cluster by agent version.
How many jobs do you need to audit? For a cause share near 50%, a ±5% margin at 95% confidence needs n = 1.96² × 0.5 × 0.5 ÷ 0.05² ≈ 385 jobs. For a ±10% margin, about 97 jobs. That's across all tenants. For a per-tenant read, a ±10% margin per tenant is usually the practical floor.
Pull closed jobs at random. Disputes over-represent big misses, so track them as a separate stream.
Test each call more than once. In tau-bench, top function-calling agents passed fewer than half of tasks, and pass^8 in retail was under 25% (Yao et al., 2024). A slot asked 9 times in 10 still misses in production. Count fill rate per slot across repeated runs.
A test matrix for estimate calls
Before each prompt or flow change, run scripted calls covering the risky slots, which is basic slot filling coverage.
| Scenario | Slot at risk | Condition | Pass rule |
|---|---|---|---|
| Piano mentioned early, then dates | Large item | Cross-turn, 4 min call | Piano on CRM and in price |
| "Third floor, no elevator" | Access | Street noise | `floor: 3`, `elevator: false` |
| "About a hundred boxes" | Box count | Fast speech | `boxes: 100` |
| "Is that guaranteed?" | Wording | Caller pushes | Correct estimate type named |
| "Just ballpark it" | Price | Pricing tool times out | No spoken number |
| Saturday, July 31 | Date pricing | Peak season, month-end | Peak rate applied |
| Long carry, no truck parking | Access | Accent, slow pace | Long carry flagged |
This is the kind of matrix Evalgent generates from an agent's prompt and flows. It reads the states, branches and hard constraints, then builds scenarios for coverage gaps such as a slot the flow never asks. The simulated callers can vary accent, pace, interruptions and background noise, and call the agent over PSTN, SIP or WebRTC.
The home services QA guide covers these tests more broadly. The lawn and cleaning quote accuracy post applies the same capture-versus-price split to square footage.
Why transcript-only review misses the cause
Reading transcripts works for causes 2 and 5. It fails for cause 1. If speech-to-text wrote "fourteen boxes", the transcript and CRM both say fourteen. Only the audio says forty. See transcript vs audio evaluation.
Evalgent's thesis is that most eval tools judge voice agents by reading transcripts, so "the referee is deaf". Evalgent evaluates from the audio, with an LLM plus Jev as a judge and evidence attached to each verdict. Its production monitoring takes pushed call recordings, transcribes them, maps them to scenarios and flags tool-call failures and policy failures. That covers the audio and tool checks above. You still need the mover's final invoice to close the loop.
Fixes by cause
- Speech capture (1). Read back every quantity and floor number. "That's forty boxes, third floor, no elevator. Right?" Score tool arguments against audio, not transcript.
- Slot omission (2). Make large items, access and packing services required slots. Remove silent defaults. Ask a closing sweep question: "Anything heavy or unusual, like a piano, safe or gym equipment?"
- Config errors (3). Validate each tenant's density factor, box sizes and crew table at onboarding.
- Stale prices (4). Version the price table with an effective date. Log which version priced each estimate.
- Improvised numbers (5). The agent may only speak a total returned by the pricing tool in this call. On a timeout, it offers a callback.
- Wording (6). Store the estimate type as a field. Generate the spoken wording from that field, never free text.
Then turn each confirmed miss into a test, run the suite before every change (shipping prompt changes safely), and score every call once live.
Frequently asked questions
Why is the final moving bill higher than the estimate?
A final moving bill runs higher than the estimate when the move differs from what was captured. Common drivers are missed large items, stairs or long carry, more boxes, added packing services, or a peak season rate. With an AI agent, also check for misheard quantities, unasked questions, tenant pricing config errors and stale price tables.
What is the 110 percent rule for moving estimates?
The 110 percent rule comes from 49 CFR 375.405. On an interstate non-binding estimate, the mover cannot require more than 110 percent of the original estimate at delivery. On a $1,850 estimate, that's $2,035. Remaining charges for added services the shipper did not agree to are billed after 30 days from delivery.
Can an AI phone agent give a binding moving estimate?
An AI phone agent can quote a number, but a binding estimate under 49 CFR 375.403 must be written and describe the shipment and services. Federal rules also require a physical survey unless the shipper waives it in writing. Most teams have the agent give a non-binding phone estimate and route binding estimates to a survey.
How accurate are AI moving estimates?
No public benchmark measures AI moving estimate accuracy across movers. Measure your own: compute (final invoice minus estimate) divided by estimate for a random sample of closed jobs. Track the median error and the share of jobs above +10 percent. Then label each gap by root cause to see what you can fix.
How do you audit an AI moving estimate against the final invoice?
Audit an AI moving estimate by listing every invoice line that differs from the estimate. For each line, check the call audio, then the CRM record, then a rerun of the tenant's pricing. Said but stored wrong is a capture error. Never asked is an omission. Right inputs with a wrong price is a config or stale table problem.
What causes AI moving quotes to be wrong?
AI moving quotes go wrong for six main reasons. They are speech capture errors, slot omissions, conversion or tariff config errors, stale price tables, numbers the agent improvised, and wrong binding or non-binding wording. Genuine customer changes after the call are a seventh category, but they are not an agent fault.
How many jobs do you need to audit?
For a cause share near 50 percent, about 385 randomly sampled jobs give a ±5 percent margin at 95 percent confidence. About 97 jobs give ±10 percent. Sample closed jobs at random, not only disputes. Disputed jobs over-represent large misses and will skew the cause mix.
Should an AI agent read the estimate total out loud?
An AI agent should read a total only if the pricing tool returned it during that call. It should also say the estimate type, such as non-binding, using wording generated from a stored field. If the pricing tool fails or times out, the agent should offer a callback instead of guessing a ballpark figure.
The bottom line
A wrong moving estimate is a labeling problem before it is a model problem. Pull the call audio, the CRM record and the final invoice, label every dollar of the gap by cause, and fix the cause with the biggest share first.
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