Webhooks
Receive real-time notifications when events occur in your WebKasa account.
Overview
Webhooks allow you to receive HTTP POST requests to your server when specific events occur. This is more efficient than polling the API for changes.
Available Events
Webhook Events
| Parameter | Type | Description |
|---|---|---|
booking.created | event | A new booking was created |
booking.confirmed | event | A booking was confirmed |
booking.cancelled | event | A booking was cancelled |
booking.completed | event | A booking was marked as completed |
event.created | event | A new event was created |
event.updated | event | An event was updated |
event.cancelled | event | An event was cancelled |
registration.created | event | A new event registration |
registration.cancelled | event | A registration was cancelled |
Payload Format
All webhook payloads follow a consistent structure:
{
"id": "wh_evt_abc123",
"type": "booking.created",
"created_at": "2024-01-15T10:30:00Z",
"data": {
"id": "bk_xyz789",
"schedule_id": "sch_abc123",
"start_time": "2024-02-15T10:00:00Z",
"end_time": "2024-02-15T11:00:00Z",
"status": "PENDING",
"attendee_name": "John Doe",
"attendee_email": "john@example.com"
}
}Verifying Webhooks
All webhook requests include a signature header for verification. Always verify the signature to ensure the webhook came from WebKasa.
X-WebKasa-Signature: sha256=abc123...import crypto from 'crypto';
function verifyWebhookSignature(
payload: string,
signature: string,
secret: string
): boolean {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(`sha256=${expectedSignature}`)
);
}
// In your webhook handler
export async function POST(request: Request) {
const payload = await request.text();
const signature = request.headers.get('X-WebKasa-Signature');
if (!signature || !verifyWebhookSignature(payload, signature, WEBHOOK_SECRET)) {
return new Response('Invalid signature', { status: 401 });
}
const event = JSON.parse(payload);
// Process the webhook...
return new Response('OK', { status: 200 });
}Handling Webhooks
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const payload = await request.text();
const signature = request.headers.get('X-WebKasa-Signature');
// Verify signature (see above)
if (!verifyWebhookSignature(payload, signature!, WEBHOOK_SECRET)) {
return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
}
const event = JSON.parse(payload);
switch (event.type) {
case 'booking.created':
await handleBookingCreated(event.data);
break;
case 'booking.confirmed':
await handleBookingConfirmed(event.data);
break;
case 'booking.cancelled':
await handleBookingCancelled(event.data);
break;
case 'registration.created':
await handleRegistrationCreated(event.data);
break;
default:
console.log(`Unhandled event type: ${event.type}`);
}
// Always return 200 to acknowledge receipt
return NextResponse.json({ received: true });
}
async function handleBookingCreated(booking: BookingData) {
// Send confirmation email
await sendConfirmationEmail(booking.attendee_email, booking);
// Update your database
await db.bookings.create({ data: booking });
// Notify team via Slack
await notifySlack(`New booking from ${booking.attendee_name}`);
}Best Practices
Return 200 Quickly
Return a 200 response as soon as you receive the webhook. Process the event asynchronously if it takes more than a few seconds.
Handle Duplicates
Webhooks may be delivered more than once. Use the id field to deduplicate and ensure idempotent processing.
Always Verify Signatures
Never process a webhook without verifying its signature. This prevents attackers from sending fake events to your endpoint.
Use HTTPS
Your webhook endpoint must use HTTPS. We do not send webhooks to HTTP endpoints.
Retry Policy
If your endpoint returns a non-2xx response, we'll retry the webhook:
- 1st retry: 1 minute after initial attempt
- 2nd retry: 5 minutes after 1st retry
- 3rd retry: 30 minutes after 2nd retry
- 4th retry: 2 hours after 3rd retry
- 5th retry: 24 hours after 4th retry
After 5 failed attempts, the webhook is marked as failed. You can view and retry failed webhooks in the dashboard.
Configure Webhooks
Set up webhook endpoints in your dashboard to start receiving events.
Configure Webhooks