# How to check availability

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

You're building a booking page and need to show open time slots without scraping every attendee's calendar by hand. Pulling each calendar, normalizing time zones, and intersecting the free blocks is the kind of work that breaks the moment one provider returns busy data in a different shape. The availability endpoint does that intersection for you and hands back the open slots in one response.

This recipe focuses on configuring the request: working hours, time zones, buffers, and the availability method for multi-host meetings. For a shorter cross-provider intersection walkthrough, start with [find open meeting times](/docs/cookbook/calendar/find-meeting-times/).

## Get available time slots

Send a `POST /v3/calendars/availability` request with a list of `participants`, a `start_time`/`end_time` window, and `duration_minutes`. The endpoint reads each participant's calendar, intersects their busy times, and returns only slots when everyone is free. Unlike most calendar calls, this one takes no grant in the path.

You pass participant email addresses and `calendar_ids` directly in the body, and every address must map to a valid Nylas grant. The `duration_minutes` field sets the meeting length and must be a multiple of 5 minutes. The `interval_minutes` field controls how often a candidate slot starts. The request below finds 30-minute slots for two participants.

```bash
curl --compressed --request POST \
	--url 'https://api.us.nylas.com/v3/calendars/availability' \
	--header 'Accept: application/json' \
	--header 'Authorization: Bearer <NYLAS_API_KEY>' \
	--header 'Content-Type: application/json' \
	--data '{
		"participants": [
			{
				"email": "leyah@example.com",
				"calendar_ids": ["leyah@example.com"],
				"open_hours": [{
					"days": [0,1,2],
					"timezone": "America/Toronto",
					"start": "9:00",
					"end": "17:00",
					"exdates": []
				}]
			},
			{
				"email": "nyla@example.com",
			}
		],
		"start_time": 1600890600,
		"end_time": 1600999200,
		"interval_minutes": 30,
		"duration_minutes": 30,
		"round_to": 15,
		"availability_rules": {
			"availability_method": "collective",
			"buffer": {
				"before": 15,
				"after": 15
			},
			"default_open_hours": [
				{
					"days": [0,1,2],
					"timezone": "America/Toronto",
					"start": "9:00",
					"end": "17:00",
					"exdates": []
				},
				{
					"days": [3,4,5],
					"timezone": "America/Toronto",
					"start": "10:00",
					"end": "18:00",
					"exdates": []
				}
			]
		}
	}'

```

```js [availabilitySlots-Node.js SDK]

import Nylas from "nylas";

const nylas = new Nylas({
  apiKey: "<NYLAS_API_KEY>",
  apiUri: "<NYLAS_API_URI>",
});

const email = "<EMAIL>";

async function getCalendarAvailability() {
  try {
    const calendar = await nylas.calendars.getAvailability({
      requestBody: {
        startTime: 1630435200,
        endTime: 1630521600,
        durationMinutes: 15,
        participants: [{ email }],
      },
    });

    console.log("Calendar:", calendar);
  } catch (error) {
    console.error("Error to create calendar:", error);
  }
}

getCalendarAvailability();


```

```python [availabilitySlots-Python SDK]

from nylas import Client

nylas = Client(
    "<NYLAS_API_KEY>",
    "<NYLAS_API_URI>"
)

grant_id = "<NYLAS_GRANT_ID>"
email = "<EMAIL>"

availability = nylas.calendars.get_availability(
  request_body={
    "start_time": 1630435200,
    "end_time": 1630521600,
    "duration_minutes": 15,
    "participants": [{"email": email}]
  }
)

print(availability)

```

The response returns a `time_slots` array, each entry carrying `start_time`, `end_time`, and the `emails` that are free for that block. See the [availability API reference](/docs/reference/api/calendar/post-availability/) for every field.

## Set working hours and time zones

Working hours restrict the search to when a participant takes meetings. Set them with `open_hours` on each participant or `default_open_hours` under `availability_rules` to apply one schedule to everyone. Each entry holds 5 fields, and a participant in Toronto and one in Berlin each get slots in their own local time.

In the `days` array, Sunday is `0` and Saturday is `6`, so `[1,2,3,4,5]` covers a standard Monday-to-Friday week. The `start` and `end` use 24-hour format with no leading zero, like `"9:00"` and `"17:00"`, and the minimum start is `0:00` with a maximum of `23:49`. The `timezone` is an Internet Assigned Numbers Authority (IANA) string such as `America/Toronto`. Add an `exdates` array of `YYYY-MM-DD` dates to drop specific days, like a holiday, from the window.

```bash
curl --request POST \
  --url 'https://api.us.nylas.com/v3/calendars/availability' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "start_time": 1600890600,
    "end_time": 1600999200,
    "duration_minutes": 30,
    "interval_minutes": 30,
    "participants": [
      {
        "email": "leyah@example.com",
        "calendar_ids": ["primary"],
        "open_hours": [{
          "days": [1, 2, 3, 4, 5],
          "timezone": "America/Toronto",
          "start": "9:00",
          "end": "17:00",
          "exdates": ["2025-12-25"]
        }]
      }
    ]
  }'
```

A per-participant `open_hours` block overrides `default_open_hours` for that person, so you can set one company-wide schedule and adjust it for individuals who keep different hours.

## Choose an availability method

The `availability_method` field under `availability_rules` decides how the endpoint treats multiple hosts. The default is `max-availability`. For a meeting where every host must attend, use `collective`; for round-robin scheduling that spreads meetings across a pool of hosts, use one of the two fairness-oriented methods. The 3 supported values are below.

| Method | What it does |
| --- | --- |
| `collective` | Returns slots when **every** participant is free at the same time. Use this for a group meeting where all hosts must attend. |
| `max-fairness` | Round-robin method that favors the host with the fewest assigned meetings, so bookings spread evenly across the pool. |
| `max-availability` | Round-robin method (the default) that favors the host with the most open time, maximizing how many slots a person sees when booking. |

Two more fields shape the slots. A `buffer` of `{ "before": 15, "after": 15 }` treats 15 minutes around each existing meeting as busy, so a 10:00-11:00 event blocks 9:45-11:15 and back-to-back bookings don't get suggested. The `round_to` value snaps slot start times to a clean boundary; with `round_to` set to `15`, a slot that would start at 9:05 rounds to 9:15.

## Things to know about availability

Availability and Free/Busy solve different problems. Availability generates bookable slots after intersecting calendars and applying working hours, buffers, and rounding. [Free/Busy](/docs/v3/calendar/check-free-busy/) is the lighter call that returns raw busy blocks for a single user when you want to build your own slot logic. Reach for availability when you want finished slots, and Free/Busy when you want the busy data.

A few constraints are worth planning for. All times use Unix seconds, and `start_time`, `end_time`, `duration_minutes`, `interval_minutes`, and `round_to` must each be multiples of 5 minutes. Every participant's email must map to a connected grant, so a participant whose grant has expired skews results toward busy or drops them from the calculation. The `availability_rules` shape the output: `round_to` snaps start times to a clean boundary and `buffer` pads existing events, which together trim the slot list. Performance scales with the participant count and the window length, so a 90-day window across 20 participants generates far more candidate slots than a 1-week window for 2 people. Keep windows tight and let `interval_minutes` thin the grid. Time zones follow the [IANA time zone database](https://en.wikipedia.org/wiki/Tz_database), so always pass a region string like `America/Toronto` rather than a raw numeric offset.

## What's next

- [Free/Busy](/docs/v3/calendar/check-free-busy/) to read raw busy blocks for one user
- [Find meeting times](/docs/cookbook/calendar/find-meeting-times/) for the cross-provider intersection walkthrough
- [Calendar API overview](/docs/v3/calendar/) for events, calendars, and scheduling concepts
- [Availability API reference](/docs/reference/api/calendar/post-availability/) for every request and response field