Skip to content

Rooms

Rooms are the physical inventory of your property. They are organized into categories (room types) and individually managed for availability, pricing, and booking assignments. This guide covers room categories, individual room management, and how rooms connect to the rest of the system.

Room Categories

A room category represents a type of room — for example, Deluxe, Standard, Suite, or Dormitory. Categories define shared attributes like base pricing and amenities, while individual rooms within a category can be managed independently.

Category Structure

mermaid
graph TD
    subgraph Hotel
        CAT1["Deluxe<br/>₹3,500/night"]
        CAT2["Suite<br/>₹7,000/night"]
        CAT3["Standard<br/>₹2,000/night"]

        CAT1 --- R101[Room 101]
        CAT1 --- R102[Room 102]
        CAT1 --- R103[Room 103]
        CAT2 --- R201[Room 201]
        CAT2 --- R202[Room 202]
        CAT3 --- R301[Room 301]
        CAT3 --- R302[Room 302]
        CAT3 --- R303[Room 303]
        CAT3 --- R304[Room 304]
    end

Create a Category

http
POST /api/room-categories
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "name": "Deluxe",
  "shortCode": "DLX",
  "basePrice": 3500,
  "maxOccupancy": 2,
  "amenities": ["AC", "WiFi", "TV", "Mini Bar", "Balcony"],
  "description": "Spacious room with city view and premium amenities"
}

Response:

json
{
  "success": true,
  "data": {
    "categoryId": "cat_001",
    "name": "Deluxe",
    "shortCode": "DLX",
    "basePrice": 3500,
    "maxOccupancy": 2,
    "amenities": ["AC", "WiFi", "TV", "Mini Bar", "Balcony"],
    "description": "Spacious room with city view and premium amenities",
    "roomCount": 0,
    "orgId": "org_456",
    "createdAt": "2026-02-23T10:00:00Z"
  }
}

Update a Category

http
PUT /api/room-categories/:categoryId
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "basePrice": 4000,
  "amenities": ["AC", "WiFi", "TV", "Mini Bar", "Balcony", "Room Service"]
}

Updating a category's price affects new bookings only. Existing bookings retain the price that was active at the time of creation.

Delete a Category

http
DELETE /api/room-categories/:categoryId
Authorization: Bearer <access_token>

WARNING

A category can only be deleted if it has no rooms assigned to it. Remove or reassign all rooms first.

List All Categories

http
GET /api/room-categories
Authorization: Bearer <access_token>

Response:

json
{
  "success": true,
  "data": [
    {
      "categoryId": "cat_001",
      "name": "Deluxe",
      "shortCode": "DLX",
      "basePrice": 3500,
      "maxOccupancy": 2,
      "amenities": ["AC", "WiFi", "TV", "Mini Bar", "Balcony"],
      "roomCount": 5,
      "availableRooms": 3
    },
    {
      "categoryId": "cat_002",
      "name": "Suite",
      "shortCode": "STE",
      "basePrice": 7000,
      "maxOccupancy": 3,
      "amenities": ["AC", "WiFi", "TV", "Mini Bar", "Jacuzzi", "Living Area"],
      "roomCount": 2,
      "availableRooms": 1
    }
  ]
}

Each category in the list includes roomCount (total rooms) and availableRooms (rooms currently not occupied or reserved) for quick reference.


Room CRUD

Create a Room

Rooms are always created within a category:

http
POST /api/rooms
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "roomNumber": "103",
  "categoryId": "cat_001",
  "floor": 1,
  "isAvailable": true,
  "notes": "Corner room, extra window"
}

Response:

json
{
  "success": true,
  "data": {
    "roomId": "room_103",
    "roomNumber": "103",
    "categoryId": "cat_001",
    "categoryName": "Deluxe",
    "floor": 1,
    "isAvailable": true,
    "status": "available",
    "notes": "Corner room, extra window",
    "orgId": "org_456",
    "createdAt": "2026-02-23T10:30:00Z"
  }
}

Room Fields

FieldTypeDescription
roomNumberStringDisplay number (e.g., "101", "A-12")
categoryIdStringReference to the room category
floorNumberFloor level
isAvailableBooleanWhether the room can be booked (maintenance toggle)
statusStringCurrent occupancy: available, reserved, occupied
notesStringInternal notes about the room

isAvailable vs status

  • isAvailable is a manual toggle. Set it to false to take a room out of service (e.g., for maintenance or renovation). Unavailable rooms cannot be booked.
  • status is system-managed. It changes automatically based on bookings: availablereserved (booking confirmed) → occupied (guest checked in) → available (guest checked out).

Update a Room

http
PUT /api/rooms/:roomId
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "roomNumber": "103A",
  "categoryId": "cat_002",
  "notes": "Upgraded to Suite after renovation"
}

You can reassign a room to a different category (e.g., after renovation upgrades the room type).

Delete a Room

http
DELETE /api/rooms/:roomId
Authorization: Bearer <access_token>

WARNING

A room can only be deleted if it has no active bookings (no confirmed or checked-in bookings referencing it). Past bookings (checked-out) are retained for historical records.

Get a Single Room

http
GET /api/rooms/:roomId
Authorization: Bearer <access_token>

List All Rooms

http
GET /api/rooms?categoryId=cat_001&floor=1&status=available
Authorization: Bearer <access_token>

Supports filtering by:

  • categoryId — Filter by room type
  • floor — Filter by floor number
  • status — Filter by available, reserved, occupied
  • isAvailable — Filter by maintenance availability (true/false)

Availability Toggle

Take a room out of service for maintenance, cleaning, or any other reason:

http
PATCH /api/rooms/:roomId/availability
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "isAvailable": false,
  "reason": "Under renovation until March 15"
}

Toggle Behavior

mermaid
stateDiagram-v2
    Available --> Unavailable: Toggle off (maintenance)
    Unavailable --> Available: Toggle on (back in service)

    state Available {
        [*] --> Free
        Free --> Reserved: Booking confirmed
        Reserved --> Occupied: Guest checked in
        Occupied --> Free: Guest checked out
    }
  • When isAvailable is set to false, the room disappears from availability searches and cannot be selected for new bookings.
  • If the room currently has an active booking (reserved or occupied), you receive a warning but can still proceed. The existing booking is not affected, but no new bookings can be made.
  • A room:statusChanged Socket.IO event is emitted so all connected clients see the change immediately.

Room Overview & Statistics

The room overview provides a snapshot of your property's room inventory:

http
GET /api/rooms/overview
Authorization: Bearer <access_token>

Response:

json
{
  "success": true,
  "data": {
    "totalRooms": 20,
    "availableRooms": 12,
    "occupiedRooms": 6,
    "reservedRooms": 2,
    "unavailableRooms": 0,
    "occupancyRate": 30.0,
    "byCategory": [
      {
        "categoryId": "cat_001",
        "categoryName": "Deluxe",
        "total": 8,
        "available": 5,
        "occupied": 2,
        "reserved": 1
      },
      {
        "categoryId": "cat_002",
        "categoryName": "Suite",
        "total": 4,
        "available": 2,
        "occupied": 2,
        "reserved": 0
      },
      {
        "categoryId": "cat_003",
        "categoryName": "Standard",
        "total": 8,
        "available": 5,
        "occupied": 2,
        "reserved": 1
      }
    ],
    "byFloor": [
      { "floor": 1, "total": 10, "available": 6, "occupied": 3, "reserved": 1 },
      { "floor": 2, "total": 10, "available": 6, "occupied": 3, "reserved": 1 }
    ]
  }
}

This powers the room management page's summary bar and the dashboard's occupancy metrics.


Room Numbering & Organization

Naming Conventions

Room numbers are free-text strings, so you can adopt any scheme that fits your property:

SchemeExampleUse Case
Numeric101, 102, 201Standard floor-room numbering
AlphanumericA-01, B-12Wing/block-based properties
NamedOcean View 1, Garden SuiteBoutique hotels or villas

Organizing by Floor

The floor field on each room enables floor-based filtering and visual grouping in the UI. The room management page groups rooms by floor, and each floor section shows its own mini occupancy summary.

Bulk Operations

For properties with many rooms, the system supports bulk creation:

http
POST /api/rooms/bulk
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "categoryId": "cat_001",
  "floor": 2,
  "rooms": [
    { "roomNumber": "201" },
    { "roomNumber": "202" },
    { "roomNumber": "203" },
    { "roomNumber": "204" },
    { "roomNumber": "205" }
  ]
}

All rooms inherit the specified category and floor. Each room is validated individually — if room 203 already exists, the others are still created and the response indicates which ones failed.


Rooms & Bookings

Rooms and bookings are tightly linked throughout the system:

mermaid
graph LR
    B["Booking<br/>BK-2026-0112"]
    R1["Room 101<br/>(Deluxe)"]
    R2["Room 205<br/>(Suite)"]
    G["Guest<br/>Priya Mehta"]
    I["Invoice<br/>INV-2026-0089"]

    G -->|guest of| B
    B -->|reserves| R1
    B -->|reserves| R2
    B -->|generates| I
    R1 -->|status: occupied| R1
    R2 -->|status: reserved| R2

How Room Status Changes

EventRoom Status BeforeRoom Status After
Booking createdavailablereserved
Guest checked inreservedoccupied
Guest checked out (room)occupiedavailable
Booking cancelledreservedavailable
Room added to bookingavailablereserved
Room removed from bookingreservedavailable

Viewing a Room's Booking History

http
GET /api/rooms/:roomId/bookings?from=2026-01-01&to=2026-02-28
Authorization: Bearer <access_token>

Returns all bookings (past and future) associated with the room in the specified date range. Useful for auditing and understanding a room's utilization pattern.


Permissions

PermissionAllows
room:createCreate new rooms
room:readView room list, details, and availability
room:updateEdit room details, toggle availability
room:deleteDelete rooms
room-category:createCreate new categories
room-category:readView categories
room-category:updateEdit category details and pricing
room-category:deleteDelete categories

Released under the MIT License.