Why did the same customer end up with two appointments on the schedule?
Usually one of three causes: the customer contacted you twice through different channels and nothing linked the two, an automation retried a write after a timeout when the first write had actually succeeded, or the customer's identity did not resolve because they called from a different number. The fix is identity resolution before writing, a duplicate check against open jobs, and an idempotency key so retries cannot create a second record.
The three causes look identical on the schedule
Two jobs for the same address on the same day tell you nothing about how they got there. Separating the causes requires looking at the creation timestamps and the source fields, and it is worth doing because the remedies do not overlap.
Timestamps seconds apart with identical content means a retry. Timestamps hours apart from different sources means a channel collision. Timestamps hours apart with slightly different customer records means identity resolution failed.
Retries: the timeout that lies
When a write to a scheduling API times out, the automation does not know whether the write happened. The request may have been processed and the response lost. Retrying blindly creates a second job. Not retrying risks creating none.
The standard answer is an idempotency key: a value derived from the meaningful content of the request, sent with the write, so the receiving system can recognize a repeat and return the original result instead of creating a new record. Where the platform does not support one natively, the integration layer has to keep its own record of attempted writes and check before retrying. This is unglamorous and it is the difference between an automation you can trust and one that needs babysitting. More on that pattern in API integration.
Channel collisions and identity
- Same person, two channels. They filled out the web form, got impatient, and called. Both create a lead. Dedupe on phone plus address plus a time window, not on name.
- Same household, two numbers. A spouse calls from a different mobile. The service address is the reliable key; the phone number is not.
- Existing customer treated as new. The agent did not look up the caller before creating a record. Always resolve identity before write, never after.
- Different spelling. Human entry and machine transcription rarely agree on names. Never dedupe on name alone.
The check that prevents most of it
Before creating any job, query for open jobs at the same service address within a sensible window and surface them to the agent. If one exists, the correct behavior is almost never to book a second appointment. It is to ask the caller whether they are calling about the existing visit, and to route to a human if the answer is complicated.
That single pre-write check catches channel collisions, repeat calls and most identity failures at once. Wiring it against ServiceTitan or Jobber takes one read call and turns a recurring dispatch annoyance into a non-event.
Topics: duplicates · idempotency · booking · identity resolution · data quality
Have a version of this question about your own business?
The useful answer usually depends on which systems you run and how they're connected. That's a conversation, not a blog post.