Introducing the new ‘primary’ alias for the Unified Calendar API Shirley Lee Published: March 4, 2019 Why do we need an alias?Kloudless’ Unified Calendar API allows developers to integrate with Google Calendar, Outlook Calendar, CalDAV, and iCalendar (via CalDAV). While recently adding RSVP functionality to the Unified Calendar API, we noticed we could improve the API by adding a way to represent the primary or default calendar without knowing its alphanumeric ID.The primary calendar is the default calendar that Google, Outlook, and CalDAV calendar services provide based on your email. This is used to receive event invitations if someone invites you to a calendar event, which will then appear on your primary calendar. However, usually this primary calendar has a specific ID, and it does not make sense for a developer to first make an API request to retrieve this ID. We can use an alias called primary both internally and externally to represent this calendar, and you can easily retrieve and respond to any event notifications.How do we support the primary alias?First, let’s look at the request a developer would make to our Kloudless Calendar API. Whenever the calendar_id parameter is specified, we need to replace it with the alias primary, starting within the URL. We’ve shown a request that creates a new event for the primary calendar: curl -X POST \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer BEARER_TOKEN' \ -d '{ "name": "test event", "start": "2019-03-01T00:00:00Z", "end": "2019-03-02T00:00:00Z" }' \ 'https://api.kloudless.com/v1/accounts/ACCOUNT_ID/cal/calendars/primary/events/' { "api": "calendar", "type": "event", "name": "test event", "calendar_id": "fdWVld2JkQGdtYWXXXXXXXX", "start": "2019-03-01T00:00:00Z", "end": "2019-03-02T00:00:00Z" }123456789101112131415curl -X POST \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer BEARER_TOKEN' \ -d '{ "name": "test event", "start": "2019-03-01T00:00:00Z", "end": "2019-03-02T00:00:00Z" }' \ 'https://api.kloudless.com/v1/accounts/ACCOUNT_ID/cal/calendars/primary/events/' { "api": "calendar", "type": "event", "name": "test event", "calendar_id": "fdWVld2JkQGdtYWXXXXXXXX", "start": "2019-03-01T00:00:00Z", "end": "2019-03-02T00:00:00Z"}You can see we specify primary in the request URL, and we receive an alphanumeric ID for the primary calendar in the response body (for ease of readability and security, we simplified the response body and masked part of the calendar ID).The API server realizes that primary is equivalent to fdWVld2JkQGdtYWXXXXXXXX, but how did we do that? Intuitively, we need to retrieve the primary calendar ID first for any API request that uses the primary alias.We’ve provided some sample pseudocode for creating a calendar event: def create_event(self, calendar_id, request_data): if calendar_id == 'primary': calendar_id = self._get_primary_calendar_id() url = self._gen_request_url(calendar_id) body = self._gen_request_body(request_data) response = self.send_request(url, body) event = self._parse_event(response, calendar_id) return event1234567891011def create_event(self, calendar_id, request_data): if calendar_id == 'primary': calendar_id = self._get_primary_calendar_id() url = self._gen_request_url(calendar_id) body = self._gen_request_body(request_data) response = self.send_request(url, body) event = self._parse_event(response, calendar_id) return eventHow do we retrieve the primary calendar from our upstream services? Let’s see what the differences are between Google Calendar, Outlook Calendar / Exchange, and CalDAV.Google CalendarFortunately, the Google Calendar API already supports using the primary shortcut. We can retrieve the primary calendar by sending a request to the following endpoint: GET https://www.googleapis.com/calendar/v3/calendars/primary1GET https://www.googleapis.com/calendar/v3/calendars/primaryOutlook Calendar / ExchangeUnlike Google Calendar. Outlook Calendar and Exchange have different endpoints based on which calendar to query. We can use the following endpoint to retrieve the primary calendar. GET https://outlook.office.com/api/v2.0/me/calendar1GET https://outlook.office.com/api/v2.0/me/calendarCalDAVCalDAV is the most complex. The primary calendar concept, named CALDAV:schedule-inbox-URL, is defined in RFC 6638 which is a scheduling extension to CalDAV. In addition, CALDAV:schedule-inbox-URL is not a required property. Therefore, not all of the CalDAV servers have the primary calendar. We have to check whether the server supports RFC 6638 and CALDAV:schedule-inbox-URL property. If not, then we use the first calendar as the primary calendar.We’ve provided another snippet of pseudocode: def _get_primary_calendar_id(self): if self._support_rfc_6638() and self._have_inbox_url(): inbox_url = self._get_inbox_url() calendar = self.get_calendar(inbox_url) return calendar.id calendars = self.list_calendars() return calendars[0].id1234567def _get_primary_calendar_id(self): if self._support_rfc_6638() and self._have_inbox_url(): inbox_url = self._get_inbox_url() calendar = self.get_calendar(inbox_url) return calendar.id calendars = self.list_calendars() return calendars[0].idHow to use the primary alias in the Unified Calendar APIOur unified API supports using the primary alias for the calendar_id parameter, including:Any CRUD operations for the primary calendarFinding availability on the primary calendarAny CRUD operations for primary calendar eventsActivity monitoring for the primary calendarHere are a few examples:Retrieve the primary calendar curl -X GET \ --header 'Accept: application/json' \ --header 'Authorization: Bearer BEARER_TOKEN' \ 'https://api.kloudless.com/v1/accounts/ACCOUNT_ID/cal/calendars/primary/'1234curl -X GET \ --header 'Accept: application/json' \ --header 'Authorization: Bearer BEARER_TOKEN' \ 'https://api.kloudless.com/v1/accounts/ACCOUNT_ID/cal/calendars/primary/'Find availability of the primary calendar curl -X POST \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer BEARER_TOKEN' \ -d '{ \ "calendars": ["primary"], \ "meeting_duration": "PT1H", \ "constraints": { \ "time_windows": [ \ { \ "start": "2017-05-20T08:00:00+07:00", \ "end": "2017-05-20T12:00:00+07:00" \ } \ ] \ } \ }' \ 'https://api.kloudless.com/v1/accounts/ACCOUNT_ID/cal/availability/'1234567891011121314151617curl -X POST \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer BEARER_TOKEN' \ -d '{ \ "calendars": ["primary"], \ "meeting_duration": "PT1H", \ "constraints": { \ "time_windows": [ \ { \ "start": "2017-05-20T08:00:00+07:00", \ "end": "2017-05-20T12:00:00+07:00" \ } \ ] \ } \ }' \ 'https://api.kloudless.com/v1/accounts/ACCOUNT_ID/cal/availability/'List events in the primary calendar curl -X GET \ --header 'Accept: application/json' \ --header 'Authorization: Bearer BEARER_TOKEN' \ 'https://api.kloudless.com/v1/accounts/ACCOUNT_ID/cal/calendars/primary/events/' 12345curl -X GET \ --header 'Accept: application/json' \ --header 'Authorization: Bearer BEARER_TOKEN' \ 'https://api.kloudless.com/v1/accounts/ACCOUNT_ID/cal/calendars/primary/events/' Monitor activity for the primary calendar curl -X PATCH \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer BEARER_TOKEN' \ -d '{"monitor_calendars": ["primary"]}' \ 'https://api.kloudless.com/v1/accounts/ACCOUNT_ID/'123456curl -X PATCH \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer BEARER_TOKEN' \ -d '{"monitor_calendars": ["primary"]}' \ 'https://api.kloudless.com/v1/accounts/ACCOUNT_ID/'ConclusionKloudless provides the very useful primary alias for developers to use when querying the primary calendar. Sign up for a free account to try out our calendar API.ReferenceGoogle Calendar API DocumentOutlook Calendar API DocumentRFC 6638