curl --request POST \
--url https://api.meetingkit.com/api/v1/calendar_events \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"workspace_id": "wks_01k6a2r9s8x7c2dvq3m5n6p4ab",
"member_email": "laia@gurusup.com",
"event": {
"kind": "calendar#event",
"id": "7kq2abc_20260929T090000Z",
"iCalUID": "7kq2abc@google.com",
"recurringEventId": "7kq2abc",
"originalStartTime": {
"dateTime": "2026-09-29T09:00:00Z"
},
"status": "confirmed",
"summary": "Weekly sync with Acme",
"start": {
"dateTime": "2026-09-29T11:00:00+02:00",
"timeZone": "Europe/Madrid"
},
"end": {
"dateTime": "2026-09-29T11:30:00+02:00",
"timeZone": "Europe/Madrid"
},
"hangoutLink": "https://meet.google.com/abc-defg-hij",
"organizer": {
"email": "marc@gurusup.com"
},
"attendees": [
{
"email": "laia@gurusup.com",
"responseStatus": "accepted"
},
{
"email": "ana@acme.com",
"responseStatus": "needsAction"
}
]
}
}
'{
"id": "cev_01k6a2r9s8x7c2dvq3m5n6p4ab",
"object": "calendar_event",
"meeting_id": "mtg_01k6a2r9s8x7c2dvq3m5n6p4ab",
"ical_uid": "7kq2abc@google.com",
"recurring": true,
"title": "Weekly sync with Acme",
"starts_at": "2026-09-29T09:00:00Z",
"ends_at": "2026-09-29T09:30:00Z",
"meeting_url": "https://meet.google.com/abc-defg-hij",
"organizer": {
"name": "Marc",
"email": "marc@gurusup.com",
"member_id": "mem_01k69x9s8x7c2dvq3m5n6p4ab"
},
"attendees": [
{
"name": "Marc",
"email": "marc@gurusup.com",
"member_id": "mem_01k69x9s8x7c2dvq3m5n6p4ab",
"response": "accepted"
},
{
"name": "Laia Puig",
"email": "laia@gurusup.com",
"member_id": "mem_01k69x2m4q8r7t6v5w4x3y2z1a",
"response": "accepted"
},
{
"name": null,
"email": "ana@acme.com",
"member_id": null,
"response": "needs_action"
}
],
"source": "calendar_sync",
"metadata": {
"gurusup_event_id": "evt_311"
},
"cancelled_at": null,
"created_at": "2026-09-22T08:00:00Z",
"updated_at": "2026-09-28T17:12:03Z"
}{
"errors": [
{
"code": "invalid",
"field": "recording.methods.bot.mode",
"message": "must be one of: audio_and_video, audio_only, inherit"
}
]
}{
"errors": [
{
"code": "invalid",
"field": "recording.methods.bot.mode",
"message": "must be one of: audio_and_video, audio_only, inherit"
}
]
}{
"errors": [
{
"code": "invalid",
"field": "recording.methods.bot.mode",
"message": "must be one of: audio_and_video, audio_only, inherit"
}
]
}{
"errors": [
{
"code": "invalid",
"field": "recording.methods.bot.mode",
"message": "must be one of: audio_and_video, audio_only, inherit"
}
]
}{
"errors": [
{
"code": "invalid",
"field": "recording.methods.bot.mode",
"message": "must be one of: audio_and_video, audio_only, inherit"
}
]
}{
"errors": [
{
"code": "invalid",
"field": "recording.methods.bot.mode",
"message": "must be one of: audio_and_video, audio_only, inherit"
}
]
}Push a calendar event
For partners that sync calendars themselves. Send each event as your calendar provider
returned it — a Google Calendar event, a Microsoft Graph event or a Nylas event — or in
the small shape, and get back the calendar event of that occurrence (source: calendar_sync),
with the meeting_id of its meeting.
We read the title, times, organizer, attendees with their response, and the meeting
link (from the conferencing fields, or found in the location or description).
- Identity. An event is its iCal UID plus, for an occurrence of a recurring event,
its original start. Push the same event again to update it; push it for every member
who has it and they share one meeting and one bot. Send a stable
iCalUID. - Owner.
member_emailcreates the member the first time, asPOST /membersdoes;member_idnames an existing one. - Recurring events. Push each occurrence (Google instances, Graph occurrences, Nylas instances). A series master, with the repeat rule itself, is refused.
- Cancelling. Push the event as your provider reports it cancelled
(
status: cancelled, including Google’s{ id, status }deletions, Graph’sisCancelledor@removed,cancelled: truein the small shape). The meeting is cancelled once no member of the workspace still has the event; pushing it live again brings it back. - Past events are kept, with their people, as past meetings. No bot is sent.
- No link. The meeting exists and
settings.sources["recording.enabled"].reasonisno_meeting_urluntil a push carries one. Only Google Meet, Zoom and Microsoft Teams links count; any other link (Webex, a dial-in page) reads as no link.
Whether a meeting is recorded follows the member’s settings; change one meeting with a
meeting: settings assignment. A member who also connects the same calendar sees each
meeting twice: use one calendar source per workspace.
curl --request POST \
--url https://api.meetingkit.com/api/v1/calendar_events \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"workspace_id": "wks_01k6a2r9s8x7c2dvq3m5n6p4ab",
"member_email": "laia@gurusup.com",
"event": {
"kind": "calendar#event",
"id": "7kq2abc_20260929T090000Z",
"iCalUID": "7kq2abc@google.com",
"recurringEventId": "7kq2abc",
"originalStartTime": {
"dateTime": "2026-09-29T09:00:00Z"
},
"status": "confirmed",
"summary": "Weekly sync with Acme",
"start": {
"dateTime": "2026-09-29T11:00:00+02:00",
"timeZone": "Europe/Madrid"
},
"end": {
"dateTime": "2026-09-29T11:30:00+02:00",
"timeZone": "Europe/Madrid"
},
"hangoutLink": "https://meet.google.com/abc-defg-hij",
"organizer": {
"email": "marc@gurusup.com"
},
"attendees": [
{
"email": "laia@gurusup.com",
"responseStatus": "accepted"
},
{
"email": "ana@acme.com",
"responseStatus": "needsAction"
}
]
}
}
'{
"id": "cev_01k6a2r9s8x7c2dvq3m5n6p4ab",
"object": "calendar_event",
"meeting_id": "mtg_01k6a2r9s8x7c2dvq3m5n6p4ab",
"ical_uid": "7kq2abc@google.com",
"recurring": true,
"title": "Weekly sync with Acme",
"starts_at": "2026-09-29T09:00:00Z",
"ends_at": "2026-09-29T09:30:00Z",
"meeting_url": "https://meet.google.com/abc-defg-hij",
"organizer": {
"name": "Marc",
"email": "marc@gurusup.com",
"member_id": "mem_01k69x9s8x7c2dvq3m5n6p4ab"
},
"attendees": [
{
"name": "Marc",
"email": "marc@gurusup.com",
"member_id": "mem_01k69x9s8x7c2dvq3m5n6p4ab",
"response": "accepted"
},
{
"name": "Laia Puig",
"email": "laia@gurusup.com",
"member_id": "mem_01k69x2m4q8r7t6v5w4x3y2z1a",
"response": "accepted"
},
{
"name": null,
"email": "ana@acme.com",
"member_id": null,
"response": "needs_action"
}
],
"source": "calendar_sync",
"metadata": {
"gurusup_event_id": "evt_311"
},
"cancelled_at": null,
"created_at": "2026-09-22T08:00:00Z",
"updated_at": "2026-09-28T17:12:03Z"
}{
"errors": [
{
"code": "invalid",
"field": "recording.methods.bot.mode",
"message": "must be one of: audio_and_video, audio_only, inherit"
}
]
}{
"errors": [
{
"code": "invalid",
"field": "recording.methods.bot.mode",
"message": "must be one of: audio_and_video, audio_only, inherit"
}
]
}{
"errors": [
{
"code": "invalid",
"field": "recording.methods.bot.mode",
"message": "must be one of: audio_and_video, audio_only, inherit"
}
]
}{
"errors": [
{
"code": "invalid",
"field": "recording.methods.bot.mode",
"message": "must be one of: audio_and_video, audio_only, inherit"
}
]
}{
"errors": [
{
"code": "invalid",
"field": "recording.methods.bot.mode",
"message": "must be one of: audio_and_video, audio_only, inherit"
}
]
}{
"errors": [
{
"code": "invalid",
"field": "recording.methods.bot.mode",
"message": "must be one of: audio_and_video, audio_only, inherit"
}
]
}Authorizations
Your API key, sent bare. See Authentication.
Body
Exactly one of member_id and member_email.
Workspace ID, beginning with wks_. Treat it as an opaque string. Integer workspace ids are still accepted.
"wks_01k6a2r9s8x7c2dvq3m5n6p4ab"
The event exactly as your provider returned it: a Google Calendar events
resource, a Microsoft Graph event (request it with
Prefer: outlook.timezone="UTC" or an IANA time zone), or a Nylas v3 event (bare, as
data, or as a webhook's data.object). Keys keep your provider's casing. Without a
provider payload, send the small shape (CalendarEventSmall).
An existing member of the workspace.
The calendar owner; created as a member the first time. Disposable-mail and reserved test domains (such as example.com) are refused with 422 invalid.
255Yours, on the calendar event of the occurrence, shared by every member who has it:
merged on every push ("" removes a key, metadata: "" removes them all). Never copied to
the meeting.
Show child attributes
Show child attributes
{ "gurusup_user_id": "usr_8812" }
Response
The calendar event of the occurrence, the same object as the meeting's calendar_event.
Versions before 2026-10-12 return the meeting instead.
One calendar event per occurrence and workspace: every member's copy of it shares this object, as they share the meeting. Its times, link and title are the occurrence's; its people come from the organizer's copy.
Beginning with cev_. One per meeting; stays the same through reschedules and every member's push.
Always calendar_event.
The meeting of this occurrence, beginning with mtg_.
The iCal UID shared by every attendee's copy of the event, or null when the calendar sent none.
Whether the event is an occurrence of a recurring series. null only in a webhook event from before 2026-10-12, which did not record it.
The event title.
Scheduled start, in ISO 8601.
Scheduled end, in ISO 8601.
The link to join the call, or null when the event has none.
Who organizes the event, or null when unknown.
Show child attributes
Show child attributes
Everyone on the invite, the organizer included. Empty once no member has the event.
Show child attributes
Show child attributes
Where the event came from.
calendar_connection: a calendar the member connected.calendar_sync: an event you pushed withPOST /calendar_events.
calendar_connection, calendar_sync Yours; set it with POST /calendar_events. Never copied to the meeting.
Show child attributes
Show child attributes
{ "gurusup_user_id": "usr_8812" }
When the event was cancelled, once no member of the workspace still has it; otherwise null.
When the event first appeared, in ISO 8601.
When the event or its meeting last changed, in ISO 8601.