Skip to Content
Hotel front desk

Hotel front desk

Read and manage your hotel inventory and bookings - useful for migrating from another system, syncing a channel manager, or building a custom booking flow on top of Cloove’s AI Front Desk.

All endpoints share the prefix /v1/hotel and authenticate with an API key. Request bodies and query parameters are snake_case; responses are camelCase.

EndpointScope
GET /v1/hotel/room-typeshotel:rooms:read
POST /v1/hotel/room-typeshotel:rooms:write
GET /v1/hotel/roomshotel:rooms:read
POST /v1/hotel/roomshotel:rooms:write
GET /v1/hotel/availabilityhotel:reservations:read
GET /v1/hotel/reservationshotel:reservations:read
GET /v1/hotel/reservations/:idhotel:reservations:read
POST /v1/hotel/reservationshotel:reservations:write
POST /v1/hotel/reservations/:id/check-inhotel:reservations:write
POST /v1/hotel/reservations/:id/check-outhotel:reservations:write
POST /v1/hotel/reservations/:id/cancelhotel:reservations:write

The hotel:read scope is a shorthand that grants every hotel :read scope.

Room types

A room type is a sellable category (e.g. “Deluxe”) with a nightly rate and capacity. Physical rooms belong to a room type.

GET /v1/hotel/room-types

Optional query: store_id to scope to one property.

{ "message": "Room types retrieved", "data": [ { "id": "rt1a2b3c-...", "storeId": "st1a2b3c-...", "name": "Deluxe Room", "description": null, "maxGuests": 2, "amenities": ["Wi-Fi", "Breakfast"], "nightlyRate": 45000, "currency": "NGN", "isActive": true, "createdAt": "2026-06-09T10:00:00.000Z" } ] }
POST /v1/hotel/room-types
FieldTypeRequiredDescription
store_iduuidYesProperty the room type belongs to
namestringYesRoom type name
nightly_ratenumberYesPrice per night
max_guestsnumberNoCapacity (defaults to 1)
amenitiesstring[]NoWhat’s included
currencystringNoISO code (defaults to NGN)
descriptionstringNoFree-text description

Rooms

GET /v1/hotel/rooms

Optional query: store_id. Each room: { id, storeId, roomTypeId, number, status, createdAt }. status is one of available, occupied, out_of_service.

POST /v1/hotel/rooms
FieldTypeRequiredDescription
store_iduuidYesProperty
room_type_iduuidYesThe room type this room backs
numberstringYesRoom number or name
statusstringNoDefaults to available

Availability

GET /v1/hotel/availability

Returns the room types with at least one room free for the given dates and party size.

ParameterTypeRequiredDescription
store_iduuidYesProperty
check_in_dateISO dateYesYYYY-MM-DD
check_out_dateISO dateYesYYYY-MM-DD
adultsnumberYesNumber of adults
childrennumberNoNumber of children
{ "message": "Availability retrieved", "data": [ { "roomType": { "id": "rt1a2b3c-...", "name": "Deluxe Room", "nightlyRate": 45000, "currency": "NGN", "...": "..." }, "availableUnits": 3, "nights": 3, "total": 135000 } ] }

Reservations

GET /v1/hotel/reservations

Filters: store_id, status, from, to (ISO dates). Returns an array of reservation objects.

GET /v1/hotel/reservations/:id

Returns a single reservation, or 404 not_found if the ID doesn’t belong to your business.

Create a reservation

POST /v1/hotel/reservations

Creates a confirmed (unpaid) reservation. The guest must already exist - create or look one up via the Contacts API and pass its customer_id. Always send an Idempotency-Key header.

FieldTypeRequiredDescription
store_iduuidYesProperty
customer_iduuidYesGuest (a contact)
room_type_iduuidYesRoom type to book
check_in_dateISO dateYesYYYY-MM-DD (not in the past)
check_out_dateISO dateYesMust be after check-in
adultsnumberYesNumber of adults
childrennumberNoNumber of children
room_iduuidNoPre-assign a specific room
notesstringNoFree-text note
{ "store_id": "st1a2b3c-...", "customer_id": "ct1a2b3c-...", "room_type_id": "rt1a2b3c-...", "check_in_date": "2026-07-01", "check_out_date": "2026-07-04", "adults": 2 }

Response 201 Created - the reservation. Because creation runs a live availability check, it returns 422 when no room of that type is free for the dates.

Manage a reservation

POST /v1/hotel/reservations/:id/check-in POST /v1/hotel/reservations/:id/check-out POST /v1/hotel/reservations/:id/cancel

Move a reservation through its lifecycle. These return 422 when the transition isn’t allowed (e.g. checking in before a room is assigned, or cancelling a stay that is already checked in).

The reservation object

{ "id": "rv1a2b3c-...", "storeId": "st1a2b3c-...", "confirmationCode": "CLV-1A2B3C4D", "status": "confirmed", "guest": { "id": "ct1a2b3c-...", "name": "Ada Lovelace" }, "roomType": { "id": "rt1a2b3c-...", "name": "Deluxe Room" }, "roomId": null, "roomNumber": null, "checkInDate": "2026-07-01", "checkOutDate": "2026-07-04", "adults": 2, "children": 0, "nightlyRate": 45000, "totalAmount": 135000, "currency": "NGN", "source": "dashboard", "createdAt": "2026-06-09T10:00:00.000Z" }

status is one of confirmed, checked_in, checked_out, cancelled, no_show.

Reservation changes emit webhooks (hotel.reservation.created, hotel.reservation.checked_in, and so on), so downstream systems stay in sync whether a booking comes from the API, the dashboard, or the AI front desk.

Last updated on