curl --request GET \
--url https://spaportal.cz/api/v1/calendar/dates \
--header 'Authorization: Bearer <token>'import requests
url = "https://spaportal.cz/api/v1/calendar/dates"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://spaportal.cz/api/v1/calendar/dates', 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://spaportal.cz/api/v1/calendar/dates",
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>"
],
]);
$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://spaportal.cz/api/v1/calendar/dates"
req, _ := http.NewRequest("GET", url, nil)
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://spaportal.cz/api/v1/calendar/dates")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://spaportal.cz/api/v1/calendar/dates")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body[
{
"date": "2026-12-01",
"selectable": false,
"availability": "NOT_AVAILABLE",
"price": null
},
{
"date": "2026-12-02",
"selectable": true,
"availability": "ON_DEMAND",
"price": {
"is_final": true,
"cs_CZ": {
"amount": 1590,
"currency": "CZK"
},
"de": {
"amount": 61.2857,
"currency": "EUR"
}
}
}
]{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}Get calendar dates
Returns calendar dates with availability and price data. Per-night prices include any active discount promotions.
selectable indicates whether the user can continue the booking flow from the date. It follows the visit type’s date-range and starting-day rules and requires a price for that date, but it does not require recorded capacity for the complete stay. A selectable date can therefore produce an ON_DEMAND booking configuration. Use the booking configuration response to distinguish a stay that can be confirmed from one that can only be requested. price is null when the date is not available or when the query is not specific enough to calculate a final price.
Default month when you omit the date range
Omit both date_from and date_to and the response starts at the first month that contains a stay you can actually book, rather than at the current month. Use this for the initial calendar load, when you do not yet know which month to show.
A month qualifies when it contains a check-in date where all of the following hold for the visit type’s minimum stay length:
- every occupied night has remaining capacity,
- every occupied night has a price, and the check-out date is priced as well,
- the date is an allowed starting day for the visit type.
The check-in date counts as an occupied night; the check-out date does not consume capacity.
The response then covers that month and the following one, as it always does. The search looks up to 24 months ahead.
Months that are closer but only bookable on request are skipped, because no stay in them can be confirmed from recorded availability. If no bookable stay is found, the response keeps the normal fallback calendar instead of returning an empty array. Priced dates that satisfy the visit type’s starting-day and date-range rules remain selectable, including dates whose resulting stay is ON_DEMAND.
This applies when hotel_id and visit_type_id are set and the visit type is not on request. room_type_id is optional. Without it, the API searches the hotel’s room types that match guests; every night of the stay must fit into the same room type, and capacity from different room types is never combined. Send guests on the initial request so the API searches the correct room occupancy. If you omit it, all room occupancies are considered.
Pass date_from or date_to to disable the automatic first-bookable-month search and control the range yourself. A date_from in the past is clamped to the current date.
curl --request GET \
--url https://spaportal.cz/api/v1/calendar/dates \
--header 'Authorization: Bearer <token>'import requests
url = "https://spaportal.cz/api/v1/calendar/dates"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://spaportal.cz/api/v1/calendar/dates', 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://spaportal.cz/api/v1/calendar/dates",
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>"
],
]);
$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://spaportal.cz/api/v1/calendar/dates"
req, _ := http.NewRequest("GET", url, nil)
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://spaportal.cz/api/v1/calendar/dates")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://spaportal.cz/api/v1/calendar/dates")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body[
{
"date": "2026-12-01",
"selectable": false,
"availability": "NOT_AVAILABLE",
"price": null
},
{
"date": "2026-12-02",
"selectable": true,
"availability": "ON_DEMAND",
"price": {
"is_final": true,
"cs_CZ": {
"amount": 1590,
"currency": "CZK"
},
"de": {
"amount": 61.2857,
"currency": "EUR"
}
}
}
]{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}{
"success": false,
"message": "<string>"
}Authorizations
See Authentication for how to obtain and send your API key.
Headers
Comma-separated list of languages to include. See Localization for details.
"cs_CZ,de"
Query Parameters
Visit type ID.
Hotel ID.
Room type ID.
Destination ID.
Number of guests.
1 <= x <= 2Start date in YYYY-MM-DD format.
End date in YYYY-MM-DD format.
Response
Calendar dates with availability and optional price data.
Whether the booking flow can start on this date. This follows price, date-range, and starting-day rules; it does not guarantee capacity for the complete stay. A selectable date may result in an ON_DEMAND booking configuration.
NOT_AVAILABLE, AVAILABLE, ON_DEMAND