# Calendar events

Calendar events are used to store and share calendar information, such as event details, dates, and times,
across different calendar applications like Microsoft Outlook, Google Calendar, Apple Calendar, etc.

OCAPI supports generation of [iCalendar events](https://icalendar.org/) for [completed orders](/digital-platform/completed-orders) that contain tickets.

## Add calendar event flow

```mermaid
flowchart TB
    A(Render an 'Add to calendar' button) --> B
    B(Generate a calendar event) --> C
    C(Open the calendar event)

    click A "#render-an-add-to-calendar-button"
    click B "#generate-a-calendar-event"
    click C "#open-the-calendar-event"
```

## Render an 'Add to calendar' button

Render an 'Add to calendar' button for a completed order. The 'Add to calendar' button should [generate a calendar event](#generate-a-calendar-event)
when pressed and [open the calendar event](#open-the-calendar-event).

## Generate a calendar event

Use the [GetCalendarEventForOrder](/openapi/digital-platform/openapi/completed-order-assets/ocapicompletedorderassets_getcalendareventfororder) endpoint to generate a calendar event for a completed order.

Points to Note
- A calendar event can only be generated for [standard orders](/digital-platform/orders/standard-orders) that contain tickets and have not [expired](/digital-platform/completed-orders/expiry).
- For orders that contain tickets to multiple showtimes, a calendar event will be generated for each showtime.
- Regardless of the number of showtimes, the endpoint will return a single `.ics` file containing a calendar event for each showtime.


## Open the calendar event

The [GetCalendarEventForOrder](/openapi/digital-platform/openapi/completed-order-assets/ocapicompletedorderassets_getcalendareventfororder)
endpoint returns a byte array with a MIME type of `text/calendar`, representing the calendar event file for the completed order.

Opening the calendar event file will prompt the patron to add it to their default calendar application.

For web, use the response `Blob` to open the calendar event, for example:

```js
/**
 * Loads a calendar event for a completed order and opens it in the default calendar application.
 */
async function onAddToCalendarButtonClick(apiUrl, gasToken, orderId) {
  // Load the calendar event.
  const response = await fetch(
    `https://${apiUrl}/ocapi/v1/orders/completed/${orderId}/assets/calendar-event`,
    {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${gasToken}`,
      },
    },
  );

  // Parse the calendar event blob.
  const calendarEventBlob = await response.blob();

  // Open the blob via a hidden link.
  const url = window.URL.createObjectURL(calendarEventBlob);
  const link = document.createElement('a');
  link.href = url;
  link.download = 'calendar-event.ics';

  // Append the link to the body and open it in the current window.
  document.body.appendChild(link);
  link.click();

  // Clean up.
  document.body.removeChild(link);
  window.URL.revokeObjectURL(url);
}
```