Cancel an appointment
Cancels the appointment and frees its seat.
reason is kept with it. The reminder cadence that belonged to the booking is stopped in the same step, so nobody is texted about an appointment that is not happening.
Cookie-auth callers must send the x-csrf-token header.
Required API key scope: projects:write.
POST
/
api
/
native-calendar
/
appointments
/
{appointmentId}
/
cancel
cURL
curl --request POST \
--url https://api.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/cancel \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"reason": "Customer called to cancel."
}'import requests
url = "https://api.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/cancel"
payload = { "reason": "Customer called to cancel." }
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({reason: 'Customer called to cancel.'})
};
fetch('https://api.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/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.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/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([
'reason' => 'Customer called to cancel.'
]),
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.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/cancel"
payload := strings.NewReader("{\n \"reason\": \"Customer called to cancel.\"\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.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/cancel")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reason\": \"Customer called to cancel.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/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 \"reason\": \"Customer called to cancel.\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"ok": true,
"appointmentId": "apt_7d21c0f4a1",
"status": "cancelled"
}
}{
"success": false,
"error": "BadRequest",
"message": "Something here doesn't look right. Please check it and try again."
}{
"success": false,
"error": "Unauthorized",
"message": "Please sign in to continue."
}{
"success": false,
"error": "Forbidden",
"message": "You don't have access to this. Ask your account admin if you need it."
}{
"success": false,
"error": "NotFound",
"message": "We couldn't find that. It may have been moved or deleted."
}{
"success": false,
"error": "TooManyRequests",
"message": "That's a lot at once. Please wait a moment and try again."
}{
"success": false,
"error": "Internal",
"message": "Something went wrong on our side. Please try again in a moment.",
"ref": "3f2b8c1e-7d4a-4f8e-9b6a-2c1d0e5f7a9b"
}{
"success": false,
"error": "ServiceUnavailable",
"message": "This isn't available right now. Please try again in a moment.",
"ref": "3f2b8c1e-7d4a-4f8e-9b6a-2c1d0e5f7a9b"
}Authorizations
Query Parameters
Body
application/json
Why, for the record.
⌘I
cURL
curl --request POST \
--url https://api.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/cancel \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"reason": "Customer called to cancel."
}'import requests
url = "https://api.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/cancel"
payload = { "reason": "Customer called to cancel." }
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({reason: 'Customer called to cancel.'})
};
fetch('https://api.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/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.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/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([
'reason' => 'Customer called to cancel.'
]),
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.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/cancel"
payload := strings.NewReader("{\n \"reason\": \"Customer called to cancel.\"\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.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/cancel")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reason\": \"Customer called to cancel.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.teamfollowup.ai/api/native-calendar/appointments/{appointmentId}/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 \"reason\": \"Customer called to cancel.\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"ok": true,
"appointmentId": "apt_7d21c0f4a1",
"status": "cancelled"
}
}{
"success": false,
"error": "BadRequest",
"message": "Something here doesn't look right. Please check it and try again."
}{
"success": false,
"error": "Unauthorized",
"message": "Please sign in to continue."
}{
"success": false,
"error": "Forbidden",
"message": "You don't have access to this. Ask your account admin if you need it."
}{
"success": false,
"error": "NotFound",
"message": "We couldn't find that. It may have been moved or deleted."
}{
"success": false,
"error": "TooManyRequests",
"message": "That's a lot at once. Please wait a moment and try again."
}{
"success": false,
"error": "Internal",
"message": "Something went wrong on our side. Please try again in a moment.",
"ref": "3f2b8c1e-7d4a-4f8e-9b6a-2c1d0e5f7a9b"
}{
"success": false,
"error": "ServiceUnavailable",
"message": "This isn't available right now. Please try again in a moment.",
"ref": "3f2b8c1e-7d4a-4f8e-9b6a-2c1d0e5f7a9b"
}