# POS Layout

### Read POS Layout

The POS Layout API allows retrieval of the visual configuration of the menu on the Point of Sale (POS) device. This defines how categories and products are arranged on the screen.

### `GET /v2/menus/{menuId}/pos_layout/groups/{parentPosLayoutItemId}` - Get POS Layout

Retrieve the layout structure for a menu. The \`parentPosLayoutItemId\` parameter is used to navigate through nested groups. Use \`0\` to retrieve the root level.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| menuId | integer | Yes | The unique identifier of the menu. |
| parentPosLayoutItemId | integer | Yes | The ID of the parent layout group. Use 0 for the root level. |

#### Response

```json
{
  "status": 200,
  "code": "menu_pos_layout_items_get_all_succeed",
  "message": "POS layout items have been retrieved successfully.",
  "data": {
    "color": "-13330213",
    "createdAt": "2025-01-01",
    "menuId": 106477,
    "parentPosLayoutItemId": 0,
    "posLayoutItemId": 12,
    "posLocalId": 456,
    "position": 1,
    "type": "category",
    "updatedAt": "2025-01-05",
    "posLayoutItems": [
      {
        "color": "-16777216",
        "createdAt": "2025-01-02",
        "menuId": 106477,
        "parentPosLayoutItemId": 12,
        "posLayoutItemId": 13,
        "posLocalId": 789,
        "position": 0,
        "type": "product",
        "updatedAt": "2025-01-05"
      }
    ]
  }
}
```

##### 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 | "menu\_pos\_layout\_items\_get\_all\_succeed" | Machine-readable application code for the result. |
| message | string | "POS layout items have been retrieved successfully." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.color | string | "-13330213" | The color value. |
| data.createdAt | string | "2025-01-01" | Timestamp when this resource was created. |
| data.menuId | integer | 106477 | Identifier of the menu. |
| data.parentPosLayoutItemId | integer | 0 | Identifier of the associated parent pos layout item. |
| data.posLayoutItemId | integer | 12 | Identifier of the associated pos layout item. |
| data.posLocalId | integer | 456 | Identifier of the associated pos local. |
| data.position | integer | 1 | The position value. |
| data.type | string | "category" | The type value. |
| data.updatedAt | string | "2025-01-05" | Timestamp when this resource was last updated. |
| data.posLayoutItems | array | \[…\] | List of pos layout items entries. |
| data.posLayoutItems\[\] | object | {…} | Object containing pos layout items fields. |
| data.posLayoutItems\[\].color | string | "-16777216" | The color value. |
| data.posLayoutItems\[\].createdAt | string | "2025-01-02" | Timestamp when this resource was created. |
| data.posLayoutItems\[\].menuId | integer | 106477 | Identifier of the menu. |
| data.posLayoutItems\[\].parentPosLayoutItemId | integer | 12 | Identifier of the associated parent pos layout item. |
| data.posLayoutItems\[\].posLayoutItemId | integer | 13 | Identifier of the associated pos layout item. |
| data.posLayoutItems\[\].posLocalId | integer | 789 | Identifier of the associated pos local. |
| data.posLayoutItems\[\].position | integer | 0 | The position value. |
| data.posLayoutItems\[\].type | string | "product" | The type value. |
| data.posLayoutItems\[\].updatedAt | string | "2025-01-05" | Timestamp when this resource was last updated. |

#### POS Layout Models

##### GetPosLayoutItem Schema

```yaml
type: object
allOf:
  - $ref: BasePosLayoutItem
  - type: object
    properties:
      posLayoutItems:
        type: array
        items:
          $ref: BasePosLayoutItem

BasePosLayoutItem:
  type: object
  properties:
    color:
      type: string
      description: Color decimal value in string (e.g. "-13330213")
    createdAt:
      type: string
      format: date
    menuId:
      type: number
    parentPosLayoutItemId:
      type: number
      description: 0 if root level
    posLayoutItemId:
      type: number
      posLocalId:
      type: number
      description: Links to Category/Product posLocalId
    position:
      type: number
      description: Linear position (layout depends on device screen size)
    type:
      type: string
      enum: [category, product]
    updatedAt:
      type: string
      format: date
```

### Write POS Layout

You can upsert (create or replace) the entire layout structure for a menu.

### `PUT /v2/menus/{menuId}/pos_layout` - Upsert POS Layout

Create or replace the POS layout items for a menu. Provide a nested tree of layout items; the system will replace the existing layout.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| menuId | integer | Yes | The unique identifier of the menu. |

#### Request Body

```json
{
  "data": [
    {
      "posLocalId": 456,
      "type": "category",
      "position": 0,
      "color": "-13330213",
      "posLayoutItems": [
        {
          "posLocalId": 789,
          "type": "product",
          "position": 0,
          "color": "-16777216",
          "posLayoutItems": []
        }
      ]
    }
  ]
}
```

##### 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 |
| --- | --- | --- | --- |
| data | array | \[…\] | Endpoint-specific response payload. |
| data\[\] | object | {…} | Endpoint-specific response payload. |
| data\[\].posLocalId | integer | 456 | Identifier of the associated pos local. |
| data\[\].type | string | "category" | The type value. |
| data\[\].position | integer | 0 | The position value. |
| data\[\].color | string | "-13330213" | The color value. |
| data\[\].posLayoutItems | array | \[…\] | List of pos layout items entries. |
| data\[\].posLayoutItems\[\] | object | {…} | Object containing pos layout items fields. |
| data\[\].posLayoutItems\[\].posLocalId | integer | 789 | Identifier of the associated pos local. |
| data\[\].posLayoutItems\[\].type | string | "product" | The type value. |
| data\[\].posLayoutItems\[\].position | integer | 0 | The position value. |
| data\[\].posLayoutItems\[\].color | string | "-16777216" | The color value. |
| data\[\].posLayoutItems\[\].posLayoutItems | array | \[\] | List of pos layout items entries. |

#### Response

```json
HTTP 204 No Content. The layout update succeeds without a JSON response body.
```

#### Data Models

##### PosLayoutItemUpsert

```yaml
type: object
required: [posLocalId, type, position]
properties:
  posLocalId:
    type: integer
    description: Links to the Category or Product posLocalId
  type:
    type: string
    enum: [category, product]
  position:
    type: integer
    description: Linear position in the layout
  color:
    type: string
    default: "0"
    description: Color decimal value (e.g. "-13330213")
  posLayoutItems:
    type: array
    items:
      $ref: PosLayoutItemUpsert
    description: Nested child layout items (recursive)
```

### POS Layout Functions

POS Layout Functions allow embedding custom webview buttons in the POS layout. Each function is scoped to a menu and defines a webview URL along with display dimensions. The POS devices linked to the menu must support functions (version check is enforced server-side).

### `GET /v2/menus/{menuId}/pos_layout_functions` - List POS Layout Functions

Retrieve all POS layout functions for a menu.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| menuId | integer | Yes | The unique identifier of the menu. |

#### Response

```json
{
  "status": 200,
  "code": "pos_layout_function_get_all_succeed",
  "message": "POS layout functions have been retrieved successfully.",
  "data": [
    {
      "posLayoutFunctionId": 1,
      "menuId": 106477,
      "functionType": "webview",
      "name": "Loyalty Lookup",
      "config": {
        "url": "https://loyalty.example.com/lookup",
        "widthPercent": 80,
        "heightPercent": 60
      },
      "createdAt": "2025-07-01T10:00:00.000Z",
      "updatedAt": "2025-07-01T10:00:00.000Z"
    }
  ]
}
```

##### 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 | "pos\_layout\_function\_get\_all\_succeed" | Machine-readable application code for the result. |
| message | string | "POS layout functions have been retrieved successfully." | 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\[\].posLayoutFunctionId | integer | 1 | Identifier of the associated pos layout function. |
| data\[\].menuId | integer | 106477 | Identifier of the menu. |
| data\[\].functionType | string | "webview" | The function type value. |
| data\[\].name | string | "Loyalty Lookup" | The name value. |
| data\[\].config | object | {…} | Object containing config fields. |
| data\[\].config.url | string | "https://loyalty.example.com/lookup" | The url value. |
| data\[\].config.widthPercent | integer | 80 | The width percent value. |
| data\[\].config.heightPercent | integer | 60 | The height percent value. |
| data\[\].createdAt | string | "2025-07-01T10:00:00.000Z" | Timestamp when this resource was created. |
| data\[\].updatedAt | string | "2025-07-01T10:00:00.000Z" | Timestamp when this resource was last updated. |

### `GET /v2/menus/{menuId}/pos_layout_functions/{posLayoutFunctionId}` - Get POS Layout Function

Retrieve a single POS layout function by its ID.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| menuId | integer | Yes | The unique identifier of the menu. |
| posLayoutFunctionId | integer | Yes | The unique identifier of the POS layout function. |

#### Response

```json
{
  "status": 200,
  "code": "pos_layout_function_get_succeed",
  "message": "POS layout function has been retrieved successfully.",
  "data": {
    "posLayoutFunctionId": 1,
    "menuId": 106477,
    "functionType": "webview",
    "name": "Loyalty Lookup",
    "config": {
      "url": "https://loyalty.example.com/lookup",
      "widthPercent": 80,
      "heightPercent": 60
    }
  }
}
```

##### 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 | "pos\_layout\_function\_get\_succeed" | Machine-readable application code for the result. |
| message | string | "POS layout function has been retrieved successfully." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.posLayoutFunctionId | integer | 1 | Identifier of the associated pos layout function. |
| data.menuId | integer | 106477 | Identifier of the menu. |
| data.functionType | string | "webview" | The function type value. |
| data.name | string | "Loyalty Lookup" | The name value. |
| data.config | object | {…} | Object containing config fields. |
| data.config.url | string | "https://loyalty.example.com/lookup" | The url value. |
| data.config.widthPercent | integer | 80 | The width percent value. |
| data.config.heightPercent | integer | 60 | The height percent value. |

### `POST /v2/menus/{menuId}/pos_layout_functions` - Create POS Layout Function

Create a new POS layout function for a menu. The POS devices linked to the menu must support functions (server-side version check is enforced).

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| menuId | integer | Yes | The unique identifier of the menu. |

#### Request Body

```json
{
  "functionType": "webview",
  "name": "Customer Survey",
  "config": {
    "url": "https://survey.example.com",
    "widthPercent": 90,
    "heightPercent": 70
  }
}
```

##### 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 |
| --- | --- | --- | --- |
| functionType | string | "webview" | The function type value. |
| name | string | "Customer Survey" | The name value. |
| config | object | {…} | Object containing config fields. |
| config.url | string | "https://survey.example.com" | The url value. |
| config.widthPercent | integer | 90 | The width percent value. |
| config.heightPercent | integer | 70 | The height percent value. |

#### Response

```json
{
  "status": 201,
  "code": "pos_layout_function_create_succeed",
  "message": "POS layout function has been created successfully.",
  "data": {
    "posLayoutFunctionId": 2,
    "menuId": 106477,
    "functionType": "webview",
    "name": "Customer Survey",
    "config": {
      "url": "https://survey.example.com",
      "widthPercent": 90,
      "heightPercent": 70
    },
    "createdAt": "2025-07-02T10:00:00.000Z"
  }
}
```

##### 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 | 201 | HTTP status code returned by the API. |
| code | string | "pos\_layout\_function\_create\_succeed" | Machine-readable application code for the result. |
| message | string | "POS layout function has been created successfully." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.posLayoutFunctionId | integer | 2 | Identifier of the associated pos layout function. |
| data.menuId | integer | 106477 | Identifier of the menu. |
| data.functionType | string | "webview" | The function type value. |
| data.name | string | "Customer Survey" | The name value. |
| data.config | object | {…} | Object containing config fields. |
| data.config.url | string | "https://survey.example.com" | The url value. |
| data.config.widthPercent | integer | 90 | The width percent value. |
| data.config.heightPercent | integer | 70 | The height percent value. |
| data.createdAt | string | "2025-07-02T10:00:00.000Z" | Timestamp when this resource was created. |

### `PUT /v2/menus/{menuId}/pos_layout_functions/{posLayoutFunctionId}` - Update POS Layout Function

Update an existing POS layout function. All body fields are optional.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| menuId | integer | Yes | The unique identifier of the menu. |
| posLayoutFunctionId | integer | Yes | The unique identifier of the POS layout function. |

#### Request Body

```json
{
  "name": "Updated Survey",
  "config": {
    "url": "https://survey-v2.example.com",
    "widthPercent": 100,
    "heightPercent": 80
  }
}
```

##### 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 | "Updated Survey" | The name value. |
| config | object | {…} | Object containing config fields. |
| config.url | string | "https://survey-v2.example.com" | The url value. |
| config.widthPercent | integer | 100 | The width percent value. |
| config.heightPercent | integer | 80 | The height percent value. |

#### Response

```json
{
  "status": 200,
  "code": "pos_layout_function_update_succeed",
  "message": "POS layout function has been updated successfully.",
  "data": {
    "posLayoutFunctionId": 2,
    "menuId": 106477,
    "functionType": "webview",
    "name": "Updated Survey",
    "config": {
      "url": "https://survey-v2.example.com",
      "widthPercent": 100,
      "heightPercent": 80
    },
    "updatedAt": "2025-07-03T10:00:00.000Z"
  }
}
```

##### 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 | "pos\_layout\_function\_update\_succeed" | Machine-readable application code for the result. |
| message | string | "POS layout function has been updated successfully." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.posLayoutFunctionId | integer | 2 | Identifier of the associated pos layout function. |
| data.menuId | integer | 106477 | Identifier of the menu. |
| data.functionType | string | "webview" | The function type value. |
| data.name | string | "Updated Survey" | The name value. |
| data.config | object | {…} | Object containing config fields. |
| data.config.url | string | "https://survey-v2.example.com" | The url value. |
| data.config.widthPercent | integer | 100 | The width percent value. |
| data.config.heightPercent | integer | 80 | The height percent value. |
| data.updatedAt | string | "2025-07-03T10:00:00.000Z" | Timestamp when this resource was last updated. |

### `DELETE /v2/menus/{menuId}/pos_layout_functions/{posLayoutFunctionId}` - Delete POS Layout Function

Delete a POS layout function.

#### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| menuId | integer | Yes | The unique identifier of the menu. |
| posLayoutFunctionId | integer | Yes | The unique identifier of the POS layout function. |

#### Response

```json
{
  "status": 200,
  "code": "pos_layout_function_delete_succeed",
  "message": "POS layout function has been deleted successfully."
}
```

##### 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 | "pos\_layout\_function\_delete\_succeed" | Machine-readable application code for the result. |
| message | string | "POS layout function has been deleted successfully." | Human-readable result message. Do not use this value for program logic. |

#### Data Models

##### PosLayoutFunctionAttributes

```typescript
interface PosLayoutFunctionAttributes {
  posLayoutFunctionId: number;
  menuId: number;
  functionType: 'webview';
  name: string;
  config: WebviewConfig;
  createdAt: Date;
  updatedAt: Date;
}

interface WebviewConfig {
  url: string;          // Must be a valid URI
  widthPercent: number; // 10-100
  heightPercent: number; // 10-100
}
```
