Trisolaris Server API Documentation (TXT Manual) Generated manually from current controller code. Date: 2026-02-04 Global behavior - Base domain: api.hoteltrisolaris.in - Auth model: Firebase principal (MyPrincipal) - superAdmin behavior: bypasses property membership and role checks in PropertyAccess - Standard error payload: { "timestamp": "...", "status": 400, "error": "Bad Request", "message": "...", "path": "/..." } ================================================================================ AUTH + SYSTEM APIS ================================================================================ - Health API is this one: GET /health What it does: - Returns server health payload. - Returns build string and status. Request body: - None. - Allowed roles: Public endpoint. - No Firebase principal required. Error Codes - 500 Internal Server Error (unexpected failure) - Root health API is this one: GET / What it does: - Same payload as /health. Request body: - None. - Allowed roles: Public endpoint. Error Codes - 500 Internal Server Error (unexpected failure) - Verify auth API is this one: POST /auth/verify What it does: - Resolves Firebase user from request token. - Returns user profile and property memberships. Request body: - None. - Allowed roles: Public route, but valid Firebase token expected for successful verify. - Requires authenticated Firebase principal flow. Error Codes - 401 Unauthorized (token missing/invalid) - Me auth API is this one: GET /auth/me What it does: - Returns current app user details and memberships. Request body: - None. - Allowed roles: Public route, valid Firebase token required for authenticated response. Error Codes - 401 Unauthorized (token missing/invalid) - Update profile API is this one: PUT /auth/me What it does: - Updates current user name in app_user. Request body (UpdateMeRequest): { "name": "Your Name" } - Allowed roles: authenticated Firebase user. - superAdmin and normal users both allowed. Error Codes - 401 Unauthorized (missing principal / user not found) - City search API is this one: GET /geo/cities/search What it does: - Searches district and locality names by prefix from local pincode directory table. - Returns a JSON array of unique strings in this format: "NAME, STATE". - District matches are ranked first. - If district matches exist, locality results from those districts are also included. - Locality suffixes like H.O / S.O / B.O are trimmed in output. - Uses local DB only (no external API call in this endpoint). Request body: - None. Query params: - q (required, minimum 2 characters) - limit (optional, default 20, min 1, max 100) - Allowed roles: authenticated Firebase user. Error Codes - 400 Bad Request (q too short) - 401 Unauthorized - Country search API is this one: GET /geo/countries/search What it does: - Searches countries from local country_reference table. - Case-insensitive match on country name, official name, ISO alpha-2, and ISO alpha-3. - Returns JSON array of uppercase country names only. - Example: q=IND can return ["INDIA", "INDONESIA", ...]. Request body: - None. Query params: - q (required, minimum 3 characters) - limit (optional, default 20, min 1, max 100) - Allowed roles: Public endpoint. Error Codes - 400 Bad Request (q too short) ================================================================================ PROPERTY + USER APIS ================================================================================ - Create property API is this one: POST /properties What it does: - Creates property with generated 7-char code. - Auto-assigns creator as ADMIN in property_user. Request body (PropertyCreateRequest): { "name": "Hotel Trisolaris", "addressText": "Varanasi", "timezone": "Asia/Kolkata", "currency": "INR", "billingCheckinTime": "12:00", "billingCheckoutTime": "11:00", "active": true, "otaAliases": ["MMT"], "emailAddresses": ["booking@hotel.com"], "allowedTransportModes": ["CAR", "BIKE"] } - Allowed roles: any authenticated app user. Error Codes - 401 Unauthorized (missing principal / user not found) - 409 Conflict (unable to generate unique property code) - List properties API is this one: GET /properties What it does: - superAdmin: returns all properties. - non-superAdmin: returns only joined properties. Request body: - None. - Allowed roles: authenticated user. Error Codes - 401 Unauthorized (missing principal / user not found) - Property code API is this one: GET /properties/{propertyId}/code What it does: - Returns property join code. Request body: - None. - Allowed roles: property member. - superAdmin can also access. Error Codes - 401 Unauthorized (missing principal) - 403 Forbidden (not member) - 404 Not Found (property not found) - Get property billing policy API is this one: GET /properties/{propertyId}/billing-policy What it does: - Returns billing check-in and check-out time for property. Request body: - None. - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Update property billing policy API is this one: PUT /properties/{propertyId}/billing-policy What it does: - Updates default billing policy at property level. Request body (PropertyBillingPolicyRequest): { "billingCheckinTime": "12:00", "billingCheckoutTime": "11:00" } - Allowed roles: ADMIN (property-scoped) - superAdmin can also access. Error Codes - 400 Bad Request (time format invalid, must be HH:mm) - 401 Unauthorized - 403 Forbidden - 404 Not Found - List property users API is this one: GET /properties/{propertyId}/users What it does: - Returns property users below/at actor hierarchy visibility. Request body: - None. - Allowed roles: ADMIN, MANAGER - superAdmin can also access. Error Codes - 401 Unauthorized - 403 Forbidden - Update property user roles API is this one: PUT /properties/{propertyId}/users/{userId}/roles What it does: - Creates/updates property membership roles. - Enforces role-assignment hierarchy. Request body (PropertyUserRoleRequest): { "roles": ["STAFF"] } - Allowed roles: - superAdmin - ADMIN (ADMIN/MANAGER/STAFF/AGENT) - MANAGER (STAFF/AGENT only) Error Codes - 400 Bad Request (unknown role) - 401 Unauthorized - 403 Forbidden (missing role / role not allowed) - 404 Not Found (property/user) - Disable property user API is this one: PUT /properties/{propertyId}/users/{userId}/disabled What it does: - Enables/disables a property membership. - Enforces hierarchy restrictions. Request body (PropertyUserDisableRequest): { "disabled": true } - Allowed roles: superAdmin, ADMIN, MANAGER (hierarchy limited) Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Delete property user API is this one: DELETE /properties/{propertyId}/users/{userId} What it does: - Removes user membership from property. Request body: - None. - Allowed roles: ADMIN - superAdmin can also access. Error Codes - 401 Unauthorized - 403 Forbidden - Update property API is this one: PUT /properties/{propertyId} What it does: - Updates property master data. Request body (PropertyUpdateRequest): { "code": "ABC1234", "name": "Hotel Trisolaris", "addressText": "Varanasi" } - Allowed roles: ADMIN - superAdmin can also access. Error Codes - 400 Bad Request (transport mode unknown / time invalid) - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict (property code exists) - Create access code API is this one: POST /properties/{propertyId}/access-codes What it does: - Creates 6-digit one-time join code with 1-minute expiry. Request body (PropertyAccessCodeCreateRequest): { "roles": ["STAFF"] } - Allowed roles: ADMIN - superAdmin can also access. Error Codes - 400 Bad Request (ADMIN role in invite / roles empty / unknown role) - 401 Unauthorized - 403 Forbidden - 404 Not Found (property) - 409 Conflict (cannot generate code) - Join with access code API is this one: POST /properties/access-codes/join What it does: - Joins current user to property using propertyCode + PIN. - Marks code as used. Request body (PropertyAccessCodeJoinRequest): { "propertyCode": "ABC1234", "code": "123456" } - Allowed roles: authenticated user. Error Codes - 400 Bad Request (property code required) - 401 Unauthorized - 404 Not Found (invalid code / property not found) - 409 Conflict (already a member) - Global users list API is this one: GET /users What it does: - Lists app users for super admin (optional phone filter). Request body: - None. - Allowed roles: superAdmin only. Error Codes - 401 Unauthorized - 403 Forbidden (super admin only) - Property user search API is this one: GET /properties/{propertyId}/users/search What it does: - Searches property members by phone. - Applies hierarchy visibility filter. Request body: - None. - Allowed roles: ADMIN - superAdmin can also access. Error Codes - 401 Unauthorized - 403 Forbidden - Get cancellation policy API is this one: GET /properties/{propertyId}/cancellation-policy What it does: - Returns property cancellation policy. - If not set, returns default values. Request body: - None. - Allowed roles: Public endpoint. Error Codes - 500 Internal Server Error (unexpected) - Upsert cancellation policy API is this one: PUT /properties/{propertyId}/cancellation-policy What it does: - Creates/updates cancellation policy. Request body (CancellationPolicyUpsertRequest): { "freeDaysBeforeCheckin": 2, "penaltyMode": "ONE_NIGHT" } - Allowed roles: ADMIN - superAdmin can also access. Error Codes - 400 Bad Request (freeDaysBeforeCheckin < 0 / unknown penaltyMode) - 401 Unauthorized - 403 Forbidden - 404 Not Found (property) - Transport modes API is this one: GET /properties/{propertyId}/transport-modes What it does: - Returns enabled transport modes for property. Request body: - None. - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found (property) ================================================================================ ROOM AMENITIES + TAGS + ICONS ================================================================================ - List amenities API is this one: GET /amenities What it does: - Returns all room amenities. Request body: - None. - Allowed roles: authenticated user. Error Codes - 401 Unauthorized - Create amenity API is this one: POST /amenities What it does: - Creates amenity master row. Request body (AmenityUpsertRequest): { "name": "WiFi", "category": "comfort", "iconKey": "wifi" } - Allowed roles: superAdmin only. Error Codes - 400 Bad Request (icon key missing on disk) - 401 Unauthorized - 403 Forbidden - 409 Conflict (amenity already exists) - Update amenity API is this one: PUT /amenities/{amenityId} What it does: - Updates amenity name/category/icon. Request body (AmenityUpsertRequest): { "name": "WiFi", "category": "comfort", "iconKey": "wifi" } - Allowed roles: superAdmin only. Error Codes - 400 Bad Request - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict - Delete amenity API is this one: DELETE /amenities/{amenityId} What it does: - Deletes amenity and detaches it from room types. Request body: - None. - Allowed roles: superAdmin only. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - List image tags API is this one: GET /image-tags What it does: - Returns room image tags. Request body: - None. - Allowed roles: Public endpoint. Error Codes - 500 Internal Server Error (unexpected) - Create image tag API is this one: POST /image-tags What it does: - Creates image tag. Request body (RoomImageTagUpsertRequest): { "name": "Lobby" } - Allowed roles: superAdmin only. Error Codes - 401 Unauthorized - 403 Forbidden - 409 Conflict - Update image tag API is this one: PUT /image-tags/{tagId} What it does: - Updates image tag name. Request body (RoomImageTagUpsertRequest): { "name": "Lobby" } - Allowed roles: superAdmin only. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict - Delete image tag API is this one: DELETE /image-tags/{tagId} What it does: - Deletes tag and removes links from room images. Request body: - None. - Allowed roles: superAdmin only. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Icon list API is this one: GET /icons/png What it does: - Lists PNG files in icon folder. Request body: - None. - Allowed roles: Public endpoint. Error Codes - 500 Internal Server Error (unexpected) - Icon file API is this one: GET /icons/png/{filename} What it does: - Streams requested icon PNG file. Request body: - None. - Allowed roles: Public endpoint. Error Codes - 400 Bad Request (path traversal attempt) - 404 Not Found ================================================================================ ROOM TYPE + ROOMS + ROOM IMAGES ================================================================================ - List room types API is this one: GET /properties/{propertyId}/room-types What it does: - Returns room types with amenity + alias data. Request body: - None. - Allowed roles: Public endpoint. If principal present, member check is applied. Error Codes - 403 Forbidden (when principal provided but user not member) - Resolve room type rate API is this one: GET /properties/{propertyId}/room-types/{roomTypeCode}/rate What it does: - Resolves effective rate for date with optional rate plan. Request body: - None. Query params: - date (required, YYYY-MM-DD) - ratePlanCode (optional) - Allowed roles: Public endpoint. If principal present, member check is applied. Error Codes - 400 Bad Request (invalid date / plan-roomType mismatch) - 404 Not Found (property/room type/rate plan/default rate) - Create room type API is this one: POST /properties/{propertyId}/room-types What it does: - Creates room type for property. Request body (RoomTypeUpsertRequest): { "code": "DLX", "name": "Deluxe", "baseOccupancy": 2, "maxOccupancy": 3, "defaultRate": 4500 } - Allowed roles: ADMIN, MANAGER - superAdmin can also access. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found (property/amenity) - 409 Conflict (room type code exists) - Update room type API is this one: PUT /properties/{propertyId}/room-types/{roomTypeId} What it does: - Updates room type metadata. Request body (RoomTypeUpsertRequest): { "code": "DLX", "name": "Deluxe" } - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict - Delete room type API is this one: DELETE /properties/{propertyId}/room-types/{roomTypeId} What it does: - Soft deletes room type by setting active=false. Request body: - None. - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - List rooms API is this one: GET /properties/{propertyId}/rooms What it does: - Returns rooms for property. - AGENT-only users see only free sellable rooms. Request body: - None. - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - Room board API is this one: GET /properties/{propertyId}/rooms/board What it does: - Returns room board statuses (FREE/OCCUPIED/MAINTENANCE/INACTIVE). Request body: - None. - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - Room board stream API is this one: GET /properties/{propertyId}/rooms/board/stream What it does: - SSE stream for room board updates. Request body: - None. - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - Room availability API is this one: GET /properties/{propertyId}/rooms/availability What it does: - Returns free room numbers grouped by room type. Request body: - None. - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - Public available rooms API is this one: GET /properties/{propertyId}/rooms/available What it does: - Returns currently available rooms. Request body: - None. - Allowed roles: Public endpoint. Error Codes - 500 Internal Server Error (unexpected) - Rooms by type API is this one: GET /properties/{propertyId}/rooms/by-type/{roomTypeCode} What it does: - Returns rooms for room type. - Supports availableOnly filter. Request body: - None. Query params: - availableOnly=true|false (optional) - Allowed roles: Public endpoint. Error Codes - 404 Not Found (room type) - Availability range API is this one: GET /properties/{propertyId}/rooms/availability-range What it does: - Returns free rooms in date range. - Includes per-room-type average rate (`averageRate`, `currency`, `ratePlanCode`). - Uses forecast logic for active stays: if `toAt` is null, occupancy is considered up to booking `expectedCheckOutAt` (if present). - Active stays with no expected checkout are treated as occupied. Request body: - None. Query params: - from=YYYY-MM-DD - to=YYYY-MM-DD - ratePlanCode (optional) - Allowed roles: property member. Error Codes - 400 Bad Request (invalid date/range) - 401 Unauthorized - 403 Forbidden - 404 Not Found (property) - Create room API is this one: POST /properties/{propertyId}/rooms What it does: - Creates room inventory entry. Request body (RoomUpsertRequest): { "roomNumber": 101, "floor": 1, "roomTypeCode": "DLX", "hasNfc": true, "active": true, "maintenance": false } - Allowed roles: ADMIN - superAdmin can also access. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found (property / room type) - 409 Conflict (room number already exists) - Update room API is this one: PUT /properties/{propertyId}/rooms/{roomId} What it does: - Updates room metadata. Request body (RoomUpsertRequest): { "roomNumber": 101, "roomTypeCode": "DLX", "hasNfc": true, "active": true, "maintenance": false } - Allowed roles: ADMIN Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict - Delete room API is this one: DELETE /properties/{propertyId}/rooms/{roomId} What it does: - Deletes room if no stays exist. - Deletes room image files + DB rows first. Request body: - None. - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict (room has stays) - 500 Internal Server Error (file delete failure) - Room image list API is this one: GET /properties/{propertyId}/rooms/{roomId}/images What it does: - Lists room images. - Auto-cleans rows whose files are missing. Request body: - None. - Allowed roles: Public endpoint. Error Codes - 404 Not Found (room) - Room image upload API is this one: POST /properties/{propertyId}/rooms/{roomId}/images What it does: - Uploads room image and thumbnail. - Stores hash and optional tags. Request body: - multipart/form-data - file (required) - tagIds (optional list) - Allowed roles: ADMIN, MANAGER - superAdmin can also access. Error Codes - 400 Bad Request (empty/invalid image) - 401 Unauthorized - 403 Forbidden - 404 Not Found (room/tag) - 409 Conflict (duplicate image hash) - Room image delete API is this one: DELETE /properties/{propertyId}/rooms/{roomId}/images/{imageId} What it does: - Deletes image files and DB row. - Reorders room and roomType image sort orders. Request body: - None. - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - 500 Internal Server Error (file delete failure) - Room image tags update API is this one: PUT /properties/{propertyId}/rooms/{roomId}/images/{imageId}/tags What it does: - Replaces tag set for image. Request body (RoomImageTagUpdateRequest): { "tagIds": ["uuid-1", "uuid-2"] } - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Room image reorder (room) API is this one: PUT /properties/{propertyId}/rooms/{roomId}/images/reorder-room What it does: - Sets explicit order among images for one room. Request body (RoomImageReorderRequest): { "imageIds": ["uuid-1", "uuid-2"] } - Allowed roles: ADMIN, MANAGER Error Codes - 400 Bad Request (images not in room) - 401 Unauthorized - 403 Forbidden - 404 Not Found - Room image reorder (room type) API is this one: PUT /properties/{propertyId}/rooms/{roomId}/images/reorder-room-type What it does: - Sets explicit order for room-type gallery sequence. Request body (RoomImageReorderRequest): { "imageIds": ["uuid-1", "uuid-2"] } - Allowed roles: ADMIN, MANAGER Error Codes - 400 Bad Request (image-property/roomType mismatch) - 401 Unauthorized - 403 Forbidden - 404 Not Found - Room image file API is this one: GET /properties/{propertyId}/rooms/{roomId}/images/{imageId}/file What it does: - Streams full-size or thumbnail room image. Request body: - None. Query params: - size=full|thumb (optional, default full) - Allowed roles: Public endpoint. Error Codes - 404 Not Found (image/file) - Room type images API is this one: GET /properties/{propertyId}/room-types/{roomTypeCode}/images What it does: - Lists all room images for a room type. - Auto-cleans rows with missing files. Request body: - None. - Allowed roles: Public endpoint. Error Codes - 404 Not Found (room type) ================================================================================ ROOM STAYS + CARDS APIS ================================================================================ - Active room stays API is this one: GET /properties/{propertyId}/room-stays/active What it does: - Returns active stays with booking and guest details. - Includes per-stay nightlyRate (nullable when rate was not set on room stay). - AGENT-only users are blocked. Request body: - None. - Allowed roles: property member except AGENT-only. Error Codes - 401 Unauthorized - 403 Forbidden - Void room stay API is this one: POST /properties/{propertyId}/room-stays/{roomStayId}/void What it does: - Soft-voids active room stay. - Writes room stay audit log. Request body (RoomStayVoidRequest): { "reason": "Duplicate entry" } - Allowed roles: ADMIN, MANAGER, STAFF - STAFF blocked after first booking payment. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found (room stay) - 409 Conflict (already checked-out) - Prepare issued card API is this one: POST /properties/{propertyId}/room-stays/{roomStayId}/cards/prepare What it does: - Allocates cardIndex. - Returns NFC sector payload for encoding. Request body (CardPrepareRequest): { "expiresAt": "2026-02-06T11:00:00+05:30" } - Allowed roles: ADMIN, MANAGER Error Codes - 400 Bad Request (expiresAt invalid or not after issuedAt) - 401 Unauthorized - 403 Forbidden - 404 Not Found (room stay/property) - 409 Conflict (room stay closed) - Issue card API is this one: POST /properties/{propertyId}/room-stays/{roomStayId}/cards What it does: - Persists issued stay card. Request body (IssueCardRequest): { "cardId": "CARD123", "cardIndex": 10001, "issuedAt": "2026-02-05T12:00:00+05:30", "expiresAt": "2026-02-06T11:00:00+05:30" } - Allowed roles: ADMIN, MANAGER Error Codes - 400 Bad Request (missing cardId/cardIndex/invalid times) - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict (active card exists) - List issued cards API is this one: GET /properties/{propertyId}/room-stays/{roomStayId}/cards What it does: - Lists all issued cards for stay. Request body: - None. - Allowed roles: STAFF, ADMIN, MANAGER, SUPERVISOR Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Revoke card API is this one: POST /properties/{propertyId}/room-stays/cards/{cardIndex}/revoke What it does: - Revokes card by cardIndex. - Returns revoke payload timeData. Request body: - None. - Allowed roles: - regular card: ADMIN - temp card: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found (card) - Get card by index API is this one: GET /properties/{propertyId}/room-stays/cards/{cardIndex} What it does: - Returns card details. Request body: - None. - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Prepare temp card API is this one: POST /properties/{propertyId}/rooms/{roomId}/cards/prepare-temp What it does: - Allocates temporary card payload (7-minute validity). Request body: - None. - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found (room/property) - Issue temp card API is this one: POST /properties/{propertyId}/rooms/{roomId}/cards/temp What it does: - Stores temporary room-only card record. Request body (IssueTempCardRequest): { "cardId": "CARD123", "cardIndex": 10002, "issuedAt": "2026-02-05T12:00:00+05:30" } - Allowed roles: ADMIN, MANAGER Error Codes - 400 Bad Request (cardId/cardIndex invalid) - 401 Unauthorized - 403 Forbidden - 404 Not Found (room) - 409 Conflict (active card exists) ================================================================================ BOOKING APIS ================================================================================ - Create booking API is this one: POST /properties/{propertyId}/bookings What it does: - Creates booking in OPEN state. - Creates/links placeholder guest by phone. Request body (BookingCreateRequest): { "source": "DIRECT", "expectedCheckInAt": "2026-02-05T12:00:00+05:30", "expectedCheckOutAt": "2026-02-06T11:00:00+05:30" } - Allowed roles: ADMIN, MANAGER, STAFF - superAdmin can also access. Error Codes - 400 Bad Request (required fields/date range/unknown enums) - 401 Unauthorized - 403 Forbidden - 404 Not Found (property) - List bookings API is this one: GET /properties/{propertyId}/bookings What it does: - Lists bookings with summary and computed pending amount. - Each booking item includes `vehicleNumbers` (always non-null: empty list or values). Request body: - None. Query params: - status (optional comma-separated) - Allowed roles: ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE Error Codes - 400 Bad Request (invalid status) - 401 Unauthorized - 403 Forbidden - 404 Not Found (property) - Get booking detail API is this one: GET /properties/{propertyId}/bookings/{bookingId} What it does: - Returns booking snapshot details with stays, billing, ledger. - Includes `billableNights` computed from booking timeline + booking billing policy. Request body: - None. - Allowed roles: ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Preview booking billable nights API is this one: POST /properties/{propertyId}/bookings/{bookingId}/billable-nights What it does: - Returns billable nights for the booking based on billing policy. - OPEN booking: request must include both expectedCheckInAt and expectedCheckOutAt. - CHECKED_IN booking: request must include expectedCheckOutAt only. - CHECKED_OUT / CANCELLED / NO_SHOW booking: request must not send expected dates; server uses saved booking timeline. Request body (BookingBillableNightsRequest): { "expectedCheckInAt": "2026-02-05T12:00:00+05:30", "expectedCheckOutAt": "2026-02-06T11:00:00+05:30" } Response body (BookingBillableNightsResponse): { "bookingId": "uuid", "status": "CHECKED_IN", "billableNights": 2 } - Allowed roles: ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE Error Codes - 400 Bad Request - Invalid timestamp format ("Invalid timestamp") - Invalid range ("Invalid date range") - Missing required expected date by status - expected dates provided for closed booking - 401 Unauthorized - 403 Forbidden - 404 Not Found - Preview expected checkout API is this one: POST /properties/{propertyId}/bookings/expected-checkout-preview What it does: - Computes expected check-out timestamp from check-in + billing policy. - `checkInAt` is required. - `billableNights` is optional (defaults to 1). - `billingMode` is optional (defaults to property policy mode behavior). - `billingCheckinTime` and `billingCheckoutTime` are optional; defaults come from property billing policy. - `propertyId` is required in path. Request body (BookingExpectedCheckoutPreviewRequest): { "checkInAt": "2026-02-05T10:30:00+05:30", "billableNights": 2, "billingMode": "PROPERTY_POLICY", "billingCheckinTime": "12:00", "billingCheckoutTime": "11:00" } Response body (BookingExpectedCheckoutPreviewResponse): { "expectedCheckOutAt": "2026-02-07T11:00+05:30", "billableNights": 2, "billingMode": "PROPERTY_POLICY", "billingCheckinTime": "12:00", "billingCheckoutTime": "11:00" } - Allowed roles: ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE Error Codes - 400 Bad Request - checkInAt required or invalid timestamp - billableNights must be > 0 - Unknown billing mode - billingCheckinTime/billingCheckoutTime invalid format - 401 Unauthorized - 403 Forbidden - 404 Not Found (property) - Booking stream API is this one: GET /properties/{propertyId}/bookings/{bookingId}/stream What it does: - SSE stream of booking updates. Request body: - None. - Allowed roles: ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Link guest API is this one: POST /properties/{propertyId}/bookings/{bookingId}/link-guest What it does: - Links booking to existing guest in same property. Request body (BookingLinkGuestRequest): { "guestId": "uuid" } - Allowed roles: property member. Error Codes - 400 Bad Request (guest not in property) - 401 Unauthorized - 403 Forbidden - 404 Not Found (booking/guest) - Bulk check-in API is this one: POST /properties/{propertyId}/bookings/{bookingId}/check-in/bulk What it does: - Creates room stays in one request. - Marks booking as CHECKED_IN. Request body (BookingBulkCheckInRequest): { "stays": [ { "roomId": "uuid", "checkInAt": "2026-02-05T12:00:00+05:30", "nightlyRate": 4500, "rateSource": "MANUAL" } ] } - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 400 Bad Request (stays missing/duplicate roomId/unknown enum) - 401 Unauthorized - 403 Forbidden - 404 Not Found (booking/room) - 409 Conflict (booking not open/room unavailable/future booking can't be checked in) - Expected checkout API is this one: POST /properties/{propertyId}/bookings/{bookingId}/expected-dates What it does: - Updates planned dates on booking (expectedCheckInAt, expectedCheckOutAt), not actual checkout. - Updates booking-level expected dates only; does not auto-change room_stay checkout timestamps. - For OPEN bookings: can update both expected check-in and expected check-out. - For OPEN bookings with linked room stays: each stay start/end must remain inside expected booking window. - For CHECKED_IN: can update only expectedCheckOutAt (check-in change is blocked). - For CHECKED_IN bookings with linked room stays: stay start must be >= booking check-in and < expected check-out; stay end cannot be after expected check-out. - For CHECKED_OUT / CANCELLED / NO_SHOW: returns conflict (Booking closed). - Validates range: if both are present, checkout must be after checkin. - Returns 204 No Content. Request body (BookingExpectedDatesUpdateRequest): { "expectedCheckInAt": "2026-02-05T12:00:00+05:30", "expectedCheckOutAt": "2026-02-06T11:00:00+05:30" } - Allowed roles: ADMIN, MANAGER, STAFF (property-scoped) - superAdmin can also access (bypasses property membership/role checks) - Requires authenticated Firebase principal (MyPrincipal) Error Codes - 400 Bad Request - Invalid timestamp format ("Invalid timestamp") for expectedCheckInAt / expectedCheckOutAt - Invalid range ("Invalid date range") when checkout is not after check-in - 401 Unauthorized - Missing auth principal / user not found - 403 Forbidden - Authenticated but not a property member or missing role (ADMIN, MANAGER, STAFF) - 404 Not Found - Booking not found, or booking does not belong to that property - 409 Conflict - "Cannot change expected check-in after check-in" - "Booking closed" for CHECKED_OUT, CANCELLED, NO_SHOW - Room stay bounds outside allowed expected window for OPEN/CHECKED_IN booking - Update booking billing policy API is this one: POST /properties/{propertyId}/bookings/{bookingId}/billing-policy What it does: - Updates booking billing mode/window. - Writes billing policy audit log when changed. Request body (BookingBillingPolicyUpdateRequest): { "billingMode": "PROPERTY_POLICY", "billingCheckoutTime": "11:00" } - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 400 Bad Request (unknown billing mode/time invalid) - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict (booking closed) - Update booking profile API is this one: POST /properties/{propertyId}/bookings/{bookingId}/profile What it does: - Updates booking profile fields at any booking stage (OPEN, CHECKED_IN, CHECKED_OUT, CANCELLED, NO_SHOW). - Supports partial updates for these fields only: - transportMode - childCount - maleCount - femaleCount - fromCity - toCity - memberRelation - If a provided field value is null, that field is cleared. - Recomputes adultCount and totalGuestCount when any of maleCount/femaleCount/childCount is updated. Request body: { "transportMode": "CAR", "childCount": 1, "maleCount": 1, "femaleCount": 1, "fromCity": "Varanasi", "toCity": "Lucknow", "memberRelation": "SELF" } - Allowed roles: ADMIN, MANAGER - superAdmin can also access. Error Codes - 400 Bad Request - Invalid request body - Unknown fields - At least one field is required - Unknown transport mode - Transport mode disabled - Unknown member relation - childCount/maleCount/femaleCount must be integer or null - childCount/maleCount/femaleCount must be >= 0 - fromCity/toCity/memberRelation/transportMode type invalid - 401 Unauthorized - 403 Forbidden - 404 Not Found - Booking check-out API is this one: POST /properties/{propertyId}/bookings/{bookingId}/check-out What it does: - Checks out all active room stays for booking. - Updates booking to CHECKED_OUT. Request body (BookingCheckOutRequest): { "checkOutAt": "2026-02-06T11:00:00+05:30", "notes": "Early checkout" } - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 400 Bad Request (invalid timestamp) - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict - Booking not checked in - Primary guest missing / guest name missing / guest phone missing / guest signature missing - checkOutAt must be after checkInAt - Room stay amount outside allowed range - Ledger mismatch tolerance failure - Room-stay specific check-out API is this one: POST /properties/{propertyId}/bookings/{bookingId}/room-stays/{roomStayId}/check-out What it does: - Checks out a specific room stay. - Auto-closes booking when last active stay closes. Request body (BookingCheckOutRequest): { "checkOutAt": "2026-02-06T11:00:00+05:30", "notes": "Shifted room" } - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 400 Bad Request (invalid timestamp) - 401 Unauthorized - 403 Forbidden - 404 Not Found (booking/stay) - 409 Conflict - booking not checked in - Primary guest missing / guest name missing / guest phone missing / guest signature missing - checkOutAt must be after checkInAt - amount or minimum duration invalid - Cancel booking API is this one: POST /properties/{propertyId}/bookings/{bookingId}/cancel What it does: - Marks booking CANCELLED. - May create CANCELLATION_PENALTY charge. Request body (BookingCancelRequest): { "reason": "Guest cancelled" } - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict (cannot cancel checked-in booking with active stays) - No-show booking API is this one: POST /properties/{propertyId}/bookings/{bookingId}/no-show What it does: - Marks booking NO_SHOW. - May create NO_SHOW_PENALTY charge. Request body (BookingNoShowRequest): { "reason": "Guest not arrived" } - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict (booking not open) - Create room request API is this one: POST /properties/{propertyId}/bookings/{bookingId}/room-requests What it does: - Creates quantity-based room-type reservation hold. Request body (BookingRoomRequestCreateRequest): { "roomTypeCode": "DLX", "quantity": 2, "fromAt": "2026-02-05T12:00:00+05:30", "toAt": "2026-02-06T11:00:00+05:30" } - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 400 Bad Request (quantity/date invalid) - 401 Unauthorized - 403 Forbidden - 404 Not Found (booking/room type) - 409 Conflict (booking closed / insufficient availability) - List room requests API is this one: GET /properties/{propertyId}/bookings/{bookingId}/room-requests What it does: - Lists room-type quantity requests for booking. Request body: - None. - Allowed roles: ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Cancel room request API is this one: DELETE /properties/{propertyId}/bookings/{bookingId}/room-requests/{requestId} What it does: - Cancels room request if not fulfilled. Request body: - None. - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict (request already fulfilled) - Booking balance API is this one: GET /properties/{propertyId}/bookings/{bookingId}/balance What it does: - Returns expectedPay, amountCollected, pending. Request body: - None. - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found ================================================================================ CHARGES + PAYMENTS APIS ================================================================================ - Create charge API is this one: POST /properties/{propertyId}/bookings/{bookingId}/charges What it does: - Adds ledger charge row. Request body (ChargeCreateRequest): { "type": "EXTRA_SERVICE", "amount": 500, "currency": "INR", "occurredAt": "2026-02-05T15:00:00+05:30", "notes": "Laundry" } - Allowed roles: ADMIN, MANAGER, FINANCE Error Codes - 400 Bad Request (amount <= 0 / unknown type / invalid timestamp) - 401 Unauthorized - 403 Forbidden - 404 Not Found - List charges API is this one: GET /properties/{propertyId}/bookings/{bookingId}/charges What it does: - Returns booking charge ledger rows. Request body: - None. - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Create payment API is this one: POST /properties/{propertyId}/bookings/{bookingId}/payments What it does: - Adds payment ledger row. Request body (PaymentCreateRequest): { "amount": 1000, "method": "CASH", "currency": "INR", "receivedAt": "2026-02-05T16:00:00+05:30", "notes": "Advance" } - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 400 Bad Request (amount <= 0 / unknown method / invalid timestamp) - 401 Unauthorized - 403 Forbidden - 404 Not Found - List payments API is this one: GET /properties/{propertyId}/bookings/{bookingId}/payments What it does: - Returns booking payment ledger rows. Request body: - None. - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Delete payment API is this one: DELETE /properties/{propertyId}/bookings/{bookingId}/payments/{paymentId} What it does: - Deletes payment row under strict rules. Request body: - None. - Allowed roles: ADMIN - superAdmin can also access. Error Codes - 400 Bad Request - Only CASH payments can be deleted - Booking must be OPEN or CHECKED_IN - 401 Unauthorized - 403 Forbidden - 404 Not Found ================================================================================ GUEST + DOCUMENT + RATING APIS ================================================================================ - Update guest API is this one: PUT /properties/{propertyId}/guests/{guestId} What it does: - Updates guest profile fields. Request body (GuestUpdateRequest): { "phoneE164": "+919999999999", "name": "John", "nationality": "Indian", "addressText": "Varanasi" } - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict (phone already exists) - Guest search API is this one: GET /properties/{propertyId}/guests/search What it does: - Searches guest by phone or vehicle number. - Returns guest profile fields including dob (if available), vehicles, and average score. Request body: - None. Query params: - phone (optional) - vehicleNumber (optional) - Allowed roles: property member. Error Codes - 400 Bad Request (phone or vehicleNumber required) - 401 Unauthorized - 403 Forbidden - Get guest API is this one: GET /properties/{propertyId}/guests/{guestId} What it does: - Returns guest profile with dob (if available), vehicles, and average score. Request body: - None. - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Guest visit count API is this one: GET /properties/{propertyId}/guests/visit-count What it does: - Returns booking count by phone number. Request body: - None. Query params: - phone (required) - Allowed roles: property member. Error Codes - 400 Bad Request (phone required) - 401 Unauthorized - 403 Forbidden - Add guest vehicle API is this one: POST /properties/{propertyId}/guests/{guestId}/vehicles What it does: - Adds or updates vehicle mapping to booking + guest. Request body (GuestVehicleRequest): { "vehicleNumber": "UP65AB1234", "bookingId": "uuid" } - Allowed roles: property member. Error Codes - 400 Bad Request (booking not in property) - 401 Unauthorized - 403 Forbidden - 404 Not Found (guest/booking) - 409 Conflict (vehicle linked to different guest) - Upload guest signature API is this one: POST /properties/{propertyId}/guests/{guestId}/signature What it does: - Uploads guest signature SVG and stores file path. Request body: - multipart/form-data file (SVG) - Allowed roles: ADMIN, MANAGER Error Codes - 400 Bad Request (file empty / only SVG allowed) - 401 Unauthorized - 403 Forbidden - 404 Not Found - Download guest signature API is this one: GET /properties/{propertyId}/guests/{guestId}/signature/file What it does: - Returns guest signature SVG file. Request body: - None. - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Upload guest document API is this one: POST /properties/{propertyId}/guests/{guestId}/documents What it does: - Uploads guest document file for booking. - Queues AI extraction. Request body: - multipart/form-data - query param bookingId (required) - file (required) - Allowed roles: ADMIN, MANAGER Error Codes - 400 Bad Request (file empty / video not allowed / booking-guest mismatch) - 401 Unauthorized - 403 Forbidden - 404 Not Found (property/guest/booking) - 409 Conflict (duplicate document hash) - List guest documents API is this one: GET /properties/{propertyId}/guests/{guestId}/documents What it does: - Lists guest documents with extracted data. Request body: - None. - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - Guest document stream API is this one: GET /properties/{propertyId}/guests/{guestId}/documents/stream What it does: - SSE stream for document updates/extraction completion. Request body: - None. - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - Download guest document API is this one: GET /properties/{propertyId}/guests/{guestId}/documents/{documentId}/file What it does: - Downloads stored document. - Supports token-based access. Request body: - None. Query params: - token (optional) - Allowed roles: ADMIN, MANAGER OR valid token. Error Codes - 401 Unauthorized (invalid token / missing auth) - 403 Forbidden - 404 Not Found (document/file) - Delete guest document API is this one: DELETE /properties/{propertyId}/guests/{guestId}/documents/{documentId} What it does: - Deletes document row + file. - Allowed only when booking is OPEN or CHECKED_IN. - Reused guest flow: if the document's linked booking is closed but the same guest has another OPEN/CHECKED_IN booking in that property, delete is allowed. Request body: - None. - Allowed roles: ADMIN, MANAGER Error Codes - 400 Bad Request (booking status not OPEN/CHECKED_IN) - 401 Unauthorized - 403 Forbidden - 404 Not Found - 500 Internal Server Error (file delete failure) - Create guest rating API is this one: POST /properties/{propertyId}/guests/{guestId}/ratings What it does: - Creates guest rating for booking. Request body (GuestRatingCreateRequest): { "bookingId": "uuid", "score": "GOOD", "notes": "Polite guest" } - Allowed roles: property member. Error Codes - 400 Bad Request (score invalid / booking mismatch) - 401 Unauthorized - 403 Forbidden - 404 Not Found - 409 Conflict (rating already exists) - List guest ratings API is this one: GET /properties/{propertyId}/guests/{guestId}/ratings What it does: - Returns rating history for guest. Request body: - None. - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found ================================================================================ INBOUND EMAIL APIS ================================================================================ - Inbound email PDF API is this one: GET /properties/{propertyId}/inbound-emails/{emailId}/file What it does: - Downloads stored inbound email PDF audit file. Request body: - None. - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found (email/pdf) - Manual inbound email upload API is this one: POST /properties/{propertyId}/inbound-emails/manual What it does: - Uploads PDF manually for email ingestion workflow. Request body: - multipart/form-data file (PDF) - Allowed roles: ADMIN, MANAGER Error Codes - 400 Bad Request (file empty / non-PDF) - 401 Unauthorized - 403 Forbidden - 404 Not Found (property) ================================================================================ RATE PLAN APIS ================================================================================ - Create rate plan API is this one: POST /properties/{propertyId}/rate-plans What it does: - Creates rate plan for room type. Request body (RatePlanCreateRequest): { "code": "CP", "name": "Corporate", "roomTypeCode": "DLX", "baseRate": 4500, "currency": "INR" } - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found (property/room type) - 409 Conflict (duplicate code) - List rate plans API is this one: GET /properties/{propertyId}/rate-plans What it does: - Lists rate plans for property. - Optional roomTypeCode filter. Request body: - None. - Allowed roles: property member. Error Codes - 401 Unauthorized - 403 Forbidden - Update rate plan API is this one: PUT /properties/{propertyId}/rate-plans/{ratePlanId} What it does: - Updates plan name/baseRate/currency. Request body (RatePlanUpdateRequest): { "name": "Corporate", "baseRate": 5000, "currency": "INR" } - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Delete rate plan API is this one: DELETE /properties/{propertyId}/rate-plans/{ratePlanId} What it does: - Deletes rate plan and related calendar overrides. Request body: - None. - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found - Upsert rate calendar API is this one: POST /properties/{propertyId}/rate-plans/{ratePlanId}/calendar What it does: - Upserts per-day rate overrides for date range. Request body (RateCalendarRangeUpsertRequest): { "from": "2026-02-05", "to": "2026-02-10", "rate": 5200 } - Allowed roles: ADMIN, MANAGER Error Codes - 400 Bad Request (invalid date/range) - 401 Unauthorized - 403 Forbidden - 404 Not Found (rate plan) - List rate calendar API is this one: GET /properties/{propertyId}/rate-plans/{ratePlanId}/calendar What it does: - Returns average rate stats for date range. Request body: - None. Query params: - from=YYYY-MM-DD - to=YYYY-MM-DD - Allowed roles: property member. Error Codes - 400 Bad Request (invalid date/range) - 401 Unauthorized - 403 Forbidden - 404 Not Found - Delete rate calendar date API is this one: DELETE /properties/{propertyId}/rate-plans/{ratePlanId}/calendar/{rateDate} What it does: - Deletes one date override. Request body: - None. - Allowed roles: ADMIN, MANAGER Error Codes - 400 Bad Request (invalid date) - 401 Unauthorized - 403 Forbidden - 404 Not Found (rate plan) ================================================================================ RAZORPAY APIS ================================================================================ - Get Razorpay settings API is this one: GET /properties/{propertyId}/razorpay-settings What it does: - Returns masked configuration status flags. Request body: - None. - Allowed roles: ADMIN, MANAGER Error Codes - 401 Unauthorized - 403 Forbidden - Upsert Razorpay settings API is this one: PUT /properties/{propertyId}/razorpay-settings What it does: - Creates/updates Razorpay keys and mode. Request body (RazorpaySettingsUpsertRequest): { "keyId": "rzp_live_xxx", "keySecret": "secret", "webhookSecret": "whsec", "isTest": false } - Allowed roles: ADMIN Error Codes - 400 Bad Request (partial key pair / missing required keys) - 401 Unauthorized - 403 Forbidden - 404 Not Found (property) - Razorpay webhook API is this one: POST /properties/{propertyId}/razorpay/webhook What it does: - Captures webhook payload. - Verifies signature. - Updates QR/link status and inserts payment ledger entries for captured/refund events. Request body: - Raw Razorpay webhook JSON - Allowed roles: Public endpoint (signature mandatory). Error Codes - 401 Unauthorized (missing/invalid signature) - 404 Not Found (property) - 400 Bad Request (settings/webhook secret not configured) - Razorpay return success API is this one: POST /properties/{propertyId}/razorpay/return/success What it does: - No-op redirect receiver. Request body: - None. - Allowed roles: Public endpoint. Error Codes - 500 Internal Server Error (unexpected) - Razorpay return failure API is this one: POST /properties/{propertyId}/razorpay/return/failure What it does: - No-op redirect receiver. Request body: - None. - Allowed roles: Public endpoint. Error Codes - 500 Internal Server Error (unexpected) - Create Razorpay QR API is this one: POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr What it does: - Creates single-use Razorpay QR for booking amount. - Reuses latest active QR for same amount when possible. Request body (RazorpayQrGenerateRequest): { "amount": 1000, "expirySeconds": 600 } - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 400 Bad Request (settings missing / amount invalid / booking inactive) - 401 Unauthorized - 403 Forbidden - 404 Not Found (booking) - 502 Bad Gateway (Razorpay failure) - Active Razorpay QR API is this one: GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/active What it does: - Returns current active QR (if any). Request body: - None. - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found (booking) - Close active Razorpay QR API is this one: POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/close What it does: - Closes latest active QR for booking. Request body: - None. - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 400 Bad Request (settings missing) - 401 Unauthorized - 403 Forbidden - 404 Not Found (booking) - 502 Bad Gateway (Razorpay close failure) - Close Razorpay QR by id API is this one: POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/{qrId}/close What it does: - Closes specific QR id. Request body: - None. - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 400 Bad Request (settings missing) - 401 Unauthorized - 403 Forbidden - 404 Not Found (booking/QR) - 502 Bad Gateway - Razorpay QR events API is this one: GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/{qrId}/events What it does: - Returns webhook-derived event timeline for QR. Request body: - None. - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 401 Unauthorized - 403 Forbidden - Razorpay QR events stream API is this one: GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr/{qrId}/events/stream What it does: - SSE stream of QR events. Request body: - None. - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 401 Unauthorized - 403 Forbidden - List Razorpay QRs API is this one: GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/qr What it does: - Lists QR requests for booking. Request body: - None. - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found (booking) - Create Razorpay payment link API is this one: POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/payment-link What it does: - Creates Razorpay payment link. - Reuses existing open link for same amount when possible. Request body (RazorpayPaymentLinkCreateRequest): { "amount": 1000, "description": "Booking payment", "viaSms": true } - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 400 Bad Request (settings missing / amount invalid / booking inactive) - 401 Unauthorized - 403 Forbidden - 404 Not Found (booking) - 502 Bad Gateway - List open Razorpay requests API is this one: GET /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/requests What it does: - Returns open QR and payment-link requests. Request body: - None. - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 401 Unauthorized - 403 Forbidden - 404 Not Found (booking) - Close Razorpay request API is this one: POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/close What it does: - Closes either QR or payment link by id. Request body (RazorpayPaymentRequestCloseRequest): { "qrId": "qr_xxx" } What it does (validation rule): - Exactly one of qrId or paymentLinkId is required. - Allowed roles: ADMIN, MANAGER, STAFF Error Codes - 400 Bad Request (bad payload / settings missing) - 401 Unauthorized - 403 Forbidden - 404 Not Found (booking/request) - 502 Bad Gateway - Razorpay refund API is this one: POST /properties/{propertyId}/bookings/{bookingId}/payments/razorpay/refund What it does: - Sends refund request to Razorpay for a captured online payment. Request body (RazorpayRefundRequest): { "paymentId": "uuid", "amount": 500, "notes": "Partial refund" } - Allowed roles: ADMIN, MANAGER, FINANCE Error Codes - 400 Bad Request - paymentId required - amount must be > 0 and <= payment amount - payment missing gateway id - non-Razorpay payment - settings missing - 401 Unauthorized - 403 Forbidden - 404 Not Found (booking/payment) - 502 Bad Gateway ================================================================================ END OF FILE ================================================================================ Note: - This file intentionally uses plain text (no markdown). - It documents current implemented endpoints from controller code only. - /properties/{propertyId}/room-stays/{roomStayId}/change-rate is not implemented in current code.