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
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]
endCreate a Category
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:
{
"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
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
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
GET /api/room-categories
Authorization: Bearer <access_token>Response:
{
"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:
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:
{
"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
| Field | Type | Description |
|---|---|---|
roomNumber | String | Display number (e.g., "101", "A-12") |
categoryId | String | Reference to the room category |
floor | Number | Floor level |
isAvailable | Boolean | Whether the room can be booked (maintenance toggle) |
status | String | Current occupancy: available, reserved, occupied |
notes | String | Internal notes about the room |
isAvailable vs status
isAvailableis a manual toggle. Set it tofalseto take a room out of service (e.g., for maintenance or renovation). Unavailable rooms cannot be booked.statusis system-managed. It changes automatically based on bookings:available→reserved(booking confirmed) →occupied(guest checked in) →available(guest checked out).
Update a Room
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
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
GET /api/rooms/:roomId
Authorization: Bearer <access_token>List All Rooms
GET /api/rooms?categoryId=cat_001&floor=1&status=available
Authorization: Bearer <access_token>Supports filtering by:
categoryId— Filter by room typefloor— Filter by floor numberstatus— Filter byavailable,reserved,occupiedisAvailable— Filter by maintenance availability (true/false)
Availability Toggle
Take a room out of service for maintenance, cleaning, or any other reason:
PATCH /api/rooms/:roomId/availability
Authorization: Bearer <access_token>
Content-Type: application/json
{
"isAvailable": false,
"reason": "Under renovation until March 15"
}Toggle Behavior
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
isAvailableis set tofalse, the room disappears from availability searches and cannot be selected for new bookings. - If the room currently has an active booking (
reservedoroccupied), you receive a warning but can still proceed. The existing booking is not affected, but no new bookings can be made. - A
room:statusChangedSocket.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:
GET /api/rooms/overview
Authorization: Bearer <access_token>Response:
{
"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:
| Scheme | Example | Use Case |
|---|---|---|
| Numeric | 101, 102, 201 | Standard floor-room numbering |
| Alphanumeric | A-01, B-12 | Wing/block-based properties |
| Named | Ocean View 1, Garden Suite | Boutique 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:
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:
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| R2How Room Status Changes
| Event | Room Status Before | Room Status After |
|---|---|---|
| Booking created | available | reserved |
| Guest checked in | reserved | occupied |
| Guest checked out (room) | occupied | available |
| Booking cancelled | reserved | available |
| Room added to booking | available | reserved |
| Room removed from booking | reserved | available |
Viewing a Room's Booking History
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
| Permission | Allows |
|---|---|
room:create | Create new rooms |
room:read | View room list, details, and availability |
room:update | Edit room details, toggle availability |
room:delete | Delete rooms |
room-category:create | Create new categories |
room-category:read | View categories |
room-category:update | Edit category details and pricing |
room-category:delete | Delete categories |