Field Service & Trades// diagnostic

The calls were answered overnight and the board is empty at 7am

In short

After hours bookings not showing in dispatch is a reconciliation failure, not a phone failure. Count four things for the overnight window — calls received, calls carrying booking intent, jobs created, jobs visible on the board — and the gap between any two adjacent counts names the layer that lost the job.

Key takeaways

  • The overnight gap is a missing contract between the answering layer and the board, not a weakness in the phone agent.
  • Four counts settle it: calls received, calls with booking intent, jobs created, jobs visible on the dispatcher's board.
  • Most operators cannot produce the second count, because no disposition is recorded per call — fix that before anything else.
  • A job sitting in a holding queue, a foreign business unit or the wrong day is lost exactly the way a dropped call is lost.
  • The deliverable is small: a nightly job, four queries and a named list of unmatched calls, sent before the board opens.

The calls almost certainly happened and the intent was almost certainly captured. What failed sits between the layer that answered the phone and the board the dispatcher opens — and because nobody counts both ends of that handoff, a booking can disappear every night for months without anyone being able to say how many.

So the first move is not to listen to recordings or retune the agent. Establish four numbers for the overnight window and compare them. Each delta points at a different layer, with a different owner and a different fix.

Confirm it before anyone blames the agent

Take one recent night and produce these four counts by hand. Twenty minutes settles an argument that otherwise runs for weeks. Every count covers the same fixed local-time window — the branch's own evening cut-off to its own morning start, not a UTC day.

CountWhere it comes fromA shortfall at the next line means
Calls received, 18:00 to 07:00Telephony or call-tracking log, by branch numberCallers who reached the answering layer and never wanted a job — abandonment, wrong number, price enquiry
Calls carrying booking intentA disposition recorded per call by the agent or operatorBookings the answering layer believed it made that became no record anywhere
Jobs created overnightThe platform, filtered on created-at inside the windowRecords that exist but are not on today's board — holding queue, wrong business unit, wrong date
Jobs visible on the 07:00 boardThe dispatch view as the dispatcher opens it, filters includedNothing below this line. This is the number the business runs on
The four overnight counts, and what a gap to the line below means

If the drop sits between the first two counts, this is not a handoff problem at all — the call itself is failing, usually on turn-taking and the first eight seconds. Start with how interruption handling decides whether callers trust the agent. And if the call count itself has fallen rather than converting badly, look upstream of the phone: check whether the listing dropped out of local results.

The five places an overnight booking goes missing

Ranked by how often each turns out to be the cause, and by how cheaply it can be ruled out.

1. It landed in a queue nobody opens

Every field service platform has a bucket for work that exists but is not scheduled — unassigned, pending, new request, needs review. An agent that cannot resolve a job type, a duration or a capacity slot will reasonably write there rather than commit to the board. That is correct behaviour. What is missing is the other half of the contract: a queue nobody must open at a stated time is a bin.

The same mechanism eats bookings that failed a rule rather than a lookup. A caller ninety minutes past the boundary should be refused on the call, with an explanation, rather than parked as a half-job — the boundary logic is covered in why the agent keeps booking jobs past the edge of the map.

2. The write failed and nothing alerted

The agent finished the call, said the words the caller needed to hear, and the create request errored or never completed. With no retry and no alert the failure is silent by construction, and the only evidence is a transcript promising a Tuesday morning arrival with no matching record. Overnight is when this bites hardest, because the failure window is eight hours long and nobody is watching.

Retries, idempotency and dead-letter handling belong to the integration layer, not to intake — see platform integration and data, platform events that never reach your listener and the integration that died overnight. Here only one thing matters: a failed write must appear in the morning count as a named call, not as an absence.

3. The job exists, under a business unit nobody looks at

A dispatcher's board is a filtered view: branch, business unit, trade, technician group. A job created overnight inherits whatever default the integration supplies, and a default set during a pilot survives into production. The job is genuinely there; it is simply outside the filter, which operationally is identical to not existing. Check this first — it is a two-minute query and a configuration fix — see the business unit code every job carries.

A variant appears when the customer record is wrong rather than the unit. A caller matched to no existing customer at 2am gets a fresh record with no branch, no history and none of the tags saved views depend on — the dedupe failure described in every repeat caller arriving as a brand-new record, surfacing as a scheduling symptom.

4. Time zones and the date boundary

A call at 21:30 local on Tuesday is already Wednesday in UTC. If the booking service computes tomorrow morning from a server clock rather than the branch's zone, the job lands on Thursday and Wednesday's board shows nothing. The same defect appears twice a year at daylight-saving transitions, where a nominal 02:30 arrival window either does not exist or exists twice.

  • Store a named zone, never an offset. An offset is wrong for half the year anywhere that observes daylight saving.
  • Resolve relative dates at the moment of speech. Tomorrow means tomorrow in the caller's branch, then written as an absolute local date and time.
  • Log both clocks. Carry the local booking time and the creation instant, because this class of bug cannot be debugged with only one.

5. A human service emailed instead of writing

Where overnight cover is a staffed answering service, the handoff is usually an email rather than a write into the platform. The service has done what it contracted to do. The job then depends on somebody opening a shared inbox before the board is set, which is not a system. If intent was captured and no records exist, this is your cause, and the choice is narrow: change the contract so the service writes into the platform, or accept that the first office hour is a transcription task and staff it. What a voice agent and an answering service each actually book sets out that trade.

A booking that exists in the platform and not on the board is indistinguishable, to the customer with a dead boiler, from a call nobody answered.

The report that makes a loss impossible to miss

The fix for the class of failure, rather than tonight's instance, is a nightly reconciliation delivered whether or not anything went wrong. Build it in this order.

  1. Pin the window per branch. A fixed local-time range in the branch's named zone, held as configuration. One hardcoded window across a multi-branch operator misreports every branch it was not written for.
  2. Emit a disposition on every call. Booked, refused with reason, deferred, escalated, no intent. Five values, mandatory, written by the answering layer at the end of the call.
  3. Join on an identifier the agent controls. Carry the call identifier onto the created job and join on that. Joining on number and name fails on shared lines, landlords and anyone booking for somebody else.
  4. Name every unmatched call. A count says something is wrong; a list of five call identifiers with timestamps, numbers and recording links says what to do in the next ten minutes.
  5. Deliver it before the board opens. If the dispatcher starts at 07:00, it lands at 06:45 in a channel they already have open.
  6. Make the report fail loudly. An empty report and a report that could not run must look different, so alert on absence.

Who owns each gap

Splitting the counts matters because each delta lands on a different desk. Unsplit, it arrives as a complaint about the phone system, which is usually innocent.

Gap between countsMost likely causeOwner of the fix
Calls received to booking intentGreeting length, turn-taking, refusal rules set too broadWhoever owns the agent's conversation design
Booking intent to jobs createdUnretried write failure, or a human handoff by emailIntegration owner, or the answering-service contract
Jobs created to jobs on the boardWrong business unit, wrong date, unopened holding queuePlatform administrator and the dispatch lead
Jobs on the board to jobs actually runCapacity that was never available when the promise was madeDispatch, not intake
Gap, most likely cause, and where the fix lives

The last row is the one people skip. An agent booking into slots the board cannot hold produces a morning of apology calls that looks identical, from outside, to a lost booking. If the counts reconcile cleanly and customers are still angry at 9am, the diagnosis is capacity — and the overnight escalation path should be explicit rather than improvised, as in when the agent is allowed to wake the on-call technician.

What this costs to build

A nightly job, four queries, a join on one identifier and a message. It is not large engineering, which is exactly why it never gets built: it is nobody's feature and the person who benefits is a dispatcher rather than a buyer. If it has slipped two quarters, scope it as an owned deliverable with a date — the shape of work we run as MVP and product builds, alongside the rest of our field service and trades work. The intake questions behind it are mapped across intake and call capture.

One caution on sequencing: do not rebuild the intake agent while the reconciliation is missing, because you will have no way to tell whether the new version is better. Instrument first.

Frequently asked questions

Short answers to the follow-ups this page tends to raise.

How do I tell a lost booking from a caller who never wanted one?

You cannot, unless the answering layer records a disposition on every call. A transcript read the next morning is an interpretation; a disposition written at the end of the call is a fact. Five values are enough — booked, refused with reason, deferred, escalated, no intent — and making the field mandatory is usually configuration rather than a build.

Should an overnight agent create jobs directly, or write to a review queue?

Either is defensible, but only if the queue has a named owner and a clearing deadline. Direct creation puts the risk on the board, where a wrong job is visible and fixable at 07:05. A review queue puts the risk in a bucket, where a missing job stays invisible until the customer rings back. If you choose the queue, its depth belongs on the morning report every day, including the days it is zero.

Does fixing this require a new integration?

Usually not. Three of the five common causes — an unopened holding queue, a wrong business unit default, and a date computed in the wrong time zone — are configuration and logic fixes inside systems you already run. Only silent write failure needs integration work, and even there the first change is alerting rather than architecture.

What gap between booking intent and jobs created is acceptable?

Zero, as a target, because every unit in that gap is a customer who was told a technician was coming. Track it as an absolute count of named calls rather than a percentage: at overnight volumes a single lost job rounds to nothing as a rate, and it is still somebody's heating.

  • intake
  • dispatch
  • reconciliation
  • after hours
// shipped work

The work behind this page

Builds from our portfolio that this page draws on.

Working on something in this space?

Tell us where you are in a sentence or two. We'll tell you honestly whether we're the right team, and what a sensible first slice of the work looks like.

Start the conversation