Skip to content

Integrations

Setupp reads every host’s real calendar. Then writes one event they are all on.

That is the Google Calendar integration in one sentence, and the rest of this page is the detail underneath it: what is live today, what is being built, what has not been started, and exactly which data Setupp touches on the way.

Real free/busy, per host
Every required host is checked against their own calendar before a slot is offered. Not a shared availability guess.
One event, equal attendees
Every host goes on the same event with optional: false. There is no primary host and no notified extras.
Google sends the invite
sendUpdates: "all", so the invitation, every change and the cancellation come from Google itself.

Available now · 7 integrations

What is running in production today.

Live means the code path exists, runs, and is what happens on a real booking. Not a design partner programme, not a waiting list. Everything further down this page is labelled with where it actually stands, which is a shorter list than most integrations pages and a more useful one.

Google Calendar31

Google Calendar

Live

Google LLC · Calendars

Reads every host's real availability and writes one event with all hosts on it as equal attendees.

  • Reads real free/busy for every connected host: a freebusy.query per calendar, on every availability request.
  • Writes one event with every host on it as a full attendee: optional: false, responseStatus: "needsAction", guestsCanSeeOtherGuests: true.
  • sendUpdates: "all", so the invite, every update and the cancellation are delivered by Google, to everyone on the event.
  • Cancelling in Setupp deletes that event and lets Google tell the room.
  • Access tokens refresh 60 seconds before they expire, so a connection does not quietly die mid-week.
A Google Calendar event has exactly one organizer. That is the Calendar API, not a setting anyone can configure away. So Setupp creates the event on one connected calendar and then makes every host, including that one, a full attendee who is actually asked.

src/lib/google/calendar.ts

What Google Calendar accesses
Outlook Calendar

Outlook Calendar

Live

Microsoft Corporation · Calendars

Same equal-invite behaviour for Microsoft 365 and Outlook.com calendars.

  • Reads real free/busy for every connected host through Microsoft Graph's /me/calendar/getSchedule.
  • Writes one event on the connected mailbox with every host as a required attendee and the booker alongside them.
  • A mailbox Graph will not answer for is treated as unknown rather than free, because an empty getSchedule row looks exactly like an open calendar.
  • Times are sent as naive local values with the zone named separately, because sending an offset too makes Graph apply the timezone twice.

Microsoft Graph, through src/lib/microsoft. Free/busy via /me/calendar/getSchedule; one event on the connected mailbox with every host as a required attendee. Requires MICROSOFT_CLIENT_ID, MICROSOFT_CLIENT_SECRET and MICROSOFT_REDIRECT_URI.

What Outlook Calendar accesses
Google Meet

Google Meet

Live

Google LLC · Video conferencing

Generates the meeting link on the calendar event itself, so every host and the booker get the same one.

  • The link is created on the calendar event itself, through conferenceData.createRequest. Hosts and booker read the same URL from the same invite.
  • The conference request id is derived from the booking id, so a retried insert returns the same link instead of minting a second one.
  • Nothing to connect separately. It comes with the Google Calendar connection.

src/lib/google/calendar.ts: conferenceData.createRequest

What Google Meet accesses
Microsoft Teams

Microsoft Teams

Live

Microsoft Corporation · Video conferencing

Teams meeting links generated on the event, alongside Outlook.

  • Requested on the Outlook event itself. No second connection, no second consent screen.
  • A personal Microsoft account cannot grant OnlineMeetings.ReadWrite; the event is created without a link rather than failing the booking.

The same app registration and the same token as Outlook, using isOnlineMeeting plus onlineMeetingProvider on the event body. There is no second consent. A personal Microsoft account cannot grant OnlineMeetings.ReadWrite, so the event is created without a link rather than failing.

What Microsoft Teams accesses
Zoom

Zoom

Live

Zoom Communications, Inc. · Video conferencing

Zoom links created per booking and shared with every host.

  • Connected per host, so the meeting is created on the account of the host who owns the booking.
  • Created before the calendar invite, so the join link is in the invitation rather than a second email.
  • Zoom rotates the refresh token on every use, so Setupp will not refresh one unless it can persist the replacement.
  • Private intake fields are excluded from the meeting agenda.

User-managed OAuth against the Zoom API, in src/lib/zoom. The meeting is created before the calendar invite so the join link is in the invite. Requires ZOOM_CLIENT_ID, ZOOM_CLIENT_SECRET and ZOOM_REDIRECT_URI.

What Zoom accesses
Slack

Slack

Live

Slack Technologies, LLC · Team communication

New bookings posted to a channel with the Setupp Score, so the team sees who's coming.

  • One write-only webhook for a single channel you pick on Slack's own screen. Setupp can read nothing and post nowhere else.
  • Each booking posts the booker, their email and company, the event type and time, and the Setupp Score with its band.
  • Slack answers failures with HTTP 200 and ok: false, so Setupp reads the body rather than the status code.

OAuth v2 with the incoming-webhook scope only. The user picks the channel on Slack's own screen, and the credential can post there and nowhere else. Requires SLACK_CLIENT_ID, SLACK_CLIENT_SECRET and SLACK_REDIRECT_URI.

What Slack accesses
HubSpot

HubSpot

Live

HubSpot, Inc. · CRM

Every confirmed booking becomes a contact, with the intake answers and the Setupp Score attached as a note.

  • Finds the contact by email first, so a returning booker updates rather than duplicating.
  • Attaches a note with the Setupp Score, its reasoning and every non-private intake answer, labelled with the question you wrote.
  • Writes contacts and notes only, never deals, companies or pipeline stages. Setupp does not make decisions about your sales process.
  • Private intake fields are excluded, the same way they are excluded from the model prompt.

OAuth against the HubSpot v3 CRM API, in src/lib/hubspot. Search by email, then create or patch the contact, then attach a note. No deals, no companies, no pipeline stages. Requires HUBSPOT_CLIENT_ID, HUBSPOT_CLIENT_SECRET and HUBSPOT_REDIRECT_URI.

What HubSpot accesses

The difference, in code

Every host is an attendee. Not a person who got notified.

Plenty of schedulers can put several people on a meeting. The question a buyer should ask is what shape that takes on the calendar: one event with equal guests, or one host's event with everyone else CC'd.

src/lib/google/calendar.ts

The attendee list Setupp sends

attendees: [  ...hosts.map((host) => ({    email: host.email,    displayName: host.name,    optional: false,                // every host, no exceptions    responseStatus: "needsAction",  // everyone is asked  })),  { email: booker.email, optional: false },],guestsCanSeeOtherGuests: true, await calendar.events.insert({  conferenceDataVersion: 1,  sendUpdates: "all",             // Google notifies every attendee});
Why it is written this way

A Google Calendar event has exactly one organizer. Any product claiming several is either creating duplicate events on separate calendars, which desynchronise the moment somebody edits one, or it is overstating things. Setupp does neither. One event is created on one connected calendar, and then every host on the booking, including the account that created it, is a full attendee with the same flags as everybody else.

The practical test: nobody is marked optional, nobody is silently auto-accepted into a meeting they never agreed to, and everyone can see who else is in the room.

And when a calendar is not connected

A host without a connected calendar has no real free/busy to check, so Setupp substitutes simulated busy time for them rather than treating them as free all week. That keeps the demo honest, but it means a collective event type is only telling the truth once every required host is connected.

Not live yet

In development

Started, incomplete, and not connectable today. Being specific about what is missing is more useful to you than a logo grid that implies otherwise.

Apple CalendarMON12

Apple Calendar

Building

Apple Inc. · Calendars

iCloud availability and events over CalDAV, with an app-specific password.

Where it stands: The client is written and tested: principal discovery, server-expanded free/busy so recurring events are not missed, event creation with a real organiser so iCloud actually sends the invitations, and a conditional reschedule that will not overwrite an edit made on somebody's phone. What it has not done is talk to a real iCloud account. That happens before it is called live, because a calendar integration that looks connected and reads nothing is worse than one that is honestly absent.

Wanted, not written

On the roadmap

No code exists for any of these. They are here so you can see the intended shape of the product and tell us which one you would actually use, not so the page looks fuller.

Zapier

Zapier

Planned

Zapier, Inc. · Automation

Booking, decline and score events available to 6,000+ apps.

Where it stands: The webhooks it needs now exist. booking.created, booking.cancelled, booking.rescheduled, booking.declined and booking.scored are delivered signed, with retries, on Business. What remains is the Zapier app itself: a published, reviewed integration in their directory. Until then, point a Zap's Catch Hook at a Setupp webhook endpoint and it works today.

What Setupp accesses

The permissions, in plain English and in full.

These are the scopes Setupp asks Google for, written exactly as they appear on the consent screen. If a line here does not match what you are shown when you connect, do not approve it.

IntegrationWhat Setupp reads or writesScopes requested, verbatim
Google Calendar31Google CalendarLiveWhat Setupp reads or writes
  • Free/busy windows for each connected host
  • Events Setupp creates, so it can update or cancel them
  • The account email address, to label the connection
Scopes requested, verbatim
  • https://www.googleapis.com/auth/calendar.events
  • https://www.googleapis.com/auth/calendar.readonly
  • https://www.googleapis.com/auth/userinfo.email
Google MeetGoogle MeetLiveWhat Setupp reads or writes
  • Conference data on events Setupp creates
Scopes requested, verbatim

No additional scopes. Meet links are created on the event through the Google Calendar connection.

Outlook CalendarOutlook CalendarLiveWhat Setupp reads or writes
  • Free/busy windows for each connected host
  • Events Setupp creates
  • The connected account's address, as a label
Scopes requested, verbatim
  • offline_access
  • User.Read
  • Calendars.ReadWrite
  • OnlineMeetings.ReadWrite
Microsoft TeamsMicrosoft TeamsLiveWhat Setupp reads or writes

Nothing. There is no connection to make yet.

Scopes requested, verbatim
  • offline_access
  • User.Read
  • Calendars.ReadWrite
  • OnlineMeetings.ReadWrite
ZoomZoomLiveWhat Setupp reads or writes
  • The connected account's own email address, as a label
  • Meetings Setupp creates
Scopes requested, verbatim
  • meeting:write:meeting
  • user:read:user
SlackSlackLiveWhat Setupp reads or writes
  • Nothing is read from Slack. The install returns one write-only webhook.
Scopes requested, verbatim
  • incoming-webhook
HubSpotHubSpotLiveWhat Setupp reads or writes
  • Contacts, to find an existing one by email before creating a new one
  • Contacts and notes Setupp writes
  • The portal id, used as a label so you can see which HubSpot is connected
Scopes requested, verbatim
  • oauth
  • crm.objects.contacts.read
  • crm.objects.contacts.write

Why calendar.readonly is on the list

Google requires a calendar read scope to answer a free/busy query at all. That is the only reason Setupp asks for it, and the read path calls nothing but freebusy.query, which returns opaque busy windows, never the contents of an event.

Revoking access from your Google Account’s permissions page cuts it off immediately: the next token refresh fails, Setupp stops reading and writing that calendar, and availability falls back to what it does with no connection at all.

What Setupp never does

Never reads what your meetings are about
Availability comes from freebusy.query, which answers with start and end times and nothing else. For any event Setupp did not create, that means no titles, no guests, no descriptions and no attachments.
Never touches an event it did not create
Every event Setupp writes is tagged with extendedProperties.private.setuppBookingId, and updates and cancellations are matched on that id. The rest of your calendar is not Setupp's business.
Never sells, shares or brokers your data
No third party receives your calendar data. It is not sold, not syndicated, and not used as training data.
Never hands a token to the browser
Tokens live in calendar_connections, a table with no row-level-security policy at all, which means the service role is its only reader. No API route returns one and nothing renders one.

Where the data lives

The services Setupp itself runs on.

Not integrations you connect. These are the ones already underneath the product. Security reviewers ask, so they are listed with the same honesty as everything else.

Supabase

Supabase

Live

Supabase Inc. · Infrastructure

Postgres database and authentication, with row-level security.

  • Postgres with row-level security enabled on every table that holds workspace data.
  • calendar_connections is the deliberate exception: no policy at all, so anon and authenticated cannot read tokens even by accident.
  • The schema is checked in, at supabase/migrations/0001_init.sql, so a security reviewer can read it rather than take our word for it.

supabase/migrations/0001_init.sql

Read the detail
Resend

Resend

Live

Resend, Inc. · Infrastructure

Transactional email for confirmations, reminders and cancellations.

  • Delivers confirmations, reminders and cancellations. Recipient, subject and body pass through Resend to reach an inbox.
  • With no key configured, messages are rendered in full and logged instead of sent, so nothing silently disappears in development.

src/lib/email/send.ts

Read the detail
Anthropic

Anthropic

Live

Anthropic PBC · Infrastructure

Generates the Setupp Score's reasoning. Falls back to a deterministic rules engine if unavailable.

  • Receives the intake answers used to write the Setupp Score's reasoning.
  • Intake fields marked private are excluded from the model prompt and from the rules engine's signals. Asking a sensitive question does not make it AI context.
  • If the model is unavailable, a deterministic rules engine produces the score instead and the booking records model: "rules".

src/lib/scoring/ai.ts

Read the detail

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

Google Calendar, Google Meet, Outlook, Microsoft Teams, Zoom, Apple Calendar, Slack, HubSpot and Zapier are trademarks of their respective owners, and logos are used to identify the services Setupp connects to. Calendly is a trademark of Calendly, Inc., named only to identify the product being compared. Setupp is not affiliated with, endorsed by, or sponsored by any of them.