Webhooks allow you to receive real-time HTTP notifications when booking events occur. Instead of polling the API for changes, Kordless pushes data to your server as events happen.
Webhooks are configured in the Kordless platform under Calendar → Settings → Webhooks.
function handleBookingCreated(booking) { console.log(`New booking: ${booking.confirmation_number}`); // Send confirmation email sendEmail({ to: booking.contact.email, subject: 'Booking Confirmed', body: `Your appointment is confirmed for ${formatDate(booking.startsAt)}` }); // Update your CRM updateCRM(booking.contact); // Sync to your calendar createCalendarEvent(booking);}function handleBookingUpdated(booking) { console.log(`Booking rescheduled: ${booking.confirmation_number}`); // Notify customer of new time sendEmail({ to: booking.contact.email, subject: 'Booking Rescheduled', body: `Your appointment has been moved to ${formatDate(booking.startsAt)}` });}function handleBookingCancelled(booking) { console.log(`Booking cancelled: ${booking.confirmation_number}`); // Send cancellation confirmation sendEmail({ to: booking.contact.email, subject: 'Booking Cancelled', body: 'Your appointment has been cancelled.' }); // Update your records markAsCancelled(booking.id);}
Return a 2xx response within 30 seconds. Process webhook data asynchronously:
Copy
app.post('/webhooks/kordless', async (req, res) => { // Verify signature first if (!verifySignature(req)) { return res.status(401).send('Invalid signature'); } // Respond immediately res.status(200).send('OK'); // Process async (don't await) processWebhookAsync(req.body);});async function processWebhookAsync(event) { // Queue for background processing await queue.add('webhook', event);}
Handle Retries Idempotently
Kordless retries failed webhooks. Make your handler idempotent:
Copy
async function handleBookingCreated(booking, webhookDeliveryId) { // Check if already processed const existing = await db.webhookEvents.findOne({ webhookDeliveryId }); if (existing) { console.log('Already processed, skipping'); return; } // Process and mark as handled await processBooking(booking); await db.webhookEvents.create({ webhookDeliveryId, processedAt: new Date() });}