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.
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
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.
- Go to Mid Call Tools in the sidebar
- Click New Mid Call Tool
- 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
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:
- Go to cal.com and click Go to App
- Navigate to Settings → API Keys
- Click Create new key, check Never expires, give it a name (e.g., “Reschedule/Cancel booking”)
- Save and copy the key
- 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.
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 |
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.
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.
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.
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.
- Go to Automation Platform by clicking “Automate platform” in the sidebar
- Click New Flow and select From Scratch
- Search for Webhook and select Catch Webhook as your trigger
- Copy the generated webhook URL
- Click Test to start listening for incoming data
Now go back to the mid-call tool you created in Step 1:
- Paste the webhook URL into the Endpoint field
- Add
/test at the end — e.g.: https://your-webhook-url.com/api/v1/webhooks/abc123.../test
- Save the tool
- Click Test Tool in the mid-call tool page — you should see the test data arrive in the automation platform
/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.
Step 6: Fetch the Customer’s Upcoming Bookings
Back in the automation flow, add the first action step after the webhook trigger.
- Click + to add an action
- Search for HTTP and select Send HTTP Request
- Configure the request:
| Field | Value |
|---|
| Method | GET |
| URL | https://api.cal.com/v2/bookings |
- Add these headers:
| Header Name | Value |
|---|
Authorization | Select from Catch Webhook → Headers → calApiKey |
cal-api-version | 2024-08-13 |
- 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.
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.
Step 7: Add Branch Logic — Cancel or Reschedule?
We need to route the flow based on what the customer requested.
- Click + and search for Branch
- Set the first value: Select from Catch Webhook → Body →
cancel_appt
- Set the condition: Boolean is True
This creates two paths:
- True branch → Customer wants to cancel
- False branch → We check for reschedule next
- On the False branch, add another Branch step
- Set the first value: Select from Catch Webhook → Body →
reschedule_appt
- 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)
Since Cal.com requires the date in UTC format, we first need to convert it.
- On the True path of the reschedule branch, click + and search for Format Date
- 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)
- Test to verify the conversion works correctly
8b: Call the Reschedule API
- 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
- Add these headers:
| Header Name | Value |
|---|
Content-Type | application/json |
cal-api-version | 2024-08-13 |
Authorization | Select from Catch Webhook → Headers → calApiKey |
- Set Body type to JSON and enter:
{
"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.
Make sure you don’t leave a trailing comma at the end of the JSON body — this will cause a parsing error.
8c: Return Response
- Add a Return Response step (search for Webhook → Return Response)
- Click on the body field, select dynamic value
- 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)
- 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
- Add these headers:
| Header Name | Value |
|---|
Content-Type | application/json |
cal-api-version | 2024-08-13 |
- Set Body type to JSON:
{
"cancellationReason": "{{trigger.body.cancellationReason}}"
}
Select the cancellationReason value from Catch Webhook → Body → cancellationReason.
- Add a Return Response step after the cancel request
- 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
- Verify all steps are correctly configured
- Click Publish to make the flow live
- Go back to your mid-call tool and change the endpoint from
/test to /sync
- 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.
- Navigate to your AI assistant
- Go to Prompts and Tools tab
- In the Custom Tools section, attach the
modify_booking tool
- 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.
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.
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.
Step 13: Test End-to-End
Using Test Assistant (Chat)
- Click Test Assistant to open the chat test interface
- Start a conversation and try booking an appointment first
- Then ask to reschedule or cancel — the assistant should ask for your email, and proceed with the appropriate action
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.
Using Speak to Assistant (Voice)
- Click Speak to Assistant for a live voice test
- Request a cancellation or reschedule during the conversation
- 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
- 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
- Log actions to Google Sheets — track all cancellations and reschedules using Google Sheets sync
- Add email notifications — send confirmation emails with 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