Events

Morgen maps Calendar Events from different providers to a common data model, inspired by the JSCalendar standard (opens in a new tab). Some differences with the JSCalendar standard are documented below.

List events

Morgen offers an endpoint to list events from a given calendar. Events are retrieved in a given time window, and recurring events are automatically expanded to their individual occurrences. Deleted or cancelled events are not included in the response.

fetch("https://api.morgen.so/v3/events/list?accountId=<ACCOUNT_ID>&calendarIds=<CALENDAR_IDS>&start=<START_DATETIME>&end=<END_DATETIME>", {
    method: "GET",
    headers: {
    "accept": "application/json",
    "Authorization": "ApiKey <API_KEY>"
    }
});
ParameterTypeDefaultRequiredDescription
accountIdQuery-YesThe calendar account ID to retrieve events from.
calendarIdsQuery-YesComma-separated list of calendar IDs to retrieve events from. Notice that these calendars must all belong to the same account identified by accountId.
startQuery-YesStart of the time window in ISO 8601 format, e.g. 2023-03-01T00:00:00Z
endQuery-YesEnd of the time window in ISO 8601 format, e.g. 2023-04-01T00:00:00Z. This must be greater than start. The interval cannot be longer than 6 months. It is recommended to retrieve no more than 2 months of events at the same time.

Here is an example response:

{
  "data": {
    "events": [
      {
        "@type": "Event",
        "id": "WyJBUU1rQURaa1lXWXpOel...",
        "calendarId": "WyI2NDBhNjJjOW...",
        "accountId": "640a62c9aa5b7e06cf420000",
        "integrationId": "o365",
        "baseEventId": "AAkALgAAAAAAHYQDEapmEc2by...",
        "created": "2023-02-28T11:50:57",
        "updated": "2023-02-28T17:56:44",
        "title": "Chat about Morgen",
        "description": "<html><body>Description of event, possibly in HTML format.</body></html>",
        "descriptionContentType": "text/html",
        "start": "2023-03-01T10:15:00",
        "duration": "PT25M",
        "showWithoutTime": false,
        "timeZone": "Europe/Berlin",
        "privacy": "public",
        "freeBusyStatus": "free",
        "locations": {
          "1": {
            "@type": "Location",
            "name": "Morgen HQ, Forrlibuckstrasse 223"
          }
        },
        "participants": {
          "ZGF2aWRAbW9yZ2Vu0000": {
            "@type": "Participant",
            "name": "John Doe",
            "email": "doe@morgen.so",
            "roles": {
              "attendee": true,
              "owner": true
            },
            "participationStatus": "needs-action"
          },
          "bWFyY29AbW9yZ2Vu0000": {
            "@type": "Participant",
            "name": "Willie White",
            "email": "white@morgen.so",
            "roles": {
              "attendee": true
            },
            "accountOwner": true,
            "participationStatus": "needs-action"
          },
          ...
        },
        "alerts": {
          "1": {
            "@type": "Alert",
            "trigger": {
              "@type": "OffsetTrigger",
              "offset": "-PT15M",
              "relativeTo": "start"
            },
            "action": "display"
          },
          ...
        },
      },
      "morgen.so:derived": {
        "virtualRoom": {
          "url": "https://us02web.zoom.us/j/82...?pwd=..."
        }
      },
      "morgen.so:metadata": {
        "updated": "2023-09-25T08:53:36.793Z"
        // Category-related fields
        "categoryId": "9b5f823f-d690-4781-8783-95052ac05740@morgen.so",
        "categoryName": "Morgen",
        "categoryColor": "#CCEACD", // Hexadecimal color code
        // Task-related fields. An event with a taskId will be displayed as a task in the Morgen calendar.
        "progress": "needs-action", // Possible values: "needs-action", "completed".
        "taskId": "0d464578-08ff-4df6-88b2-19083b296df7",
      }
      ...
    ]
  }
}
 

Please refer to the JSCalendar standard (opens in a new tab) for more information about the data model. Please consider the following differences:

Differences with JSCalendar

Additional fields

Morgen returns some additional fields for convenience and to provide more information about the event:

  • integrationId: The ID of the integration the event belongs to.
  • accountId: The ID of the account the event belongs to.
  • calendarId: The ID of the calendar the event belongs to.
  • baseEventId: The provider ID of the base event the event belongs to. This is the ID of the recurring event for recurring events, and the ID of the event itself for non-recurring events.
  • masterBaseEventId: The provider ID of the master base event the event belongs to. This is the ID of the master recurring event for recurring events, and will not be returned for non-recurring events.
  • morgen.so:derived: An object containing useful field derived from other event information. Read-only.
  • morgen.so:metadata: An objects containing Morgen-specific metadata, such as the event category and the link to a task.
⚠️

Additional fields might be added in the future. If you are storing the event in your database, please make sure to ignore unknown fields.

Create an event

Morgen offers an endpoint to create events in a given calendar. The event is created in the calendar of the account identified by the accountId parameter.

fetch("https://api.morgen.so/v3/events/create", {
    method: "POST",
    headers: {
    "accept": "application/json",
    "Authorization": "ApiKey <API_KEY>"
    },
    body: JSON.stringify({"accountId": <ACCOUNT_ID>, "calendarId": <CALENDAR_ID>, ...eventfields})
    });

The fields accountId and calendarId are mandatory. Other fields of an event are described in the JSCalendar standard (opens in a new tab).

Update an event

The following endpoint can be used to update an event in a given calendar.

fetch("https://api.morgen.so/v3/events/update?seriesUpdateMode=<UPDATE_MODE>", {
    method: "POST",
    headers: {
    "accept": "application/json",
    "Authorization": "ApiKey <API_KEY>"
    },
    body: JSON.stringify({"accountId": <ACCOUNT_ID>, "calendarId": <CALENDAR_ID>, "id": <EVENT_ID>, ...eventfields})
});
ParameterTypeDefaultRequiredDescription
seriesUpdateModeQuerysingleNoDefines how to update recurring events. Possible values are: all (update all events), future (update this and future occurrences), single (update this event only, default). This parameter has no effect on non-recurring events.
idBody-YesThe ID of the event to update.
accountIdBody-YesThe ID of the account the event belongs to.
calendarIdBody-YesThe ID of the calendar the event belongs to.

Other fields of an event are described in the JSCalendar standard (opens in a new tab).

⚠️

Currently seriesUpdateMode only supports the default value (single).

💡

Updates are patch updates. Only the fields that are provided will be updated. All other fields will remain unchanged. To avoid unintended changes, it is recommended to always provide only the fields that need to be updated.

Here is an example of a request to update an event title, while leaving all other fields unchanged:

fetch("https://api.morgen.so/v3/events/update", {
    method: "POST",
    headers: {
    "accept": "application/json",
    "Authorization": "ApiKey <API_KEY>"
    },
    body: JSON.stringify({
      "accountId": "0123123", 
      "calendarId": "WyJhbmNvbmEubXJjQGdtYWl", 
      "id": "WyJhbmNvbmEubXJjQGdtYWlsLmNvbSI",
      "title": "Title updated"
    })
});

Request the creation of a virtual meeting room

Both the create and update endpoints support the creation of a virtual meeting room for the event. To request the creation of a virtual meeting room, set the morgen.so:requestVirtualRoom field to default in the body of the request. This will create a virtual meeting room with the default settings of the integration. Google Meet will be added if the event is saved in a Google Calendar, while Microsoft Teams will be added if the event is saved in a Office 365 Calendar.

fetch("https://api.morgen.so/v3/events/create", {
    method: "POST",
    headers: {
    "accept": "application/json",
    "Authorization": "ApiKey <API_KEY>"
    },
    body: JSON.stringify({"accountId": <ACCOUNT_ID>, "calendarId": <CALENDAR_ID>, "morgen.so:requestVirtualRoom": "default", ...eventfields})
    });

Please notice that once a room has been attached to an event it cannot be removed with an update.

💡

Notice that Google Meet cannot be used on an Office 365 calendar. Similarly Microsoft Teams cannot be used on a Google Calendar. Usually this is not an issue, as these services are always used together with the corresponding calendar.

💡

Support for Zoom and Webex is planned. It will be possible to request a virtual meeting room with Zoom and Webex and attach the meeting room to events created in any calendar.

Delete an event

The following endpoint can be used to update an event in a given calendar.

fetch("https://api.morgen.so/v3/events/delete?seriesUpdateMode=<UPDATE_MODE>", {
    method: "POST",
    headers: {
    "accept": "application/json",
    "Authorization": "ApiKey <API_KEY>"
    },
    body: JSON.stringify({"accountId": <ACCOUNT_ID>, "calendarId": <CALENDAR_ID>, "id": <EVENT_ID>})
    });
ParameterTypeDefaultRequiredDescription
seriesUpdateModeQuerysingleNoDefines how to update recurring events. Possible values are: all (update all events), future (update this and future occurrences), single (update this event only, default). This parameter has no effect on non-recurring events.
idBody-YesThe ID of the event to update.
accountIdBody-YesThe ID of the account the event belongs to.
calendarIdBody-YesThe ID of the calendar the event belongs to.
⚠️

Currently seriesUpdateMode only supports the default value (single).