curl --request POST \
--url https://api.cal.id/booking/{id}/cancel \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"cancellationReason": "Rescheduling required"
}
'import requests
url = "https://api.cal.id/booking/{id}/cancel"
payload = { "cancellationReason": "Rescheduling required" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({cancellationReason: 'Rescheduling required'})
};
fetch('https://api.cal.id/booking/{id}/cancel', 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.id/booking/{id}/cancel",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'cancellationReason' => 'Rescheduling required'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cal.id/booking/{id}/cancel"
payload := strings.NewReader("{\n \"cancellationReason\": \"Rescheduling required\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cal.id/booking/{id}/cancel")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"cancellationReason\": \"Rescheduling required\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cal.id/booking/{id}/cancel")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cancellationReason\": \"Rescheduling required\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"success": true,
"message": "Booking cancelled",
"onlyRemovedAttendee": false,
"bookingId": 5312,
"bookingUid": "bk_9f2c1d7a4e"
},
"message": "Booking cancelled"
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "Rate limit exceeded",
"error": {
"code": "TOO_MANY_REQUESTS",
"message": "Too many requests. Please retry after the rate limit window resets."
}
}Cancel a booking
Cancels a booking and notifies the host and attendees. Optional body fields control the scope: cancellationReason is recorded on the booking, allRemainingBookings cancels the rest of a recurring series, seatReferenceUid removes a single attendee from a seated event — which returns onlyRemovedAttendee: true and leaves the booking itself standing — and autoRefund handles payment reversal. Cancelling is not reversible; if the meeting is still going ahead at a different time, use PATCH /booking/{id}/reschedule instead.
curl --request POST \
--url https://api.cal.id/booking/{id}/cancel \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"cancellationReason": "Rescheduling required"
}
'import requests
url = "https://api.cal.id/booking/{id}/cancel"
payload = { "cancellationReason": "Rescheduling required" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({cancellationReason: 'Rescheduling required'})
};
fetch('https://api.cal.id/booking/{id}/cancel', 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.id/booking/{id}/cancel",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'cancellationReason' => 'Rescheduling required'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cal.id/booking/{id}/cancel"
payload := strings.NewReader("{\n \"cancellationReason\": \"Rescheduling required\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cal.id/booking/{id}/cancel")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"cancellationReason\": \"Rescheduling required\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cal.id/booking/{id}/cancel")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cancellationReason\": \"Rescheduling required\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"success": true,
"message": "Booking cancelled",
"onlyRemovedAttendee": false,
"bookingId": 5312,
"bookingUid": "bk_9f2c1d7a4e"
},
"message": "Booking cancelled"
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"message": "Rate limit exceeded",
"error": {
"code": "TOO_MANY_REQUESTS",
"message": "Too many requests. Please retry after the rate limit window resets."
}
}Authorizations
Use the Authorization header with Bearer scheme.
Examples:
- API Key: Authorization: Bearer calid_xxxxx
Path Parameters
Numeric booking identifier.
x > 1101
Body
Optional controls for cancellation scope, seated-event seat cancellation, and payment refund handling.
Optional controls for cancellation scope, seated-event seat cancellation, and payment refund handling.
When true, cancels all remaining future bookings in the recurring series from now onward.
false
Optional reason stored on cancelled booking records and used in cancellation notifications.
"Rescheduling required"
Optional seat reference UID for cancelling a specific attendee seat in seated event types.
"seat_123"
Optional actor email recorded as the canceller (cancelledBy) on the booking.
"owner@example.com"
When true, attempts payment cancellation/refund for paid bookings and marks booking payment metadata as refunded.
false
Was this page helpful?