> ## Documentation Index
> Fetch the complete documentation index at: https://docs.autocalls.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Cancel & Reschedule Cal.com Appointments

> Learn how to create a mid-call tool that lets your AI assistant cancel or reschedule Cal.com bookings during live phone calls

This tutorial shows how to create a mid-call tool that allows your AI voice assistant to cancel or reschedule Cal.com bookings during a live phone conversation, using the Automation Platform.

<iframe width="100%" height="400" src="https://www.youtube.com/embed/HfjVafIyerQ" title="Tutorial: Cancel & Reschedule Cal.com Appointments with AI Voice Assistant" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />

## What You'll Learn

* Creating and configuring a custom mid-call tool with headers and parameters
* Building an automation flow that handles both cancellation and rescheduling via Cal.com API v2
* Understanding the difference between `/test` and `/sync` webhook endpoints
* Converting timezone-aware dates to UTC for the Cal.com API
* Writing AI prompt instructions so the assistant knows when and how to use the tool
* Testing the full flow end-to-end

## Prerequisites

* Autocalls.ai platform access
* Cal.com account with API key (v2)
* AI assistant already created and configured
* Phone number assigned for inbound or outbound calls

## Step 1: Create the Mid-Call Tool

We'll start by creating the tool that the assistant will call during live conversations. Later, we'll build the automation and come back to set the endpoint URL.

1. Go to **Mid Call Tools** in the sidebar
2. Click **New Mid Call Tool**
3. Configure the basic settings:
   * **Name**: `modify_booking` — must contain only lowercase letters, numbers, and underscores
   * **Description**: `Use this tool to cancel or reschedule a booking`
   * **Endpoint**: We'll fill this in after creating the automation (Step 5)
   * **Timeout**: `20` seconds
   * **Method**: POST

## Step 2: Add Headers

Add two headers to the tool:

| Header Name    | Value                                 |
| -------------- | ------------------------------------- |
| `Content-Type` | `application/json` (added by default) |
| `calApiKey`    | Your Cal.com API key                  |

To get your Cal.com API key:

1. Go to [cal.com](https://cal.com) and click **Go to App**
2. Navigate to **Settings → API Keys**
3. Click **Create new key**, check **Never expires**, give it a name (e.g., "Reschedule/Cancel booking")
4. **Save and copy** the key
5. Paste it as the value for the `calApiKey` header

The `calApiKey` header passes your Cal.com API key to the automation. The automation reads it from the webhook headers and uses it to authenticate all Cal.com API requests — keeping the key secure and out of the request body.

## Step 3: Configure Parameters

These are the values the AI assistant will extract from the conversation and send in the request body:

| Name                 | Type       | Description                                                                                   |
| -------------------- | ---------- | --------------------------------------------------------------------------------------------- |
| `email`              | String     | Email of the customer in the correct format. e.g: [john@example.com](mailto:john@example.com) |
| `cancellationReason` | String     | Reason of cancellation if customer wants to cancel                                            |
| `cancel_appt`        | True/False | TRUE only if the customer wants to cancel appointment. FALSE instead                          |
| `reschedule_appt`    | True/False | TRUE only if the customer wants to reschedule appointment. FALSE instead                      |
| `reschedule_reason`  | String     | The reason of reschedule                                                                      |
| `startDateTime`      | String     | The start date and time in ISO 8601 format for the new booking (e.g., 2025-01-14T15:00:00)    |

We use the `cancel_appt` and `reschedule_appt` boolean parameters to determine which branch the automation takes — cancel or reschedule.

<Note>
  **Timezone consideration:** If your assistant is set to a specific timezone (e.g., Europe/Bucharest), it will offer slots to the customer in that timezone. The customer picks a date and time, and we send it to the automation. Cal.com requires the date in UTC format — we'll handle the conversion in the automation using a Format Date step.
</Note>

<Tip>
  Parameter descriptions are critical. The AI reads them to understand what data to collect during the call and how to populate each field. Be specific about formats and when each parameter applies.
</Tip>

Save the tool for now. We'll come back to set the endpoint URL once we create the automation.

## Step 4: Create the Automation Flow

Now we'll build the automation that receives data from the mid-call tool, interacts with Cal.com's API, and returns the result.

1. Go to **Automation Platform** by clicking "Automate platform" in the sidebar
2. Click **New Flow** and select **From Scratch**
3. Search for **Webhook** and select **Catch Webhook** as your trigger
4. Copy the generated webhook URL
5. Click **Test** to start listening for incoming data

## Step 5: Set the Tool Endpoint

Now go back to the mid-call tool you created in Step 1:

1. Paste the webhook URL into the **Endpoint** field
2. Add `/test` at the end — e.g.: `https://your-webhook-url.com/api/v1/webhooks/abc123.../test`
3. **Save** the tool
4. Click **Test Tool** in the mid-call tool page — you should see the test data arrive in the automation platform

<Warning>
  **`/test` vs `/sync` — Important:**

  * **`/test`** — Use during development. The automation platform captures sample data when you click "Test Flow". The tool won't receive a meaningful response back.
  * **`/sync`** — Use in production. This mode waits for the Return Response step and sends the actual result back to the AI assistant.

  Always start with `/test` for building and debugging, then switch to `/sync` when going live.
</Warning>

## Step 6: Fetch the Customer's Upcoming Bookings

Back in the automation flow, add the first action step after the webhook trigger.

1. Click **+** to add an action
2. Search for **HTTP** and select **Send HTTP Request**
3. Configure the request:

| Field      | Value                             |
| ---------- | --------------------------------- |
| **Method** | GET                               |
| **URL**    | `https://api.cal.com/v2/bookings` |

4. Add these **headers**:

| Header Name       | Value                                             |
| ----------------- | ------------------------------------------------- |
| `Authorization`   | Select from Catch Webhook → Headers → `calApiKey` |
| `cal-api-version` | `2024-08-13`                                      |

5. Add these **query parameters**:

| Parameter       | Value                                      |
| --------------- | ------------------------------------------ |
| `status`        | `upcoming`                                 |
| `attendeeEmail` | Select from Catch Webhook → Body → `email` |

This fetches all upcoming bookings for the customer's email. You can also filter by name if you don't need email.

<Tip>
  **Testing tip:** To verify this step works, temporarily hardcode your own email in the `attendeeEmail` query parameter, create a test booking on your Cal.com public page, then click "Test Step". Once you see the booking returned successfully, replace the hardcoded email with the dynamic value from the webhook body.
</Tip>

## Step 7: Add Branch Logic — Cancel or Reschedule?

We need to route the flow based on what the customer requested.

1. Click **+** and search for **Branch**
2. Set the first value: Select from Catch Webhook → Body → `cancel_appt`
3. Set the condition: **Boolean is True**

This creates two paths:

* **True branch** → Customer wants to cancel
* **False branch** → We check for reschedule next

4. On the **False branch**, add another **Branch** step
5. Set the first value: Select from Catch Webhook → Body → `reschedule_appt`
6. Set the condition: **Boolean is True**

If this is true, the customer wants to reschedule the appointment.

## Step 8: Build the Reschedule Branch (True side of second Branch)

### 8a: Format the Date to UTC

Since Cal.com requires the date in UTC format, we first need to convert it.

1. On the **True path** of the reschedule branch, click **+** and search for **Format Date**
2. Configure:
   * **Input:** Select from Catch Webhook → Body → `startDateTime`
   * **From Format:** ISO format
   * **From Timezone:** Your assistant's timezone (e.g., `Europe/Bucharest`)
   * **To Format:** ISO format
   * **To Timezone:** `UTC` (GMT)
3. **Test** to verify the conversion works correctly

### 8b: Call the Reschedule API

1. Add an **HTTP Request** step after Format Date:

| Field      | Value                                                     |
| ---------- | --------------------------------------------------------- |
| **Method** | POST                                                      |
| **URL**    | `https://api.cal.com/v2/bookings/{bookingUid}/reschedule` |

For the `{bookingUid}` part, delete it and insert the UID from the Get Bookings step: select **Send HTTP Request → Body → data → 0 → uid**

2. Add these **headers**:

| Header Name       | Value                                             |
| ----------------- | ------------------------------------------------- |
| `Content-Type`    | `application/json`                                |
| `cal-api-version` | `2024-08-13`                                      |
| `Authorization`   | Select from Catch Webhook → Headers → `calApiKey` |

3. Set **Body** type to JSON and enter:

```json theme={null}
{
  "start": "{{format_date_step.result}}",
  "reschedulingReason": "{{trigger.body.reschedule_reason}}"
}
```

Replace `format_date_step.result` with the actual output from the Format Date step (select it from the dynamic values panel), and `trigger.body.reschedule_reason` with the value from the webhook body.

<Warning>
  Make sure you don't leave a trailing comma at the end of the JSON body — this will cause a parsing error.
</Warning>

### 8c: Return Response

1. Add a **Return Response** step (search for Webhook → Return Response)
2. Click on the body field, select dynamic value
3. Delete the `{}` and insert the full body from the reschedule HTTP request step

This sends the reschedule result back to the AI assistant via the `/sync` endpoint.

## Step 9: Build the Cancel Branch (True side of first Branch)

1. On the **True path** of the first branch, add an **HTTP Request** step:

| Field      | Value                                                 |
| ---------- | ----------------------------------------------------- |
| **Method** | POST                                                  |
| **URL**    | `https://api.cal.com/v2/bookings/{bookingUid}/cancel` |

For `{bookingUid}`, insert the UID from the Get Bookings step: **Send HTTP Request → Body → data → 0 → uid**

2. Add these **headers**:

| Header Name       | Value              |
| ----------------- | ------------------ |
| `Content-Type`    | `application/json` |
| `cal-api-version` | `2024-08-13`       |

3. Set **Body** type to JSON:

```json theme={null}
{
  "cancellationReason": "{{trigger.body.cancellationReason}}"
}
```

Select the `cancellationReason` value from Catch Webhook → Body → `cancellationReason`.

4. Add a **Return Response** step after the cancel request
5. Click on the body field, select dynamic value, delete the `{}`, and insert the full body from the cancel HTTP request step

This tells the AI assistant whether the cancellation was successful or not.

## Step 10: Publish and Switch to /sync

1. **Verify** all steps are correctly configured
2. Click **Publish** to make the flow live
3. Go back to your mid-call tool and change the endpoint from `/test` to `/sync`
4. **Save** the tool

Now the tool will wait for the automation's Return Response and send the actual Cal.com response back to the AI assistant during the call.

## Step 11: Attach the Tool to Your Assistant

1. Navigate to your AI assistant
2. Go to **Prompts and Tools** tab
3. In the **Custom Tools** section, attach the `modify_booking` tool
4. **Save** the assistant

Also make sure you have **Cal.com Appointment Scheduling** connected in the assistant settings with your API key and event selected — this enables the assistant to also book new appointments, not just cancel or reschedule.

As for call variables, you can place the `email` variable here with a default value. During a real call, if the customer's email isn't available as a variable, the assistant will need to ask for it during the conversation — make sure your prompt instructs it to do so.

## Step 12: Configure the AI Prompt

Open the **AI Prompt Editor** to instruct the AI on when and how to use the tool. You can type natural language instructions and let the editor generate the prompt rules for you.

Example instructions to give the AI Prompt Editor:

```
If the customer wants to cancel or reschedule an appointment:
1. First ask for their email address
2. For reschedule: call the get_slots tool first to check available times, then call modify_booking with the chosen slot
3. For cancel: ask for cancellation reason, then call modify_booking
4. Always confirm the action with the customer before proceeding
```

The AI Prompt Editor will generate the appropriate system prompt rules. Review them, click **Accept**, then **Save**.

<Tip>
  If you're using the Web Widget and the customer's phone number or email isn't automatically available, add instructions in the system prompt to request that information during the conversation.
</Tip>

## Step 13: Test End-to-End

### Using Test Assistant (Chat)

1. Click **Test Assistant** to open the chat test interface
2. Start a conversation and try booking an appointment first
3. Then ask to reschedule or cancel — the assistant should ask for your email, and proceed with the appropriate action

<Note>
  In the test chat, the assistant may ask for a phone number since it's not a real call. For web widget usage, add phone/email collection instructions to the system prompt.
</Note>

### Using Speak to Assistant (Voice)

1. Click **Speak to Assistant** for a live voice test
2. Request a cancellation or reschedule during the conversation
3. Check the automation platform to verify the flow executed correctly and the correct branch was taken

### Production Testing

Make a real phone call to your assistant's number and test the full cancel/reschedule flow with actual Cal.com bookings.

## Best Practices

### Tool Configuration

* **Use descriptive parameter descriptions** — the AI relies on these to extract the right data from the conversation
* **Set timeout to 20 seconds** — the flow involves multiple API calls (get bookings + cancel/reschedule)
* **Always use `/sync` in production** — otherwise the AI won't receive the response data

### Prompt Design

* **Request email early** — the tool needs it for the Cal.com booking lookup
* **For reschedule: use get\_slots first** — have the AI check available times before calling the reschedule tool
* **Handle edge cases** — what if the customer doesn't know their email? What if no upcoming bookings are found? Add instructions for these scenarios

### Security

* **Pass API keys via headers** — not in the request body or parameters
* **Never expose keys** in parameter descriptions or prompt instructions

## Troubleshooting

### Common Issues

**Tool returns empty response:**

* Make sure you're using `/sync` not `/test` in production
* Verify the Return Response step is configured in your flow
* Check that the flow is published

**AI doesn't use the tool:**

* Review the tool description — it must clearly indicate when to use it
* Check that the tool is attached to the correct assistant
* Verify your prompt includes explicit instructions about when to call the tool

**Cal.com API returns errors:**

* Confirm your API key is valid and has the correct permissions
* Check the `cal-api-version` header matches (`2024-08-13`)
* Verify the booking UID exists and status is "upcoming"

**Wrong timezone for rescheduled appointment:**

* Make sure the Format Date step converts from your assistant's timezone to UTC
* Verify the "From Timezone" matches your assistant's configured timezone

**Wrong branch is taken:**

* Ensure `cancel_appt` and `reschedule_appt` are True/False type parameters, not strings
* Check that Branch conditions use "Boolean is True" operator

## Next Steps

Once your cancellation and rescheduling flow is working:

* **Send confirmation SMS** — add a post-action SMS step using [SMS automation](/automation-platform/calls-related/sms-capabilities)
* **Log actions to Google Sheets** — track all cancellations and reschedules using [Google Sheets sync](/automation-platform/tutorials/google-sheets-sync)
* **Add email notifications** — send confirmation emails with [Post-Call Email Automation](/automation-platform/tutorials/post-call-email-automation)
* **Handle multiple bookings** — modify the flow to let the customer choose which booking to modify if they have more than one
