Skip to content

Booking Lifecycle

Every booking in The Booking Kit follows a defined state machine. All transitions are recorded in an append-only audit trail.

┌──────────┐
│ pending │
└────┬─────┘
┌──────────┼──────────┐
▼ ▼ ▼
┌─────────┐ ┌────────┐ ┌──────────┐
│confirmed│ │rejected│ │(auto- │
└────┬────┘ └────────┘ │ reject) │
│ └───────────┘
┌────────┼────────┬─────────┐
▼ ▼ ▼ ▼
┌─────────┐ ┌──────┐ ┌──────────┐ ┌────────┐
│completed│ │no_show│ │cancelled │ │resched-│
└─────────┘ └──────┘ └──────────┘ │uled │
└────────┘
StatusDescription
pendingAwaiting provider confirmation (confirmation mode only)
confirmedBooking is confirmed and on the schedule
completedAppointment has taken place
cancelledCancelled by customer or provider
rescheduledOriginal booking moved to a new time
no_showCustomer did not attend
rejectedProvider declined the booking (confirmation mode)
FromTo
pendingconfirmed, rejected
confirmedcompleted, cancelled, rescheduled, no_show

Auto-confirm event types skip pending and go directly to confirmed.

Event types can require manual approval before bookings are confirmed:

import { getInitialBookingStatus, getAutoRejectDeadline } from "@thebookingkit/core";
// Returns "pending" or "confirmed" based on event type config
const status = getInitialBookingStatus(eventType.requiresConfirmation);
// Auto-reject deadline (default: 24 hours)
const deadline = getAutoRejectDeadline(booking.createdAt);

See Confirmation Mode for full details.

Every status change is recorded in the booking_events table:

ColumnDescription
booking_idFK to the booking
event_typeThe type of change (status_change, created, updated, etc.)
old_statusPrevious status
new_statusNew status
actor_idWho made the change (provider, customer, or system)
metadataJSONB with additional context
created_atWhen the change occurred

The booking_events table is append-only — rows are never updated or deleted. This provides a complete history of every booking for auditing, dispute resolution, and analytics.

A database trigger automatically creates audit entries on booking status changes.

Customers can manage their bookings via signed tokens (no login required):

import { generateBookingToken, verifyBookingToken } from "@thebookingkit/core";
// Generate a token for a booking (e.g., in confirmation email)
const token = generateBookingToken(bookingId, customerEmail, secret);
// Verify and extract the booking ID from a token
const { bookingId, email } = verifyBookingToken(token, secret);

These tokens are used in cancel/reschedule links in emails.