# Checking calendar availability

Source: https://developer.nylas.com/docs/v3/calendar/calendar-availability/

The Nylas APIs offer multiple ways to get information about users' availability, so you can book meetings or run other time-based operations. This page describes the [Availability endpoint](/docs/reference/api/calendar/post-availability/) and how to work with it.

## How the Availability endpoint works

You can use the [Availability endpoint](/docs/reference/api/calendar/post-availability/) to find space in a user's `primary` calendar for a meeting with specific and detailed criteria. These endpoints allow you to query for availability amongst a group of participants, so you can book collective meetings or you can book one person who is available. The endpoints return a list of `time_slots` which meet the criteria you set in your request, along with information about which participants meet the criteria.


**Diagram: How Nylas turns an Availability request into time slots.** Nylas reads each person's calendar, applies their working hours and breaks, and returns the times a meeting fits. Use `collective` when everyone must attend. Use a round-robin method when any one person can take the meeting: `max-availability` (the default) offers every time someone is free, and `max-fairness` spreads meetings to whoever was booked least recently.

```mermaid
flowchart TD
  request["Ask when a meeting fits"]
  busy["Find when each person is busy"]
  rules["Block out off-hours and breaks"]
  method_0_collective["Keep only times everyone shares"]
  method_1_maxavail["Offer every time someone is free"]
  method_2_maxfair["Offer times for whoever is due next"]
  slots["Return the times that work"]
  book["Book the chosen time"]
  request --> busy
  busy --> rules
  rules -->|"Depends on who must attend, set by availability_method"| method_0_collective
  rules -->|"Depends on who must attend, set by availability_method"| method_1_maxavail
  rules -->|"Depends on who must attend, set by availability_method"| method_2_maxfair
  method_0_collective --> slots
  method_1_maxavail --> slots
  method_2_maxfair --> slots
  slots --> book
```

- Your app: **Ask when a meeting fits**: Your app tells Nylas who should attend, the date range to search, and how long the meeting is. Each person must have connected their calendar to your app (a grant).
  - Request details: [`POST /v3/calendars/availability`](/docs/reference/api/calendar/post-availability/) with `participants`, `start_time`, `end_time`, and `duration_minutes`.
  - Request details: `participants[].calendar_ids`: the calendars to check. Without it, Nylas uses the participant's primary calendar.
  - Request details: `availability_rules.default_open_hours`: working hours for everyone. A participant's own `open_hours` replace them.
  - Request details: `availability_rules.buffer`: `before` and `after` minutes to keep free around existing events, 0 to 120 in steps of 5.
  - Request details: `interval_minutes`: how often a slot can start. Defaults to `duration_minutes`.
  - Request details: `round_to`: rounds slot start times, in minutes. Defaults to 15.
  - Request details: `availability_rules.availability_method`: `collective`, `max-fairness`, or `max-availability` (default).
  - Request details: `availability_rules.round_robin_group_id`: for round robin, Nylas ranks participants by events whose metadata `key5` has this value.
- Nylas: **Find when each person is busy**: Nylas reads the events on each person's calendars in the date range you asked about (`start_time` to `end_time`).
- Nylas: **Block out off-hours and breaks**: Time outside a person's working hours (open hours), or on a day off you listed (`exdates`), counts as busy. Nylas also keeps a break free before and after each existing meeting (the buffer).
- One of these paths (Depends on who must attend, set by `availability_method`):
  - **Everyone attends (`collective`)**
    - Nylas: **Keep only times everyone shares**: A time counts only when every person is free. Use it for meetings that everyone attends.
  - **Any one person hosts (`max-availability`, round robin)**
    - Nylas: **Offer every time someone is free**: A time counts when any one person is free. Nylas lines people up so whoever was booked least recently is first (round robin). It counts bookings in the `round_robin_group_id` group.
  - **Spread meetings evenly (`max-fairness`, round robin)**
    - Nylas: **Offer times for whoever is due next**: Nylas lines people up the same way, then checks only those booked least recently. If they have no free time, Nylas falls back to `max-availability`.
- Nylas: **Return the times that work**: Nylas returns a list of meeting times (`time_slots`), each the length you asked for, with the people free at that time (`emails`). Round-robin results also include `order`: who is next in line to host.
  - Response details: Each slot is `duration_minutes` long, and slots start every `interval_minutes`.
- Your app: **Book the chosen time**: Your app creates the meeting on the calendar. For round robin, pick the host from the people free at that time, following `order`. Request: [`POST /v3/grants/{grant_id}/events`](/docs/reference/api/events/create-event/).


Each Availability request has a few main components:

- [The top-level meeting information](#meeting-information).
- [Open hours and availability rules](#open-hours-and-availability-rules).

For more complex examples, see the [Group booking documentation](/docs/v3/calendar/group-booking/).

If you want to find simple information about a single participant's availability, see the [Free/Busy documentation](/docs/v3/calendar/check-free-busy/).

### Meeting information

The properties at the top level of an Availability request specify when you want to book the meeting, and the participants you want to include. Nylas checks the participants' availability during the specified time period.

```json
{
  "participants": [
    {
      "email": "user@example.com",
      "calendar_ids": ["primary"],
      "open_hours": [
        {
          "value": null,
          "days": [0, 1, 2],
          "timezone": "America/Toronto",
          "start": "9:00",
          "end": "17:00"
        }
      ]
    }
  ],
  "start_time": 1659366000,
  "end_time": 1659733200,
  "interval_minutes": 30,
  "duration_minutes": 30,
  "round_to": 15,
  "availability_rules": {
    "availability_method": "collective",
    "buffer": {
      "before": 15,
      "after": 15
    }
  }
}
```

The order in which you include participants' email addresses doesn't matter, but they _must_ be associated with valid Nylas grants, and should be unique within their application.

> **Warn:** 
> **You can pass up to 50 email addresses in an Availability request, but a large list might slow down response times or cause provider rate limiting**. When possible, Nylas recommends you keep your list of participants small.

You can also set the `interval_minutes` parameter, which specifies the calendar granularity. For example, if you want to book a half-hour meeting some time after 10:00am, but you want it to start at a 15 minute interval, set `interval_minutes` to `15`. In this case, Nylas checks for available half-hour time slots beginning at 10:00am, then at 10:15, 10:30, 10:45, and so on. By default, `interval_minutes` is the same as `duration_minutes`. The minimum interval is `5`.

The `interval_minutes` and `round_to` parameters are independent, but you can use them together.

### Open hours and availability rules

Open hours are optional, and they let you combine a calendar's _technical_ availability with a participant's _preferred_ availability. Think of this as setting the "working hours" on a calendar, so nobody books a meeting in the middle of the night with your team on the East Coast.

You can set `default_open_hours` in the `availability_rules` object. This default applies to all participants. You can then override it on a per-participant basis in the `participants` object.

The examples below show...

- A `default_open_hours` object that sets the open hours to between 9:00am and 5:00pm in the Chicago timezone, Monday through Friday. It also excludes (prevents meetings on) December 24th, December 25th, and January 1st.
- A participant's `open_hours` item that overrides the `default_open_hours` and sets their working hours to between 9:00am and 5:00pm Toronto time, on Monday, Tuesday, and Wednesday only. It also excludes January 31st as a day they're taking off from work.

```json [openHours-Default open hours]
"availability_rules": {
  ...
  "default_open_hours": [{
    "days": [1, 2, 3, 4, 5],
    "timezone": "America/Chicago",
    "start": "9:00",
    "end": "17:00",
    "exdates": ["2023-12-24", "2023-12-25", "2024-01-01"]
  }]
}
```

```json [openHours-Participant open hours]
"participants": [{
    "email": "jane.doe@example.com",
    "calendar_ids": "primary",
    "open_hours": [{
      "days": [1, 2, 3],
      "timezone": "America/Toronto",
      "start": "9:00",
      "end": "17:00",
      "exdates": ["2024-01-31"]
    }]
}]
```

## Availability responses

When you make a `POST` request to the [Availability endpoint](/docs/reference/api/calendar/post-availability/), Nylas returns the availability information as entries in a `time_slots` array. For `collective` requests, each entry represents a time slot where all participants are available. For round-robin requests (`max-availability` or `max-fairness`), each entry's `emails` array lists the participants who are free during that slot, and the response includes an `order` array. You can then use the time slots to book your meeting.

The following JSON snippets show example responses to Availability requests.

```json
{
  "request_id": "5fa64c92-e840-4357-86b9-2aa364d35b88",
  "data": {
    "time_slots": [
      {
        "emails": ["user2@example.com", "user1@example.com"],
        "start_time": 1659367800,
        "end_time": 1659369600
      },
      {
        "emails": ["user2@example.com", "user1@example.com"],
        "start_time": 1605805200,
        "end_time": 1605807000
      }
    ]
  }
}
```

```json [availabilityResponse-Round robin response]
{
  "request_id": "5fa64c92-e840-4357-86b9-2aa364d35b88",
  "data": {
    "order": ["user1@example.com", "user2@example.com"],
    "time_slots": [
      {
        "emails": ["user2@example.com", "user1@example.com"],
        "start_time": 1659367800,
        "end_time": 1659369600
      },
      {
        "emails": ["user1@example.com"],
        "start_time": 1659376800,
        "end_time": 1659378600
      }
    ]
  }
}
```

## Add buffer time

In some cases, you might want to allow an attendee to book a meeting, but you also want to block out time before or after the meeting for your teammate to preform related actions. For example, you might want to give a support agent 10 minutes to review bug reports before a booking, or give a medical professional 20 minutes after a meeting to write and file case notes.

In these cases, you can add this `buffer` to your [Availability request](/docs/reference/api/calendar/post-availability/). Nylas returns booking time slots that meet your event's criteria _and_ the requested buffer criteria. It's up to you to remember that you passed a buffer, and book the extra time you requested for the team member.

The `buffer` is in the `availability_rules` object, and you set it in minutes `before` and `after` the available time slot. You can set buffer time in increments of five minutes.

## Troubleshooting Availability responses

When you work with Availability requests and modifiers, you might find a slot on a participant's calendar that _looks_ like it should be available, but isn't returned as an available time slot. When this happens, you should check the following things:

- Have you set a buffer time around meetings? If so, how much?
- Are you setting open hours? Are they set to the correct timezone for the participant?
- Have you set an interval or any rounding?