Cal.com Integration
Receive Cal.com booking events in WebhookLane. Cal.com is a source — it sends events when bookings are created, rescheduled, or cancelled.
Prerequisites
- A Cal.com account with access to developer settings
Setup
- Create a source in WebhookLane
Go to Sources → Create source, name it "Cal.com", and copy the ingest URL. - Add the webhook in Cal.com
In Cal.com, go to Settings → Developer → Webhooks and click New. Paste your WebhookLane ingest URL as the subscriber URL and select the event triggers you need.
Event Triggers
Cal.com supports these webhook event triggers:
BOOKING_CREATED— A new booking is confirmedBOOKING_RESCHEDULED— An existing booking is rescheduledBOOKING_CANCELLED— A booking is cancelledMEETING_ENDED— A meeting has endedRECORDING_READY— A meeting recording is available
Payload Structure
{
"triggerEvent": "BOOKING_CREATED",
"payload": {
"title": "30 Min Meeting",
"startTime": "2025-03-15T10:00:00Z",
"endTime": "2025-03-15T10:30:00Z",
"attendees": [
{ "name": "Jane Doe", "email": "[email protected]" }
],
"organizer": {
"name": "John Smith",
"email": "[email protected]"
},
"location": "https://meet.google.com/..."
}
} Example Transform
Send a Slack notification when a new booking is created:
{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "New Booking: {{slackEscape payload.title}}"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*When:* {{formatTime payload.startTime}} - {{formatTime payload.endTime}}\n*Attendees:* {{mapJoin payload.attendees "name"}}\n*Location:* {{slackEscape payload.location}}"
}
}
]
} Example Filter
Only process new bookings (ignore reschedules and cancellations):
- Field:
triggerEvent, Operator: equals, Value:BOOKING_CREATED
Tips
- Cal.com nests the booking data under a
payloadkey. Access fields likepayload.title,payload.startTime, etc. - Use
formatTimewith an optional timezone argument:{{formatTime payload.startTime "America/New_York"}}. - The
mapJoinhelper is useful for listing attendee names:{{mapJoin payload.attendees "name"}}. - You can set up separate routes for different event types using filters on the
triggerEventfield.