Context
Webhook events let power users connect CalendarGenie to CRM, Slack, or billing tools. The GTM strategy targets at least 1 published integration (Zapier or Slack) by Q3. This requires a reliable event delivery system with HMAC-signed payloads.
Scope
Database
CREATE TABLE webhooks (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
url TEXT NOT NULL,
secret_hash TEXT NOT NULL,
events TEXT[] NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT true,
created_by INTEGER NOT NULL REFERENCES users(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE webhook_deliveries (
id SERIAL PRIMARY KEY,
webhook_id INTEGER NOT NULL REFERENCES webhooks(id) ON DELETE CASCADE,
event_type TEXT NOT NULL,
payload JSONB NOT NULL,
response_status INTEGER,
response_body TEXT,
attempt INTEGER NOT NULL DEFAULT 1,
delivered_at TIMESTAMPTZ,
failed_at TIMESTAMPTZ,
next_retry_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_webhook_deliveries_pending ON webhook_deliveries(next_retry_at) WHERE delivered_at IS NULL AND failed_at IS NULL;
Events
| Event |
Trigger |
Payload |
booking.created |
New booking confirmed |
Booking + project + time block details |
booking.cancelled |
Booking cancelled |
Booking + cancellation timestamp |
booking.rescheduled |
Booking rescheduled |
Old + new booking details |
session.completed |
Time block end_time passes with active booking |
Booking + session details |
Delivery
- Queue webhook delivery as background job (existing job queue)
- Sign payload with HMAC-SHA256 using webhook secret
- Include signature in
X-CalendarGenie-Signature header
- Retry failed deliveries: 3 attempts with exponential backoff (1min, 5min, 30min)
- Mark as failed after max attempts
- 10-second timeout per delivery attempt
Backend Endpoints
| Method |
Path |
Auth |
Description |
| GET |
/api/v1/admin/webhooks |
Admin |
List all webhooks for tenant |
| POST |
/api/v1/admin/webhooks |
Admin |
Create webhook (url, events, secret auto-generated) |
| PUT |
/api/v1/admin/webhooks/:id |
Admin |
Update webhook (url, events, active status) |
| DELETE |
/api/v1/admin/webhooks/:id |
Admin |
Delete webhook |
| POST |
/api/v1/admin/webhooks/:id/test |
Admin |
Send test event to verify endpoint |
| GET |
/api/v1/admin/webhooks/:id/deliveries |
Admin |
View delivery history |
Frontend
- Webhook management page in admin area
- Create webhook: URL input + event checkboxes + auto-generated secret (shown once)
- Delivery log table: event type, status, timestamp, response code
- Test button sends a
test.ping event
- Toggle active/inactive per webhook
Security
- Webhook secrets: generated server-side, 256-bit entropy
- Stored as bcrypt hash — raw secret shown only at creation time
- HMAC signature prevents payload tampering
- URL validation: HTTPS required in production
Effort
L (1-2 weeks)
Acceptance Criteria
Context
Webhook events let power users connect CalendarGenie to CRM, Slack, or billing tools. The GTM strategy targets at least 1 published integration (Zapier or Slack) by Q3. This requires a reliable event delivery system with HMAC-signed payloads.
Scope
Database
Events
booking.createdbooking.cancelledbooking.rescheduledsession.completedDelivery
X-CalendarGenie-SignatureheaderBackend Endpoints
/api/v1/admin/webhooks/api/v1/admin/webhooks/api/v1/admin/webhooks/:id/api/v1/admin/webhooks/:id/api/v1/admin/webhooks/:id/test/api/v1/admin/webhooks/:id/deliveriesFrontend
test.pingeventSecurity
Effort
L (1-2 weeks)
Acceptance Criteria