Bookings
Bookings are the central entity in the Booking Management System. A booking connects a guest to one or more rooms for a date range. This guide covers the complete booking lifecycle — from creation through checkout.
Booking Lifecycle
Every booking follows a well-defined lifecycle:
stateDiagram-v2
[*] --> Confirmed: Create booking
Confirmed --> CheckedIn: Check-in guest
Confirmed --> Cancelled: Cancel booking
CheckedIn --> CheckedOut: Checkout all rooms
CheckedIn --> CheckedIn: Add/remove rooms
CheckedOut --> [*]
Cancelled --> [*]| Status | Description |
|---|---|
confirmed | Booking is created and rooms are reserved. Guest has not yet arrived. |
checked-in | Guest has arrived and is occupying the room(s). |
checked-out | Guest has departed. Invoice is finalized. |
cancelled | Booking was cancelled. Rooms are released. |
Creating a Booking
Step-by-Step
- Select or create a guest — Search existing guests by name, email, or phone. If the guest is new, create their profile inline.
- Choose dates — Pick check-in and check-out dates.
- Select rooms — Browse available rooms (filtered by your selected dates) and add one or more to the booking.
- Review pricing — Pricing auto-calculates based on room category rates × number of nights.
- Confirm — Submit the booking.
API: Create Booking
POST /api/bookings
Authorization: Bearer <access_token>
Content-Type: application/json
{
"guestId": "guest_123",
"checkIn": "2026-03-01",
"checkOut": "2026-03-05",
"rooms": ["room_101", "room_205"],
"notes": "Late arrival expected",
"source": "walk-in"
}Response:
{
"success": true,
"data": {
"bookingId": "bk_456",
"bookingNumber": "BK-2026-0112",
"guestId": "guest_123",
"guestName": "Priya Mehta",
"checkIn": "2026-03-01",
"checkOut": "2026-03-05",
"rooms": [
{ "roomId": "room_101", "roomNumber": "101", "category": "Deluxe" },
{ "roomId": "room_205", "roomNumber": "205", "category": "Suite" }
],
"status": "confirmed",
"totalAmount": 28000,
"invoiceId": "inv_789",
"createdAt": "2026-02-23T14:30:00Z"
}
}What Happens on Create
sequenceDiagram
participant U as User
participant API as Backend
participant FS as Firestore
participant RD as Redis
participant WS as Socket.IO
U->>API: POST /api/bookings
API->>FS: Check room availability for dates
FS-->>API: Rooms available ✓
API->>FS: Create booking document
API->>FS: Create invoice document (auto-generated)
API->>FS: Update room status
API->>RD: Invalidate booking & room caches
API->>WS: Emit "booking:created"
API-->>U: 201 Created + booking dataKey automated actions:
- Availability check — The system verifies no conflicting bookings exist for the selected rooms and dates. If a conflict exists, the request returns
409 Conflict. - Invoice generation — An invoice is automatically created with line items for each room × number of nights.
- Series increment — The booking number (e.g.,
BK-2026-0112) and invoice number are auto-incremented from the organization's series configuration. - Cache invalidation — Room availability and booking list caches are cleared.
- Real-time event — All connected clients in the organization receive the
booking:createdevent.
Room Availability
Before creating a booking, the system checks room availability. You can also query availability directly.
API: Check Availability
GET /api/rooms/availability?checkIn=2026-03-01&checkOut=2026-03-05
Authorization: Bearer <access_token>Response:
{
"success": true,
"data": {
"available": [
{ "roomId": "room_101", "roomNumber": "101", "category": "Deluxe", "price": 3500 },
{ "roomId": "room_205", "roomNumber": "205", "category": "Suite", "price": 7000 }
],
"unavailable": [
{ "roomId": "room_102", "roomNumber": "102", "category": "Deluxe", "conflictingBooking": "BK-2026-0108" }
]
}
}Availability is determined by checking for any existing bookings that overlap with the requested date range:
Conflict exists if:
existing.checkIn < requested.checkOut AND existing.checkOut > requested.checkInCheck-In (Arrival)
When a guest arrives, mark the booking as checked in:
API: Check In
PATCH /api/bookings/:bookingId/checkin
Authorization: Bearer <access_token>
Content-Type: application/json
{
"roomId": "room_101",
"guestIdProof": "AADHAAR-XXXX-1234",
"arrivalTime": "2026-03-01T14:00:00Z"
}Response:
{
"success": true,
"data": {
"bookingId": "bk_456",
"status": "checked-in",
"rooms": [
{ "roomId": "room_101", "roomNumber": "101", "status": "occupied", "checkedInAt": "2026-03-01T14:00:00Z" },
{ "roomId": "room_205", "roomNumber": "205", "status": "reserved" }
]
}
}Check-In Behavior
- Individual rooms within a booking can be checked in separately (e.g., guest arrives for one room, second room's guest arrives later).
- The booking status changes to
checked-inwhen the first room is checked in. - Room status changes from
reservedtooccupied. - A
booking:checkinSocket.IO event is broadcast.
Managing Rooms During a Stay
Adding a Room
A guest might request an additional room during their stay:
POST /api/bookings/:bookingId/rooms
Authorization: Bearer <access_token>
Content-Type: application/json
{
"roomId": "room_103",
"checkIn": "2026-03-02",
"checkOut": "2026-03-05"
}This:
- Checks availability for the new room and dates.
- Adds the room to the booking's
rooms[]array. - Updates the invoice with additional line items.
- Invalidates relevant caches.
Removing a Room
Remove a room before checkout (e.g., guest cancels one of multiple rooms):
DELETE /api/bookings/:bookingId/rooms/:roomId
Authorization: Bearer <access_token>This:
- Removes the room from the booking.
- Adjusts the invoice (removes or credits the line items).
- Releases the room back to available status.
WARNING
A booking must always have at least one room. If you need to remove all rooms, cancel the booking instead.
Checkout
Checkout finalizes the booking and triggers invoice settlement.
Individual Room Checkout
For bookings with multiple rooms, check out rooms individually as different guests may depart at different times:
PATCH /api/bookings/:bookingId/checkout/room/:roomId
Authorization: Bearer <access_token>
Content-Type: application/json
{
"departureTime": "2026-03-05T11:00:00Z"
}Each room checkout:
- Sets the room status to
available. - Records the departure time.
- Emits a
booking:checkoutevent for that room.
Overall Checkout
When all rooms are vacated (or to check out all at once):
PATCH /api/bookings/:bookingId/checkout
Authorization: Bearer <access_token>
Content-Type: application/json
{
"departureTime": "2026-03-05T11:00:00Z"
}Checkout Flow
sequenceDiagram
participant U as User
participant API as Backend
participant FS as Firestore
participant WS as Socket.IO
U->>API: PATCH /bookings/:id/checkout
API->>FS: Update booking status → "checked-out"
API->>FS: Release all rooms → "available"
API->>FS: Finalize invoice
API->>WS: Emit "booking:checkout"
API-->>U: 200 OK + final booking dataAt checkout:
- Booking status changes to
checked-out. - All associated rooms are released.
- The invoice is finalized (no more line items can be added).
- Outstanding balance is calculated and shown for settlement.
Cancellation
Cancel a booking that hasn't been fully checked out:
PATCH /api/bookings/:bookingId/cancel
Authorization: Bearer <access_token>
Content-Type: application/json
{
"reason": "Guest requested cancellation",
"refundAmount": 5000
}Cancellation Behavior
- Booking status changes to
cancelled. - All reserved rooms are released.
- If payments were already made, a credit note is generated for the refund amount.
- The invoice is marked as
cancelled. - Already-checked-in rooms are force-released.
WARNING
Cancellation is irreversible. A cancelled booking cannot be reactivated. If a guest returns, create a new booking.
Guest Change
Transfer a booking to a different guest (in case of a name error or actual guest change):
PATCH /api/bookings/:bookingId/guest
Authorization: Bearer <access_token>
Content-Type: application/json
{
"newGuestId": "guest_789"
}- The booking's
guestIdis updated. - The linked invoice's guest reference is also updated.
- An audit log entry records the change with both old and new guest IDs.
Related Entities
Invoices
Every booking automatically creates an invoice. The invoice contains line items for:
- Room charges (rate × nights per room)
- Taxes (applied based on the organization's tax configuration)
- Additional charges (minibar, room service — if added manually)
The invoice updates dynamically as rooms are added/removed from the booking.
Payments
Payments are recorded against invoices:
POST /api/payments
Authorization: Bearer <access_token>
Content-Type: application/json
{
"invoiceId": "inv_789",
"amount": 15000,
"method": "upi",
"reference": "UPI-TXN-123456"
}Payment methods supported: cash, card, upi, bank_transfer, other.
Credit Notes
If an overcharge or cancellation requires a refund, credit notes are issued against the invoice. They reduce the outstanding balance without deleting payment history.
Booking Permissions
| Permission | Allows |
|---|---|
booking:create | Create new bookings |
booking:read | View booking list and details |
booking:update | Modify bookings (add/remove rooms, change guest) |
booking:checkin | Perform check-in |
booking:checkout | Perform checkout |
booking:cancel | Cancel bookings |
booking:delete | Permanently delete booking records |
Permissions are assigned through roles. See the Architecture guide for details on the RBAC system.