Calendly doesn't want you to know your calendar is an API
Booking tools rent you back your own data. Mine reads iCloud over CalDAV, prices bots out in layers, and attacks itself on every deploy.
The Hook
Every “book a call” button on the internet runs through somebody else’s server. Calendly’s Standard plan is $12 a month, $144 a year, and the thing it sells is a fact you already own: when you are free. That fact lives in the calendar your phone syncs before breakfast. The button on my site now points at a Rust server on a box I was already paying for. Calendly gets nothing.
The Context
The protocol underneath is CalDAV, calendar data over plain HTTP, and every serious calendar host speaks it: iCloud, Google, Fastmail. You authenticate with an app-specific password, ask for the events in a window, and compute the gaps yourself. One quirk: iCloud rejects the free-busy query, the one verb in the spec designed for exactly this job, so my server fetches expanded events and derives the busy intervals on its own. Subtract those from working hours, then apply house rules: 30-minute slots, a 15-minute buffer after every meeting, an hour of travel padding around in-person ones, 12 hours of minimum notice, at most two bookings a day, 21 days out. That is the entire product. The rest of a booking tool is a form, an email, and an .ics invite.
I got one thing wrong on the way in. I wanted the browser to be the only way to book, and there is no such thing. The page is a client of an HTTP API, and anyone with curl is the same client wearing no costume. What exists instead of a wall is a stack of tolls: a honeypot field no human ever sees, Cloudflare Turnstile (a bot check that stays invisible unless it doubts you), five booking attempts per IP per quarter hour, and a web server that only answers to Cloudflare’s own addresses. None of these stops a determined attacker. Each one prices out a lazier one.
You cannot make the browser the only door. You can make every other door expensive.
The Approach
My favourite part is not the server. It is the deploy, which attacks its own production service on every push before calling itself green. First the workflow asks the freshly started service for free slots, and a good answer proves the whole read path in one stroke: the config, the CalDAV login against iCloud, the event expansion, the slot maths. Then it turns hostile. It tries to book a meeting without the bot-check token, and the deploy only passes if production refuses with a 403, the status code for “forbidden”. Two quieter checks close it out: the bookings database must sit on the persistent volume, where a redeploy cannot erase it, and the service must be listening on the loopback address only, invisible from the open internet.
The hostile probe is the one that matters. A health check that asks “are you up?” passes on the day you accidentally ship the bot gate disabled. A health check that tries to book without the token fails that deploy on the spot, which is the only moment anyone is looking.
The Takeaways
- Read your own calendar. CalDAV is HTTP plus an app-specific password, no vendor in between. The one quirk to know up front: iCloud refuses the free-busy query, so fetch expanded events and compute the gaps yourself.
- Price bots out instead of locking them out. An API open to your booking page is open to curl. Each cheap layer removes one class of abuser; the honest goal is cost, not impossibility.
- Make the deploy attempt the forbidden action. Asserting a 403 on every push is the cheapest security regression test you will ever write.
- Own the whole funnel. Page, calendar read and write, confirmation email, invite file, reminders: one server, already paid for, and the $144 a year stays home.
The booking system was the detour. The main plot is still whether Polymarket can be traded systematically, and the next post goes back to the market.
Get the next episode first
Every week: the progress unfiltered, plus what I can't post publicly. The build, the number, green or red.