---
title: "ui.layout-request@1 · OpenVibe.Services"
canonical: "https://openvibe.services/docs/contracts/ui.layout-request"
updated: null
---

# ui.layout-request@1 · OpenVibe.Services

HTML: [ui.layout-request@1 · OpenVibe.Services](https://openvibe.services/docs/contracts/ui.layout-request)

# UiLayoutRequest `ui.layout-request@1`

Generated at 2026-11-13 06:25:48 UTC from [`openvibe-contracts v0.419.0`](https://github.com/OpenVibers/OpenVibe.Contracts/tree/v0.419.0) and [`openvibe-sdk v0.161.0`](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.161.0).

- Version: 1.0.0
- Owner: contracts
- Visibility: public
- Status: active
- Compatibility: backward
- Schema: [`https://openvibe.network/contracts/ui/layout-request.v1.json`](/docs/contracts/ui.layout-request.json)

ui.layout-request@1: what an editor sends OpenVibe.AI's ui.layout.suggest task, and what Network forwards for a signed-in person. It is the surface's catalog, the layout shown now (or null for the default one) and the words the person typed (max 500 characters), for one device class. The catalog is the only power the answer can use; the current layout is the starting arrangement; the words never contain markup that becomes part of it.

## Fields

| Field | Type | Required | Description | Constraints |
| --- | --- | --- | --- | --- |
| `catalog` | [ui.surface](/docs/contracts/ui.surface) | yes |  |  |
| `layout` | one of | yes | The arrangement shown now, or null when the person is looking at the default. |  |
| `words` | string | yes | The person's own description, e.g. "put Stop on the left and make it huge". | - `minLength 1`<br>- `maxLength 500` |
| `device` | enum | yes |  | - `one of "phone", "tablet", "computer"` |

## Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

 Valid: no-layout

~~~~
{
  "catalog": {
    "id": "bot.controls",
    "version": 1,
    "name": "Robot controls",
    "devices": [
      "phone"
    ],
    "grid": {
      "columns": {
        "phone": 4,
        "tablet": 8,
        "computer": 12
      },
      "cell_px": {
        "phone": 44,
        "tablet": 44,
        "computer": 44
      }
    },
    "theme_tokens": [
      "danger"
    ],
    "parts": [
      {
        "id": "stop",
        "name": "Stop",
        "kind": "button",
        "required": true,
        "pressed": true,
        "min": {
          "w": 2,
          "h": 2
        },
        "styles": {
          "tints": [
            "danger"
          ],
          "shapes": [
            "round"
          ]
        },
        "bindings": {
          "keys": [
            "Space"
          ],
          "gamepad": [
            "south"
          ]
        }
      }
    ]
  },
  "layout": null,
  "words": "make it work with one thumb",
  "device": "phone"
}
~~~~

Valid: phone

~~~~
{
  "catalog": {
    "id": "bot.controls",
    "version": 1,
    "name": "Robot controls",
    "devices": [
      "phone"
    ],
    "grid": {
      "columns": {
        "phone": 4,
        "tablet": 8,
        "computer": 12
      },
      "cell_px": {
        "phone": 44,
        "tablet": 44,
        "computer": 44
      }
    },
    "theme_tokens": [
      "danger",
      "surface"
    ],
    "parts": [
      {
        "id": "stop",
        "name": "Stop",
        "kind": "button",
        "required": true,
        "pressed": true,
        "min": {
          "w": 2,
          "h": 2,
          "px": 64
        },
        "styles": {
          "tints": [
            "danger"
          ],
          "shapes": [
            "round"
          ]
        },
        "bindings": {
          "keys": [
            "Space"
          ],
          "gamepad": [
            "south"
          ]
        }
      },
      {
        "id": "stick",
        "name": "Drive stick",
        "kind": "stick",
        "required": false,
        "pressed": true,
        "min": {
          "w": 3,
          "h": 3
        },
        "styles": {
          "tints": [
            "surface"
          ],
          "shapes": [
            "round"
          ]
        },
        "bindings": {
          "keys": [
            "W",
            "A",
            "S",
            "D"
          ],
          "gamepad": [
            "left-stick"
          ]
        }
      }
    ]
  },
  "layout": {
    "surface": "bot.controls",
    "surface_version": 1,
    "device": "phone",
    "name": "Default",
    "author": {
      "name": "OpenVibe"
    },
    "sharing": "private",
    "parts": [
      {
        "id": "stop",
        "visible": true,
        "place": {
          "x": 0,
          "y": 0,
          "w": 2,
          "h": 2
        },
        "style": {
          "tint": "danger",
          "shape": "round",
          "opacity": 1,
          "label": true
        },
        "bindings": {
          "keys": [
            "Space"
          ],
          "gamepad": [
            "south"
          ]
        }
      },
      {
        "id": "stick",
        "visible": true,
        "place": {
          "x": 0,
          "y": 2,
          "w": 4,
          "h": 3
        },
        "style": {
          "tint": "surface",
          "shape": "round",
          "opacity": 1,
          "label": false
        },
        "bindings": {
          "keys": [
            "W",
            "A",
            "S",
            "D"
          ],
          "gamepad": [
            "left-stick"
          ]
        }
      }
    ]
  },
  "words": "put Stop on the left and make it huge, and give me a vertical head slider on the right edge",
  "device": "phone"
}
~~~~

Rejected: empty-words

~~~~
{
  "catalog": {
    "id": "bot.controls",
    "version": 1,
    "name": "Robot controls",
    "devices": [
      "phone"
    ],
    "grid": {
      "columns": {
        "phone": 4,
        "tablet": 8,
        "computer": 12
      },
      "cell_px": {
        "phone": 44,
        "tablet": 44,
        "computer": 44
      }
    },
    "theme_tokens": [
      "danger"
    ],
    "parts": [
      {
        "id": "stop",
        "name": "Stop",
        "kind": "button",
        "required": true,
        "pressed": true,
        "min": {
          "w": 2,
          "h": 2
        },
        "styles": {
          "tints": [
            "danger"
          ],
          "shapes": [
            "round"
          ]
        },
        "bindings": {
          "keys": [
            "Space"
          ],
          "gamepad": [
            "south"
          ]
        }
      }
    ]
  },
  "layout": null,
  "words": "",
  "device": "phone"
}
~~~~

## Validate

~~~~
const contracts = require('openvibe-contracts');
contracts.validate('ui.layout-request@1', value);   // { valid, errors: [{ path, message }] }
~~~~
