webhooks
Detailed documentation for webhook management endpoints in the Cal.diy API v2.
$ npx -y skills add calcom/cal.com --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Detailed documentation for webhook management endpoints in the Cal.diy API v2.
Agent definition
webhooks.mdWebhooks API Reference
Detailed documentation for webhook management endpoints in the Cal.diy API v2.
Endpoints Overview
| Method | Endpoint | Description | |--------|----------|-------------| | GET | /v2/webhooks | List webhooks | | POST | /v2/webhooks | Create a webhook | | GET | /v2/webhooks/{webhookId} | Get a webhook | | PATCH | /v2/webhooks/{webhookId} | Update a webhook | | DELETE | /v2/webhooks/{webhookId} | Delete a webhook |
List Webhooks
GET /v2/webhooks
Response
{
"status": "success",
"data": [
{
"id": "webhook-id-123",
"subscriberUrl": "https://your-app.com/webhook",
"triggers": ["BOOKING_CREATED", "BOOKING_CANCELLED"],
"active": true,
"payloadTemplate": null,
"secret": "whsec_..."
}
]
}Create a Webhook
POST /v2/webhooks
Request Body
{
"subscriberUrl": "https://your-app.com/webhook",
"triggers": ["BOOKING_CREATED", "BOOKING_CANCELLED", "BOOKING_RESCHEDULED"],
"active": true,
"payloadTemplate": null,
"secret": "your-webhook-secret"
}Fields
| Field | Type | Required | Description | |-------|------|----------|-------------| | subscriberUrl | string | Yes | URL to receive webhook payloads | | triggers | array | Yes | Events that trigger the webhook | | active | boolean | No | Enable/disable webhook (default: true) | | payloadTemplate | string | No | Custom payload template | | secret | string | No | Secret for signature verification |
Webhook Triggers
| Trigger | Description | |---------|-------------| | BOOKING_CREATED | New booking created | | BOOKING_CANCELLED | Booking cancelled | | BOOKING_RESCHEDULED | Booking rescheduled | | BOOKING_CONFIRMED | Pending booking confirmed | | BOOKING_REJECTED | Booking rejected | | BOOKING_REQUESTED | Booking request received (requires confirmation) | | BOOKING_PAYMENT_INITIATED | Payment started | | BOOKING_NO_SHOW_UPDATED | Attendee marked as no-show | | MEETING_STARTED | Video meeting started | | MEETING_ENDED | Video meeting ended | | RECORDING_READY | Meeting recording available | | INSTANT_MEETING | Instant meeting created | | RECORDING_TRANSCRIPTION_GENERATED | Transcription ready | | FORM_SUBMITTED | Routing form submitted |
Webhook Payload
BOOKING_CREATED Payload
{
"triggerEvent": "BOOKING_CREATED",
"createdAt": "2024-01-15T10:00:00.000Z",
"payload": {
"type": "30min",
"title": "30 Minute Meeting",
"description": "Meeting description",
"startTime": "2024-01-15T10:00:00.000Z",
"endTime": "2024-01-15T10:30:00.000Z",
"organizer": {
"id": 123,
"name": "Jane Smith",
"email": "jane@company.com",
"timeZone": "America/New_York"
},
"attendees": [
{
"name": "John Doe",
"email": "john@example.com",
"timeZone": "America/New_York"
}
],
"location": "https://cal.com/video/abc123",
"destinationCalendar": {
"integration": "google_calendar",
"externalId": "calendar-id"
},
"uid": "booking-uid-123",
"metadata": {},
"responses": {
"name": "John Doe",
"email": "john@example.com"
}
}
}BOOKING_CANCELLED Payload
{
"triggerEvent": "BOOKING_CANCELLED",
"createdAt": "2024-01-15T12:00:00.000Z",
"payload": {
"uid": "booking-uid-123",
"title": "30 Minute Meeting",
"startTime": "2024-01-15T10:00:00.000Z",
"endTime": "2024-01-15T10:30:00.000Z",
"cancellationReason": "Schedule conflict",
"organizer": {...},
"attendees": [...]
}
}BOOKING_RESCHEDULED Payload
{
"triggerEvent": "BOOKING_RESCHEDULED",
"createdAt": "2024-01-15T11:00:00.000Z",
"payload": {
"uid": "new-booking-uid",
"rescheduleUid": "original-booking-uid",
"title": "30 Minute Meeting",
"startTime": "2024-01-16T14:00:00.000Z",
"endTime": "2024-01-16T14:30:00.000Z",
"reschedulingReason": "Conflict with another meeting",
"organizer": {...},
"attendees": [...]
}
}Signature Verification
Webhooks include a signature header for verification:
X-Cal-Signature-256: sha256=<signature>
Verification Example (Node.js)
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return `sha256=${expectedSignature}` === signature;
}
// In your webhook handler
app.post('/webhook', (req, res) => {
const signature = req.headers['x-cal-signature-256'];
const payload = JSON.stringify(req.body);
if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process webhook
const { triggerEvent, payload: data } = req.body;
// ...
res.status(200).send('OK');
});Get a Webhook
GET /v2/webhooks/{webhookId}Update a Webhook
PATCH /v2/webhooks/{webhookId}Request Body
{
"active": false,
"triggers": ["BOOKING_CREATED"]
}Delete a Webhook
DELETE /v2/webhooks/{webhookId}Event Type Webhooks
Create webhooks specific to an event type:
List Event Type Webhooks
GET /v2/event-types/{eventTypeId}/webhooksCreate Event Type Webhook
POST /v2/event-types/{eventTypeId}/webhooks{
"subscriberUrl": "https://your-app.com/webhook",
"triggers": ["BOOKING_CREATED"],
"active": true
}Organization Webhooks
For organization-wide webhooks:
List Organization Webhooks
GET /v2/organizations/{orgId}/webhooksCreate Organization Webhook
POST /v2/organizations/{orgId}/webhooksOAuth Client Webhooks
For platform integrations:
List OAuth Client Webhooks
GET /v2/oauth-clients/{clientId}/webhooksCreate OAuth Client Webhook
POST /v2/oauth-
Read more
Webhooks API Reference
Detailed documentation for webhook management endpoints in the Cal.diy API v2.
Endpoints Overview
| Method | Endpoint | Description | |--------|----------|-------------| | GET | /v2/webhooks | List webhooks | | POST | /v2/webhooks | Create a webhook | | GET | /v2/webhooks/{webhookId} | Get a webhook | | PATCH | /v2/webhooks/{webhookId} | Update a webhook | | DELETE | /v2/webhooks/{webhookId} | Delete a webhook |
List Webhooks
GET /v2/webhooks
Response
{
"status": "success",
"data": [
{
"id": "webhook-id-123",
"subscriberUrl": "https://your-app.com/webhook",
"triggers": ["BOOKING_CREATED", "BOOKING_CANCELLED"],
"active": true,
"payloadTemplate": null,
"secret": "whsec_..."
}
]
}Create a Webhook
POST /v2/webhooks
Request Body
{
"subscriberUrl": "https://your-app.com/webhook",
"triggers": ["BOOKING_CREATED", "BOOKING_CANCELLED", "BOOKING_RESCHEDULED"],
"active": true,
"payloadTemplate": null,
"secret": "your-webhook-secret"
}Fields
| Field | Type | Required | Description | |-------|------|----------|-------------| | subscriberUrl | string | Yes | URL to receive webhook payloads | | triggers | array | Yes | Events that trigger the webhook | | active | boolean | No | Enable/disable webhook (default: true) | | payloadTemplate | string | No | Custom payload template | | secret | string | No | Secret for signature verification |
Webhook Triggers
| Trigger | Description | |---------|-------------| | BOOKING_CREATED | New booking created | | BOOKING_CANCELLED | Booking cancelled | | BOOKING_RESCHEDULED | Booking rescheduled | | BOOKING_CONFIRMED | Pending booking confirmed | | BOOKING_REJECTED | Booking rejected | | BOOKING_REQUESTED | Booking request received (requires confirmation) | | BOOKING_PAYMENT_INITIATED | Payment started | | BOOKING_NO_SHOW_UPDATED | Attendee marked as no-show | | MEETING_STARTED | Video meeting started | | MEETING_ENDED | Video meeting ended | | RECORDING_READY | Meeting recording available | | INSTANT_MEETING | Instant meeting created | | RECORDING_TRANSCRIPTION_GENERATED | Transcription ready | | FORM_SUBMITTED | Routing form submitted |
Webhook Payload
BOOKING_CREATED Payload
{
"triggerEvent": "BOOKING_CREATED",
"createdAt": "2024-01-15T10:00:00.000Z",
"payload": {
"type": "30min",
"title": "30 Minute Meeting",
"description": "Meeting description",
"startTime": "2024-01-15T10:00:00.000Z",
"endTime": "2024-01-15T10:30:00.000Z",
"organizer": {
"id": 123,
"name": "Jane Smith",
"email": "jane@company.com",
"timeZone": "America/New_York"
},
"attendees": [
{
"name": "John Doe",
"email": "john@example.com",
"timeZone": "America/New_York"
}
],
"location": "https://cal.com/video/abc123",
"destinationCalendar": {
"integration": "google_calendar",
"externalId": "calendar-id"
},
"uid": "booking-uid-123",
"metadata": {},
"responses": {
"name": "John Doe",
"email": "john@example.com"
}
}
}BOOKING_CANCELLED Payload
{
"triggerEvent": "BOOKING_CANCELLED",
"createdAt": "2024-01-15T12:00:00.000Z",
"payload": {
"uid": "booking-uid-123",
"title": "30 Minute Meeting",
"startTime": "2024-01-15T10:00:00.000Z",
"endTime": "2024-01-15T10:30:00.000Z",
"cancellationReason": "Schedule conflict",
"organizer": {...},
"attendees": [...]
}
}BOOKING_RESCHEDULED Payload
{
"triggerEvent": "BOOKING_RESCHEDULED",
"createdAt": "2024-01-15T11:00:00.000Z",
"payload": {
"uid": "new-booking-uid",
"rescheduleUid": "original-booking-uid",
"title": "30 Minute Meeting",
"startTime": "2024-01-16T14:00:00.000Z",
"endTime": "2024-01-16T14:30:00.000Z",
"reschedulingReason": "Conflict with another meeting",
"organizer": {...},
"attendees": [...]
}
}Signature Verification
Webhooks include a signature header for verification:
X-Cal-Signature-256: sha256=<signature>
Verification Example (Node.js)
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return `sha256=${expectedSignature}` === signature;
}
// In your webhook handler
app.post('/webhook', (req, res) => {
const signature = req.headers['x-cal-signature-256'];
const payload = JSON.stringify(req.body);
if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process webhook
const { triggerEvent, payload: data } = req.body;
// ...
res.status(200).send('OK');
});Get a Webhook
GET /v2/webhooks/{webhookId}Update a Webhook
PATCH /v2/webhooks/{webhookId}Request Body
{
"active": false,
"triggers": ["BOOKING_CREATED"]
}Delete a Webhook
DELETE /v2/webhooks/{webhookId}Event Type Webhooks
Create webhooks specific to an event type:
List Event Type Webhooks
GET /v2/event-types/{eventTypeId}/webhooksCreate Event Type Webhook
POST /v2/event-types/{eventTypeId}/webhooks{
"subscriberUrl": "https://your-app.com/webhook",
"triggers": ["BOOKING_CREATED"],
"active": true
}Organization Webhooks
For organization-wide webhooks:
List Organization Webhooks
GET /v2/organizations/{orgId}/webhooksCreate Organization Webhook
POST /v2/organizations/{orgId}/webhooksOAuth Client Webhooks
For platform integrations:
List OAuth Client Webhooks
GET /v2/oauth-clients/{clientId}/webhooksCreate OAuth Client Webhook
POST /v2/oauth-
Repo: calcom/cal.com
Other agents on caldiy.
- knowledge-base
This file contains domain knowledge about the Cal.diy product and codebase. For coding guidelines and rules, see [`rules/`](rules/).
Open agent - api-no-breaking-changes
**Impact: CRITICAL**
Open agent - api-thin-controllers
**Impact: HIGH**
Open agent - architecture-circular-dependencies
**Impact: CRITICAL**
Open agent - architecture-feature-boundaries
**Impact: CRITICAL**
Open agent - architecture-features-modules
The `packages/features` package should contain only framework-agnostic code: - Repositories (data access layer) - Services (business logic) - Core utilities and helpers - Types and interfaces
Open agent

