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.
| Count | Where it comes from | A shortfall at the next line means |
|---|---|---|
| Calls received, 18:00 to 07:00 | Telephony or call-tracking log, by branch number | Callers who reached the answering layer and never wanted a job — abandonment, wrong number, price enquiry |
| Calls carrying booking intent | A disposition recorded per call by the agent or operator | Bookings the answering layer believed it made that became no record anywhere |
| Jobs created overnight | The platform, filtered on created-at inside the window | Records that exist but are not on today's board — holding queue, wrong business unit, wrong date |
| Jobs visible on the 07:00 board | The dispatch view as the dispatcher opens it, filters included | Nothing below this line. This is the number the business runs on |
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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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 counts | Most likely cause | Owner of the fix |
|---|---|---|
| Calls received to booking intent | Greeting length, turn-taking, refusal rules set too broad | Whoever owns the agent's conversation design |
| Booking intent to jobs created | Unretried write failure, or a human handoff by email | Integration owner, or the answering-service contract |
| Jobs created to jobs on the board | Wrong business unit, wrong date, unopened holding queue | Platform administrator and the dispatch lead |
| Jobs on the board to jobs actually run | Capacity that was never available when the promise was made | Dispatch, not intake |
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
The work behind this page
Builds from our portfolio that this page draws on.
FieldRoute
An AI field-service platform that auto-dispatches the best-matched technician, optimizes routes, and tracks first-time-fix against every SLA.
OperationsPatient Front Desk
AI receptionist for clinics — auto intake, smart scheduling, and insurance verification before the patient walks in.
Healthcare AIRead next
- A home warranty dispatch is not a customer callA warranty dispatch arrives with an authorisation number, a covered scope someone else defined, and a payer who is not in the house. Booking it like a retail call produces uncloseable jobs.definition
- A no-heat call got booked as a routine tune-upA job sits on the board at routine priority and the recording describes an emergency. Before retuning anything, join booked jobs to their transcripts and score them against your own tier table.diagnostic
- Emergency, urgent, same-day, routine: four tiers and who defines themThere is no industry-wide definition of an emergency call. The operator writes one, and until those conditions exist as data no intake agent applies them consistently.definition
- The job type is the schema: what a booking code has to carryDispatch, duration, skill matching and pricing all read the job type. Treating it as a dropdown label rather than a schema is why the board looks full and the day falls apart.definition
Related across the site
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