Skip to main content
If your product already syncs calendars through Google, Microsoft Graph or Nylas, you don’t need your users to connect theirs a second time. Forward each event you receive to MeetingKit, as it is. Every push creates or updates one meeting with source: "calendar_sync". Push events or connect calendars, not both, in one workspace: see How meetings get in.

Push an event

Send the event exactly as your provider gave it to you, with the member it belongs to:
The response is 200 with the calendar event: the occurrence as MeetingKit sees it, with its cev_ id and the meeting_id of the meeting it belongs to: one per meeting, shared by every member who has the event. Add a top-level metadata to keep your own ids on it; it is merged on every push. Whether a bot joins follows the member’s recording choices.
  • Pass member_email or member_id, not both. An email that is not a member yet creates one, invisibly. Members created this way count toward the limit of 100 new members an hour per workspace.
  • The request is at most 64 KB. The event’s description is used only to find the meeting link and is never stored.

Accepted events

Without a provider, send the minimal shape instead:
ical_uid is required: if your events have none, send any string that is stable and unique per event. Times without an offset are read as UTC. An event with no end lasts 30 minutes; an all-day Nylas event lasts the day.

When events change

Push the event again every time your provider tells you it changed. Each push replaces the member’s copy of the event.
  • Rescheduled or new link: the meeting keeps its mtg_ id, and its bot moves.
  • Colleagues on the same call: push each member’s copy. Copies with the same iCal UID land in one meeting, with one bot.
  • Retries and backfills: pushing the same event again is safe.
  • Past events: accepted. They become past meetings with their participants, and no bot is sent.
  • No meeting link: the meeting exists, with recording off (settings.sources["recording.enabled"].reason: "no_meeting_url") until a push brings a link. Only Google Meet, Zoom and Microsoft Teams links count: a Webex or other link reads as no link.

Recurring events

Push each occurrence separately. Series masters aren’t supported yet: one is refused with 422 recurring_series_not_supported. Providers expand occurrences for you (Google singleEvents=true, Graph calendarView, Nylas expand_recurring).
An occurrence that was moved must keep its original start: originalStartTime in Google, originalStart in Graph, original_start_time in Nylas, or original_starts_at in the minimal shape. Without it, the moved occurrence becomes a second meeting.

Cancelled events

Push the cancelled event: Google status: "cancelled" (the bare { "id", "status": "cancelled" } Google sends for a deleted event works), Graph isCancelled: true or a delta @removed, Nylas status: "cancelled" or an event.deleted webhook, or cancelled: true in the minimal shape. The member’s copy is removed. When no member of the workspace still has the event, the meeting moves to phase: "cancelled", the calendar event gets its cancelled_at, and its bot is cancelled. Pushing the event again, live, brings it back.

Errors and limits