Skip to content

Calendar API

All endpoints require authentication and calendar tool permissions. Calendar events are fetched from Google Calendar via service account delegation, combined with synthetic events from Nucleus data.

GET /api/calendar/calendars

Permission: calendar / view

Returns the user’s primary Google Calendar and the shared Tribe calendar.

Response: { calendars }

Returns { calendars: [] } if Google Calendar is not configured.

GET /api/calendar/events

Permission: calendar / view

Query parameters:

ParamTypeDescription
timeMinstringStart of date range (ISO 8601, required)
timeMaxstringEnd of date range (ISO 8601, required)
calendarIdsstringComma-separated calendar IDs (default: primary)

Response: { events }

Events include both Google Calendar events and synthetic events based on user settings:

Synthetic TypeSourceColor
birthdayUsers with date_of_birthbanana
anniversaryUsers with start_datesage
leaveApproved leave requestspeacock
public_holidayPublic holidays tabletomato
new_starterUsers starting in rangebasil
culture_eventConfirmed/planned eventsgrape

Each synthetic event type can be toggled via calendar settings.

POST /api/calendar/events

Permission: calendar / update

Creates a Google Calendar event.

Request body:

FieldTypeDescription
calendarIdstringTarget calendar ID (required)
summarystringEvent title
descriptionstringEvent description
locationstringEvent location
startobject{ dateTime?, date?, timeZone? }
endobject{ dateTime?, date?, timeZone? }
attendeesarrayOptional list of { email, displayName? } invitees. Google sends invite emails (sendUpdates=all)

Response: { event } (201)

On error, the worker returns { error, detail } where detail carries the underlying Google API message (e.g. "insufficient permissions"). Surfaces in the toast on the create form.

PUT /api/calendar/events/:calendarId/:eventId

Permission: calendar / update

Fully updates a Google Calendar event.

Path parameters:

ParamTypeDescription
calendarIdstringCalendar ID
eventIdstringEvent ID

Request body:

FieldTypeDescription
summarystringEvent title
descriptionstringEvent description
locationstringEvent location
startobject{ dateTime?, date?, timeZone? }
endobject{ dateTime?, date?, timeZone? }
attendeesarrayOptional { email, displayName? } list. Replaces the full attendee list — pass everyone you want kept

Response: { event }

PATCH /api/calendar/events/:calendarId/:eventId

Permission: calendar / update

Partially updates a Google Calendar event (e.g. move time via drag-and-drop).

Path parameters:

ParamTypeDescription
calendarIdstringCalendar ID
eventIdstringEvent ID

Request body:

FieldTypeDescription
startobject{ dateTime?, date?, timeZone? }
endobject{ dateTime?, date?, timeZone? }

Response: { event }

DELETE /api/calendar/events/:calendarId/:eventId

Permission: calendar / update

Path parameters:

ParamTypeDescription
calendarIdstringCalendar ID
eventIdstringEvent ID

Response: { ok: true }

POST /api/calendar/events/:calendarId/:eventId/respond

Permission: calendar / update

Updates the calling user’s responseStatus on a Google Calendar event. The worker fetches the existing attendee list, replaces only the matching attendee’s status, and PATCHes back with sendUpdates=all so the organiser sees the response.

Also upserts a row into calendar_invite_seen so the next pass of the invite-scan cron does not re-fire a meeting_invited notification for this event.

Path parameters:

ParamTypeDescription
calendarIdstringCalendar ID
eventIdstringEvent ID

Request body:

FieldTypeDescription
statusstringOne of accepted, declined, tentative

Response: { event }

GET /api/calendar/places

Permission: calendar / view

Searches for locations using Nominatim (OpenStreetMap) for the event location picker.

Query parameters:

ParamTypeDescription
qstringSearch query (min 2 characters)
tzstringUser timezone (used to bias results to country)

Response: { results } — array of { id, label } objects (up to 5).

GET /api/calendar/settings

Permission: calendar / view

Returns the user’s calendar display preferences.

Response: { settings }

Default settings include default_view: "month", all synthetic event toggles enabled, and show_weekends: 0 (weekends hidden — month and week views render Mon–Fri only until the user opts in).

SettingTypeDescription
default_viewstringCalendar view (month, week, day)
visible_calendar_idsstringJSON array of visible calendar IDs
show_birthdaysnumberShow birthday events (0/1, default 1)
show_anniversariesnumberShow work anniversary events (0/1, default 1)
show_leavenumberShow approved leave (0/1, default 1)
show_public_holidaysnumberShow public holidays (0/1, default 1)
show_new_startersnumberShow new starter events (0/1, default 1)
show_eventsnumberShow culture events (0/1, default 1)
show_weekendsnumberShow Saturday/Sunday columns in month/week views (0/1, default 0)
viewed_person_idsstringJSON array of person IDs to filter by
PUT /api/calendar/settings

Permission: calendar / update

Saves the user’s calendar preferences. Uses upsert.

Request body: Same fields as the settings response (with arrays as native arrays, not JSON strings).

Response: { ok: true }