Analytics API
Dashboard analytics — occupancy, revenue, outstanding balances, expense-vs-revenue trends, and room calendar.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/analytics/:orgId/overview | Dashboard overview metrics |
| GET | /api/analytics/:orgId/occupancy | Occupancy trend over time |
| GET | /api/analytics/:orgId/revenue | Revenue breakdown |
| GET | /api/analytics/:orgId/outstanding | Outstanding balance & aging |
| GET | /api/analytics/:orgId/expense-revenue | Expense vs. revenue comparison |
| GET | /api/analytics/:orgId/calendar | Room availability calendar |
Path Parameters
| Parameter | Type | Description |
|---|---|---|
orgId | string | Organization ID |
Query Parameters
| Endpoint | Parameter | Type | Default | Description |
|---|---|---|---|---|
| Occupancy | days | number | 30 | Number of days to look back |
| Revenue | period | string | daily | Grouping period (daily, weekly, monthly) |
| Revenue | days | number | 30 | Number of days to look back |
| Expense-Revenue | days | number | 180 | Number of days to look back |
| Calendar | days | number | 14 | Number of days to look ahead |
Dashboard Overview
GET /api/analytics/:orgId/overviewResponse — 200 OK
json
{
"success": true,
"data": {
"occupiedRooms": 38,
"totalRooms": 50,
"occupancyRate": 76.0,
"checkInsToday": 5,
"checkOutsToday": 3,
"revenueToday": 87500,
"outstandingBalance": 245000
}
}Occupancy Trend
GET /api/analytics/:orgId/occupancy?days=30Response — 200 OK
json
{
"success": true,
"data": [
{ "date": "2026-01-25", "occupancy": 72.0, "occupied": 36, "total": 50 },
{ "date": "2026-01-26", "occupancy": 74.0, "occupied": 37, "total": 50 },
{ "date": "2026-01-27", "occupancy": 80.0, "occupied": 40, "total": 50 },
{ "date": "2026-01-28", "occupancy": 78.0, "occupied": 39, "total": 50 },
{ "date": "2026-01-29", "occupancy": 82.0, "occupied": 41, "total": 50 },
{ "date": "2026-01-30", "occupancy": 76.0, "occupied": 38, "total": 50 },
{ "date": "2026-01-31", "occupancy": 70.0, "occupied": 35, "total": 50 }
]
}Revenue Breakdown
GET /api/analytics/:orgId/revenue?period=daily&days=30Response — 200 OK
json
{
"success": true,
"data": [
{ "label": "2026-02-17", "amount": 92000, "count": 6 },
{ "label": "2026-02-18", "amount": 85500, "count": 5 },
{ "label": "2026-02-19", "amount": 110000, "count": 8 },
{ "label": "2026-02-20", "amount": 78000, "count": 4 },
{ "label": "2026-02-21", "amount": 95000, "count": 7 },
{ "label": "2026-02-22", "amount": 120000, "count": 9 },
{ "label": "2026-02-23", "amount": 87500, "count": 5 }
]
}Outstanding Balance & Aging
GET /api/analytics/:orgId/outstandingResponse — 200 OK
json
{
"success": true,
"data": {
"totalOutstanding": 245000,
"brackets": [
{ "label": "0-30 days", "min": 0, "max": 30, "count": 8, "total": 125000 },
{ "label": "31-60 days", "min": 31, "max": 60, "count": 4, "total": 72000 },
{ "label": "61-90 days", "min": 61, "max": 90, "count": 2, "total": 33000 },
{ "label": "90+ days", "min": 91, "max": null, "count": 1, "total": 15000 }
],
"topInvoices": [
{
"invoiceId": "665f6a7b8c9d0e1f2a3b4c60",
"invoiceNumber": "INV-1035",
"guestName": "Vikram Singh",
"amount": 45000,
"dueDate": "2026-02-10",
"daysOverdue": 13
},
{
"invoiceId": "665f6a7b8c9d0e1f2a3b4c61",
"invoiceNumber": "INV-1028",
"guestName": "Meera Joshi",
"amount": 32000,
"dueDate": "2026-01-25",
"daysOverdue": 29
},
{
"invoiceId": "665f6a7b8c9d0e1f2a3b4c62",
"invoiceNumber": "INV-1020",
"guestName": "Anil Kapoor",
"amount": 28500,
"dueDate": "2026-01-15",
"daysOverdue": 39
}
]
}
}Expense vs. Revenue
GET /api/analytics/:orgId/expense-revenue?days=180Response — 200 OK
json
{
"success": true,
"data": {
"data": [
{ "month": "2025-09", "revenue": 1850000, "expense": 920000 },
{ "month": "2025-10", "revenue": 2100000, "expense": 980000 },
{ "month": "2025-11", "revenue": 1950000, "expense": 1050000 },
{ "month": "2025-12", "revenue": 2400000, "expense": 1100000 },
{ "month": "2026-01", "revenue": 2250000, "expense": 1020000 },
{ "month": "2026-02", "revenue": 1980000, "expense": 940000 }
],
"summary": {
"totalRevenue": 12530000,
"totalExpense": 6010000,
"netProfit": 6520000
}
}
}Room Calendar
GET /api/analytics/:orgId/calendar?days=14Response — 200 OK
json
{
"success": true,
"data": {
"dates": [
"2026-02-23", "2026-02-24", "2026-02-25", "2026-02-26",
"2026-02-27", "2026-02-28", "2026-03-01", "2026-03-02",
"2026-03-03", "2026-03-04", "2026-03-05", "2026-03-06",
"2026-03-07", "2026-03-08"
],
"rooms": [
{
"roomId": "665a1b2c3d4e5f6a7b8c0001",
"roomNumber": "101",
"category": "Deluxe",
"days": [
{ "date": "2026-02-23", "status": "occupied", "guestName": "Arjun Mehta" },
{ "date": "2026-02-24", "status": "occupied", "guestName": "Arjun Mehta" },
{ "date": "2026-02-25", "status": "checkout", "guestName": "Arjun Mehta" },
{ "date": "2026-02-26", "status": "available", "guestName": null },
{ "date": "2026-02-27", "status": "reserved", "guestName": "Sneha Verma" },
{ "date": "2026-02-28", "status": "reserved", "guestName": "Sneha Verma" },
{ "date": "2026-03-01", "status": "reserved", "guestName": "Sneha Verma" },
{ "date": "2026-03-02", "status": "available", "guestName": null },
{ "date": "2026-03-03", "status": "available", "guestName": null },
{ "date": "2026-03-04", "status": "available", "guestName": null },
{ "date": "2026-03-05", "status": "available", "guestName": null },
{ "date": "2026-03-06", "status": "available", "guestName": null },
{ "date": "2026-03-07", "status": "available", "guestName": null },
{ "date": "2026-03-08", "status": "available", "guestName": null }
]
},
{
"roomId": "665a1b2c3d4e5f6a7b8c0002",
"roomNumber": "102",
"category": "Deluxe",
"days": [
{ "date": "2026-02-23", "status": "available", "guestName": null },
{ "date": "2026-02-24", "status": "reserved", "guestName": "Kiran Rao" },
{ "date": "2026-02-25", "status": "reserved", "guestName": "Kiran Rao" },
{ "date": "2026-02-26", "status": "reserved", "guestName": "Kiran Rao" },
{ "date": "2026-02-27", "status": "available", "guestName": null },
{ "date": "2026-02-28", "status": "available", "guestName": null },
{ "date": "2026-03-01", "status": "maintenance", "guestName": null },
{ "date": "2026-03-02", "status": "maintenance", "guestName": null },
{ "date": "2026-03-03", "status": "available", "guestName": null },
{ "date": "2026-03-04", "status": "available", "guestName": null },
{ "date": "2026-03-05", "status": "available", "guestName": null },
{ "date": "2026-03-06", "status": "available", "guestName": null },
{ "date": "2026-03-07", "status": "available", "guestName": null },
{ "date": "2026-03-08", "status": "available", "guestName": null }
]
},
{
"roomId": "665a1b2c3d4e5f6a7b8c0003",
"roomNumber": "201",
"category": "Suite",
"days": [
{ "date": "2026-02-23", "status": "occupied", "guestName": "Vikram Singh" },
{ "date": "2026-02-24", "status": "occupied", "guestName": "Vikram Singh" },
{ "date": "2026-02-25", "status": "occupied", "guestName": "Vikram Singh" },
{ "date": "2026-02-26", "status": "occupied", "guestName": "Vikram Singh" },
{ "date": "2026-02-27", "status": "checkout", "guestName": "Vikram Singh" },
{ "date": "2026-02-28", "status": "available", "guestName": null },
{ "date": "2026-03-01", "status": "available", "guestName": null },
{ "date": "2026-03-02", "status": "available", "guestName": null },
{ "date": "2026-03-03", "status": "reserved", "guestName": "Deepika Nair" },
{ "date": "2026-03-04", "status": "reserved", "guestName": "Deepika Nair" },
{ "date": "2026-03-05", "status": "reserved", "guestName": "Deepika Nair" },
{ "date": "2026-03-06", "status": "available", "guestName": null },
{ "date": "2026-03-07", "status": "available", "guestName": null },
{ "date": "2026-03-08", "status": "available", "guestName": null }
]
}
]
}
}