Tables & Floors
The physical structure of a restaurant — floors and tables: reading the layout and parameters for seating and availability.
This group of endpoints describes the physical structure of a restaurant: floors, areas, tables and their current state on the floor (free/occupied/reserved). A partner needs it to read the seating map, learn table capacities and real-time states, and to build a floor plan.
All endpoints require a Bearer token (see Authentication).
Base path for table management: /api/tm/admin/restaurants/{restaurantId}.
| Method | Path | Purpose |
|---|---|---|
GET | /tables | List of tables with capacity and availability |
GET | /floorareas | Summary by area for each floor |
GET | /floors | List of floors with aggregates |
GET | /floors/{floorId} | One floor (plan/map) |
GET | /tables/monitors | Real-time table state |
GET | /tables/timeline | Table occupancy timeline for a day |
GET | /tables/settings | Table settings (combinations, blocks) |
PUT | /tables/state | Change the state of a booking at a table |
POST/PUT/DELETE | /floors, /floors/{floorId} | Floor management (CRUD) |
POST | /floor-plan/image | Generate a floor plan from a photo |
A note on terms. In Hostme a “floor” is a separate seating map: it has a
floorId, a name and an optional background map. An “area” is a text grouping of tables within a floor (e.g. “Outdoor Seating”, “By the window”). A table has anareafield and a link to its floor.
List of tables
GET /tables
Returns all the restaurant’s tables with their capacity, area, tags and availability rules (for reservations and for the waitlist). This is the main table directory for a partner integration.
| Parameter | In | Type | Description |
|---|---|---|---|
restaurantId * | path | integer | Restaurant identifier |
includeEvents | query | boolean | Include tables that belong to events |
Key table fields (TableContract)
| Field | Type | Description |
|---|---|---|
tableNumber | string | Table number/name (the primary table identifier in operations) |
tableTopSize | integer | Table capacity (number of seats) |
area | string | The area the table belongs to |
tags | array<string> | Arbitrary table tags |
isOffline | boolean | The table is taken out of service (unavailable) |
eventId | integer? | Event ID if the table is tied to an event |
eventStartDate / eventEndDate | date-time? | Event period for the table |
reservability | object | Availability rules for online booking (TableAvailabilityContract) |
waitability | object | Availability rules for the waitlist (TableAvailabilityContract) |
Availability object (TableAvailabilityContract)
Same structure for reservability and waitability:
| Field | Type | Description |
|---|---|---|
reservable | boolean | Whether the table is available for booking/waiting |
minCoversRequired | integer | Minimum guests to be seated at this table |
depositAmount | string? | Required deposit (if set) |
description | string? | Explanation/conditions |
hours | array | Availability hours by weekday (WeekDayOpenHoursContract) |
Each hours element contains weekDay (weekday number) and an array of time intervals
with open / close fields (date-span format, time since midnight) and an optional name.
Example
curl -G https://api.hostmeapp.com/api/tm/admin/restaurants/123/tables \ -H "Authorization: Bearer $TOKEN" \ --data-urlencode "includeEvents=false"Summary by area
GET /floorareas
Returns aggregated statistics for each area within each floor: how many tables and seats in total, and how many of them are available online. Handy for capacity dashboards.
| Parameter | In | Type |
|---|---|---|
restaurantId * | path | integer |
Response fields (FloorAreaContract)
| Field | Type | Description |
|---|---|---|
floorId | string | The floor the area belongs to |
floorName | string | Floor name |
area | string | Area name |
tables | integer | Total tables in the area |
onlineTables | integer | Tables available online |
covers | integer | Total seats (covers) |
onlineCovers | integer | Seats available online |
curl https://api.hostmeapp.com/api/tm/admin/restaurants/123/floorareas \ -H "Authorization: Bearer $TOKEN"List of floors
GET /floors
Returns the restaurant’s floors with table and seat aggregates. The includeOffline and
includeEvents parameters control whether offline floors and event floors are included.
| Parameter | In | Type | Description |
|---|---|---|---|
restaurantId * | path | integer | Restaurant identifier |
includeOffline | query | boolean | Include offline floors |
includeEvents | query | boolean | Include floors that belong to events |
Response fields (FloorInfoContract)
| Field | Type | Description |
|---|---|---|
floorId | string | Floor identifier |
name | string | Floor name |
floorUrl | string | Link to the floor image/map |
isOffline | boolean | The floor is taken out of service |
tables | integer | Total tables |
tableNumbers | string | List of table numbers |
onlineTables | integer | Tables available online |
covers | integer | Total seats |
onlineCovers | integer | Seats available online |
event | object? | Event info (EventInfoContract: id, name, tickets[]) if this is an event floor |
curl -G https://api.hostmeapp.com/api/tm/admin/restaurants/123/floors \ -H "Authorization: Bearer $TOKEN" \ --data-urlencode "includeOffline=false"One floor
GET /floors/{floorId}
Returns the data of a specific floor by floorId (name, map/plan, offline flag).
Use it to load the floor’s background layout.
| Parameter | In | Type |
|---|---|---|
restaurantId * | path | integer |
floorId * | path | string |
The exact schema of the success response (200) is not fixed in the specification. For the floor structure, refer to
FloorContract(see “Floor management” below):floorId,name,map,floorUrl,isOffline.
Real-time table state
GET /tables/monitors
Returns a “snapshot” of the floor: whether the restaurant is open and the current state of each table (free, occupied, reserved, etc.), including the attached guest, servers and seating timings. This is the main endpoint for rendering a live floor map.
| Parameter | In | Type | Description |
|---|---|---|---|
restaurantId * | path | integer | Restaurant identifier |
WithNextSlot | query | boolean | Include the time of the nearest free slot |
Time | query | date-time | The point in time the state is computed for |
TableTurnOver | query | integer | Estimated table turnover time, minutes |
ExcludeId | query | string | Exclude a booking from the calculation (e.g. the current one) |
Response structure (RestaurantState)
| Field | Type | Description |
|---|---|---|
isOpen | boolean | Whether the restaurant is open right now |
monitors | array | Table states (TableMonitorContract) |
events | array | Active events (EventInfoContract) |
Table monitor fields (TableMonitorContract)
| Field | Type | Description |
|---|---|---|
id | string | Table identifier |
tableNumber | string | Table number/name |
state | string | Text state of the table |
type | string | Table type |
status | enum | Numeric table status: 0, 1, 2, 3, 4 (see below) |
eventId | integer? | Event, if the table is tied to one |
registrationTime | date-time? | Guest registration time |
reservationTime | date-time? | Booking time |
assignmentTime | date-time? | Table assignment time |
estimatedReleaseTime | date-time? | Expected release |
nextAvailableSlotTime | date-time? | Nearest free slot (with WithNextSlot=true) |
user | object | Data of the current seating/booking (TableUserInfoContract): guest, groupSize, servers, profile, requests |
Table statuses (TableStatus)
The status field is an integer enum with values 0…4. The exact labels for the numbers are
not fixed in the specification; treat the text state field as the
human-readable state and use status as a stable machine code. Don’t
hard-code the meaning of the numbers — check against state.
curl -G https://api.hostmeapp.com/api/tm/admin/restaurants/123/tables/monitors \ -H "Authorization: Bearer $TOKEN" \ --data-urlencode "Time=2026-07-01T19:00:00" \ --data-urlencode "WithNextSlot=true"Occupancy timeline
GET /tables/timeline
Returns snapshots of the floor state through the day — for building a timeline of table load. Besides the state of each table, it includes guest aggregates (seated, waiting, reserved) and turnover progress bars.
| Parameter | In | Type | Description |
|---|---|---|---|
restaurantId * | path | integer | Restaurant identifier |
Date | query | date | The day the timeline is built for |
TableTurnOver | query | integer | Estimated table turnover time, minutes |
ExcludeId | query | string | Exclude a booking from the calculation |
Response structure (FloorStateTimeline)
| Field | Type | Description |
|---|---|---|
lastActiveSlot | date-span | Last active slot of the day |
snapshotsUpdatedAt | date-time | When the snapshots were recalculated |
snapshots | array | Snapshots by time (FloorTablesSnapshot) |
Each FloorTablesSnapshot contains the time (dateTime, timestamp, shiftDate), aggregates
(tablesCount, busyTablesCount, groupTotalMembers, seatedMembersCount,
reservationMembersCount, waitingMembersCount) and a monitors array (TableTimelineContract)
with the same set of statuses/timings as in /tables/monitors, plus table
(tableProgressBar) and card (cardProgressBar) progress bars.
curl -G https://api.hostmeapp.com/api/tm/admin/restaurants/123/tables/timeline \ -H "Authorization: Bearer $TOKEN" \ --data-urlencode "Date=2026-07-01"A timeline recalculation can be triggered manually:
POST /tables/timeline/recalculate(no body).
Table settings
GET /tables/settings
Returns the table combination and blocking rules. These settings affect how the
system picks tables for a booking. Read — GET, change — PUT with a
TablesSettingsContract body.
| Parameter | In | Type |
|---|---|---|
restaurantId * | path | integer |
Settings fields (TablesSettingsContract, for PUT)
| Field | Type | Description |
|---|---|---|
blockingPeriods | array | Table blocking periods (BlockingPeriodContract: tables[], starts, ends, time[]) |
tableCombinations | array | Preset table combinations (TableCombinationContract: tables[], minCovers, maxCovers, isForOnline, enabled) |
onlyPresetCombinations | boolean | Allow only preset combinations |
password | string? | Password for changing the settings (if used) |
curl https://api.hostmeapp.com/api/tm/admin/restaurants/123/tables/settings \ -H "Authorization: Bearer $TOKEN"Change table state
PUT /tables/state
Changes the state of a booking/seating at a table (e.g. move a guest to “seated”,
“finished”, etc.). Body — ChangeTableStateContract.
| Field | Type | Description |
|---|---|---|
bookingId | string | Booking/seating identifier |
state | string | New state |
Response — the updated booking (BookingContract) with the current status and timings.
curl -X PUT https://api.hostmeapp.com/api/tm/admin/restaurants/123/tables/state \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "bookingId": "ABC_ID", "state": "Seated" }'Releasing a table. There are separate
PUT /tables/{bookingId}/release(release a table by booking) andPOST /tables/release(bulk release). Seating / assigning a table to a booking — viaPUT /seat/{registrationId}(bodyRegisterAtTableContract). These operations belong to the host’s work on the floor; see also Reservations.
Floor management (CRUD) — overview
Creating, editing and deleting floors. A partner rarely needs these operations (the structure is usually maintained by restaurant staff), so here is a brief overview.
| Method | Path | Purpose |
|---|---|---|
POST | /floors | Create a floor |
PUT | /floors/{floorId} | Edit a floor |
DELETE | /floors/{floorId} | Delete a floor |
Create/edit body — FloorContract:
| Field | Type | Description |
|---|---|---|
floorId | string? | Floor identifier (when editing) |
name | string? | Floor name |
map | string? | Floor plan (DSL/markup of the seating map) |
floorUrl | string? | Link to the background image |
isOffline | boolean | Take the floor out of service |
curl -X POST https://api.hostmeapp.com/api/tm/admin/restaurants/123/floors \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Terrace", "isOffline": false }'
GET /merge?ids=...is also available — a service operation for merging tables; not required for a typical partner integration.
Floor plan from a photo
POST /floor-plan/image
Accepts a photo of a floor plan (a downscaled JPEG, ≤1024px on the long side, Base64-encoded) and
returns a generated plan in PlanDSL format (JSON). Recognition is done by a
two-pass Gemini 2.5 Flash vision model with an automatic fallback provider
(OpenRouter) when the quota is exhausted. Path: /api/restaurants/{restaurantId}/floor-plan/image.
| Parameter | In | Type |
|---|---|---|
restaurantId * | path | integer |
Request body (FloorPlanFromImageRequest)
| Field | Type | Description |
|---|---|---|
imageBase64 * | string | Base64-encoded JPEG image |
contentType * | string | MIME type; must be image/jpeg |
Response (FloorPlanFromImageResponse)
| Field | Type | Description |
|---|---|---|
planDSL | string | PlanDSL JSON string generated by the model |
modelUsed | string? | Which provider handled the request (Gemini or OpenRouter) |
tokensUsed | integer? | How many tokens were consumed (for cost accounting) |
curl -X POST https://api.hostmeapp.com/api/restaurants/123/floor-plan/image \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "imageBase64": "/9j/4AAQSkZJRg...", "contentType": "image/jpeg" }'The client downscales the image to ≤1024px itself before sending. The returned
planDSLcan be saved to the floor’smapfield (FloorContract).
General rules (headers,
ProblemDetailserror format, response codes) — in Conventions and Errors. The lifecycle of bookings at tables — in Reservations.