8.8 KiB
TrisolarisPMS API Usage
1) Booking
Create booking
POST /properties/{propertyId}/bookings Auth: ADMIN/MANAGER/STAFF
Body (JSON) Required:
- expectedCheckInAt (String, ISO-8601, required)
- expectedCheckOutAt (String, ISO-8601, required)
Optional:
- source (String, default "WALKIN")
- transportMode (String enum)
- adultCount (Int)
- totalGuestCount (Int)
- notes (String)
{ "source": "WALKIN", "expectedCheckInAt": "2026-01-28T12:00:00+05:30", "expectedCheckOutAt": "2026-01-29T10:00:00+05:30", "transportMode": "CAR", "adultCount": 2, "totalGuestCount": 3, "notes": "Late arrival" }
Behavior If expectedCheckInAt >= now(property timezone) -> booking becomes CHECKED_IN, and checkinAt is set, expected fields are null.
Response
{ "id": "uuid", "status": "OPEN|CHECKED_IN", "checkInAt": "2026-01-28T12:00:00+05:30" | null, "expectedCheckInAt": "..." | null, "expectedCheckOutAt": "..." | null }
List bookings
GET /properties/{propertyId}/bookings Optional query param:
- status (comma-separated), e.g. status=OPEN,CHECKED_IN
Behavior:
- If status is omitted, returns all bookings for the property (newest first).
Response: List of BookingListItem with id, status, guestId, source, times, counts, expectedGuestCount, notes.
Check-in (creates RoomStay)
POST /properties/{propertyId}/bookings/{bookingId}/check-in Auth: ADMIN/MANAGER
Body Required:
- roomIds (List)
Optional:
- checkInAt (String)
- transportMode (String enum)
- nightlyRate (Long)
- rateSource (MANUAL|RATE_PLAN|OTA)
- ratePlanCode (String)
- currency (String)
- notes (String)
{ "roomIds": ["uuid1","uuid2"], "checkInAt": "2026-01-28T12:00:00+05:30", "nightlyRate": 2500, "rateSource": "MANUAL", "ratePlanCode": "EP", "currency": "INR", "notes": "Late arrival" }
Pre-assign room stay
POST /properties/{propertyId}/bookings/{bookingId}/room-stays Auth: ADMIN/MANAGER
Body Required:
- roomId (UUID)
- fromAt (String)
- toAt (String)
Optional:
- nightlyRate (Long)
- rateSource (MANUAL|RATE_PLAN|OTA)
- ratePlanCode (String)
- currency (String)
- notes (String)
{ "roomId": "uuid", "fromAt": "2026-01-29T12:00:00+05:30", "toAt": "2026-01-30T10:00:00+05:30", "nightlyRate": 2800, "rateSource": "RATE_PLAN", "ratePlanCode": "EP", "currency": "INR" }
Active room stays
GET /properties/{propertyId}/room-stays/active Auth: any member except AGENT-only
Response: list of ActiveRoomStayResponse
[ { "roomStayId":"uuid", "bookingId":"uuid", "guestId":"uuid-or-null", "guestName":"Name", "guestPhone":"+9111...", "roomId":"uuid", "roomNumber":"101", "roomTypeName":"DELUXE", "fromAt":"2026-01-29T12:00:00+05:30", "checkinAt":"2026-01-29T12:05:00+05:30", "expectedCheckoutAt":"2026-01-30T10:00:00+05:30" } ]
Change room (move guest)
POST /properties/{propertyId}/room-stays/{roomStayId}/change-room Auth: ADMIN/MANAGER/STAFF
Body
{ "newRoomId":"uuid", "movedAt":"2026-01-30T15:00:00+05:30", "idempotencyKey":"any-unique-string" }
Response
{ "oldRoomStayId":"uuid", "newRoomStayId":"uuid", "oldRoomId":"uuid", "newRoomId":"uuid", "movedAt":"2026-01-30T15:00:00+05:30" }
2) Guests
Create guest + link to booking
POST /properties/{propertyId}/guests Auth: property member Body (required):
- bookingId (UUID)
Optional:
- phoneE164 (String)
- name (String)
- nationality (String)
- addressText (String)
{ "bookingId": "uuid", "phoneE164": "+911111111111", "name": "John", "nationality": "IN", "addressText": "Varanasi" }
Behavior:
- If phone already exists -> links existing guest to booking and returns it.
- If booking already has a guest -> 409.
Response (GuestResponse)
{ "id": "uuid", "name": "John", "phoneE164": "+911111111111", "nationality": "IN", "addressText": "Varanasi", "signatureUrl": "/properties/{propertyId}/guests/{guestId}/signature/file", "vehicleNumbers": [], "averageScore": null }
Add guest vehicle + link to booking
POST /properties/{propertyId}/guests/{guestId}/vehicles Auth: property member Body:
{ "vehicleNumber": "UP32AB1234", "bookingId": "uuid" }
Upload signature (SVG only)
POST /properties/{propertyId}/guests/{guestId}/signature Auth: ADMIN/MANAGER Multipart:
- file (SVG)
Download signature
GET /properties/{propertyId}/guests/{guestId}/signature/file Auth: property member Returns image/svg+xml.
Search guest by phone
GET /properties/{propertyId}/guests/search?phone=+911111111111
3) Room Types (default rate + rate resolve)
Room type create/update
Fields now include defaultRate:
RoomTypeUpsertRequest
{ "code": "DELUX", "name": "Deluxe", "baseOccupancy": 2, "maxOccupancy": 3, "sqFeet": 150, "bathroomSqFeet": 30, "defaultRate": 2500, "active": true, "otaAliases": [], "amenityIds": [] }
Resolve preset rate for date
GET /properties/{propertyId}/room-types/{roomTypeCode}/rate?date=YYYY-MM-DD&ratePlanCode=optional Auth: public if no auth, or member
Response
{ "roomTypeCode": "DELUX", "rateDate": "2026-02-01", "rate": 2800, "currency": "INR", "ratePlanCode": "WEEKEND" }
4) Rate Plans + Calendar
Create rate plan
POST /properties/{propertyId}/rate-plans Auth: ADMIN/MANAGER
Body Required:
- code (String)
- name (String)
- roomTypeCode (String)
- baseRate (Long)
Optional:
- currency (String, default property currency)
{ "code":"WEEKEND", "name":"Weekend", "roomTypeCode":"DELUX", "baseRate":2800, "currency":"INR" }
Response RatePlanResponse
List plans
GET /properties/{propertyId}/rate-plans?roomTypeCode=optional Auth: member
Update
PUT /properties/{propertyId}/rate-plans/{ratePlanId} Body:
{ "name":"Weekend", "baseRate":3000, "currency":"INR" }
Delete
DELETE /properties/{propertyId}/rate-plans/{ratePlanId}
Calendar upsert (batch)
POST /properties/{propertyId}/rate-plans/{ratePlanId}/calendar Body: Array
[ { "rateDate":"2026-02-01", "rate":3200 }, { "rateDate":"2026-02-02", "rate":3500 } ]
Calendar list
GET /properties/{propertyId}/rate-plans/{ratePlanId}/calendar?from=YYYY-MM-DD&to=YYYY-MM-DD
Calendar delete
DELETE /properties/{propertyId}/rate-plans/{ratePlanId}/calendar/{rateDate}
5) RoomStay rate change (mid-stay renegotiation)
POST /properties/{propertyId}/room-stays/{roomStayId}/change-rate Auth: ADMIN/MANAGER
Body Required:
- effectiveAt (String, ISO-8601)
- nightlyRate (Long)
- rateSource (MANUAL|RATE_PLAN|OTA)
Optional:
- ratePlanCode (String)
- currency (String)
{ "effectiveAt": "2026-01-30T12:00:00+05:30", "nightlyRate": 2000, "rateSource": "MANUAL", "currency": "INR" }
Response
{ "oldRoomStayId":"uuid", "newRoomStayId":"uuid", "effectiveAt":"..." }
Check-out (closes all active stays on booking)
POST /properties/{propertyId}/bookings/{bookingId}/check-out Auth: ADMIN/MANAGER
Body
{ "checkOutAt":"2026-01-30T10:00:00+05:30", "notes":"optional" }
Response: 204 No Content
Bulk check-in (creates multiple room stays)
POST /properties/{propertyId}/bookings/{bookingId}/check-in/bulk
Body:
{ "stays": [ { "roomId": "uuid", "checkInAt": "2026-01-29T12:00:00+05:30", "checkOutAt": "2026-01-30T10:00:00+05:30", "nightlyRate": 6000, "rateSource": "MANUAL", "ratePlanCode": "EP", "currency": "INR" }, { "roomId": "uuid", "checkInAt": "2026-01-29T12:00:00+05:30", "checkOutAt": "2026-01-30T10:00:00+05:30", "nightlyRate": 8000, "rateSource": "MANUAL", "ratePlanCode": "EP", "currency": "INR" } ] }
Behavior
- Creates one RoomStay per stay with its own rate.
- Sets booking CHECKED_IN, checkinAt = earliest stay check-in.
- If any checkOutAt provided, booking expectedCheckoutAt = latest of those.
- Rejects duplicate room IDs.
- Rejects invalid stay date range (checkOutAt <= checkInAt).
- Blocks occupied rooms.
6) Payments + Balance
Add payment
POST /properties/{propertyId}/bookings/{bookingId}/payments Auth: ADMIN/MANAGER/STAFF
Body Required:
- amount (Long)
- method (CASH|CARD|UPI|BANK|ONLINE)
Optional:
- currency (String, default property currency)
- reference (String)
- notes (String)
- receivedAt (String)
{ "amount": 1200, "method": "CASH", "currency": "INR", "reference": "RCP-123", "notes": "Advance" }
Response
{ "id":"uuid", "bookingId":"uuid", "amount":1200, "currency":"INR", "method":"CASH", "reference":"RCP-123", "notes":"Advance", "receivedAt":"2026-01-28T12:00:00+05:30", "receivedByUserId":"uuid" }
List payments
GET /properties/{propertyId}/bookings/{bookingId}/payments
Booking balance
GET /properties/{propertyId}/bookings/{bookingId}/balance
{ "expectedPay": 2745, "amountCollected": 1200, "pending": 1545 }
7) Compose Notes
- Use
androidx.compose.foundation.text.KeyboardOptionsfor keyboard options imports.