Offer a time you can actually keep.
Availability is computed from working hours, the skills a job needs, the zones you drive to and the buffer around every visit. A slot is held with an expiry, and confirming it is a single transaction that cannot produce two vans at one address.
Tue 14
08:0011:30Wed 15
09:0013:0015:30Thu 16
10:00Held 9:41 — released if nobody confirms
Mon
Tue
Wed
Thu
Fri
Booked visitsExternal busy
The model never invents a time.
The most expensive failure in an AI booking flow is a slot that was never free. Lavenity does not ask a model when someone is available: availability is a search over resources, their weekly hours and exceptions, their skills and zones, and the buffers before and after each visit.
What the customer is offered is what the search returned. Holding one writes a row with an expiry, and confirming re-checks the hold, the request version and the availability before it commits — so a slow customer loses a hold rather than someone else's morning.
The scheduling rules a service business already has
Slots that survive contact with reality
Skills, service zones and per-resource buffers all narrow the search before a time is shown. A resource who cannot do the job, or does not drive to that postcode, is not offered.
Tue 14
08:0011:30Wed 15
09:0013:0015:30Thu 16
10:00Held 9:41 — released if nobody confirms
Hours, zones and emergencies you control
Working hours carry a timezone. Service zones are the postcodes you actually cover. An emergency out of hours follows the policy you wrote, not the model's judgement.
- Working hoursMon–Fri 07:00–17:00 · Europe/Berlin
- Service zones10115–10999, 12043–12059
- EmergencyOut of hours → straight to a human
- Bookable services2 of 9 allowed
Holds that release themselves
An abandoned hold expires on its own, so a hesitant customer never freezes a morning.
Buffers before and after
Travel and write-up time are part of the slot, not something the day absorbs.
Zone-aware, not zone-blind
Out-of-zone stays possible and stays a decision — the picker names the reason.
Confirm twice, book once
Repeated and concurrent confirmations return the same appointment. Proven against Postgres.
Search, hold, confirm
Three steps, each one safe to repeat. That is what lets an unreliable channel drive a reliable calendar.
- 01
Search returns real slots
A read with no side effects: cacheable, repeatable, and identical whether it was asked for by an operator or by an integration.
- 02
The slot is held, briefly
A hold is a row with an expiry, not a note. It blocks the time while the customer decides, and it releases itself if they do not.
- 03
Confirmation commits everything at once
The appointment, the work order and the outbound confirmation are one transaction. Nothing is half-booked because a process restarted.
A constraint in the database beats a check in the code.
Two requests arriving in the same millisecond will always defeat an application-level “is this free?”. Lavenity puts the guarantee where concurrency cannot get around it, and proves it with an integration suite that fires confirmations in parallel at a real Postgres.
A week you can read
The dispatch calendar shows visits, holds and the gaps between them.
An emergency path
Out-of-hours urgency follows your written policy, including straight to a human.
A cancellation that cleans up
Cancelling frees the slot and withdraws work nobody has started.
Give customers a time, not a callback promise
Set up one resource and one service, and the calendar starts answering for you.