# Table Layout

Table layouts represent the visual floor plan of a restaurant. Each layout contains one or more rooms, each of which holds tables. Layouts can be published to POS devices so that staff can see and manage table assignments in real time.

**Access flag required:** Creating, updating, deleting, and publishing table layouts requires the `CAN_EDIT_TABLE_LAYOUT` access flag.

**Detecting changes:** a layout's `updatedAt` also moves when one of its rooms or tables changes, not only when the layout record itself is edited. An integration that polls a layout and compares `updatedAt` can rely on it to decide whether to re-read the floor plan.

### Guest App Table Reads

Guest applications address table service by `restaurantId`. The layout is read from the restaurant's own box first, with the cloud copy as a fallback, so the endpoint still answers while the restaurant is offline. The box is the authority: it decides which tables can be ordered on, and it refuses an unknown one at injection. Live sessions are advisory box data.

### `GET /table_layout` - Get the Operating Table Layout

Returns the layout attached to the restaurant master POS, including rooms and tables. Read from the restaurant box first, since the box is what accepts or refuses an order on a table, and served from the cloud copy when the box cannot answer, so the endpoint still responds while the restaurant is offline. The source field says which of the two answered. Requires an authenticated Admin, Brand, or POS role.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| restaurantId | integer | Yes | Restaurant identifier passed as a query parameter. |

#### Response

```json
{
  "status": 200,
  "code": "table_layout_success",
  "message": "Table layout retrieved.",
  "data": {
    "tableLayoutId": "7c1a2c4e-0d7d-4f7a-9b3e-2f4f4b3a1d20",
    "name": "Plan principal",
    "restaurantId": 920,
    "updatedAt": "2026-06-10T07:12:00.000Z",
    "source": "box",
    "rooms": [
      {
        "roomId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "name": "Main dining room",
        "position": 1,
        "tables": [
          {
            "tableId": "9be05f3a-6a52-4f6e-bb0e-95c2a1f0d811",
            "name": "12"
          }
        ]
      }
    ]
  }
}
```

##### Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "table\_layout\_success" | Machine-readable application code for the result. |
| message | string | "Table layout retrieved." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.tableLayoutId | string | "7c1a2c4e-0d7d-4f7a-9b3e-2f4f4b3a1d20" | Identifier of the associated table layout. |
| data.name | string | "Plan principal" | The name value. |
| data.restaurantId | integer | 920 | Identifier of the restaurant. |
| data.updatedAt | string | "2026-06-10T07:12:00.000Z" | Timestamp when this resource was last updated. |
| data.source | string | "box" | The source value. |
| data.rooms | array | \[…\] | List of rooms entries. |
| data.rooms\[\] | object | {…} | Object containing rooms fields. |
| data.rooms\[\].roomId | string | "a1b2c3d4-e5f6-7890-abcd-ef1234567890" | Identifier of the associated room. |
| data.rooms\[\].name | string | "Main dining room" | The name value. |
| data.rooms\[\].position | integer | 1 | The position value. |
| data.rooms\[\].tables | array | \[…\] | List of tables entries. |
| data.rooms\[\].tables\[\] | object | {…} | Object containing tables fields. |
| data.rooms\[\].tables\[\].tableId | string | "9be05f3a-6a52-4f6e-bb0e-95c2a1f0d811" | Identifier of the associated table. |
| data.rooms\[\].tables\[\].name | string | "12" | The name value. |

**Reading `source`:** `box` means the answer came from the restaurant own point of sale, and it is authoritative: those are exactly the tables an order will be accepted on. `cloud` means the box did not answer and the platform served its own copy, which stays available but may be ahead of what the point of sale has actually loaded, so a table it lists can still be refused at order creation with `table_not_found`. Both answers carry the `updatedAt` of the layout they come from, so a cron that diffs it keeps working across a fallback. A restaurant whose box is not enrolled yet is always served from the cloud copy.

### `GET /table_sessions` - List Live Table Sessions

Returns advisory live sessions from the restaurant box. Filters are combined, and status must be OPEN, CLOSED, or CANCELED.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| restaurantId | integer | Yes | Restaurant identifier passed as a query parameter. |
| tableId | string (UUID) | No | Optional table UUID filter. |
| status | OPEN \| CLOSED \| CANCELED | No | Optional uppercase session status filter. |

#### Response

```json
{
  "status": 200,
  "code": "table_session_success",
  "message": "Table sessions retrieved.",
  "data": {
    "tableSessions": [
      {
        "tableSessionId": "5c1f8e2d-3b4a-4c5d-9e6f-7a8b9c0d1e2f",
        "tableId": "9be05f3a-6a52-4f6e-bb0e-95c2a1f0d811",
        "status": "OPEN",
        "coversNumber": 3,
        "underPayment": false,
        "openedAt": "2026-08-03T10:00:00.000Z",
        "closedAt": null
      }
    ]
  }
}
```

##### Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "table\_session\_success" | Machine-readable application code for the result. |
| message | string | "Table sessions retrieved." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.tableSessions | array | \[…\] | List of table sessions entries. |
| data.tableSessions\[\] | object | {…} | Object containing table sessions fields. |
| data.tableSessions\[\].tableSessionId | string | "5c1f8e2d-3b4a-4c5d-9e6f-7a8b9c0d1e2f" | Identifier of the associated table session. |
| data.tableSessions\[\].tableId | string | "9be05f3a-6a52-4f6e-bb0e-95c2a1f0d811" | Identifier of the associated table. |
| data.tableSessions\[\].status | string | "OPEN" | HTTP status code returned by the API. |
| data.tableSessions\[\].coversNumber | integer | 3 | The covers number value. |
| data.tableSessions\[\].underPayment | boolean | false | The under payment value. |
| data.tableSessions\[\].openedAt | string | "2026-08-03T10:00:00.000Z" | Date or timestamp for opened. |
| data.tableSessions\[\].closedAt | null | null | Date or timestamp for closed. |

### Backoffice Layout Management

### `GET /table-layouts?restaurantId={restaurantId}` - List Table Layouts

Retrieve all table layouts for a given restaurant. Each layout includes its rooms and tables.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| restaurantId | integer | Yes | The restaurant ID to filter layouts for (query parameter). |

#### Response

```json
{
  "status": 200,
  "code": "table_layout_succeed",
  "message": "Table layout found.",
  "data": [
    {
      "tableLayoutUuid": "f0e1d2c3-b4a5-6789-0fed-cba987654321",
      "restaurantId": 200,
      "name": "Ground Floor Layout",
      "rooms": [
        {
          "roomId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "name": "Main Dining Hall",
          "position": 0
        },
        {
          "roomId": "dd445566-7788-99aa-bbcc-ddeeff001122",
          "name": "Terrace",
          "position": 1
        }
      ]
    }
  ]
}
```

##### Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "table\_layout\_succeed" | Machine-readable application code for the result. |
| message | string | "Table layout found." | Human-readable result message. Do not use this value for program logic. |
| data | array | \[…\] | Endpoint-specific response payload. |
| data\[\] | object | {…} | Endpoint-specific response payload. |
| data\[\].tableLayoutUuid | string | "f0e1d2c3-b4a5-6789-0fed-cba987654321" | The table layout uuid value. |
| data\[\].restaurantId | integer | 200 | Identifier of the restaurant. |
| data\[\].name | string | "Ground Floor Layout" | The name value. |
| data\[\].rooms | array | \[…\] | List of rooms entries. |
| data\[\].rooms\[\] | object | {…} | Object containing rooms fields. |
| data\[\].rooms\[\].roomId | string | "a1b2c3d4-e5f6-7890-abcd-ef1234567890" | Identifier of the associated room. |
| data\[\].rooms\[\].name | string | "Main Dining Hall" | The name value. |
| data\[\].rooms\[\].position | integer | 0 | The position value. |

### `GET /table-layouts/{tableLayoutUuid}` - Get Table Layout

Retrieve a single table layout by its UUID, including all rooms and tables.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| tableLayoutUuid | string (UUID) | Yes | The UUID of the table layout. |

#### Response

```json
{
  "status": 200,
  "code": "table_layout_succeed",
  "message": "Table layout found.",
  "data": {
    "tableLayoutUuid": "f0e1d2c3-b4a5-6789-0fed-cba987654321",
    "restaurantId": 200,
    "name": "Ground Floor Layout",
    "rooms": [
      {
        "roomId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "name": "Main Dining Hall",
        "position": 0,
        "tables": [
          {
            "tableId": "11112222-3333-4444-5555-666677778888",
            "name": "T1",
            "positionX": 100,
            "positionY": 200,
            "height": 80,
            "width": 80
          }
        ]
      }
    ]
  }
}
```

##### Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "table\_layout\_succeed" | Machine-readable application code for the result. |
| message | string | "Table layout found." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.tableLayoutUuid | string | "f0e1d2c3-b4a5-6789-0fed-cba987654321" | The table layout uuid value. |
| data.restaurantId | integer | 200 | Identifier of the restaurant. |
| data.name | string | "Ground Floor Layout" | The name value. |
| data.rooms | array | \[…\] | List of rooms entries. |
| data.rooms\[\] | object | {…} | Object containing rooms fields. |
| data.rooms\[\].roomId | string | "a1b2c3d4-e5f6-7890-abcd-ef1234567890" | Identifier of the associated room. |
| data.rooms\[\].name | string | "Main Dining Hall" | The name value. |
| data.rooms\[\].position | integer | 0 | The position value. |
| data.rooms\[\].tables | array | \[…\] | List of tables entries. |
| data.rooms\[\].tables\[\] | object | {…} | Object containing tables fields. |
| data.rooms\[\].tables\[\].tableId | string | "11112222-3333-4444-5555-666677778888" | Identifier of the associated table. |
| data.rooms\[\].tables\[\].name | string | "T1" | The name value. |
| data.rooms\[\].tables\[\].positionX | integer | 100 | The position x value. |
| data.rooms\[\].tables\[\].positionY | integer | 200 | The position y value. |
| data.rooms\[\].tables\[\].height | integer | 80 | The height value. |
| data.rooms\[\].tables\[\].width | integer | 80 | The width value. |

### `POST /table-layouts` - Create Table Layout

Create a new table layout for a restaurant. A default room is automatically created within the layout.

#### Request Body

```json
{
  "restaurantId": 200,
  "name": "Upper Floor Layout"
}
```

##### Request Body Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| restaurantId | integer | 200 | Identifier of the restaurant. |
| name | string | "Upper Floor Layout" | The name value. |

#### Response

```json
{
  "status": 200,
  "code": "table_layout_created",
  "message": "Table layout created.",
  "data": {
    "tableLayoutUuid": "ab12cd34-ef56-7890-abcd-1234567890ab",
    "restaurantId": 200,
    "name": "Upper Floor Layout",
    "rooms": [
      {
        "roomId": "00112233-4455-6677-8899-aabbccddeeff",
        "name": "Default Room",
        "position": 0,
        "tables": []
      }
    ]
  }
}
```

##### Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "table\_layout\_created" | Machine-readable application code for the result. |
| message | string | "Table layout created." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.tableLayoutUuid | string | "ab12cd34-ef56-7890-abcd-1234567890ab" | The table layout uuid value. |
| data.restaurantId | integer | 200 | Identifier of the restaurant. |
| data.name | string | "Upper Floor Layout" | The name value. |
| data.rooms | array | \[…\] | List of rooms entries. |
| data.rooms\[\] | object | {…} | Object containing rooms fields. |
| data.rooms\[\].roomId | string | "00112233-4455-6677-8899-aabbccddeeff" | Identifier of the associated room. |
| data.rooms\[\].name | string | "Default Room" | The name value. |
| data.rooms\[\].position | integer | 0 | The position value. |
| data.rooms\[\].tables | array | \[\] | List of tables entries. |

### `PUT /table-layouts/{tableLayoutUuid}` - Update Table Layout

Update a table layout name and its associated POS devices. The posDevices array specifies which POS device IDs should be linked to this layout.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| tableLayoutUuid | string (UUID) | Yes | The UUID of the table layout to update. |

#### Request Body

```json
{
  "name": "Ground Floor Layout (Renamed)",
  "posDevices": [
    8063,
    8064
  ]
}
```

##### Request Body Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| name | string | "Ground Floor Layout (Renamed)" | The name value. |
| posDevices | array | \[…\] | List of pos devices entries. |
| posDevices\[\] | integer | 8063 | The pos devices value. |

#### Response

```json
{
  "status": 200,
  "code": "table_layout_updated",
  "message": "Table layout was successfully updated.",
  "data": {
    "tableLayoutUuid": "f0e1d2c3-b4a5-6789-0fed-cba987654321",
    "restaurantId": 200,
    "name": "Ground Floor Layout (Renamed)"
  }
}
```

##### Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "table\_layout\_updated" | Machine-readable application code for the result. |
| message | string | "Table layout was successfully updated." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.tableLayoutUuid | string | "f0e1d2c3-b4a5-6789-0fed-cba987654321" | The table layout uuid value. |
| data.restaurantId | integer | 200 | Identifier of the restaurant. |
| data.name | string | "Ground Floor Layout (Renamed)" | The name value. |

### `DELETE /table-layouts/{tableLayoutUuid}` - Delete Table Layout

Delete a table layout and all its rooms and tables. This action is irreversible.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| tableLayoutUuid | string (UUID) | Yes | The UUID of the table layout to delete. |

#### Response

```json
{
  "status": 200,
  "code": "table_layout_deleted",
  "message": "Table layout was successfully deleted.",
  "data": {}
}
```

##### Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "table\_layout\_deleted" | Machine-readable application code for the result. |
| message | string | "Table layout was successfully deleted." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |

### `POST /table-layouts/{tableLayoutUuid}/publish` - Publish Table Layout to POS

Publish a table layout so that it becomes active on linked POS devices. Staff will see the updated floor plan on their registers.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| tableLayoutUuid | string (UUID) | Yes | The UUID of the table layout to publish. |

#### Response

```json
{
  "status": 200,
  "code": "table_layout_published",
  "message": "Table layout was successfully published.",
  "data": {}
}
```

##### Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

| Property | Type | Example | Description |
| --- | --- | --- | --- |
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "table\_layout\_published" | Machine-readable application code for the result. |
| message | string | "Table layout was successfully published." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
