Retell AI + Cal.com Integration STUCK

Issue: Retell AI + Cal.com v2 Integration “Bad Request” Loop

The Goal: Automate a phone call booking flow where the AI identifies a slot via check_availability and books it via book_appointment.

Dynamic Variables: Using {{user_name}} and {{user_number}} which automatically maps to the built-in {{to_number}} variable when an outbound ph number is made.

Cal. com Event: All questions disabled except Name and Phone.

Location: Set to “Phone Call.”
API Version: Using the 2026-02-25 header.

The Problem: Both the check_availability and book_appointment modules are consistently failing with a 400 Bad Request. The Error Message: “Attendee email or phone number properties wrong. They must have at least one contact method (email or phone number).”

What I’ve Verified: The phone number is being captured correctly from {{to_number}}.

The Cal .com booking page only requires two parameters (Name/Phone), which matches the Retell module inputs. I’ve tried mapping variables manually and using defaults, but the API keeps insisting the contact method is missing or malformed.

I have been troubleshooting for 3 days and have exhausted the standard “check your API key” and “check your Event ID” advice.

If anyone has successfully connected Cal. com v2 to Retell recently, what is the “magic sauce” for the JSON body or the field mapping? Is the API expecting the phone number in a specific object (e.g., inside attendee vs responses) Any help to stop this 400-error loop would be massive. Cheers! Photos attached of the cal.com set up.

Hey @akshayeghela

Could you please share the agent ID with any relevant Call ID? This will help us investigate the issue more effectively.

Thank you!

Agent ID: agent_d62e7fe077eaf026eece63417d

Call ID: call_e0836281dae272687a58bc765dc

another call id where I had an issue
call_0603f730b985c94f172404631a0

Hey @akshayeghela

I’ve escalated this to our team for further review.

We’ll update you as soon as we hear back.

Best regards

Hey @akshayeghela

Could you please try changing the contact method to email instead of phone.

Best regards

Hi Shaw, the issue is, is that i want retell to book the cal meeting only at the time and in the notes section or title have the phone number that my client needs to call.

The email is not needed as i don’t want the retell AI caller to ask the user for their email.

We already have all the users information before the call and we are just wanting to call them, qualify them and then book them into my clients calendar.

Hi @akshayeghela, this sounds like the issue I had struggled with for a long time as well. I wanted the meeting location to be a phone and not a virtual meeting. I wanted to text the appointment reminder, not email.
I was getting errors pertaining to “attendeePhoneNumber” and also “location”, but was able to correct with my own book API Request.

I used the function Retell AI provides OOTB to check availability, but I had to make my own API request to make the booking work. I could not get function book_appointment_cal provides OOTB to format the request body properly for the v2 request. Are you trying to use the Retell AI cal.com OOTB functions or are you making your own API request to cal.com?

Hey @akshayeghela

A fix was recently pushed, We recommend configuring the agent to explicitly ask for the phone number during the conversation. This will help the system capture and extract it more accurately.

Thank You

We are still having the same issue and we do ask for the number and email address. It’s still coming back as an error. The only required field we have is phone number. The name is not broken into first, last. I don’t understand why it’s not working.

Hey @ek1

Can you create a new ticket Support Help here and share the details with Agent ID and Call ID.

Thank You

I’ll try setting up the API request again using the cal.com documentation and share any issues I encounter. Although I initially switched to the booking tool for simplicity and scalability, I’m revisiting the API approach now.

While we can do this, our aim is to make the user experience seamless. The agent should automatically utilise the phone number variable available at the start of the call rather than asking for it again. So ill try what @omnicontactai suggested and then come back with any issues that occur.

How were you able to successfully set up the custom API call?

I’ve been working on this for a few hours now, but I keep encountering minor errors throughout the process. I’ve attached a screenshot of my current configuration for reference.

I am specifically having trouble with the JSON setup. It doesn’t seem to be saving correctly, likely due to how the variables are structured. I’ve tried using the provided examples as a starting point, but I haven’t had much luck yet.

Additionally, I attempted to use a code block prior to the “book appointments” step to define the entire JSON structure, hoping to reference that variable directly in the payload parameters. Unfortunately, that approach didn’t work either.

Currently, I have verified that the name, description, API endpoint, and headers are all accurate. However, I’m still struggling to configure the parameters and the actual payload. I would appreciate it if you could show me how you structured your parameters to successfully pass the name and phone number to book the appointment.

I’ve found the documentation to be a bit too high-level to address these specific integration details, so any guidance you can provide would be very helpful.

This is what i have in the parameters box and how my API request looks

{
“type”: “object”,
“properties”: {
“start”: {
“type”: “string”,
“description”: “The UTC ISO 8601 timestamp from the code node (e.g. 2026-08-13T09:00:00Z).”
},
“eventTypeId”: {
“type”: “number”
},
“attendee”: {
“type”: “object”,
“properties”: {
“name”: {
“type”: “string”
},
“email”: {
“type”: “string”
},
“timeZone”: {
“type”: “string”
},
“phoneNumber”: {
“type”: “string”
}
},
“required”: [
“name”,
“email”,
“timeZone”
]
},
“bookingFieldsResponses”: {
“type”: “object”,
“properties”: {
“notes”: {
“type”: “string”
}
}
}
},
“required”: [
“start”,
“attendee”
]
}

I use LateNode to make the request, but I would think it would be possible within Retell AI, especially if you use the javascript node within a converstaion flow. This is the body of the request that works. It was difficult to figure out. cal.com event does need to be set up a certain way.

{
“start”: “{{$14.utc_time}}”,
“eventTypeId”: {{$4.body.args.cal_event_type}},
“attendee”: {
“name”: “{{$4.body.args.user_firstname}} {{$4.body.args.user_lastname}}”,
“email”: “{{$14.user_email}}”,
“timeZone”: “{{$4.body.args.time_zone}}”,
“phoneNumber”: “{{$14.user_number}}”,
“language”: “en”
},
“location”: “{{$4.body.args.user_address}}”,
“bookingFieldsResponses”: {
“call_summary”: “{{$4.body.args.call_summary}}”
}
}

If this doesn’t work then I think something is wrong with your cal.com settings. Try this. If no luck I’ll get you my cal.com settings.

Send me the error message from cal.com that displays in Retell AI and I’ll let you know if this is the same issue I had.