Calendar availability
Managing availability to schedule events is one of the most common calendar activities. Nylas provides you with different ways to check availability:
When to use what
Not sure which option to use?
Use Free/busy when:
- You only need to check one email address.
- You only need to know if someone is busy, and don’t need to compare their schedule with another.
- When you know that the calendar belongs to an account in your provider organization. (Free/Busy can only check accounts within your organization.)
Use the Availability endpoint when:
- You need to check availability for multiple participants and organize itineraries.
- Some participants are outside your organization, and you need to know when they are busy.
- You need to check for specific event duration and intervals.
- You want to set additional unavailable times that are not on the calendar.
Feature support
Endpoint | Scopes | Provider Availability | SDK Support | Feature Availability |
---|---|---|---|---|
Availability | calendar calendar.read_only |
Microsoft |
Python - Open Hours is not supported. | Availability does support Room Resources. Just treat it as an email address when checking availability. |
Consecutive Availability | calendar calendar.read_only |
Microsoft |
None | Consecutive Availability does support Room Resources. Just treat it as an email address when checking availability. |
Free/Busy | calendar calendar.read_only |
Microsoft |
Python Java Node |
Free/Busy does not support Virtual Calendars. Free/Busy does not support Room Resources. |
Free/Busy
Free/Busy lets you pass in a time frame and email to return busy times. Free/Busy checks the provider's primary calendar. The email address must be part of the same organization.
Let's look at an example of using /calendars/free-busy
for accounts within your organization.
Send a POST request to /calendars/free-busy
with the request body :
start_time
- Unix timestamp for the beginning of the free/busy window.end_time
- Unix timestamp for the end of the free/busy window.emails
- Email address on the same domain to check. Only one email at a time can be checked. The primary calendar is used to check availability. This works for Microsoft and Gmail accounts.calendars
- Use the calendars array to check for other provider types. (Optional)- Each
account_id
represents an individual and supports other providers. Each value in the array forcalendar_ids
is a unique calendar for that individual.
- Each
Example: Free/Busy requests
The cURL examples below show a request with one account and a request with multiple accounts and calendars. You can view shared time slots for different individuals with different providers for multiple accounts and calendars.
curl --request POST \
--url https://api.nylas.com/calendars/free-busy \
--header 'Authorization: Bearer <NYLAS_ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"start_time": "1409594400",
"end_time": "1409598000",
"emails": [
"string"
],
"calendars": [
{
"account_id": "3aols9hb9fkqtso7zkzcmwgwv",
"calendar_ids": [
"string"
]
}
]
}'
curl --request POST \
--url https://api.nylas.com/calendars/free-busy \
--header 'Authorization: Bearer <NYLAS_ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"start_time": "1633374000",
"end_time": "1633381200",
"emails": [],
"calendars": [
{
"account_id": "exampleaccountid1",
"calendar_ids": [
"examplecalendaridA",
"examplecalendaridB"
]
},
{
"account_id": "exampleaccountid2",
"calendar_ids": [
"examplecalendaridC",
]
}
]
}'
Example: Free/Busy responses
There are four busy time slots. This means they are free any other time not listed. If there are no busy slots, the request returns an empty time_slots
array.
[
{
"email": "[email protected]",
"object": "free_busy",
"calendar_id": "string",
"time_slots": [
{
"end_time": 1600907400,
"object": "time_slot",
"start_time": 1600890568,
"status": "busy"
},
{
"end_time": 1600961400,
"object": "time_slot",
"start_time": 1600959600,
"status": "busy"
},
{
"end_time": 1600966500,
"object": "time_slot",
"start_time": 1600963200,
"status": "busy"
},
{
"end_time": 1600984800,
"object": "time_slot",
"start_time": 1600979400,
"status": "busy"
}
]
}
]
[
{
"calendar_id": "examplecalendaridA",
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"end_time": 1633379400,
"object": "time_slot",
"start_time": 1633377600,
"status": "busy"
}
]
},
{
"calendar_id": "examplecalendaridB",
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"end_time": 1633374900,
"object": "time_slot",
"start_time": 1633371300,
"status": "busy"
},
{
"end_time": 1633383900,
"object": "time_slot",
"start_time": 1633380300,
"status": "busy"
}
]
},
{
"calendar_id": "examplecalendaridC",
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"end_time": 1633377600,
"object": "time_slot",
"start_time": 1633374000,
"status": "busy"
},
{
"end_time": 1633377600,
"object": "time_slot",
"start_time": 1633374000,
"status": "busy"
},
{
"end_time": 1633377600,
"object": "time_slot",
"start_time": 1633374000,
"status": "busy"
}
]
}
]
Example: Free/Busy empty time slots
[
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": []
}
]
Learn More
Review the Free/Busy Status API
How to create a Calendar availability request
There are 2 availability endpoints:
/calendars/availability
- Check multiple calendars to find available time slots for a single meeting./calendars/availability/consecutive
- Check to find availability for multiple meetings with several participants. Use this endpoint to build itineraries where participants with the same availability are combined.
Each endpoint checks the provider's primary calendar.
The requests to check calendar availability and consecutive availability are made of 3 sections; meeting times, free_busy, and open_hours.
First, you’ll review the 3 main sections of a calendar availability POST request. They consist of:
Then you’ll review the response for calendars/availability
and /calendars/availability/consecutive
. Finally, there are examples of each showing how you can tailor each request to your needs.
Meeting time
Meeting time is used to check availability for the specified meeting time between the participants in the emails array. The emails must be in the same organization. The order the emails are entered does not matter.
Create meeting times for both availability and consecutive availability using the request body:
- duration_minutes - The total number of minutes the event should last.
- start_time - Unix timestamp for the beginning meeting.
- end_time - Unix timestamp for the end of the meeting.
- interval_minutes - How many minutes it should check for availability. For example, if you need to schedule a 30 minute meeting (duration_minutes) and want to check for availability every 10 minutes (interval_minutes).
- emails - Emails on the same domain to check. If you are using
/calendar/availability
it accepts an array of emails. If you are using/calendar/consecutive/availability
, it accepts a 2D array of emails.
Consecutive Availability 2D Array
When you are using the /consecutive/availability
endpoint, emails are entered as a 2D array.
Example: Meeting time partial request
The following JSON snippets show responses to a meeting time request.
{
"duration_minutes": 30,
"start_time": 1600890568,
"end_time": 1600999200,
"interval_minutes": 10,
"emails": [
"[email protected]",
"[email protected]"
],
...
}
{
"duration_minutes": 30,
"start_time": 1605794400,
"end_time": 1605826800,
"interval_minutes": 10,
"emails": [
"[email protected]",
"[email protected]",
"[email protected]"
],
...
}
Checking Multiple Emails
You can pass in up to 50 emails. Since this endpoint uses synchronous requests (one email at a time), this can slow down response times with large requests. You should also keep your provider rate limits in mind.
Free busy
To check availability for emails not in your organization, you can add them to the free_busy
array. Each email address and time slot is its own object. This means if you want to add different busy times for the same email address, you need to add another object for that email address.
Free/Busy works like the free/busy endpoint. You need to know the times the email address outside of your organization is busy. You input these as the start and end times.
Free/Busy is optional for /calendar/availability
and /calendar/consecutive/availability
. It must still be included as an empty array when not in use.
Create free/busy times for both availability and consecutive availability using the request body:
- free_busy - A dictionary of free/busy data for users not in your organization. Pass in the emails and times they are busy. Not required as an empty array if checking users in the same organization.
- email - Email address of guests to check.
- object - Always free/busy.
- time_slots - Array containing the start and end times.
- start_time - Unix timestamp for the beginning of the free/busy window.
- end_time - Unix timestamp for the end of the free/busy window.
- object - Always time_slot.
- status - Always busy.
- time_slots - Array containing the start and end times.
Free/Busy
Free/Busy is the same for /calendar/availability
and /calendar/consecutive/availability
.
Example: Free/Busy partial request
The following JSON snippets show responses to a Free/Busy request.
...
"free_busy": [
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1601042400,
"end_time": 1601044200,
"object": "time_slot",
"status": "busy"
}
]
},
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1601042400,
"end_time": 1601044200,
"object": "time_slot",
"status": "busy"
}
]
},
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1601047800,
"end_time": 1601051400,
"object": "time_slot",
"status": "busy"
}
]
}
]
...
...
"free_busy": [
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1605819600,
"end_time": 1605821400,
"object": "time_slot",
"status": "busy"
}
]
}
],
...
Open hours
Open hours let you combine calendar availability with preferred availability. For example, meeting time will check for open times on the email’s calendar, and adding open hours lets you add additional unavailability.
When creating an open_hours
object keep in mind:
- Open Hours is optional for
calendars/availability
andcalendars
/consecutive/availability. - Emails added to open hours must all be in the meeting time emails array.
- Emails not in the organization cannot use
open_hours
. They should be input usingfree_busy
.
Create open hours for both availability and consecutive availability using the request body:
- open_hours - Additional times email accounts are unavailable.
- emails - Emails on the same domain to check. If you are using /calendar/availability it accepts an array of emails. If you are
using calendar/consecutive/availability, it accepts a 2D array of
emails. - days - The days the participants are available entered as an integer. Monday corresponds to 0 and Sunday corresponds to 6.
- timezone - IANA time zone database formatted string (e.g.
America/New_York). - start - Start time in 24 time clock. Leading 0’s are left off. The minimum and maximum start time is 00:00.
- end - End time in a 24 hour time clock. Leading 0’s are left off. The minimum and maximum end time is 00:00.
- object_type - Always open_hours.
Open Hours
Open Hours is the same for /calendars/availability
and /calendars/consecutive/availability
.
The following JSON snippets show responses to an open hours request.
...
"open_hours": [
{
"emails": [
"[email protected]"
],
"days": [
"0"
],
"timezone": "America/Chicago",
"start": "10:00",
"end": "14:00",
"object_type": "open_hours"
}
]
...
"open_hours": [
{
"emails": [
[
"[email protected]"
]
],
"days": [
"0"
],
"timezone": "America/Chicago",
"start": "10:00",
"end": "14:00",
"object_type": "open_hours"
}
]
Availability and Consecutive Availability request
Now that you have gone through each section, you can see the final JSON requests for both endpoints below.
{
"duration_minutes": 30,
"start_time": 1605794400,
"end_time": 1605826800,
"interval_minutes": 10,
"emails": [
"[email protected]"
],
"free_busy": [
{
"email": "[email protected]",
"object": "free/busy",
"time_slots": [
{
"start_time": 1601042400,
"end_time": 1601044200,
"object": "time_slot",
"status": "busy"
}
]
}
],
"open_hours": [
{
"emails": [
"[email protected]"
],
"days": [
"0"
],
"timezone": "America/Chicago",
"start": "10:00",
"end": "14:00",
"object_type": "open_hours"
}
]
}
{
"duration_minutes": 30,
"start_time": 1605794400,
"end_time": 1605826800,
"interval_minutes": 10,
"emails": [
[
"[email protected]"
]
],
"free_busy": [
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1605819600,
"end_time": 1605821400,
"object": "time_slot",
"status": "busy"
}
]
}
],
"open_hours": [
{
"emails": [
[
"string"
]
],
"days": [
"0"
],
"timezone": "America/Chicago",
"start": "10:00",
"end": "14:00",
"object_type": "open_hours"
}
]
}
Availability response
Once you make your POST request, each endpoint will return availability information.
- Availability - Returns a list of time slots where all participants are available.
- Consecutive Availability - Returns all possible groupings that share time slots. If only one person is available, it will return in the response. Use this information to schedule groups of people together for meetings.
The following JSON snippets show responses to availability requests.
{
"object": "availability",
"time_slots": [
{
"end": 1605803400,
"object": "time_slot",
"start": 1605801600,
"status": "free"
},
{
"end": 1605804000,
"object": "time_slot",
"start": 1605802200,
"status": "free"
},
{
"end": 1605804600,
"object": "time_slot",
"start": 1605802800,
"status": "free"
},
{
"end": 1605805200,
"object": "time_slot",
"start": 1605803400,
"status": "free"
},
{
"end": 1605805800,
"object": "time_slot",
"start": 1605804000,
"status": "free"
},
{
"end": 1605806400,
"object": "time_slot",
"start": 1605804600,
"status": "free"
},
{
"end": 1605807000,
"object": "time_slot",
"start": 1605805200,
"status": "free"
},
{
"end": 1605816000,
"object": "time_slot",
"start": 1605814200,
"status": "free"
}
]
}
[
[
{
"emails": [
"[email protected]",
"[email protected]"
],
"end_time": 1605794400,
"start_time": 1605792600
},
{
"emails": [
"[email protected]"
],
"end_time": 1605796200,
"start_time": 1605794400
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605801600,
"start_time": 1605799800
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end_time": 1605803400,
"start_time": 1605801600
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605802200,
"start_time": 1605800400
},
{
"emails": [
"[email protected]"
],
"end_time": 1605804000,
"start_time": 1605802200
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605802800,
"start_time": 1605801000
},
{
"emails": [
"[email protected]"
],
"end_time": 1605804600,
"start_time": 1605802800
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605803400,
"start_time": 1605801600
},
{
"emails": [
"[email protected]"
],
"end_time": 1605805200,
"start_time": 1605803400
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605803400,
"start_time": 1605801600
},
{
"emails": [
"[email protected]"
],
"end_time": 1605805200,
"start_time": 1605803400
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605804000,
"start_time": 1605802200
},
{
"emails": [
"[email protected]"
],
"end_time": 1605805800,
"start_time": 1605804000
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605804000,
"start_time": 1605802200
},
{
"emails": [
"[email protected]"
],
"end_time": 1605805800,
"start_time": 1605804000
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605804600,
"start_time": 1605802800
},
{
"emails": [
"[email protected]"
],
"end_time": 1605806400,
"start_time": 1605804600
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605804600,
"start_time": 1605802800
},
{
"emails": [
"[email protected]"
],
"end_time": 1605806400,
"start_time": 1605804600
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605805200,
"start_time": 1605803400
},
{
"emails": [
"[email protected]"
],
"end_time": 1605807000,
"start_time": 1605805200
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605805200,
"start_time": 1605803400
},
{
"emails": [
"[email protected]"
],
"end_time": 1605807000,
"start_time": 1605805200
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605811200,
"start_time": 1605809400
},
{
"emails": [
"[email protected]"
],
"end_time": 1605813000,
"start_time": 1605811200
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605811800,
"start_time": 1605810000
},
{
"emails": [
"[email protected]"
],
"end_time": 1605813600,
"start_time": 1605811800
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605812400,
"start_time": 1605810600
},
{
"emails": [
"[email protected]"
],
"end_time": 1605814200,
"start_time": 1605812400
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605813000,
"start_time": 1605811200
},
{
"emails": [
"[email protected]"
],
"end_time": 1605814800,
"start_time": 1605813000
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605813000,
"start_time": 1605811200
},
{
"emails": [
"[email protected]"
],
"end_time": 1605814800,
"start_time": 1605813000
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605813600,
"start_time": 1605811800
},
{
"emails": [
"[email protected]"
],
"end_time": 1605815400,
"start_time": 1605813600
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605813600,
"start_time": 1605811800
},
{
"emails": [
"[email protected]"
],
"end_time": 1605815400,
"start_time": 1605813600
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605814200,
"start_time": 1605812400
},
{
"emails": [
"[email protected]"
],
"end_time": 1605816000,
"start_time": 1605814200
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605814200,
"start_time": 1605812400
},
{
"emails": [
"[email protected]"
],
"end_time": 1605816000,
"start_time": 1605814200
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605814800,
"start_time": 1605813000
},
{
"emails": [
"[email protected]"
],
"end_time": 1605816600,
"start_time": 1605814800
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605815400,
"start_time": 1605813600
},
{
"emails": [
"[email protected]"
],
"end_time": 1605817200,
"start_time": 1605815400
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605816000,
"start_time": 1605814200
},
{
"emails": [
"[email protected]"
],
"end_time": 1605817800,
"start_time": 1605816000
}
],
[
{
"emails": [
"[email protected]"
],
"end_time": 1605826800,
"start_time": 1605825000
},
{
"emails": [
"[email protected]"
],
"end_time": 1605828600,
"start_time": 1605826800
}
]
]
Learn More
Review the Availability APIs.
Collective meetings
Collective meetings allow for an organizer to host an event with another organizer or an assigned attendee. Attendees can select mutually available time slots for the event. This applies for both internal and external participants. Use the Availability for a Single Meeting endpoint for each of the options.
- With
free_busy
- Using calendars from multiple providers
- Round-robin with
max-availability
for participants within the same organization - Round-robin with
max-fairness
for participants within the same organization
Check collective availability with Free/Busy
This option uses free_busy
object information.
curl --location --request POST 'https://api.nylas.com/calendars/availability' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--data-raw '{
"duration_minutes": 15,
"start_time": 1647889200,
"end_time": 1647900000,
"interval_minutes": 5,
"emails": [
"[email protected]",
"[email protected]",
"[email protected]"
],
"free_busy": [
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1647889200,
"end_time": 1647896400,
"object": "time_slot",
"status": "busy"
}
]
},
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1647889200,
"end_time": 1647896400,
"object": "time_slot",
"status": "busy"
}
]
},
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1647889200,
"end_time": 1647896400,
"object": "time_slot",
"status": "busy"
}
]
}
]
}'
{
"object": "availability",
"time_slots": [
{
"end": 1647897300,
"end_time": 1647897300,
"object": "time_slot",
"start": 1647896400,
"start_time": 1647896400,
"status": "free"
},
{
"end": 1647897600,
"end_time": 1647897600,
"object": "time_slot",
"start": 1647896700,
"start_time": 1647896700,
"status": "free"
},
{
"end": 1647897900,
"end_time": 1647897900,
"object": "time_slot",
"start": 1647897000,
"start_time": 1647897000,
"status": "free"
},
{
"end": 1647898200,
"end_time": 1647898200,
"object": "time_slot",
"start": 1647897300,
"start_time": 1647897300,
"status": "free"
},
{
"end": 1647898500,
"end_time": 1647898500,
"object": "time_slot",
"start": 1647897600,
"start_time": 1647897600,
"status": "free"
},
{
"end": 1647898800,
"end_time": 1647898800,
"object": "time_slot",
"start": 1647897900,
"start_time": 1647897900,
"status": "free"
},
{
"end": 1647899100,
"end_time": 1647899100,
"object": "time_slot",
"start": 1647898200,
"start_time": 1647898200,
"status": "free"
},
{
"end": 1647899400,
"end_time": 1647899400,
"object": "time_slot",
"start": 1647898500,
"start_time": 1647898500,
"status": "free"
},
{
"end": 1647899700,
"end_time": 1647899700,
"object": "time_slot",
"start": 1647898800,
"start_time": 1647898800,
"status": "free"
},
{
"end": 1647900000,
"end_time": 1647900000,
"object": "time_slot",
"start": 1647899100,
"start_time": 1647899100,
"status": "free"
}
]
}
Check collective availability from multiple providers
This option for collective meetings uses calendars from multiple providers.
curl --location --request POST 'https://api.nylas.com/calendars/availability' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--data-raw '{
"duration_minutes": 15,
"start_time": 1647892800,
"end_time": 1647907200,
"interval_minutes": 5,
"emails": [
"[email protected]",
"[email protected]"
],
"free_busy": [],
"calendars": [
{
"account_id": "<ACCOUNT_ID>",
"calendar_ids": ["<CALENDAR_ID>", "<CALENDAR_ID>"]
},
{
"account_id": "<ACCOUNT_ID>",
"calendar_ids": ["<CALENDAR_ID>"]
}
]
}'
{
"object": "availability",
"time_slots": [
{
"end": 1647906300,
"end_time": 1647906300,
"object": "time_slot",
"start": 1647905400,
"start_time": 1647905400,
"status": "free"
},
{
"end": 1647906600,
"end_time": 1647906600,
"object": "time_slot",
"start": 1647905700,
"start_time": 1647905700,
"status": "free"
},
{
"end": 1647906900,
"end_time": 1647906900,
"object": "time_slot",
"start": 1647906000,
"start_time": 1647906000,
"status": "free"
},
{
"end": 1647907200,
"end_time": 1647907200,
"object": "time_slot",
"start": 1647906300,
"start_time": 1647906300,
"status": "free"
}
]
}
Check collective meetings using Round-Robin with max availability
This example checks availability for participants in the same organization.
curl --location --request POST 'https://api.nylas.com/calendars/availability' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--data-raw '{
"duration_minutes": 15,
"start_time": 1647986400,
"end_time": 1647993600,
"interval_minutes": 5,
"emails": [
"[email protected]",
"[email protected]"
],
"free_busy": [],
"buffer": 30,
"round_robin": "max-availability",
"open_hours": [
{
"emails": [
"[email protected]",
"[email protected]"
],
"days": [
0,
1,
2,
3,
4
],
"timezone": "America/Los_Angeles",
"start": "10:00",
"end": "16:00",
"object_type": "open_hours"
}
]
}'
{
"object": "availability",
"order": [
"[email protected]",
"[email protected]"
],
"time_slots": [
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647987300,
"end_time": 1647987300,
"object": "time_slot",
"start": 1647986400,
"start_time": 1647986400,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647987600,
"end_time": 1647987600,
"object": "time_slot",
"start": 1647986700,
"start_time": 1647986700,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647987900,
"end_time": 1647987900,
"object": "time_slot",
"start": 1647987000,
"start_time": 1647987000,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647988200,
"end_time": 1647988200,
"object": "time_slot",
"start": 1647987300,
"start_time": 1647987300,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647988500,
"end_time": 1647988500,
"object": "time_slot",
"start": 1647987600,
"start_time": 1647987600,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647988800,
"end_time": 1647988800,
"object": "time_slot",
"start": 1647987900,
"start_time": 1647987900,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647989100,
"end_time": 1647989100,
"object": "time_slot",
"start": 1647988200,
"start_time": 1647988200,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647989400,
"end_time": 1647989400,
"object": "time_slot",
"start": 1647988500,
"start_time": 1647988500,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647989700,
"end_time": 1647989700,
"object": "time_slot",
"start": 1647988800,
"start_time": 1647988800,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647990000,
"end_time": 1647990000,
"object": "time_slot",
"start": 1647989100,
"start_time": 1647989100,
"status": "free"
}
]
}
Check collective meetings using Round-Robin with max fairness
The examples below are for collective meetings using round-robin with max-fairness
. This option returns time slots with at least 50% of available participants. Excluded participants are ordered from most recently booked. If max-fairness
has no available slots, the results return information from max-availability
.
curl --location --request POST 'https://api.nylas.com/calendars/availability' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--data-raw '{
"duration_minutes": 15,
"start_time": 1647986400,
"end_time": 1647993600,
"interval_minutes": 5,
"emails": [
"[email protected]",
"[email protected]",
"[email protected]"
],
"free_busy": [],
"buffer": 30,
"round_robin": "max-fairness",
"open_hours": [
{
"emails": [
"[email protected]",
"[email protected]",
"[email protected]"
],
"days": [
0,
1,
2,
3,
4
],
"timezone": "America/Los_Angeles",
"start": "10:00",
"end": "16:00",
"object_type": "open_hours"
}
]
}'
{
"object": "availability",
"order": [
"[email protected]",
"[email protected]"
],
"time_slots": [
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647987300,
"end_time": 1647987300,
"object": "time_slot",
"start": 1647986400,
"start_time": 1647986400,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647987600,
"end_time": 1647987600,
"object": "time_slot",
"start": 1647986700,
"start_time": 1647986700,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647987900,
"end_time": 1647987900,
"object": "time_slot",
"start": 1647987000,
"start_time": 1647987000,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647988200,
"end_time": 1647988200,
"object": "time_slot",
"start": 1647987300,
"start_time": 1647987300,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647988500,
"end_time": 1647988500,
"object": "time_slot",
"start": 1647987600,
"start_time": 1647987600,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647988800,
"end_time": 1647988800,
"object": "time_slot",
"start": 1647987900,
"start_time": 1647987900,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647989100,
"end_time": 1647989100,
"object": "time_slot",
"start": 1647988200,
"start_time": 1647988200,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647989400,
"end_time": 1647989400,
"object": "time_slot",
"start": 1647988500,
"start_time": 1647988500,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647989700,
"end_time": 1647989700,
"object": "time_slot",
"start": 1647988800,
"start_time": 1647988800,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1647990000,
"end_time": 1647990000,
"object": "time_slot",
"start": 1647989100,
"start_time": 1647989100,
"status": "free"
}
]
}
Group meetings
Group meetings involve a single organizer creating an event with multiple invitees and attendees. The organizer sets a single event time and a maximum capacity for attendees.
Use the Create an Event or Update an Event endpoints with the capacity
field in the request body. The capacity
field defaults to -1
to set no limit on attendees.
If the participant count for the event exceeds the capacity
field, Nylas returns a 400
error response with the updated message.
Example: Group meetings request body
The capacity
field allows for hosts to control the number of attendees and participants for the event. View the sample JSON request body below. If this field isn't included, the default value is -1
for unlimited attendees.
{
"title": "Fireside Forum",
"when": {
"start_time": 1649991600,
"end_time": 1649995200,
"start_timezone": "America/Toronto",
"end_timezone": "America/Toronto"
},
"round_robin_order": [],
"capacity": 5,
"calendar_id":"<calendar_id>",
"participants": [
{
"email": "<participant email>"
}
]
}
Virtual Calendars
To use Virtual Calendars with Calendar Availability, pass in any events, busy time slots, or times you don't want booked from the Virtual Calendar to the free_busy
object.
Learn More
Check out our guide on Virtual Calendar availability.
Availability examples
Use these examples as a quick reference when making calendar availability requests.
Check availability in same organization
The following JSON snippets show responses to availability requests made to accounts in the same organization.
/calendars/availability/consecutive
requires emails to be entered as a 2D array.
{
"duration_minutes": 30,
"start_time": 1600890568,
"end_time": 1600999200,
"interval_minutes": 10,
"emails": [
"[email protected]",
"[email protected]"
]
}
{
"duration_minutes": 30,
"start_time": 1605794400,
"end_time": 1605826800,
"interval_minutes": 10,
"emails": [
["[email protected]"],
["[email protected]"]
],
"free_busy": []
}
Check availability for accounts outside the organization
The following JSON snippets show responses to availability requests made to accounts in different organizations.
{
"duration_minutes": 30,
"start_time": 1601042400,
"end_time": 1601085600,
"interval_minutes": 10,
"emails": [
"[email protected]",
"[email protected]"
],
"free_busy": [
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1601042400,
"end_time": 1601044200,
"object": "time_slot",
"status": "busy"
}
]
},
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1601042400,
"end_time": 1601044200,
"object": "time_slot",
"status": "busy"
}
]
},
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1601047800,
"end_time": 1601051400,
"object": "time_slot",
"status": "busy"
}
]
}
]
}
{
"duration_minutes": 30,
"start_time": 1605794400,
"end_time": 1605826800,
"interval_minutes": 10,
"emails": [
["[email protected]"],
["[email protected]"]
],
"free_busy": [
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1605819600,
"end_time": 1605821400,
"object": "time_slot",
"status": "busy"
}
]
}
]
}
Check availability with open hours
The following JSON snippets show responses to availability requests made using open hours.
- Accounts outside the organization are entered in the free_busy array.
/calendars/availability/consecutive
requires emails to be entered as a 2D array.- Open hours are optional when checking availability.
{
"duration_minutes": 30,
"start_time": 1605794400,
"end_time": 1605826800,
"interval_minutes": 10,
"emails": [
"[email protected]",
"[email protected]",
"[email protected]"
],
"free_busy": [
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1605819600,
"end_time": 1605821400,
"object": "time_slot",
"status": "busy"
}
]
}
],
"open_hours": [
{
"emails": [
"[email protected]",
"[email protected]",
],
"days": [
0,
1,
2,
3,
4,
5,
6
],
"timezone": "America/Chicago",
"start": "10:00",
"end": "14:00",
"object_type": "open_hours"
}
]
}
{
"duration_minutes": 30,
"start_time": 1605794400,
"end_time": 1605826800,
"interval_minutes": 10,
"emails": [
["[email protected]"],
["[email protected]"]
],
"free_busy": [
{
"email": "[email protected]",
"object": "free_busy",
"time_slots": [
{
"start_time": 1605819600,
"end_time": 1605821400,
"object": "time_slot",
"status": "busy"
}
]
}
],
"open_hours": [
{
"emails": [
"[email protected]"
],
"days": [
0,
1,
2,
3,
4,
5,
6
],
"timezone": "America/Chicago",
"start": "10:00",
"end": "14:00",
"object_type": "open_hours"
}
]
}
Check for Free/Busy
The following JSON snippet shows a response to a Free/Busy request.
- Can only check accounts within your organization.
{
"start_time":"1600890568",
"end_time":"1600999200",
"emails": ["[email protected]"]
}
{
"start_time":"1600890568",
"end_time":"1600999200",
"emails": ["[email protected]"]
}
Round-Robin
You can use round-robin scheduling to check availability for a single meeting.
Round-robin accepts:
null
max-availability
max-fairness
Null
Will return times when everyone is available.
Max availability
Max availability will return all time slots where at least one person specified in free_busy
, calendars
, or emails
is available.
Example: Max availability request
The example below shows a list of available time slots for a single person along with the list of configured participants.
curl --request POST \
--url https://api.nylas.com/calendars/availability \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"duration_minutes": 60,
"interval_minutes": 60,
"start_time": 1634734800,
"end_time": 1634749200,
"emails": [],
"free_busy": [],
"round_robin": "max-availability",
"calendars": [
{
"account_id": "exampleaccountid1",
"calendar_ids": [
"examplecalendaridA",
"examplecalendaridB"
]
},
{
"account_id": "exampleaccountid2",
"calendar_ids": [
"examplecalendaridC",
]
}
]
}'
// This response includes the order of emails for a time slots with multiple emails. The suggestions are preferences based on the most recently created Event.
{
"object": "availability",
"order": [
"[email protected]",
"[email protected]"
],
"time_slots": [
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1634738400,
"object": "time_slot",
"start": 1634734800,
"status": "free"
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"end": 1634742000,
"object": "time_slot",
"start": 1634738400,
"status": "free"
},
{
"emails": [
"[email protected]"
],
"end": 1634745600,
"object": "time_slot",
"start": 1634742000,
"status": "free"
},
{
"emails": [
"[email protected]"
],
"end": 1634749200,
"object": "time_slot",
"start": 1634745600,
"status": "free"
}
]
}
Max fairness
Max fairness will return time slots where the least recently booked 50% of people are available. Max fairness defaults to max-availability if no time slots are found. Max fairness is calculated using the round_robin_order
from Create Event.
To use max-fairness
you need to create a new event with an array of emails in round_robin_order
.
Consecutive availability meeting parameter
The /calendars/availability/consecutive accepts a parameter, meetings
. Meetings allow an organizer to see consecutive meeting times with breaks in between.
Available times for consecutive meetings
To find meeting times add the meetings
array. It will look for meetings times that match and are consecutive between each group of emails. You can also specify meeting length by adding duration_minutes
.
The following JSON snippet shows an account's available times for consecutive meetings.
{
"start_time": 1633374000,
"end_time": 1633381200,
"interval_minutes": 15,
"free_busy": [
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": [
{
"status": "busy",
"start_time": 300,
"object": "time_slot",
"end_time": 1699
}
]
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
}
],
"meetings": [
{
"emails": [
"[email protected]",
"[email protected]",
"[email protected]"
],
"duration_minutes": 45
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"duration_minutes": 15
},
{
"emails": [
"[email protected]"
]
},
{
"emails": [
"[email protected]"
]
}
]
}
Available time with gaps
The following JSON code sample will look for meetings that have time slots between them. To specify time between meetings, pass in an empty
emails array with duration_minutes
. The duration_minutes
will indicate the time between the meetings.
{
"start_time": 1633374000,
"end_time": 1633381200,
"interval_minutes": 15,
"free_busy": [
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": [
{
"status": "busy",
"start_time": 300,
"object": "time_slot",
"end_time": 1699
}
]
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
}
],
"meetings": [
{
"emails": [
"[email protected]",
"[email protected]",
"[email protected]"
],
"duration_minutes": 10
},
{
"emails": [
"[email protected]",
"[email protected]",
],
"duration_minutes": 5
},
{
"emails": [
"[email protected]"
]
},
{
"emails": [],
"duration_minutes": 5,
}
]
}
Meetings array limitations
There are a few things to keep in mind when adding meetings
.
-
If
meetings.emails
is present, then theemails
is ignored. -
If
meetings.duration_minutes
is present, thenduration_minutes
is ignored, as in the JSON snippet below, the following behavior is true.- The response returns a minimum of 1 and a maximum of 10,000.
- The maximum number of meetings is 500.
- If
meeting.duration_minutes
is used, thenduration_minutes
is ignored. - If
meeting.emails
is used, thenemails
is ignored. - If
meetings.emails
is empty, butduration_minutes
is present, then it is treated as a meeting gap. - Meeting gaps are not scheduled, at the start of the meeting, at the end of the meeting, or next to another gap.
{
"start_time": 1633374000,
"end_time": 1633381200,
"duration_minutes": 30, // This duration integer is ignored if meetings.duration_minutes are added.
"interval_minutes": 15,
"emails": [
["[email protected]", "[email protected]"], // This emails array is ignored, if meetings.emails are added.
],
"free_busy": [
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": [
{
"status": "busy",
"start_time": 300,
"object": "time_slot",
"end_time": 1699
}
]
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
},
{
"object": "free_busy",
"email": "[email protected]",
"time_slots": []
}
],
"meetings": [
{
"emails": [
"[email protected]",
"[email protected]",
"[email protected]"
],
"duration_minutes": 10
},
{
"emails": [
"[email protected]",
"[email protected]"
],
"duration_minutes": 5
},
{
"emails": [
"[email protected]"
]
},
{
"emails": [],
"duration_minutes": 5,
}
]
}