shouldivibecodeit

Should I vibe codeSavvyCal?

Scheduling links with overlay calendars and nicer booking UX

The overlay is the product. Drawing it means holding a stranger's calendar credential, for the sake of a nicer grid.

?

Their verdict, the Basic price and the build-time estimate come from their entry, MIT-licensed. Checked 2026-08-04.

Can you build it?asked by canivibecodeit.com ↗KINDAweekend project · weekend
?

Our verdict, the regret score and everything below it. Editorial and unsponsored — nobody can pay to be moved.

Should you ship it?asked by usYOUR FUNERALit’ll work. then it’ll get you.

The honest answer

why the verdict is what it is

SavvyCal's signature move is that the person booking you can lay their own calendar over your availability grid and see the overlap at a glance. It is a lovely idea, and it is the reason this entry is yellow rather than blue. To draw that overlay your server has to read a stranger's calendar, which means one of two things: an OAuth grant from someone who is not your customer, or a secret iCal feed URL they paste in. Both are bearer credentials for a person's entire schedule — the ICS variant especially, because those links carry no expiry, no scope and no revocation short of the owner regenerating them, and yours will land in a bookers table as a plain string, because that is exactly what it looks like. Everything else here is the ordinary scheduling grind the Calendly and Appointlet entries already document, and it is real. But the overlay is the feature you are copying, and copying it turns a booking page into a small custodian of other people's calendars. That is a different job from the one you thought you were signing up for.

What actually breaks

not "if". the specific failures.

  • The overlay credential, which is the whole point of the product: an OAuth grant or a secret ICS URL belonging to someone who is not your user, sitting in your database with no expiry you control
  • Free/busy caching, which is the obvious performance fix and quietly converts "read their calendar during a booking" into "keep a copy of their week"
  • The gap between rendering a slot as free and writing the event, where two people who loaded the page eleven seconds apart both take 10:00
  • Reminders, which live in a cron job on a box that will restart during a deploy and take Tuesday's reminders with it
  • The public booking endpoint, which is an unauthenticated write to your own week — bots find those and fill it with test entries
  • Meeting titles, the most quietly revealing field in anybody's calendar, which the overlay pulls down alongside the times
  • Round robin, once it is distributing meetings to colleagues who never read your code and cannot see why they got four in a row
  • Paid bookings, where a scheduling bug stops being an apology and becomes a refund
and then, at 3am

It surfaces during a security questionnaire, of all places. A prospect's IT reviewer asks a routine question — what third-party calendar data do you store, and for how long — and you go looking, because the honest answer is that you have never thought about it. What you find is a table with four hundred and ten rows. Every one belongs to somebody who opened your booking link over the past year and clicked the button that overlays their calendar on yours, and every row holds the token or the feed URL that made the overlay work, plus a cached blob of their free/busy for the week they were looking at, because caching it was the obvious fix when the page felt slow. Eleven of those rows belong to people at the company now asking. None of them consented to storage; they consented to a picture. There is no expiry job, because you never wrote one, and no delete endpoint, because nobody had ever asked. The questionnaire wants a retention period. You are now writing a deletion script and a privacy notice on a Wednesday afternoon, for a feature you added because it looked nice.

Is that you?

the verdict is a default, not a law

ship it if
  • It is one link, for you, showing your own availability, with no overlay of anybody else's calendar
  • Bookings land in a calendar you own and the confirmation is an ICS attachment rather than a write into the invitee's calendar
  • You are content for the failure mode to be "the page is down and someone emails you instead"
  • Nothing is charged at the point of booking
don’t ship it if
  • You are copying the overlay, which means holding calendar credentials belonging to people who never signed up for anything
  • It routes to colleagues, because a routing bug is invisible: the form says thank you and nobody is assigned
  • It takes payment at booking, which turns every timezone bug into a refund and a support conversation
  • Your reminders are a cron job with no delivery record and no retry
  • The booking endpoint is public and you have not thought about rate limits, because it is an unauthenticated write to your week

If you build it anyway

the checklist, then the prompt that enforces it

  1. Do not store the overlay. Read the invitee's free/busy inside the request that renders the page, use it, throw it away — no cache, no row, no token at rest. If that is too slow, the honest fix is a narrower window, not a database table.
  2. If a credential must persist, make it expire by construction: a short-lived token, a deletion job that runs whether or not anyone asks, and a visible disconnect control on the booking page itself.
  3. Never treat an ICS feed URL as configuration. It is a bearer credential for an entire calendar, it does not expire, and it belongs in the same bucket as an API key.
  4. Close the race properly. Put a unique constraint on organiser plus start time and create the real calendar event inside the transaction that claims the slot — not after it, and not in a background job.
  5. Store every time as UTC plus the IANA zone the user chose, and compute local times at render. Recurring availability held as local wall-clock strings is why meetings move by an hour twice a year.
  6. Rate-limit and CAPTCHA the create endpoint before you share the link anywhere public. A booking form is an unauthenticated write and bots treat it as one.
  7. Make reminders durable: a queue with retries and a per-booking delivery record, not a cron job whose failure mode is silence.
  8. Publish what you keep. One paragraph on the booking page saying what is read, whether it is stored and for how long costs nothing and is the difference between a nice feature and a surprise.
the guardrail prompt
I am building a scheduling link with a calendar overlay — the invitee can see
their own events on top of my availability. Treat other people's calendar data
as the most sensitive thing in the system and build in this order.

1. Before any overlay code exists, write down where invitee calendar data lives
   and for how long. The default answer is nowhere, and zero seconds: read it
   inside the request that renders the grid and discard it.
2. Refuse to add a free/busy cache table. If I ask for one because the page
   feels slow, push back and narrow the query window instead.
3. If an ICS feed URL is involved, treat it as a bearer credential for the
   owner's whole calendar. Never log it, never put it in a URL you emit, and
   give it a hard expiry and a delete endpoint in the same commit.
4. Build the slot race before the UI. Unique constraint on organiser plus start
   time, and create the real calendar event inside the transaction that claims
   the slot. Show me two concurrent bookings failing correctly.
5. Store every timestamp as UTC plus the IANA timezone identifier the user
   picked. Availability rules are local wall-clock rules and must be resolved
   at render time, never stored as fixed offsets.
6. Write the DST test first: a recurring 09:00 availability across the last
   Sunday in October, in two zones that change on different dates.
7. Rate-limit and CAPTCHA the create endpoint before the link is shareable. It
   is an unauthenticated write to my week and bots will find it.
8. Reminders go on a durable queue with retries and a per-booking delivery
   record. A cron job whose failure mode is silence is not a reminder system.
9. My own calendar token gets encrypted at rest with a key held outside the
   database, plus a documented revoke path.
10. Put a plain sentence on the booking page saying what is read from the
    invitee's calendar, whether it is stored, and for how long.
11. Out of scope unless I ask explicitly: round robin routing, paid bookings and
    custom domains. Routing fails silently and payments turn every scheduling
    bug into a refund. At $12 a seat a month, say so before I build either.
paste this before you build — not after something breaks31 lines · 2158 chars

That one keeps you out of trouble. For the prompt that actually builds it, canivibecodeit.com has one.

their build prompt ↗

Or don’t build it

the boring option, and the way back out

just pay for it

Almost immediately, and the pricing makes the case. Twelve dollars a user a month buys DST correctness across two calendar providers, a booking flow that thousands of people have already raced simultaneously, reminders that fire when your server does not, and — the part you would most regret rebuilding — a worked-out position on holding invitees' calendar data. Build your own if you want one personal link on your own domain with no overlay and no payments, which is a genuinely nice weekend and a completely different product.

$12/mo is cheaper than your weekend.

your exit plan, if you already built it

The bookings themselves are safe — they are events in a real calendar and they survive your app disappearing. Two things do not. The first is the link: anything printed, embedded in a signature or sitting in a bio needs a redirect you keep alive, so host the booking page on a path you control rather than a domain you might drop. The second is the calendar data you accumulated from other people, which migrates nowhere and should simply be destroyed before you switch off — export nothing, delete the tokens, and revoke the grants from your side so nobody is left with a dangling authorisation to an app that no longer exists.

prior art · someone already did this
Cal.com

Open-source scheduling platform with the booking mechanics, provider integrations and timezone handling already written.

Questions

Is the overlay really the risky part? It is just showing them their own calendar.

It is showing them their own calendar, which is why it feels harmless. The mechanics are what matter: your server cannot draw that grid without reading their events, and it cannot read their events without a credential they handed over. The moment that credential is persisted — and the moment somebody caches free/busy to make the page feel snappier — you are storing third-party calendar data. That is a category of obligation, not a rendering detail.

How is this different from the Calendly and Appointlet entries?

Those cover the shared scheduling problems and cover them well: Calendly on rate-limiting a public availability page, Appointlet on timezone arithmetic going wrong twice a year. Neither holds anything belonging to the person booking. SavvyCal's differentiator is precisely that it does, so this entry is about custody rather than correctness. Read all three if you are actually building one.

What will an agent get wrong here?

It will implement the overlay by storing the invitee's token or feed URL on first use, because that makes the second visit fast and the code simpler. It will then add a free/busy cache when the grid feels slow, and it will write neither an expiry nor a delete path, because nothing in the requirement mentioned either. The result works perfectly and accumulates a table you would rather not describe to anyone.

Can I keep the nice booking experience without the risk?

Mostly, yes. The high-fidelity week view, the sensible defaults and the preferred slots are all rendering, and they are the parts people compliment. The overlay is the only feature that requires somebody else's data. Ship the week view, skip the overlay, and you keep the compliment and lose the custody problem.

sources
  • GDPR Art. 5 — principles relating to processing, including storage limitation (EU)
  • GDPR Art. 32 — security of processing (EU)
  • Google API Services User Data Policy — restricted scopes and app verification
did you build it?

Every week, someone ships something they shouldn’t have.

New verdicts, the worst thing that landed in the trap, and the occasional incident report. No other email, ever.

also on the regret index
CalendlyDEMO ONLY

A booking link publishes your availability to the internet. Rate-limit it before you share it.

TidyCalDEMO ONLY

TidyCal is twenty-nine dollars once. Yours is a weekend now and a calendar-API migration every spring.

AppointletYOUR FUNERAL

Timezone maths is the product, not a feature. It goes wrong twice a year, silently, in someone else's calendar.

last reviewed 2026-08-05 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice