curl --request GET \
--url https://api.cal.com/v2/discover/listings \
--header 'Authorization: <authorization>'import requests
url = "https://api.cal.com/v2/discover/listings"
headers = {"Authorization": "<authorization>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<authorization>'}};
fetch('https://api.cal.com/v2/discover/listings', 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/discover/listings",
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: <authorization>"
],
]);
$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/discover/listings"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "<authorization>")
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/discover/listings")
.header("Authorization", "<authorization>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cal.com/v2/discover/listings")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = '<authorization>'
response = http.request(request)
puts response.read_body{
"status": "success",
"data": {
"listings": [
{
"listingId": 12,
"service": "Deep tissue massage",
"provider": "Riverside Massage",
"priceInCents": 9000,
"currency": "usd",
"price": "$90.00",
"newClientDiscountPercent": 15,
"rating": 4.8,
"reviewCount": 132,
"verified": true,
"durationMinutes": 60,
"online": false,
"city": "Austin",
"neighborhood": "Zilker",
"timeZone": "America/Chicago",
"nextAvailableChecked": true,
"nextAvailableSlot": "2026-11-10T15:00:00.000Z"
}
],
"notFoundListingIds": [
56
]
}
}Get Discover listings by id
Returns published Discover listings by id, with the fields their public cards show: service name, provider, price, new-client discount, the provider’s rating, review count and verification, duration, whether it is online, city, neighborhood and the business’s time zone. With includeNextAvailable, also the earliest open slot in the next 7 days for the first 10 listings. Any id that is not a published listing is returned in notFoundListingIds. Requests with includeNextAvailable are limited to 60 per minute per user, shared across all of the user’s API keys and access tokens. If accessed using an OAuth access token, the EVENT_TYPE_READ scope is required.
curl --request GET \
--url https://api.cal.com/v2/discover/listings \
--header 'Authorization: <authorization>'import requests
url = "https://api.cal.com/v2/discover/listings"
headers = {"Authorization": "<authorization>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<authorization>'}};
fetch('https://api.cal.com/v2/discover/listings', 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/discover/listings",
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: <authorization>"
],
]);
$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/discover/listings"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "<authorization>")
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/discover/listings")
.header("Authorization", "<authorization>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cal.com/v2/discover/listings")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = '<authorization>'
response = http.request(request)
puts response.read_body{
"status": "success",
"data": {
"listings": [
{
"listingId": 12,
"service": "Deep tissue massage",
"provider": "Riverside Massage",
"priceInCents": 9000,
"currency": "usd",
"price": "$90.00",
"newClientDiscountPercent": 15,
"rating": 4.8,
"reviewCount": 132,
"verified": true,
"durationMinutes": 60,
"online": false,
"city": "Austin",
"neighborhood": "Zilker",
"timeZone": "America/Chicago",
"nextAvailableChecked": true,
"nextAvailableSlot": "2026-11-10T15:00:00.000Z"
}
],
"notFoundListingIds": [
56
]
}
}Headers
value must be Bearer <token> where <token> is api key prefixed with cal_, managed user access token, or OAuth access token
Query Parameters
Discover listing ids, such as the listingId values a Discover search returned. Repeat the parameter (ids=12&ids=34) or separate the ids with commas (ids=12,34). Duplicates are read once.
1 - 50 elements1 <= x <= 2147483647[12, 34]
Also look up each listing's earliest open slot in the next 7 days. Only the first 10 listings are checked, so list the ones you care about first.
true
Was this page helpful?