# Get free/busy schedule

> **POST** `https://api.us.nylas.com/v3/grants/{grant_id}/calendars/free-busy`

Source: https://developer.nylas.com/docs/reference/api/calendar/post-calendars-free-busy/

(Not supported for iCloud) Returns the free/busy schedule for the specified
list of email addresses.

### Keep in mind

- The grant ID included in the request _must_ have access to view the provided email addresses'
free/busy data. This is usually configured by the provider.
- All specified email addresses must use the same provider.
- This endpoint always returns `200 OK`, even if one of the responses returns an error. Be sure
to check for any errors in the list of responses.
- Microsoft's availability calculation is limited to a maximum of 1,000 entries per time slot for
each email address included in the request.
- The free/busy response does not include all-day room resource bookings on Google or Microsoft.
- You can include up to 20 email addresses for Microsoft Graph, and up to 50 email addresses for Google in a single request.

**Authentication:** NYLAS_API_KEY, ACCESS_TOKEN

## Parameters

### Path parameters

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `grant_id` | string | Yes | ID of the grant to access. Use `/me/` to refer to the grant associated with an access token. |

## Request body

Content-Type: application/json

- `start_time` (integer) **(required)** - The start of a time block, in seconds using the Unix timestamp format. Nylas uses `start_time` and `end_time` to assess
the specified account's free/busy schedule.
- `end_time` (integer) **(required)** - The end of a time block, in seconds using the Unix timestamp format. Nylas uses `start_time` and `end_time` to
assess the specified account's free/busy schedule.

For Google and EWS accounts, Nylas can query a timespan of up to 3 months from the `start_time`.

For Microsoft Graph accounts, Nylas can query a timespan of up to 62 days from the `start_time`.
- `emails` (array) **(required)** - A list of email addresses to check the free/busy schedules for.
- `tentative_as_busy` (boolean) - When `true`, Nylas treats tentative events as busy.

## Responses

### 200 - Free/Busy Response

- `request_id` (string) - The request ID.
- `data` (array) - An array of free/busy schedules. Nylas returns one free/busy schedule for each email address
specified in the request.
  - `email` (string) - The participant's email address.
  - `time_slots` (array,null) - An array of busy time slots. This field may be `null` when a free/busy lookup returns
an error for a specific email address.
  - `error` (string) - If Nylas encounters an error fetching data for a participant, this field contains
a description of the error.
  - `object` (string) - The object type. If the request succeeds, the value is `free_busy`. If the request
fails, the value is `error`.

### 400 - Bad Request

- `request_id` (string) - The request ID.
- `error` (object) - The response error object.
  - `type` (string) - The error type.
  - `message` (string) - The error message.
  - `provider_error` (object) - The error from the provider.

### 401 - Unauthorized

- `request_id` (string) - The request ID.
- `error` (object) - The response error object.
  - `type` (string) - The error type.
  - `message` (string) - The error message.
  - `provider_error` (object) - The error from the provider.

### 429 - Rate Limit

- `request_id` (string) - The request ID.
- `error` (object) - The response error object.
  - `type` (string) - The error type.
  - `message` (string) - The error message.

### 504 - Provider Failure

- `request_id` (string) - The request ID.
- `error` (object) - The response error object.
  - `type` (string) - The error type.
  - `message` (string) - The error message.

## Code samples

### cURL

```bash
curl --compressed --request POST \
	--url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/calendars/free-busy' \
	--header 'Accept: application/json' \
	--header 'Authorization: Bearer <NYLAS_API_KEY>' \
	--header 'Content-Type: application/json' \
	--data '{
		"start_time": 1682467200,
		"end_time": 1682550000,
		"emails": ["leyah@example.com"]
	}'
```

### Node.js SDK

```javascript
import Nylas from "nylas";

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

const email = "<EMAIL>";

async function getFreeBusyCalendarInfo() {
  try {
    const calendar = await nylas.calendars.getFreeBusy({
      identifier: "<NYLAS_GRANT_ID>",
      requestBody: {
        startTime: 1630435200,
        endTime: 1630521600,
        emails: [email],
      },
    });

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

getFreeBusyCalendarInfo();

```

### Python SDK

```python
from nylas import Client

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

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

free_busy = nylas.calendars.get_free_busy(
  grant_id,
  request_body={
    "start_time":1630435200,
    "end_time":1630521600,
    "emails":[email]
  }
)

print(free_busy)
```

### Ruby SDK

```ruby
# Load gems
require 'nylas'
require 'date'

# Initialize Nylas client
nylas = Nylas::Client.new(
	api_key: "<NYLAS_API_KEY>"
)

# Get today’s date
today = Date.today

# When do we start and end searching for availability
start_time = Time.local(today.year, today.month, today.day, 8, 0,0).strftime("%s").to_i
end_time = Time.local(today.year, today.month, today.day, 17, 0,0).strftime("%s").to_i

# Body of our request
request_body = {
		"emails": [
		"<EMAIL_ACCOUNT>"
	],
	"start_time": start_time,
	"end_time": end_time
}

# Call the get_availability endpoint
available, _request_ids = nylas.calendars.get_free_busy(identifier: "<NYLAS_GRANT_ID>", 
request_body: request_body)

# Display available spots
available.each {|time_slots|
	time_slots[:time_slots].each {|slots|
		puts "From: #{Time.at(slots[:start_time]).to_datetime.strftime("%H:%M:%S")}" \
             "To: #{Time.at(slots[:end_time]).to_datetime.strftime("%H:%M:%S")}"
	}
}

```

### Java SDK

```java
// Import Nylas packages
import com.nylas.NylasClient;
import com.nylas.models.*;

// Import Java packages
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

public class FreeBusy {
  public static void main(String[] args) throws Exception {
    NylasClient nylas = new NylasClient.Builder("<NYLAS_API_KEY>").build();

    LocalDate today = LocalDate.now();
    // Our day starts at 8:00am
    Instant sixPmUtc = today.atTime(13, 0).toInstant(ZoneOffset.UTC);
    int startTime = (int) sixPmUtc.getEpochSecond();
    // Add 10 hours, so our day ends at 6:00pm
    Instant sixPmUtcPlus = sixPmUtc.plus(10, ChronoUnit.HOURS);
    int endTime = (int) sixPmUtcPlus.getEpochSecond();

    // Add emails to check Free/Busy
    List<String> emails = new ArrayList<>();
    emails.add("<EMAIL>");

    GetFreeBusyRequest request = new GetFreeBusyRequest(startTime, endTime, emails);

    Response<List<GetFreeBusyResponse>> response = nylas.calendars().
        getFreeBusy("<NYLAS_GRANT_ID>", request);

    for(GetFreeBusyResponse freeBusy : response.getData()) {
      if (freeBusy.getObject() == FreeBusyType.FREE_BUSY) {
        GetFreeBusyResponse.FreeBusy freeBusyData = (GetFreeBusyResponse.FreeBusy) freeBusy;
        List<FreeBusyTimeSlot> times = freeBusyData.getTimeSlots();
        
        for(FreeBusyTimeSlot time : times){
          // Format dates in a readable way
          String startDate = new SimpleDateFormat("HH:mm:ss").
              format(new java.util.Date((time.getStartTime() * 1000L)));
              
          String endDate = new SimpleDateFormat("HH:mm:ss").
              format(new java.util.Date((time.getEndTime() * 1000L)));
                  
          // Print out the time slots
          System.out.println("From: " + startDate + " to: " + endDate);
        }
      } else if (freeBusy.getObject() == FreeBusyType.ERROR) {
        GetFreeBusyResponse.FreeBusyError freeBusyError = (GetFreeBusyResponse.FreeBusyError) freeBusy;
      } else {
        throw new Exception("Unknown free busy type");
      }
    }
  }
}
```

### Kotlin SDK

```kotlin
// Import Nylas packages
import com.nylas.NylasClient
import com.nylas.models.*

// Import Kotlin/Java Packages
import java.lang.Exception
import java.time.LocalDateTime
import java.time.ZoneOffset
import java.util.*

fun main(args: Array<String>) {

    // Initialize Nylas client
    val nylas: NylasClient = NylasClient(
        apiKey = "<NYLAS_API_KEY>"
    )

    // Get today's day
    var startDate = LocalDateTime.now()
    // Set time. As we're using UTC we need to add the hours in difference
    // from our own Timezone
    startDate = startDate.withHour(13);
    startDate = startDate.withMinute(0);
    startDate = startDate.withSecond(0);
    val endDate = startDate.withHour(23);
    val emails : List<String> = listOf("<USER_EMAIL>")

    // Make the request for Free/Busy
    val request : GetFreeBusyRequest = GetFreeBusyRequest(
        startDate.toEpochSecond(ZoneOffset.UTC).toInt(),
        endDate.toEpochSecond(ZoneOffset.UTC).toInt(), emails)

    // Call the Free/Busy endpoint
    val response : Response<List<GetFreeBusyResponse>> = nylas.calendars().
    getFreeBusy("<NYLAS_GRANT_ID>", request)
    // Loop the list of Free/Busy objects
    for(freeBusy in response.data){
        if(freeBusy.getObject() == FreeBusyType.FREE_BUSY){
            // Get the free/busy data
            val freeBusyData: GetFreeBusyResponse.FreeBusy = freeBusy as
                    GetFreeBusyResponse.FreeBusy
            // Get the busy time slots
            val times : List<FreeBusyTimeSlot>  = freeBusyData.timeSlots
            // Loop the busy times
            for(time : FreeBusyTimeSlot in times){
                // Format dates in a readable way
                val startTime = Date(time.startTime.toLong() * 1000)
                val endTime = Date(time.endTime.toLong() * 1000)
                // Print out the time slots
                println("From: $startTime to $endTime")
            }
        }else if(freeBusy.getObject() == FreeBusyType.ERROR){
            val freeBusyData: GetFreeBusyResponse.FreeBusyError = freeBusy as
                    GetFreeBusyResponse.FreeBusyError
        }else{
            throw Exception("Unknown free busy type")
        }
    }
}

```
