How to Retrieve Actual Booking Information from Calendly Webhooks Instead of Just Subscription Details

I’m working with the Calendly API and running into a frustrating problem. When I set up my webhook, I expect to get the actual appointment data when someone books or cancels a meeting. However, all I’m getting back is the webhook subscription information itself.

I need to capture real booking events like when someone schedules or cancels an appointment. The API should send me detailed information about the booking, but instead I just get confirmation that my webhook is active.

Here’s my current implementation:

$api_endpoint = 'https://calendly.com/api/v1/hooks';
$callback_url = 'MY_CALLBACK_URL_HERE';
$post_data = 'url='.$callback_url.'&events[]=invitee.created&events[]=invitee.canceled';

$handle = curl_init();
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_URL, $api_endpoint);
curl_setopt($handle, CURLOPT_POST, 1);
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($handle, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($handle, CURLOPT_HTTPHEADER, array(
    "X-TOKEN: MY_API_TOKEN"
));

$response = curl_exec($handle);
echo $response;
curl_close($handle);

// Process incoming webhook data
$input_data = trim(file_get_contents("php://input"));
$parsed_data = json_decode($input_data, true);
echo $parsed_data;

The response I get looks like this:
{"data":[{"type":"hooks","id":380871,"attributes":{"url":"MY_CALLBACK_URL","created_at":"2019-04-17T11:07:36Z","events":["invitee.created","invitee.canceled"],"state":"active"}}]}

This just shows my webhook is set up correctly, but where is the actual appointment data? What am I missing in my setup?

Your code mixes webhook creation with webhook processing in the same script - that’s the problem.

That response you’re seeing? It’s from the webhook creation call, not actual booking events. The API is just saying “hey, your webhook is now active” - which means it’s working.

The real booking data comes when someone actually books an appointment. Calendly will POST to your callback URL with the event details.

I hit this exact same confusion last year. Here’s the fix:

Separate your webhook creation from your webhook handler. Run the creation part (your curl code) once to set up the webhook. Your callback URL should only handle processing:

// This should be your entire callback handler
$input_data = trim(file_get_contents("php://input"));
$parsed_data = json_decode($input_data, true);

// Log it to see what you're actually getting
file_put_contents('webhook_log.txt', print_r($parsed_data, true), FILE_APPEND);

Also, you’re using the v1 API which is deprecated. Switch to v2:

https://api.calendly.com/webhook_subscriptions

Real booking events will have payload data with invitee details, event times, cancellation info, etc. But you’ll only see this when actual bookings happen, not during webhook setup.