Unified Rental System API
Documentation
Overview
The Unified Rental System API provides a comprehensive set of endpoints for managing
hotel rooms, office spaces, and commercial shop rentals. This RESTful API allows you to
manage properties, rentable units, clients, agreements (reservations/leases), bills, and
services.
Base URL
All API endpoints are prefixed with /api .
Authentication
Authentication is not implemented in the current version. It is recommended to
implement an authentication mechanism before deploying to production.
Common Response Formats
Success Response
{
"message": "Operation successful",
"data": { ... }
}
Error Response
{
"error": "Error message describing what went wrong"
}
HTTP Status Codes
• 200 OK : Request succeeded
• 201 Created : Resource created successfully
• 400 Bad Request : Invalid request parameters
• 404 Not Found : Resource not found
• 500 Internal Server Error : Server error
API Endpoints
Properties
Create a Property
Endpoint: POST /properties
Request Body:
{
"name": "Seaside Resort",
"address": "123 Beach Road",
"city": "Miami",
"state": "FL",
"country": "USA",
"zip_code": "33139",
"property_type": "HOTEL",
"description": "Luxury beachfront resort"
}
Required Fields:
- name : String
- address : String
- city : String
- country : String
- property_type : String (one of: "HOTEL", "OFFICE_BUILDING",
"COMMERCIAL_COMPLEX", "MIXED_USE")
Response (201 Created):
{
"message": "Property created successfully",
"property_id": 1
}
Get All Properties
Endpoint: GET /properties
Query Parameters:
- property_type : Filter by property type (optional)
Response (200 OK):
{
"properties": [
{
"property_id": 1,
"name": "Seaside Resort",
"address": "123 Beach Road",
"city": "Miami",
"state": "FL",
"country": "USA",
"zip_code": "33139",
"property_type": "HOTEL",
"description": "Luxury beachfront resort",
"created_at": "2025-06-15T12:00:00",
"updated_at": "2025-06-15T12:00:00"
}
]
}
Get a Specific Property
Endpoint: GET /properties/{property_id}
Response (200 OK):
{
"property": {
"property_id": 1,
"name": "Seaside Resort",
"address": "123 Beach Road",
"city": "Miami",
"state": "FL",
"country": "USA",
"zip_code": "33139",
"property_type": "HOTEL",
"description": "Luxury beachfront resort",
"created_at": "2025-06-15T12:00:00",
"updated_at": "2025-06-15T12:00:00"
}
}
Update a Property
Endpoint: PUT /properties/{property_id}
Request Body:
{
"name": "Seaside Resort & Spa",
"description": "Luxury beachfront resort with full-service spa"
}
Response (200 OK):
{
"message": "Property updated successfully"
}
Delete a Property
Endpoint: DELETE /properties/{property_id}
Response (200 OK):
{
"message": "Property deleted successfully"
}
Rentable Unit Types
Create a Rentable Unit Type
Endpoint: POST /rentable_unit_types
Request Body:
{
"property_id": 1,
"name": "Deluxe Suite",
"description": "Spacious suite with ocean view",
"base_price": 250.00,
"unit_class": "HOTEL_ROOM",
"max_occupancy": 4,
"amenities": "King bed, sofa bed, balcony, mini-bar"
}
Required Fields:
- property_id : Integer
- name : String
- base_price : Numeric
- unit_class : String (one of: "HOTEL_ROOM", "OFFICE_SPACE", "COMMERCIAL_SHOP")
Response (201 Created):
{
"message": "Rentable unit type created successfully",
"type_id": 1
}
Get All Rentable Unit Types
Endpoint: GET /rentable_unit_types
Query Parameters:
- property_id : Filter by property (optional)
- unit_class : Filter by unit class (optional)
Response (200 OK):
{
"rentable_unit_types": [
{
"type_id": 1,
"property_id": 1,
"name": "Deluxe Suite",
"description": "Spacious suite with ocean view",
"base_price": "250.00",
"unit_class": "HOTEL_ROOM",
"max_occupancy": 4,
"amenities": "King bed, sofa bed, balcony, mini-bar",
"created_at": "2025-06-15T12:00:00",
"updated_at": "2025-06-15T12:00:00"
}
]
}
Get a Specific Rentable Unit Type
Endpoint: GET /rentable_unit_types/{type_id}
Response (200 OK):
{
"rentable_unit_type": {
"type_id": 1,
"property_id": 1,
"name": "Deluxe Suite",
"description": "Spacious suite with ocean view",
"base_price": "250.00",
"unit_class": "HOTEL_ROOM",
"max_occupancy": 4,
"amenities": "King bed, sofa bed, balcony, mini-bar",
"created_at": "2025-06-15T12:00:00",
"updated_at": "2025-06-15T12:00:00"
}
}
Update a Rentable Unit Type
Endpoint: PUT /rentable_unit_types/{type_id}
Request Body:
{
"base_price": 275.00,
"description": "Spacious suite with panoramic ocean view"
}
Response (200 OK):
{
"message": "Rentable unit type updated successfully"
}
Delete a Rentable Unit Type
Endpoint: DELETE /rentable_unit_types/{type_id}
Response (200 OK):
{
"message": "Rentable unit type deleted successfully"
}
Rentable Units
Create a Rentable Unit
Endpoint: POST /rentable_units
Request Body:
{
"property_id": 1,
"type_id": 1,
"name": "Room 101",
"status": "AVAILABLE",
"floor": "1",
"unit_number": "101",
"current_area_sqm": 45.5
}
Required Fields:
- property_id : Integer
- type_id : Integer
- name : String
- status : String (one of: "AVAILABLE", "OCCUPIED_LEASED", "MAINTENANCE",
"OUT_OF_ORDER")
Response (201 Created):
{
"message": "Rentable unit created successfully",
"unit_id": 1
}
Get All Rentable Units
Endpoint: GET /rentable_units
Query Parameters:
- property_id : Filter by property (optional)
- type_id : Filter by unit type (optional)
- status : Filter by status (optional)
Response (200 OK):
{
"rentable_units": [
{
"unit_id": 1,
"property_id": 1,
"type_id": 1,
"name": "Room 101",
"status": "AVAILABLE",
"floor": "1",
"unit_number": "101",
"current_area_sqm": "45.50",
"created_at": "2025-06-15T12:00:00",
"updated_at": "2025-06-15T12:00:00"
}
]
}
Get a Specific Rentable Unit
Endpoint: GET /rentable_units/{unit_id}
Response (200 OK):
{
"rentable_unit": {
"unit_id": 1,
"property_id": 1,
"type_id": 1,
"name": "Room 101",
"status": "AVAILABLE",
"floor": "1",
"unit_number": "101",
"current_area_sqm": "45.50",
"created_at": "2025-06-15T12:00:00",
"updated_at": "2025-06-15T12:00:00"
}
}
Update a Rentable Unit
Endpoint: PUT /rentable_units/{unit_id}
Request Body:
{
"status": "MAINTENANCE",
"current_area_sqm": 46.0
}
Response (200 OK):
{
"message": "Rentable unit updated successfully"
}
Delete a Rentable Unit
Endpoint: DELETE /rentable_units/{unit_id}
Response (200 OK):
{
"message": "Rentable unit deleted successfully"
}
Clients
Create a Client
Endpoint: POST /clients
Request Body:
{
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone": "555-123-4567",
"client_type": "INDIVIDUAL",
"company_name": null,
"address": "456 Main St",
"city": "Boston",
"state": "MA",
"country": "USA",
"zip_code": "02108"
}
Required Fields:
- first_name : String
- last_name : String
- email : String
- client_type : String (one of: "INDIVIDUAL", "COMPANY")
Response (201 Created):
{
"message": "Client created successfully",
"client_id": 1
}
Get All Clients
Endpoint: GET /clients
Query Parameters:
- client_type : Filter by client type (optional)
Response (200 OK):
{
"clients": [
{
"client_id": 1,
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone": "555-123-4567",
"client_type": "INDIVIDUAL",
"company_name": null,
"address": "456 Main St",
"city": "Boston",
"state": "MA",
"country": "USA",
"zip_code": "02108",
"created_at": "2025-06-15T12:00:00",
"updated_at": "2025-06-15T12:00:00"
}
]
}
Get a Specific Client
Endpoint: GET /clients/{client_id}
Response (200 OK):
{
"client": {
"client_id": 1,
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone": "555-123-4567",
"client_type": "INDIVIDUAL",
"company_name": null,
"address": "456 Main St",
"city": "Boston",
"state": "MA",
"country": "USA",
"zip_code": "02108",
"created_at": "2025-06-15T12:00:00",
"updated_at": "2025-06-15T12:00:00"
}
}
Update a Client
Endpoint: PUT /clients/{client_id}
Request Body:
{
"phone": "555-987-6543",
"address": "789 Park Ave"
}
Response (200 OK):
{
"message": "Client updated successfully"
}
Delete a Client
Endpoint: DELETE /clients/{client_id}
Response (200 OK):
{
"message": "Client deleted successfully"
}
Agreements
Create an Agreement
Endpoint: POST /agreements
Request Body:
{
"client_id": 1,
"unit_id": 1,
"agreement_type": "HOTEL_STAY",
"start_date": "2025-06-15",
"end_date": "2025-06-20",
"total_amount": 1250.00,
"security_deposit": 200.00,
"status": "CONFIRMED",
"num_adults": 2,
"num_children": 1,
"ota_booking_id": "OTA12345",
"source": "direct",
"lease_term_months": null,
"lease_conditions_notes": null
}
Required Fields:
- client_id : Integer
- unit_id : Integer
- agreement_type : String (one of: "HOTEL_STAY", "OFFICE_LEASE",
"COMMERCIAL_LEASE")
- start_date : String (YYYY-MM-DD)
- end_date : String (YYYY-MM-DD)
Response (201 Created):
{
"message": "Agreement created successfully",
"agreement_id": 1
}
Get All Agreements
Endpoint: GET /agreements
Query Parameters:
- client_id : Filter by client (optional)
- unit_id : Filter by unit (optional)
- property_id : Filter by property (optional)
- status : Filter by status (optional)
- agreement_type : Filter by agreement type (optional)
Response (200 OK):
{
"agreements": [
{
"agreement_id": 1,
"client_id": 1,
"property_id": 1,
"unit_id": 1,
"agreement_type": "HOTEL_STAY",
"start_date": "2025-06-15",
"end_date": "2025-06-20",
"total_amount": "1250.00",
"security_deposit": "200.00",
"status": "CONFIRMED",
"num_adults": 2,
"num_children": 1,
"ota_booking_id": "OTA12345",
"source": "direct",
"lease_term_months": null,
"lease_conditions_notes": null,
"created_at": "2025-06-15T12:00:00",
"updated_at": "2025-06-15T12:00:00"
}
]
}
Get a Specific Agreement
Endpoint: GET /agreements/{agreement_id}
Response (200 OK):
{
"agreement": {
"agreement_id": 1,
"client_id": 1,
"property_id": 1,
"unit_id": 1,
"agreement_type": "HOTEL_STAY",
"start_date": "2025-06-15",
"end_date": "2025-06-20",
"total_amount": "1250.00",
"security_deposit": "200.00",
"status": "CONFIRMED",
"num_adults": 2,
"num_children": 1,
"ota_booking_id": "OTA12345",
"source": "direct",
"lease_term_months": null,
"lease_conditions_notes": null,
"created_at": "2025-06-15T12:00:00",
"updated_at": "2025-06-15T12:00:00"
}
}
Update an Agreement
Endpoint: PUT /agreements/{agreement_id}
Request Body:
{
"status": "CHECKED_IN",
"total_amount": 1350.00
}
Response (200 OK):
{
"message": "Agreement updated successfully"
}
Delete an Agreement
Endpoint: DELETE /agreements/{agreement_id}
Response (200 OK):
{
"message": "Agreement deleted successfully"
}
Bills
Create a Bill
Endpoint: POST /bills
Request Body:
{
"agreement_id": 1,
"client_id": 1,
"issue_date": "2025-06-15",
"due_date": "2025-06-30",
"total_amount": 1250.00,
"paid_amount": 0.00,
"payment_status": "UNPAID",
"notes": "Initial bill for hotel stay"
}
Required Fields:
- agreement_id : Integer
- client_id : Integer
Response (201 Created):
{
"message": "Bill created successfully",
"bill_id": 1
}
Get All Bills
Endpoint: GET /bills
Query Parameters:
- client_id : Filter by client (optional)
- agreement_id : Filter by agreement (optional)
- payment_status : Filter by payment status (optional)
Response (200 OK):
{
"bills": [
{
"bill_id": 1,
"agreement_id": 1,
"client_id": 1,
"issue_date": "2025-06-15",
"due_date": "2025-06-30",
"total_amount": "1250.00",
"paid_amount": "0.00",
"payment_status": "UNPAID",
"notes": "Initial bill for hotel stay",
"created_at": "2025-06-15T12:00:00",
"updated_at": "2025-06-15T12:00:00"
}
]
}
Get a Specific Bill
Endpoint: GET /bills/{bill_id}
Response (200 OK):
{
"bill": {
"bill_id": 1,
"agreement_id": 1,
"client_id": 1,
"issue_date": "2025-06-15",
"due_date": "2025-06-30",
"total_amount": "1250.00",
"paid_amount": "0.00",
"payment_status": "UNPAID",
"notes": "Initial bill for hotel stay",
"created_at": "2025-06-15T12:00:00",
"updated_at": "2025-06-15T12:00:00",
"bill_items": [
{
"bill_item_id": 1,
"description": "Room Charge - Deluxe Suite",
"quantity": "5.00",
"unit_price": "250.00",
"total_price": "1250.00",
"item_date": "2025-06-15"
}
]
}
}
Update a Bill
Endpoint: PUT /bills/{bill_id}
Request Body:
{
"paid_amount": 1250.00,
"payment_status": "PAID",
"notes": "Paid in full on checkout"
}
Response (200 OK):
{
"message": "Bill updated successfully"
}
Delete a Bill
Endpoint: DELETE /bills/{bill_id}
Response (200 OK):
{
"message": "Bill and associated items deleted successfully"
}
Bill Items
Create a Bill Item
Endpoint: POST /bills/{bill_id}/items
Request Body:
{
"description": "Room Service - Dinner",
"quantity": 1,
"unit_price": 75.00,
"item_date": "2025-06-16"
}
Required Fields:
- description : String
- unit_price : Numeric
Response (201 Created):
{
"message": "Bill item added successfully",
"bill_item_id": 2,
"updated_bill_total": "1325.00"
}
Get All Bill Items for a Bill
Endpoint: GET /bills/{bill_id}/items
Response (200 OK):
{
"bill_items": [
{
"bill_item_id": 1,
"bill_id": 1,
"description": "Room Charge - Deluxe Suite",
"quantity": "5.00",
"unit_price": "250.00",
"total_price": "1250.00",
"item_date": "2025-06-15",
"created_at": "2025-06-15T12:00:00",
"updated_at": "2025-06-15T12:00:00"
},
{
"bill_item_id": 2,
"bill_id": 1,
"description": "Room Service - Dinner",
"quantity": "1.00",
"unit_price": "75.00",
"total_price": "75.00",
"item_date": "2025-06-16",
"created_at": "2025-06-16T18:00:00",
"updated_at": "2025-06-16T18:00:00"
}
]
}
Get a Specific Bill Item
Endpoint: GET /bills/{bill_id}/items/{item_id}
Response (200 OK):
```json
{
"bill_item": {
"bill_item_id": 2,
"bill_id
(Content truncated due to size limit. Use line ranges to read in chunks)