Skip to content
All writing
PrivacyBuying

What to ask a scheduling tool before you connect a calendar

A booking link is an unauthenticated endpoint that reads a real calendar, so here is the security review checklist for one, written by a vendor.

Vedant Kulkarni · 9 September 2026 · 8 min read

Somebody in procurement has sent you a spreadsheet, or you are the one sending it. A scheduling tool wants access to a calendar, and a calendar is one of the most revealing objects a company owns: who met whom, how often, and when it stopped.

This is a checklist for reviewing one, written by a vendor, which you should hold against it. Nothing below is a claim about any other product: every item is about how the category works, about how you check something yourself, or about Setupp, where the answer is in the code. None of it is legal advice.

Start with the mechanism, because the rest follows from it. A booking page has no sign-in. Anyone with the URL can open it, and opening it causes a query against a real calendar belonging to a real person. That is how the category works, and it deserves understanding rather than assuming: the read is triggered by a stranger, and whatever comes back is returnable to anybody who asks.

So the first question is what comes back. A free/busy response is a list of start and end times: busy from 14:00 to 14:30, with no titles, guests, descriptions or locations. A response built from a full calendar read carries all of those, and the tool has to be trusted to strip them. Both render an identical calendar, and only one makes the stripping load bearing.

The second is what happens when the person asking should not see times at all. If a tool puts screening questions in front of the calendar, ask whether the gate is on the page or on the API. Setupp's availability endpoint refuses a gated event type without a short-lived pass the server mints when the answers clear. A gate on the page and none on the API is not a gate.

Every calendar you have seen on a booking page was produced by an unauthenticated request against somebody's real diary. The question is not whether that happens. It is what came back, and who was allowed to ask.

What a calendar scope actually grants

A free/busy read returns opaque busy windows. A full calendar read returns events: titles, guests, descriptions, locations, attachments. That is the difference between knowing somebody's Tuesday afternoon is spoken for and knowing who they spent it with.

The awkward part is that the narrower behaviour often needs a broad-sounding permission anyway. Google will not answer a free/busy query without a calendar read scope, so an application reading only busy windows still asks for something that sounds larger. The check is a comparison, not a reading.

  • The consent screen, which lists every scope requested and is the one screen whose wording the vendor did not write. If it asks for more than the documentation said, stop there.
  • The vendor's own documentation, not its marketing page. A page printing the scopes verbatim, as strings, is one somebody has to keep accurate. "We access only what we need" stays true whatever the code does.

Setupp requests three, printed in full on the integrations page and in the privacy policy: calendar.readonly for the free/busy read, calendar.events for the one event per booking, and userinfo.email to label the connection. They are on both pages as strings, so the consent screen can be checked against something you read first.

The questions worth asking, in the order they get useful

Copy these. The cheap ones come first, and a vendor who cannot answer the first three quickly has told you something before you reach the rest.

  1. Which scopes does the application request, verbatim, and where can I read them without starting an OAuth flow? A verbatim list is a maintenance commitment. A paraphrase is not.
  2. Who else receives this data? Named companies, not categories. "Industry-standard sub-processors" is not a list. Ask for a page, and check whether it carries a date.
  3. Where is the booking data stored, and is it the same region as my calendar? Often not. A transfer is workable when it is disclosed rather than discovered.
  4. What happens to somebody who fills in the form and is turned away? Ask separately about a rejected applicant, a screened-out lead and an abandoned half-filled form.
  5. When an AI or scoring feature is involved, what is in the request? Not "we use AI": a field list, whether the provider trains on it, and what happens when it is unavailable.
  6. Who at the vendor can read my calendar or my bookers' answers, and when? A good answer names the conditions.
  7. What is deleted when I close my account, and what is not? Backups, delivery logs and billing records are the usual survivors. A vendor who can name them has checked.
  8. What certifications do you hold, and what does each cover? Read the scope statement, not the badge. An audit scoped to one product line is not an audit of what you are buying.

The one nobody asks: what is kept about people who did not book

Every checklist covers the customer record. Almost none cover the non-customer, which is where the surprising volume lives. Three groups: whoever abandoned the form halfway, whoever answered honestly and was told they did not qualify, and whoever a scoring feature ranked low so nobody called. All three are rows in most systems, which is rarely a decision anybody made: the row is half written by the time the rules run.

The alternative takes deliberate effort, so it is worth seeing one. Setupp's declined log records that a rule turned somebody away: the workspace, the event type, the ids of the rules that fired, the question keys behind them, and the time. No name, no email, no company, none of the answers.

And no hash of them either. Hashing is not anonymisation when the input space is small: anybody with a list of addresses can hash it too, and a hash works perfectly as a join key. A row you can join to a person is a row about a person. For the same reason there is no IP address on it, no user agent and no session id.

The feature still works, because its job was never to identify anybody. The operator question is "my rules declined forty people this month, thirty-two on the budget question, so is my floor wrong?" Counts and rule ids answer that. Bookers who choose to leave an address go in a different table, because consent is the difference.

The decision, the rules that produced it, and the time. Nothing that identifies the person the decision was about, and not a hash of it either, because a hashed email address is still personal data.

Put this question to a vendor and the answer you want is a description of a table, not a policy commitment. A schema with no column for a name is stronger than a promise never to fill one in.

“Is it GDPR compliant” is the wrong question

It is on most questionnaires, and no vendor can answer it about your use of their product. Compliance is a property of a deployment: what you collect, why, whose data it is, and what you do when somebody asks for it back. There is no certificate behind the phrase either. An organisation can be audited against ISO 27001 or have a SOC 2 report written about it, but nobody hands you a GDPR certificate, and treating a badge as one is how a review ends up satisfied by graphic design.

The answerable version is narrower and more useful. Who else sees this data? It has one correct answer, it is a list, and only the vendor can produce it. What a good one looks like:

  • Named companies, not "our cloud provider". A name withheld as commercially sensitive is itself an answer.
  • On a page, with a date. A list in a sales email was assembled once, for you. A page has to be maintained.
  • Each entry saying what it receives. "Anthropic" tells you nothing. "Anthropic receives the intake answers and the scoring criteria, never the booker's email address or any calendar data" does.
  • Regions stated, transfers included. If you or your bookers are in the UK or the EEA, a vendor who leaves those out is worse than one who names them.

Setupp's list runs to nine services on the privacy policy, each with a line saying what it receives. The database is in Mumbai and several processors work out of the United States, which for a UK or EEA customer is a transfer. Setupp holds no SOC 2 report and no ISO 27001 certificate, and the policy says so in a section of its own.

Your calendar and the tool's database are frequently under different jurisdictions, because they are different systems run by different companies. That is ordinary. Not knowing which ones is the problem.

The trade-offs an honest review has to include

An embed that inherits your design can read your page

There are two ways to put a booking form on your site. An iframe is a second document, isolated in both directions. A script that mounts into your DOM is a guest in your document, and to match your typeface, colours and radius it has to read your computed styles. That is the technique, not a side effect of it.

That is a capability, and it deserves understanding before a script tag goes on a page. Setupp's embed works this way, and what it reads and what it undertakes never to touch is written out in full. If you want isolation rather than inheritance, an iframe is the right answer.

Self-hosting removes a sub-processor and adds a job

Running the software yourself takes a company off the list, a real gain when that company is the objection. What it adds is patching, backups you have restored rather than configured, key rotation and somebody on call when the CVE lands. For many teams that is a worse security position, because the sub-processor was doing that work and now nobody is. Setupp has no self-hosted edition, so discount this paragraph accordingly.

Where Setupp lands is on pages rather than in this paragraph. The privacy policy names what is collected, what each sub-processor receives, and what we decline to claim. The integrations page prints every scope verbatim next to what the code does. Read them, then ask all eight questions anyway. If another vendor answers better, buy theirs.

One last thing, since it is where most of this data comes from. If your booking form asks qualifying questions you have built a collection point, and how much it collects is your choice. Putting the questions in front of the calendar argues for that on sales grounds. The quieter consequence is that fewer people reach the parts of the system that store anything.

Stop taking calls you would have declined.

Connect a calendar, write the five questions you already ask on every call, and set the floor you already have in your head. About twenty minutes. Then never spend another Tuesday afternoon finding out about a mismatch.

One host free, forever. No card, no sales call to get a trial.

What you get on day one
  1. 01Multi-recipient invitesfrom Pro
  2. 02Qualification before the calendarfrom Pro
  3. 03A score on every booking
  4. 04An embed that inherits your brandfrom Pro