Op deze pagina
Het begon met iets kleins. Een lead kreeg 9:15 voorgesteld, zei ja en hoorde toen dat het tijdstip al weg was: een andere lead had vier minuten eerder ja gezegd tegen dezelfde 9:15. Niemand had iets verkeerd gedaan. De assistent had ze allebei het vroegste vrije tijdstip voorgesteld, en maar één van de twee kon het krijgen.
Dat gebeurde telkens als leads vlak na elkaar binnenkwamen. Een sms-campagne naar een oude lijst met leads begint met hoogstens 10 mensen per minuut een gesprek (campagnes zitten in het Business-abonnement), dus de antwoorden komen ook vlak na elkaar terug. Hetzelfde gebeurt als een advertentie live gaat en de formulieren vollopen, of op een drukke maandagochtend. Elk gesprek dat bij de planningsstap aankwam, kreeg dezelfde briefing mee: de vroegste vrije tijdstippen in de werkruimte, waarbij alleen ingeplande afspraken als bezet telden. Dus kregen ze allemaal 9:00 voorgesteld. Het eerste “ja” kreeg het tijdstip, de rest hoorde “Sorry, dat tijdstip is al weg. Past een ander moment?”, en bij die extra ronde haken leads af. Het is een dubbele boeking die in geen enkele agenda te zien is, want een agenda ziet alleen de ene afspraak die wel is ingepland.
Daarom reserveert de assistent van Send4 nu het tijdstip dat hij voorstelt, standaard twee uur, en krijgt de volgende lead het volgende vrije tijdstip. Speel de golf leads hieronder af, eerst zonder reserveringen en dan met.
- AnoukIngepland ma 09:00
- BramIngepland ma 10:00
- DaanIngepland ma 11:00
- EvaIngepland ma 12:00
- FleurIngepland ma 13:00
- GijsIngepland ma 14:00
- IrisIngepland ma 15:00
- JeroenIngepland ma 16:00
- KimIngepland di 09:00
- LotteIngepland di 10:00
Met reserveringen kregen 10 leads 10 verschillende tijdstippen, en hoefde niemand opnieuw gevraagd te worden.
Waarom de voor de hand liggende oplossingen niet werken
Drie oplossingen liggen voor de hand, en geen ervan werkt. Twee tijdstippen voorstellen in plaats van één helpt niet, want het tweede tijdstip is evenmin gereserveerd en botst op dezelfde manier. De assistent doet daarom het omgekeerde: hij stelt één tijdstip voor, als een vraag waarop de lead ja of nee kan zeggen. De AI laten onthouden wat hij heeft voorgesteld, helpt ook niet. Het voorgestelde tijdstip bestond alleen als tekst in een bericht, dus niets kon het reserveren. En het tijdstip al bij het voorstel inplannen vult de agenda met afspraken waar niemand mee heeft ingestemd.
Een voorlopige reservering, geen afspraak
In agendataal is dit een optie, of een voorlopige reservering: het tijdstip wordt vrijgehouden terwijl de lead beslist, en er is nog niets ingepland. In Send4 is een reservering een eigen record en geen soort afspraak, want anders zou alles wat afspraken leest, van de agenda tot exports en webhooks, moeten leren om die over te slaan.
Een reservering duurt standaard twee uur. Je stelt de duur per planningsstap in, van 0, waarmee je reserveringen uitzet, tot 24 uur. Ze eindigt eerder als het tijdstip te dichtbij komt voor de minimale tijd vooraf (“Minimum notice”). Moet een afspraak minstens een uur van tevoren worden ingepland, dan verloopt een reservering voor 10:00 die om 08:55 is gemaakt, al om 09:00, want daarna had niemand dat tijdstip nog kunnen inplannen. Meer berichten verlengen de reservering niet, dus een praatgrage lead kan een tijdstip niet eindeloos vasthouden. Reserveringen gelden voor de hele werkruimte, niet per verkoper.
De reservering is niet bindend, omdat we een lead die nu wil inplannen niet willen afwijzen voor een lead die dat misschien wil. Zolang er een vrij tijdstip zonder reservering is, slaat de assistent tijdstippen over die voor andere leads zijn gereserveerd. Maar een lead die om precies zo’n tijdstip vraagt, kan het toch inplannen, en wie als eerste bevestigt, krijgt het. Schrijft de andere lead daarna weer, dan vertelt de assistent dat het tijdstip weg is en stelt hij een ander voor. Is elk vrij tijdstip al gereserveerd, dan stelt de assistent toch het vroegste voor, zonder een nieuwe reservering te maken. Een tijdstip dat ook een ander al voorgesteld kreeg, is beter dan helemaal geen voorstel.
Zo vermijd je dubbele boekingen: het systeemontwerp
De regel is simpel: stel geen tijdstip voor waarover iemand anders nog beslist. Onze eerste beslissing was dat het AI-model zelf geen tijdstippen kiest. Dat doet gewone code, de picker, en de assistent krijgt de opdracht om precies dat tijdstip voor te stellen. Wil de lead een ander tijdstip, dan moet de assistent een tool aanroepen (tool call) die de reservering verplaatst. Zo staat elk tijdstip dat hij voorstelt als record vast in plaats van alleen in de tekst van een bericht, en heeft de tool die de afspraak inplant het laatste woord. Wat hierna komt, is voor ontwikkelaars, en voor iedereen die een online afsprakensysteem ontwerpt. We schreven het plan op 25 september en bouwden het twee dagen later, en twee reviews van het plan leverden de meeste edge cases hieronder op.
Buffertijd tussen afspraken
Met afspraken van 30 minuten en 10 minuten buffertijd krijgt de tweede lead 10:00 voorgesteld, niet 09:30. Zeggen ze ja tegen 09:00 en 09:30, dan valt 09:30 binnen de buffer van de eerste afspraak en wordt de tweede boeking geweigerd. De tijd tussen het einde van de eerste afspraak en het begin van de volgende moet dus minstens zo lang zijn als de langste van de twee buffers:
ruimte tussen afspraken ≥ max(buffer A, buffer B)
Het is de grootste van de twee, omdat twee planningsstappen een verschillende buffer kunnen hebben. Versleep hieronder de duur en de buffers, en kijk waar de volgende afspraak kan beginnen.
ruimte tussen afspraken ≥ max(buffer A, buffer B)
30 min ≥ max(10, 10) = 10 min
De volgende lead krijgt 10:00 voorgesteld. Tussen het einde van de afspraak van de eerste lead en het begin van de volgende is er 30 minuten ruimte, en de langste van de twee buffers is 10 minuten. Een afspraak om 09:30 laat maar 0 minuten ruimte over, minder dan 10, dus die zou worden geweigerd.
De duur telt op dezelfde manier mee. Een planningsstap kan diensten van verschillende lengte aanbieden. Zolang de lead nog geen dienst heeft gekozen, houden we in de agenda genoeg tijd vrij voor de langste dienst. Met een dienst van 30 en een van 90 minuten schuift de volgende lead zo op naar 11:00. Na de keuze passen we dat tijdvak aan de duur van de gekozen dienst aan. De picker controleert op botsingen met afspraken en met de reserveringen van andere leads, en reserveert het eerste tijdstip dat erdoor komt:
# Kies één tijdstip om een lead voor te stellen, en reserveer het.
function offerTime(lead):
for time in openTimes(after: now + minimumNotice):
if clashes(time, meetings): continue
if clashes(time, holdsOfOtherLeads): continue
hold(time, lead, until: earliest(now + holdLength, time − minimumNotice))
return time
# Elk open tijdstip is gereserveerd: stel toch het vroegste voor, zonder reservering.
return firstOpen(openTimes, ignoring: holds)
# Twee afspraken botsen als de ruimte tussen het einde van de ene en het begin van de andere te klein is.
function clashes(a, b):
return gap(a, b) < max(a.buffer, b.buffer)
Wanneer een reservering niet meer telt
Een reservering telt alleen zolang het gesprek bij de planningsstap is. Een gesprek dat eindigt of doorgaat naar de volgende stap, blokkeert het tijdstip niet meer, dus geen enkele uitweg uit die stap hoeft eraan te denken om zelf op te ruimen. Heeft iemand van je team een gesprek overgenomen, dan kan het gereserveerde tijdstip ook aan andere leads worden voorgesteld, en een tijdstip dat de lead afwijst, is op dat moment weer beschikbaar.
Voordat de assistent een gereserveerd tijdstip opnieuw voorstelt, toetst hij het aan dezelfde regels als een boeking. Werktijden kunnen veranderen, er kan een dag worden geblokkeerd, of iemand plant met de hand een afspraak in. Past een tijdstip niet meer, dan laat de assistent het los en stelt hij de lead een ander voor. Met een laat ja gaat het andersom. Zegt een lead drie uur later ja en is het tijdstip nog vrij, dan krijgt hij datzelfde tijdstip. De assistent stapt niet over op een nieuw tijdstip, want de lead zei ja tegen dat ene tijdstip, en niet tegen wat er nu toevallig vrij is.
Tests blijven hier helemaal buiten. Een testgesprek in de flowbuilder neemt nooit het tijdstip van een echte lead in, en een testboeking nooit het gereserveerde tijdstip van een echte lead.
De race condition in ons boekingssysteem
Deze kwamen we onderweg tegen, en het is het schoolvoorbeeld van een dubbele boeking: twee boekingen voor hetzelfde lege tijdslot op hetzelfde moment konden allebei slagen. De controle vóór een boeking zette een lock op de afspraken die al in dat tijdslot stonden, en een leeg tijdslot heeft er geen, dus er viel niets te locken. Beide boekingen controleerden, zagen allebei niets en sloegen allebei een afspraak op. Onze AI-queue draaide op twee workers, dus twee keer ja kon echt op hetzelfde moment worden verwerkt, en de tabel met afspraken had geen constraint die het opving.
We hebben dat gat gedicht terwijl we de reserveringen bouwden. Een tijdstip kiezen en een afspraak inplannen gebruiken nu dezelfde lock, één per account, dus de tweede boeking wacht tot de eerste klaar is en vindt die afspraak. De assistent stelt de tweede lead daarna een ander tijdstip voor. Lukt het niet om de lock te krijgen, dan gaat de boeking door zoals vroeger, want het ja van een klant mag nooit mislukken door onze cache. Doorloop het hieronder stap voor stap, eerst zonder de lock en dan met.
- 09:00 Anouk
Stap 7 van 7
Met de lock wachtte Brams boeking, vond daarna Anouks afspraak en werd geweigerd. De assistent stelde Bram 10:00 voor, het volgende vrije tijdstip.
Wat je in Send4 ziet
Gereserveerde tijdstippen staan in de Send4-agenda als gearceerde blokken met “Offered to …”, naast de belafspraken die al zijn ingepland. Het zijn geen afspraken en ze tellen ook niet als afspraken, en klik je erop, dan open je het gesprek.
Hoelang een tijdstip gereserveerd blijft, stel je per planningsstap in. In het helpcentrum lees je hoe: hoe voorgestelde tijdstippen worden gereserveerd.
Wat een reservering niet doet
Een reservering is niet bindend, dus twee leads kunnen nog steeds botsen als de een vraagt om het tijdstip dat voor de ander is gereserveerd. Het is geen garantie. Een reservering kent ook alleen de Send4-agenda. Kijkt de assistent in de eigen agenda van de verkoper voordat hij een tijdstip voorstelt?
Nog niet. Afspraken komen in de Send4-agenda.
Beschikbaarheid per verkoper is er evenmin: elke planningsstap stelt de tijdstippen voor die vrij zijn in die ene Send4-agenda. En een grote golf leads kan een hele ochtend met reserveringen vullen, zodat latere leads de middag of de volgende dag voorgesteld krijgen. Gebeurt dat, maak de reservering op die planningsstap dan korter.
Plan je belafspraken met leads, lees dan hoe salesafspraken inplannen met Send4 werkt: de assistent stelt jouw vragen, reserveert een tijdstip en plant de belafspraak in, allemaal in hetzelfde gesprek.
Vragen
Wat is een dubbele boeking?
Twee afspraken op hetzelfde tijdstip, of twee mensen die allebei te horen krijgen dat hetzelfde tijdstip van hen is. Beantwoordt een AI-assistent veel leads tegelijk, dan komt de tweede soort het vaakst voor, omdat iedereen het vroegste vrije tijdstip voorgesteld krijgt.
Hoe vermijd je dubbele boekingen?
Reserveer een tijdstip zolang je het voorstelt, houd buffertijd tussen afspraken en controleer het tijdstip opnieuw als iemand ja zegt. De AI-assistent van Send4 reserveert elk tijdstip dat hij voorstelt standaard twee uur, zodat de volgende lead het volgende vrije tijdstip krijgt.
Wat is een voorlopige reservering?
Een tijdstip dat voor iemand wordt vrijgehouden terwijl die beslist, zonder dat het al is ingepland. Bij Send4 is zo’n reservering niet bindend. Zolang er een vrij tijdstip zonder reservering is, slaat de assistent tijdstippen over die voor andere leads zijn gereserveerd. Is elk vrij tijdstip gereserveerd, dan stelt hij het vroegste voor zonder een nieuwe reservering te maken. Een lead die om precies een gereserveerd tijdstip vraagt, kan het toch inplannen, en wie als eerste bevestigt, krijgt het.
Waarvoor dient buffertijd tussen afspraken?
Buffertijd laat ruimte na de ene afspraak voordat de volgende kan beginnen. In Send4 is dat standaard 10 minuten. Bij twee gereserveerde tijdstippen is de tijd tussen het einde van de eerste afspraak en het begin van de volgende minstens zo lang als de langste van hun twee buffers.
Kan AI afspraken maken?
Ja. De AI-assistent van Send4 plant belafspraken in via sms, of via e-mail met het Business-abonnement, en zet ze in de Send4-agenda. Elk tijdstip dat hij voorstelt, blijft gereserveerd terwijl de lead beslist.
Wat is het verschil tussen een AI-assistent en een online afsprakensysteem?
In een online afsprakensysteem kiest de klant zelf een vrij tijdstip in een agenda. De AI-assistent van Send4 beantwoordt de aanvraag per sms, of per e-mail in het Business-abonnement, vraagt wat jij wilt weten en stelt één tijdstip voor. Dat tijdstip blijft gereserveerd terwijl de lead beslist, en de ingeplande belafspraak komt in de Send4-agenda.
Werkt Send4 met Google Meet of Microsoft Teams?
Nog niet. Het gesprek wordt in Send4 ingepland, en de link stuur je zelf.
Kijkt de assistent in mijn eigen agenda voordat hij een tijdstip voorstelt?
Nog niet. Afspraken komen in de Send4-agenda.
Komen gereserveerde tijdstippen in mijn agenda?
Nee. Een reservering bestaat alleen in Send4. Ze staat in de Send4-agenda als een gearceerd blok, en ze is geen afspraak.
Viktoras Lava
CTO
Viktoras bouwt het product van Send4. In september 2026 zette hij het reserveren van voorgestelde tijdstippen live.