The AI Booking Agent Booked a Week of Jobs Wrong

Why this matters

An AI booking agent that fails loudly gets fixed on day one. The expensive kind fails quietly: every call sounds polite, every booking "succeeds", and the damage shows up days later as a tech driving into the next county, two techs' worth of work stacked in one slot, and an emergency sitting in Thursday's routine queue. This is one shop's week of that, how they stopped the harm first, and how the call logs pointed past three plausible causes to the one setting nobody had questioned.

The shop: residential HVAC and plumbing, seven techs, two office staff. On a Monday the owner's office manager switched their AI phone agent from "take the details and hand them to dispatch" to "book the job directly", to cut the after-hours backlog. Nothing else changed.

Stop the harm before working out why

Friday 14:00, two signals inside an hour. A tech called in from an address 50 minutes past the shop's farthest service town, booked by the agent on Wednesday night. Then the dispatcher found Thursday's 10:00 slot holding two jobs for the same tech at opposite ends of town.

The office manager did three things before anyone looked for a cause, in this order:

  1. Took the agent off direct booking. It went back to taking details and handing them to dispatch, the mode that had worked for months. A known-good mode beats any fix you have not tested.
  2. Searched the week's transcripts for emergency words (no heat, gas, smell, burning, leak, sparking, water near anything electrical, plus any mention of oxygen, an infant or someone elderly) and called every one of those customers back before 15:00, whatever the booking said.
  3. Counted before theorising, so the diagnosis would have numbers to explain.

The callbacks found four emergencies that had been booked as normal work. Two needed instructions before dispatch. A customer whose mother uses home oxygen had a 51 degree house and was planning to run a space heater; the dispatcher told her to keep any heater well clear of the oxygen equipment and never to heat the house with a gas oven, which produces carbon monoxide, and sent the on-call tech that afternoon. A customer with a tripping breaker and a burning smell was told to leave that breaker off and not reset it, and to call 911 if the smell came back with smoke. The other two, a water heater leaking toward a panel and no heat with an infant at home, were moved to same-day. With nobody in danger, the diagnosis could start.

The three symptoms, counted

The agent made 61 bookings Monday to Friday. Against the dispatcher's own rules:

  • 7 out of area, all at addresses outside the shop's ZIP code list.
  • 4 emergencies booked as routine, the four above.
  • 9 duplicate slots, each landing on a tech who already had a job in that time.

No booking appeared in more than one list, so 20 of the 61 bookings, about a third, were wrong. Three unlike failures from one change is itself evidence. Either three separate things broke on the same Monday, or one thing sits upstream of all three.

First suspect: the model misunderstood the callers

The obvious theory, and the one the owner held: the AI is not smart enough for booking. If that were true, the transcripts and the agent's own call summaries would show it mishearing or misclassifying the calls.

They showed the opposite. Here is the log entry for the oxygen call, trimmed:

CALL 0418   Wed 19:52   duration 4m10s
Caller: "no heat, my mother's on oxygen,
         it's 51 degrees in here"
Agent summary:
  intent  = no heat
  urgency = HIGH
  zip     = 4xxxx (checked)
  slot    = Thu 10:00
Booking result:
  status   = created
  channel  = ONLINE BOOKING
  priority = Normal
  type     = Maintenance visit
  tech     = next open template slot

The agent understood the call: it tagged urgency HIGH in its own summary. Somewhere between the agent and the job record, HIGH became Normal and a no-heat call became a maintenance visit. All four emergency transcripts looked the same. The model was not the fault, and replacing it would have changed nothing.

The number that lied was on the agent's dashboard all week: a booking success rate of 98 percent. It counted bookings the system accepted, not bookings that were right. Every one of the 20 bad jobs was a success by that measure.

Second suspect: the service-area list was wrong

The out-of-area bookings pointed at the agent's FAQ, which holds the ZIP code list. If someone had edited it, or the agent was reading an old copy, out-of-area jobs would follow.

The list was correct. All seven ZIPs were missing from it, as they should have been. The transcripts showed something more useful: in five of the seven calls the agent said "let me make sure we cover that address", the booking went through, and it replied "you're all set". Its instructions, written by the office manager on Monday, said: "The booking system will reject any address we do not serve, so you do not need to check the ZIP yourself."

That sentence was true of the dispatcher's screen. It had been copied into the agent's instructions as if it were true of every way into the schedule. The list was fine; the agent had been told not to use it. That pointed at the booking path, not at the content.

Third suspect: calendar sync lag

Duplicate slots usually mean two systems reading a calendar a few minutes apart. If the agent saw a stale copy, it would book into slots the dispatcher had just filled.

Lag dies on the timestamps. In all 9 duplicates the dispatcher's job had been on the calendar for at least a day before the agent booked over it, and in one case for three days. No sync is that slow. The second clue was in the times: all 9 landed on 08:00, 10:00, 13:00 or 15:00, the four start times of the shop's public online booking template. The dispatcher books on any quarter hour; the agent only ever booked on those four.

The channel field

The log entry had already said it: channel = ONLINE BOOKING. When the office manager chose "book directly", the integration's default booking path was the shop's public online booking channel, the one behind the "Book now" button on its website. That channel was built for homeowners picking a tune-up, and it carries the website's assumptions:

Rule Dispatcher booking Online booking channel
Service area Checked against the ZIP list on save Left to the website's town dropdown; a typed address is accepted
Priority Set by the dispatcher Not a field; every job is Normal
Job type Chosen per call Defaults to Maintenance visit
Availability Every tech's live calendar A fixed template of public slots that does not see jobs placed directly on a tech

Each symptom is one row. No address check produced the 7 out-of-area jobs. No priority field turned 4 HIGH summaries into Normal jobs. A template that cannot see the dispatcher's jobs produced 9 double-booked slots on exactly the four template times. One configuration choice explained all 20 bad bookings, and one sentence in the agent's instructions explained why it never caught the area problem itself.

The assumption under all of it: "the agent books the way our dispatcher books." It booked the way the website books, because that was the door it had been handed.

The fix, and how they proved it

They changed three things, one at a time, through their change log. See related: The Automation Change Control SOP.

  1. The door. The agent no longer creates jobs. It creates a booking request in the dispatcher's queue carrying its summary, urgency included, and confirms to the caller "we have your request, and the office will confirm a time by" a stated hour. Direct booking stays off until the field software can route agent bookings through the same checks as the dispatcher's screen.
  2. The instruction. The sentence about the booking system rejecting addresses came out. The agent now checks the ZIP list itself and tells an out-of-area caller so on the call.
  3. The emergency rule. Any HIGH urgency, or any of the emergency words, transfers to a person instead of producing a request.

Proof, before going live: they replayed 15 of the logged calls, the 4 emergencies, the 7 out-of-area calls and 4 of the duplicates, as scripted test calls. All 4 emergencies transferred, all 7 out-of-area callers were told on the call, and the 4 requests arrived with urgency intact. See related: Setting Up an AI Phone Answering Service and Testing It.

Proof, after: the following week the agent took 48 requests. Zero out of area, zero duplicates, and 3 emergency calls, all transferred within a minute. They then added "channel" to the columns of their weekly call review, so a change in which door the agent uses can never again go unnoticed for a week. See related: The Weekly AI Call Review SOP.

The question to ask of any agent that writes to your system

An AI agent inherits the rules of whatever path it writes through, not the rules in your head. Before switching one to act rather than take messages, open one record it created and read every field against the same job made by a person: priority, type, assigned tech, how availability was decided. Ten minutes on one record would have shown this shop "ONLINE BOOKING" on Monday afternoon instead of Friday.

Two things would have hidden the cause longer. If the shop had used a different template time for each tech, the four-time signature in the duplicates would not have shown. And if the owner had acted on the first suspect and moved to another AI service, the same default path would likely have come with it, and the second week would have looked like the first.

References

  • See related: The Weekly AI Call Review SOP
  • See related: Setting Up an AI Phone Answering Service and Testing It
  • See related: The Automation Change Control SOP
  • See related: What a Scheduling Optimizer Ignores
  • See related: Automation Versus AI: Two Different Tools