curl --request GET \
--url https://api.cal.com/v2/slots \
--header 'Authorization: Bearer <token>' \
--header 'cal-api-version: <cal-api-version>'import requests
url = "https://api.cal.com/v2/slots"
headers = {
"cal-api-version": "<cal-api-version>",
"Authorization": "Bearer <token>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {'cal-api-version': '<cal-api-version>', Authorization: 'Bearer <token>'}
};
fetch('https://api.cal.com/v2/slots', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cal.com/v2/slots",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"cal-api-version: <cal-api-version>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.cal.com/v2/slots"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("cal-api-version", "<cal-api-version>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.cal.com/v2/slots")
.header("cal-api-version", "<cal-api-version>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cal.com/v2/slots")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["cal-api-version"] = '<cal-api-version>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"status": "success",
"data": {
"2033-09-05": [
{
"start": "2033-09-05T09:00:00.000+02:00"
},
{
"start": "2033-09-05T10:00:00.000+02:00"
}
],
"2033-09-06": [
{
"start": "2033-09-06T09:00:00.000+02:00"
},
{
"start": "2033-09-06T10:00:00.000+02:00"
}
]
}
}Get available time slots for an event type
There are 4 ways to get available slots for event type of an individual user:
-
By event type id. Example ‘/v2/slots?eventTypeId=10&start=2033-09-05&end=2033-09-06&timeZone=Europe/Rome’
-
By event type slug + username. Example ‘/v2/slots?eventTypeSlug=intro&username=bob&start=2033-09-05&end=2033-09-06’
-
By event type slug + username + organization slug when searching within an organization. Example ‘/v2/slots?organizationSlug=org-slug&eventTypeSlug=intro&username=bob&start=2033-09-05&end=2033-09-06’
-
By usernames only (used for dynamic event type - there is no specific event but you want to know when 2 or more people are available). Example ‘/v2/slots?usernames=alice,bob&username=bob&organizationSlug=org-slug&start=2033-09-05&end=2033-09-06’. As you see you also need to provide the slug of the organization to which each user in the ‘usernames’ array belongs.
And 3 ways to get available slots for team event type:
-
By team event type id. Example ‘/v2/slots?eventTypeId=10&start=2033-09-05&end=2033-09-06&timeZone=Europe/Rome’. Note for managed event types: Managed event types are templates that create individual child event types for each team member. You cannot fetch slots for the parent managed event type directly. Instead, you must:
- Find the child event type IDs (the ones assigned to specific users)
- Use those child event type IDs to fetch slots as individual user event types using as described in the individual user section above.
-
By team event type slug + team slug. Example ‘/v2/slots?eventTypeSlug=intro&teamSlug=team-slug&start=2033-09-05&end=2033-09-06’
-
By team event type slug + team slug + organization slug when searching within an organization. Example ‘/v2/slots?organizationSlug=org-slug&eventTypeSlug=intro&teamSlug=team-slug&start=2033-09-05&end=2033-09-06’
All of them require “start” and “end” query parameters which define the time range for which available slots should be checked. Optional parameters are:
- timeZone: Time zone in which the available slots should be returned. Defaults to UTC.
- duration: Only use for event types that allow multiple durations or for dynamic event types. If not passed for multiple duration event types defaults to default duration. For dynamic event types defaults to 30 aka each returned slot is 30 minutes long. So duration=60 means that returned slots will be each 60 minutes long.
- format: Format of the slots. By default return is an object where each key is date and value is array of slots as string. If you want to get start and end of each slot use “range” as value.
- bookingUidToReschedule: When rescheduling an existing booking, provide the booking’s unique identifier to exclude its time slot from busy time calculations. This ensures the original booking time appears as available for rescheduling.
curl --request GET \
--url https://api.cal.com/v2/slots \
--header 'Authorization: Bearer <token>' \
--header 'cal-api-version: <cal-api-version>'import requests
url = "https://api.cal.com/v2/slots"
headers = {
"cal-api-version": "<cal-api-version>",
"Authorization": "Bearer <token>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {'cal-api-version': '<cal-api-version>', Authorization: 'Bearer <token>'}
};
fetch('https://api.cal.com/v2/slots', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cal.com/v2/slots",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"cal-api-version: <cal-api-version>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.cal.com/v2/slots"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("cal-api-version", "<cal-api-version>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.cal.com/v2/slots")
.header("cal-api-version", "<cal-api-version>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cal.com/v2/slots")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["cal-api-version"] = '<cal-api-version>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"status": "success",
"data": {
"2033-09-05": [
{
"start": "2033-09-05T09:00:00.000+02:00"
},
{
"start": "2033-09-05T10:00:00.000+02:00"
}
],
"2033-09-06": [
{
"start": "2033-09-06T09:00:00.000+02:00"
},
{
"start": "2033-09-06T10:00:00.000+02:00"
}
]
}
}Authorizations
Headers
Query Parameters
Time starting from which available slots should be checked.
Must be in UTC timezone as ISO 8601 datestring.
You can pass date without hours which defaults to start of day or specify hours:
2024-08-13 (will have hours 00:00:00 aka at very beginning of the date) or you can specify hours manually like 2024-08-13T09:00:00Z.
"2033-09-05"
Time until which available slots should be checked.
Must be in UTC timezone as ISO 8601 datestring.
You can pass date without hours which defaults to end of day or specify hours:
2024-08-20 (will have hours 23:59:59 aka at the very end of the date) or you can specify hours manually like 2024-08-20T18:00:00Z.
"2033-09-06"
The usernames for which available slots should be checked separated by a comma.
Checking slots by usernames is used mainly for dynamic events where there is no specific event but we just want to know when 2 or more people are available.
Must contain at least 2 usernames.
"alice,bob"
Response
A map of available slots indexed by date, where each date is associated with an array of time slots. If format=range is specified, each slot will be an object with start and end properties denoting start and end of the slot. For seated slots each object will have attendeesCount and bookingUid properties. If no slots are available, the data field will be an empty object {}.
Was this page helpful?