Calendar booking notifications
When a booking is confirmed, TimeTime can materialize it as an event on one or more third-party calendars (Google Calendar or Microsoft Outlook). The shape of that provider event — title, body, attendees, conference link, color, who gets notified — is controlled per calendar by a calendar booking notification.
This guide walks through the available knobs, how to express common use cases (1-on-1, group events, multi-resource fan-out), and the provider-specific quirks worth knowing.
Where notifications live
A CalendarBookingNotification can be attached to two places:
- Event Type (
eventType.notifications.calendars). Notifications declared here fire on every booking of that event type. - Resource (
resource.bookingNotifications.calendars). When a booking uses that resource, the resource's notifications also fire.
Both lists are merged at booking time. Notifications targeting the same calendar are deduplicated; if the same calendar id appears in both, the Event Type's notification wins.
Anatomy of a notification
There are two variants, picked via the type discriminator. Both share most
fields; only the conference behavior differs.
Google variant
{
"type": "GoogleCalendarEventBookingNotification",
"calendarId": "<google calendar id from /v1/me>",
"overlapMode": "NEW_EVENT",
"addOrganizerAsAttendee": true,
"addAttendees": true,
"guestsCanSeeOtherGuests": true,
"guestNotificationsMode": "ALL",
"extraEmailAttendees": [],
"createGoogleMeetBehavior": {
"mode": "IF_EVENT_NEEDS_AN_ONLINE_CONFERENCE",
"reuseOnlineConferenceIfPresent": true
},
"colorId": null
}
Microsoft variant
{
"type": "MicrosoftCalendarEventBookingNotification",
"calendarId": "<microsoft calendar id from /v1/me>",
"overlapMode": "NEW_EVENT",
"addOrganizerAsAttendee": true,
"addAttendees": true,
"guestsCanSeeOtherGuests": true,
"extraEmailAttendees": [],
"createTeamsMeetingBehavior": {
"mode": "IF_EVENT_NEEDS_AN_ONLINE_CONFERENCE",
"reuseOnlineConferenceIfPresent": true
}
}
Fields, in plain English
| Field | What it controls |
|---|---|
type | Discriminator. Must be the literal GoogleCalendarEventBookingNotification or MicrosoftCalendarEventBookingNotification. |
calendarId | The TimeTime id of the target calendar. Opaque string — fetch from GET /v1/me → thirdPartyCalendars[].id and use verbatim. |
overlapMode | What to do when multiple bookings land on the same slot. See Overlap modes. |
addOrganizerAsAttendee | When false, the organizer's email is omitted from the attendee list. They still own the event. Useful when the calendar owner is a scheduler booking on behalf of others. |
addAttendees | When false, only the organizer ends up on the provider event — every other participant is dropped. This is also the lever to suppress attendee notification emails on Microsoft (Graph has no per-call equivalent of Google's sendUpdates). |
guestsCanSeeOtherGuests | When false, attendees other than the organizer cannot see one another in the event details. Maps to Google's guestsCanSeeOtherGuests (1:1) and to the inverse of Microsoft's event.hideAttendees. |
guestNotificationsMode (Google only) | ALL / EXTERNAL_ONLY / NONE. Routed to Google's sendUpdates query parameter on insert + attendee patches. |
extraEmailAttendees | Additional email addresses always added as attendees to the provider event (assistants, observers, managers cc'd on every booking). |
createGoogleMeetBehavior (Google only) / createTeamsMeetingBehavior (MS only) | Whether and how a Meet/Teams conference is attached. See Conferences. |
colorId (Google only) | Optional Google colorId for the event. null keeps the default color. Microsoft Graph uses categories instead and ignores this field. |
Overlap modes
overlapMode determines what happens when two or more bookings land on the
same slot ((eventTypeId, start, end, calendarId)). This is only possible when
the event type's maxConcurrentBookings > 1.
NEW_EVENT (default)
Each booking creates its own provider event. The events are independent — separate ids, separate titles, separate conference links (Meet/Teams), separate attendee lists.
Use this for 1-on-1 services where each booking is private to its booker.
ADD_NEW_ATTENDEES_TO_EXISTING_EVENT
The slot's first booking creates the provider event. Subsequent bookings on the same slot don't create new events — instead, their attendees are merged into the existing one. All bookings end up sharing a single provider event and a single conference link.
Use this for group events: webinars, group classes, group interviews where candidates shouldn't each get their own meeting URL.
What changes for shared events
Because one provider event backs multiple bookings, TimeTime adjusts how the event is written so the first booker's identity doesn't leak to later attendees:
- The title is just the event-type name (e.g.
"Group Interview"), not"<first-booker> - Group Interview". - The body keeps the generic info (event-type description, location, online conference link) but omits answered-question values, booker notes, and the per-booking management link.
If you also want attendees to be hidden from each other, set
guestsCanSeeOtherGuests: false — see the next section.
Privacy & notifications
| You want… | Set… |
|---|---|
| Attendees not to see one another | guestsCanSeeOtherGuests: false |
| No notification emails to attendees (Google) | guestNotificationsMode: "NONE" |
| No notification emails to attendees (Microsoft) | addAttendees: false (MS Graph has no per-call sendUpdates) |
| Organizer not visible in the attendee list | addOrganizerAsAttendee: false |
| Always-on observers (managers, assistants) | extraEmailAttendees: ["manager@acme.com"] |
Conferences
The createGoogleMeetBehavior.mode / createTeamsMeetingBehavior.mode field
controls when the provider creates an online conference link attached to the
event:
ALWAYS— every booking gets a Meet/Teams link, even in-person bookings.NEVER— never request one. The location's joining URL (if any) is preserved as the event location.IF_EVENT_NEEDS_AN_ONLINE_CONFERENCE— default. Defers to the event type'slocation. ForGoogleMeetLocation,MicrosoftOutlookLocation, or an onlineBookerSelectionLocationanswer, a conference is created. For offlineFixedLocation(e.g. "Conference Room A") it isn't.
reuseOnlineConferenceIfPresent (true by default): when the booking already
carries a conference link from a prior sync target, the adapter reuses that
link instead of creating a new one. This guarantees one conference per
booking across multiple notification targets — without it, a booking with
notifications on both a Google and a Microsoft calendar could end up with two
distinct meeting links.
Picking a calendar id
Calendar ids are stable opaque strings. Don't try to parse, derive, or construct them — fetch from the API and use the value verbatim.
curl -H "Authorization: Bearer $TT_API_KEY" https://api.timetime.in/v1/me
The response contains a thirdPartyCalendars array; each entry has an id plus
human-readable fields (provider, account, name, primary) so you can
identify the calendar you want:
{
"thirdPartyCalendars": [
{
"id": "<opaque calendar id>",
"provider": "MICROSOFT",
"account": "user@example.com",
"name": "Calendar",
"primary": true,
"readOnly": false
}
]
}
Copy the id and use it as the calendarId on the notification.
Worked examples
1-on-1 sales call with Google Meet
{
"name": "30-min discovery call",
"duration": "PT30M",
"step": "PT30M",
"maxConcurrentBookings": 1,
"location": { "type": "GoogleMeetLocation" },
"notifications": {
"calendars": [
{
"type": "GoogleCalendarEventBookingNotification",
"calendarId": "<sales google calendar id>",
"overlapMode": "NEW_EVENT",
"addOrganizerAsAttendee": true,
"addAttendees": true,
"guestsCanSeeOtherGuests": true,
"guestNotificationsMode": "ALL",
"extraEmailAttendees": [],
"createGoogleMeetBehavior": {
"mode": "IF_EVENT_NEEDS_AN_ONLINE_CONFERENCE",
"reuseOnlineConferenceIfPresent": true
}
}
]
}
}
Group interview with Teams (multiple bookings, one event)
{
"name": "Group interview — backend hires",
"duration": "PT1H",
"step": "PT1H",
"maxConcurrentBookings": 8,
"location": { "type": "MicrosoftOutlookLocation" },
"notifications": {
"calendars": [
{
"type": "MicrosoftCalendarEventBookingNotification",
"calendarId": "<recruiter microsoft calendar id>",
"overlapMode": "ADD_NEW_ATTENDEES_TO_EXISTING_EVENT",
"addOrganizerAsAttendee": true,
"addAttendees": true,
"guestsCanSeeOtherGuests": false,
"extraEmailAttendees": [],
"createTeamsMeetingBehavior": {
"mode": "IF_EVENT_NEEDS_AN_ONLINE_CONFERENCE",
"reuseOnlineConferenceIfPresent": true
}
}
]
}
}
What happens: every candidate booking the same slot lands on the same
Outlook event, with the same Teams meeting link, but they can't see each
other in the attendee list. The event title is just "Group interview — backend hires", with no candidate emails.
Tutor + room, each on its own calendar
When an event type uses resources, every resource that participates in the booking contributes its own notifications. Below: a tutoring session needs both a tutor and a room; each is a resource with its own calendar, and the booking fans out to both.
PUT /v1/resources/tutor-alice:
{
"name": "Alice",
"bookingNotifications": {
"calendars": [
{
"type": "GoogleCalendarEventBookingNotification",
"calendarId": "<alice google calendar id>",
"overlapMode": "NEW_EVENT",
"addOrganizerAsAttendee": true,
"addAttendees": true,
"guestsCanSeeOtherGuests": true,
"guestNotificationsMode": "ALL",
"extraEmailAttendees": [],
"createGoogleMeetBehavior": {
"mode": "NEVER",
"reuseOnlineConferenceIfPresent": true
}
}
]
}
}
PUT /v1/resources/room-101:
{
"name": "Room 101",
"bookingNotifications": {
"calendars": [
{
"type": "GoogleCalendarEventBookingNotification",
"calendarId": "<room-101 google calendar id>",
"overlapMode": "NEW_EVENT",
"addOrganizerAsAttendee": true,
"addAttendees": false,
"guestsCanSeeOtherGuests": false,
"guestNotificationsMode": "NONE",
"extraEmailAttendees": [],
"createGoogleMeetBehavior": {
"mode": "NEVER",
"reuseOnlineConferenceIfPresent": true
}
}
]
}
}
When a booking uses both resources, two provider events are created — one on Alice's calendar (with attendees and notification emails) and one on Room 101's calendar (silent, just a placeholder so the room shows as busy). If the event type also declares a notification on the booker's calendar, that's a third target — all three are merged and deduped at dispatch time.
Provider-specific quirks
Microsoft Graph
- No per-call
sendUpdates.guestNotificationsModeis accepted on the Microsoft variant for API symmetry but ignored. To suppress notifications, useaddAttendees: false. guestsCanSeeOtherGuests: falseis implemented by setting Graph'sevent.hideAttendees: true.- No equivalent of Google's
colorId; the field is absent from the Microsoft variant.
Google Calendar
colorIdvalues are documented in Google's colors.get API.guestNotificationsMode = EXTERNAL_ONLYonly sends emails to attendees outside the calendar's owning domain.
Backwards compatibility
The legacy eventType.thirdPartyCalendars field is still honored when
notifications.calendars is empty or absent. Mixing both: when
notifications.calendars is present and non-empty, it takes precedence — the
legacy field is ignored for that event type.
The legacy field is marked deprecated in the API spec; new integrations should
use notifications.calendars exclusively.
Reference
Full JSON schema and inline examples in the
OpenAPI reference
under CalendarBookingNotification, GoogleCalendarEventBookingNotification,
and MicrosoftCalendarEventBookingNotification.