HVAC AI Missing Service Plan Customers? How to Check

On this page
A member calls in July. Her AC is out. She paid for a Gold plan that promises priority service and no diagnostic fee. The AI receptionist doesn't find her, so it books her as a new customer, quotes the standard fee and puts her in the regular queue. Nobody notices until she disputes the invoice or cancels at renewal.
This post is for product teams at field service management (FSM) software companies. Your agent answers calls for hundreds of HVAC contractors, and each one sells its own plans. HVAC service agreement customers are the callers who matter most to those contractors. They are also the easiest to get wrong without a single error in the logs. Below: how recognition breaks, what it corrupts downstream, the metrics to track and a test plan you can copy.
Why member recognition is the first tool call that matters
Every member call runs the same agentic workflow. The agent captures who is calling, looks them up, resolves the membership status, applies benefits, books a slot and does the write-back to the FSM. If the first step returns the wrong answer, every later step is correct for the wrong customer.
Member recognition rate: the share of calls from active service agreement customers where the agent links the call to the correct existing customer and membership before it books or quotes anything.
The stakes are concrete. FieldPulse's help center says its Operator AI phone agent "answers your inbound calls in a natural voice" and books jobs onto the schedule. If the caller isn't already a customer, it creates a new customer record tagged "Operator AI Generated" (FieldPulse help). That is sensible design. It also means a missed lookup doesn't fail loudly. It writes a second customer.
What HVAC service agreement customers are owed varies by contractor. Every HVAC maintenance plan is different. Housecall Pro's sample HVAC plans show the range (Housecall Pro template):
| Sample tier | Visits | Scheduling benefit | Pricing benefit |
|---|---|---|---|
| Starter (free) | 1 per year | None listed | Member promotions |
| Bronze, 1 year | 2 per year | Priority scheduling | 10% off parts and labor |
| Silver, 2 years | 2 per year | Next-day scheduling | 10% off parts, labor on failures covered |
| Gold, 3 years | 2 per year | Same-day scheduling | Labor on failures covered, 15% off installs |
FieldPulse's own guide notes that "some companies waive the diagnostic fee" and that discounts of "around 15%" are common (FieldPulse). Your agent has to load each contractor's version of this table and apply it correctly. A generic prompt can't.
For the wider home services checklist, see our AI receptionist for home services QA guide. This post goes deep on one slice of it.
Six ways the agent misses a member
Recognition fails in a few repeatable ways. Each looks fine in the transcript.

1. New or borrowed phone. The member calls from a work line, a new cell or a spouse's phone. Caller ID lookup returns nothing. Numbers also churn. The FCC lets a permanently disconnected number be reassigned after a minimum aging period of 45 days (FCC report to Congress). A stale phone on file can match the wrong household.
2. Household name mismatch. The account is under "Maria Ortiz". Her husband calls and gives "Daniel Reyes". The agent searches by name and finds nobody.
3. Address formatting. The caller says "four eighteen Maple Avenue, unit B". The record says "418 MAPLE AVE APT B". USPS Publication 28 lists AV, AVEN, AVENU, AVN and AVNUE as common variants of AVENUE, with AVE as the standard (USPS Pub 28, C1). Exact string match fails on every one of them.
4. Plan attached to the location, not the person. In ServiceTitan, recurring services attach to the service location and can cover one location or all of a customer's locations (ServiceTitan help). A landlord calling about a rental needs the location's plan, not their home's.
5. Status confusion. The agent sees a membership record and treats it as active. It may be suspended, expired or canceled.
6. Wrong tier. The agent recognises the member but applies Bronze benefits to a Gold plan, or another contractor's defaults.
The first four are lookup failures. The last two are resolution failures, and they hit even when lookup works. Track them separately, because an HVAC membership AI can pass every lookup test and still fail here.
Why lookups fail: caller ID, names and house numbers
Three inputs drive almost every lookup. Each has its own failure mechanism.
Caller ID. Your telephony layer passes a `From` value. It may be E.164 (`+15125550147`), a national format, or a withheld value such as "anonymous". Contractors type phones into the FSM by hand, so stored values vary too. Normalise both sides with a library like Google's libphonenumber before comparing. Treat an unparseable caller ID as missing, not as a new customer.
Names. Speech recognition is weakest exactly where lookup needs it. On the Earnings-21 benchmark, five commercial ASR systems showed 45.2% to 51.7% word error rate on person names, against 5.0% to 9.8% on dates (Del Rio et al., Interspeech 2021). Those are 2021-era models on earnings calls, not HVAC calls. The direction still holds. A 2025 paper reports up to a 30% relative WER reduction on named entities by adding context to the recognizer (arXiv 2506.10779). The production lesson: once caller ID or address narrows the candidates, pass the household names on file as context. Then confirm, don't search from scratch. Our entity accuracy guide covers how to measure this.
House numbers and streets. "Four eighteen" can become 418, 4018 or 480. Street suffixes and unit labels vary. Normalise the street with a suffix table and compare house numbers as exact tokens.
A three-zone decision, not a yes or no
Record linkage solved this shape of problem decades ago. Fellegi and Sunter's 1969 model scores each candidate pair, then uses two thresholds to split outcomes into link, possible link and non-link (Fellegi and Sunter, JASA 1969). The middle band goes to review.
On a phone call, "review" means one more question. Ask for the service address or ZIP before you write anything.

Here is a simplified resolver. The weights and thresholds are illustrative. Tune them per platform from labelled calls.
# Simplified member resolver: three outcomes, never a silent "new customer".
import re
from difflib import SequenceMatcher
import phonenumbers
SUFFIX = {"avenue": "ave", "av": "ave", "street": "st", "str": "st",
"drive": "dr", "drv": "dr", "court": "ct", "lane": "ln"}
def e164(raw):
try:
n = phonenumbers.parse(raw, "US")
except phonenumbers.NumberParseException:
return None # withheld, "anonymous" or garbled caller ID
if not phonenumbers.is_valid_number(n):
return None
return phonenumbers.format_number(n, phonenumbers.PhoneNumberFormat.E164)
def norm_street(s):
words = re.sub(r"[^a-z0-9 ]", " ", s.lower()).split()
return " ".join(SUFFIX.get(w, w) for w in words)
def score(caller, rec):
s = 0.0
if caller.get("phone") and caller["phone"] in rec["phones"]:
s += 4.0
if caller.get("house_no") and caller["house_no"] == rec["house_no"]:
s += 2.0
if caller.get("street"):
ratio = SequenceMatcher(None, norm_street(caller["street"]),
norm_street(rec["street"])).ratio()
s += 2.0 if ratio >= 0.85 else 0.0
if caller.get("last_name", "").lower() in rec["household_names"]:
s += 1.5
return s
def resolve(caller, candidates, link=5.0, review=2.5):
ranked = sorted(((score(caller, r), r) for r in candidates),
key=lambda x: -x[0])
if not ranked or ranked[0][0] < review:
return "new_customer", None
best, rec = ranked[0]
runner_up = ranked[1][0] if len(ranked) > 1 else 0.0
if best >= link and runner_up < link:
return "match", rec
return "verify", rec # ask one question before writing anythingRun it on the spouse case. The husband calls from a new cell, says "418 Maple Ave" and gives "Reyes". The phone misses, but house number, street and household name score 5.5. The result is `match`. A name-only search would have created a duplicate.
Two details matter. First, `household_names` should hold every adult on the account, not just the billing contact. Second, a tie between two strong candidates goes to `verify`, never to the first row.
Benefits must follow recognition, and the quote must match
Recognition is necessary but not sufficient. The agent then has to apply the right benefits on this call.
Four benefits show up in most plans:
- Priority scheduling. In a heat wave, members should get the earliest slot. If the agent books from the public calendar, members wait like everyone else.
- Diagnostic fee. If the plan waives it, the agent must not quote it. Saying "$89 for the diagnostic" to a Gold member is a billing dispute in waiting.
- Repair discount. The agent should state the member price or no price at all. It should never quote the non-member price to a member.
- Included tune-ups. These visits are free to maintenance agreement members. ServiceTitan notes that recurring services aren't charged to the customer (ServiceTitan help).
Price talk is where transcript review misleads. The transcript shows a polite booking. The defect is a number the plan said not to quote. Grade pricing turns against the contractor's plan config, not against tone.
Membership also shapes which technician and slot are offered. That routing problem gets its own post: why your HVAC AI books the wrong tech. Here, the test is narrower. Did the member get the member slot window and the member price?
Lapsed, suspended and renewal calls
Status is where agents overgrant or undergrant. ServiceTitan's documentation spells out the statuses (ServiceTitan help):
| Status | Benefits on this call | Included visits | What the agent should do |
|---|---|---|---|
| Active | Yes | Bookable | Apply tier benefits, offer due tune-up |
| Suspended | No | Recurring events stay bookable | Book the visit, quote standard pricing, flag for office |
| Expired | No | Recurring services deactivated | Book as standard, offer renewal handoff |
| Canceled | No | Recurring services deactivated | Book as standard, no member language |
| Deleted | Not visible | None | Treat as no plan, check for duplicates |
The suspended row is the trap. The recurring service event can still be booked, yet benefits are off. An agent that reads "has recurring event" as "is active" will waive fees it shouldn't.
Lapsed members treated as active cost the contractor money. Active members treated as lapsed cost the renewal. SmartAC puts the second risk plainly: "If a customer pays for two tune-ups a year and no one calls to schedule them, they will cancel at renewal" (SmartAC). A member calling about a repair is the cheapest moment to book a tune-up that is due. Test that the agent offers it.
What one missed member breaks downstream
The call ends politely. The damage lands in the FSM:
1. A duplicate customer with the caller's new phone and a slightly different address.
2. A job on the duplicate, with no membership attached.
3. A diagnostic fee and non-member pricing on the invoice.
4. A standard queue slot instead of the member window.
5. The real record's tune-up still unbooked and its visit history now split.
Duplicates compound. Visit history splits, so the next lookup is less likely to hit the right record. Renewal reminders go to one record while service history sits on the other.
Here is a worked example with assumed inputs, not measured data. A contractor takes 1,000 inbound calls in a July week. Assume 35% come from service agreement customers, or 350 calls. At a 92% recognition rate, 28 members are treated as new. If half of those need a diagnostic at an assumed $89 fee, that's 14 wrongly charged fees, about $1,246. It also means up to 28 duplicate records. Across 300 contractors on one platform, that's 8,400 missed members a week. Each one is a refund, a merge or a churn risk.
The arithmetic is simple. The point is that a few points of recognition rate are a support queue, not a rounding error.
The metrics to track
Track these per contractor and per release. Set thresholds per platform. The values below are starting points, not industry benchmarks.

- Member recognition rate = member calls correctly linked ÷ all calls from active members. Start at a 97% target.
- False member rate = non-members or lapsed members given member benefits ÷ calls where benefits were applied. Keep it under 1%.
- Benefit application accuracy = calls where fee, discount, slot window and visit coverage all match the plan ÷ recognised member calls. Target 98%.
- Duplicate record rate = new customers created on a call that match an existing record ÷ new customers created by the agent. Keep it under 2%.
- Due tune-up offer rate = calls where a due included visit was offered ÷ member calls with a visit due. Start at 90%.
Count the denominators from ground truth, not from the agent's own claim. If the agent never recognised a member, the transcript won't say "member". Your fixture or the FSM's membership table will.
How to test HVAC service agreement customers before every release
Members can't be tested with a generic script. Every contractor's plans differ, so the fixtures must too.
1. Export each contractor's membership config. Pull tiers, benefits, diagnostic fee rules, discount rates, slot windows, visit counts and statuses. Store it as data your grader reads. The multi-tenant testing guide shows how to group contractors by config shape.
2. Seed a sandbox FSM with synthetic members. Create households with two adults, a rental location, a suspended plan, an expired plan and a member whose phone was changed. Use fictional 555-01xx numbers.
3. Write identity variants for each member. Spouse's name, a new cell, a work line, withheld caller ID, "Avenue" spoken in full, a unit number and a misheard house number.
4. Add caller conditions. Run the same variants with different accents, fast speech, background noise and interruptions. Names fail more under noise, so pair them. Our synthetic callers guide covers profile design.
5. Assert on the FSM state, not the transcript. After each call, check the linked customer ID, the membership on the job, the quoted fee, the slot window and whether a new customer was created. A silent tool failure only shows up in the record.
6. Size the run. For a 95% recognition rate, the 95% confidence half-width is about ±4.3 points at 100 member calls and ±3.0 points at 200. Use at least 200 member scenarios per config shape.
7. Gate releases on deltas. Compare each prompt or model change against the last release on the same fixtures. Block a release that drops recognition or raises duplicates. See how to ship prompt changes safely.
Evalgent fits steps 3 to 6. It generates test scenarios from the agent's prompt and flows, including policies like "never quote the diagnostic fee to a member". It runs caller profiles with accent, pace, interruptions and background noise over PSTN, SIP or WebRTC. It then judges from the audio, not only the transcript, with evidence for each verdict.
Monitoring recognition in production
Pre-release tests cover the variants you thought of. Production finds the rest. Three checks catch most misses:
- Duplicate sweep. Nightly, compare agent-created customers against existing records by normalised phone, street and household name. Any hit is a likely missed member.
- Benefit audit. For every call linked to a member, compare the quoted fee and slot against the plan config.
- Status audit. Flag calls where benefits were applied to a suspended, expired or canceled plan.
Evalgent's production monitoring can take pushed call recordings, transcribe them, map them to scenarios and judge them. It flags tool-call failures, latency spikes and policy failures, with fix recommendations. Pair that with the FSM sweep above. Our guide to monitoring voice agents in production covers the pipeline.
The same pattern shows up in other trades. Plumbing agents misbook jobs in similar ways (plumbing AI booking errors). Home warranty agents misjudge coverage (home warranty claims AI). Credit unions face a stricter version of the identity step (member verification QA).
Frequently asked questions
How does an AI receptionist recognize service agreement members?
An AI receptionist recognizes service agreement members by matching caller ID, service address and household names against the FSM's customer and membership records. Strong agents normalise phone numbers to E.164 and street suffixes to a standard form. They also use a middle "verify" band that asks one confirming question instead of guessing between existing member and new customer.
What happens when a member calls from a different phone number?
When a member calls from a different phone number, a caller-ID-only lookup returns nothing. Many agents then create a new customer. The fix is to fall back to service address and household name before creating anything. Then ask whether to add the new number to the existing account, so the next call matches directly.
Should the AI waive the diagnostic fee for members?
The AI should waive the diagnostic fee for members only when that contractor's plan says so and the membership is active. Plans differ. Some waive the fee, some discount it and some don't mention it. Suspended, expired and canceled plans carry no benefits in ServiceTitan's model, so the agent should check status first.
How do you prevent duplicate customer records from AI calls?
To prevent duplicate customer records from AI calls, never create a customer on a failed exact match. Score candidates on phone, address and household name. Ask one verifying question in the uncertain band. Then run a nightly sweep comparing agent-created customers with existing records. Track the duplicate-record rate per contractor and per release.
How should the AI handle expired or suspended memberships?
An AI should handle expired or suspended memberships by booking the visit at standard pricing without member language. In ServiceTitan, suspended memberships keep recurring visits bookable while benefits stop. Expired ones deactivate recurring services. The agent should flag both for the office and offer a renewal handoff instead of promising member benefits.
Can an AI receptionist book included tune-up visits?
An AI receptionist can book included tune-up visits when the FSM exposes which recurring visits are due and how many remain. Test that it books them at no charge and offers a due visit during repair calls. Unbooked tune-ups are a common reason members feel the plan gave them nothing at renewal.
What is a good member recognition rate?
A good member recognition rate is one you measure against ground truth and track per contractor. No public benchmark exists for HVAC voice agents. A practical starting target is 97% or higher, with false-member grants under 1% and duplicate customers under 2%. Then tighten those targets as your fixtures grow.
How do you test membership rules across many contractors?
To test membership rules across many contractors, export each contractor's plan config as data and seed a sandbox FSM with synthetic members. Run identity variants and caller conditions against it. Assert on the FSM record after each call. Group contractors by config shape so 300 tenants need dozens of fixture sets, not 300.
The bottom line
An HVAC AI receptionist that misses HVAC service agreement customers fails silently, by booking members as new customers. Measure recognition, benefit accuracy and duplicates against each contractor's plan config, and test identity variants before every release.
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