Skip to main content
A Playground Definition is a JSON object mapping heavily to the Workflow Definition structure, but it is explicitly designed to define customizable, interactive application layouts rather than invisible backend processes.

High-Level Structure

Every Playground Definition uses the following JSON signature:

Top-Level Properties

Layout Types

A Playground Definition is rendered with one of two layouts. The layout type is chosen when the playground is created and is immutable — it cannot be changed later. Attempting to upload a definition whose layout block differs from the persisted layout will fail with invalid_layout.

Free-Form Layout

The default. Widgets are positioned with absolute pixel coordinates on a 2D canvas; widget size comes from width / height ports declared per-widget. Suited to ad-hoc canvases where widgets are placed anywhere by drag-and-drop.
The legacy shape (no layout block, version: "1.0.1") is equivalent to {"type": "free_form"} and continues to be served as-is. Newly created free-form playgrounds always carry the explicit layout block. zoom is optional on free-form layouts as well — same range and semantics as in grid (see zoom below): the value is the canvas zoom level the user last saved, and it’s the only mutable field on layout.

Grid Layout

Widgets are placed on a fixed-column grid. Widget position and size are expressed in grid units rather than pixels, and the grid configuration (columns, row_height) is set at creation time.

layout Properties (grid)

columns, row_height, margin, and container_padding are immutable for the lifetime of the playground. zoom, vertical_sizing, and reference_rows may be updated freely across uploads.

Vertical Sizing

vertical_sizing controls how the effective row height is derived from the viewport. There are three modes:
  • pitch (default, and the behavior when the field is absent): row_height is used as a fixed pixel pitch. The number of visible rows depends on the viewport height, and content that extends beyond the viewport scrolls normally. This is the historical behavior.
  • fit: the grid scales so that all occupied rows fit exactly within the viewport height — effective row height = viewport height ÷ (bottom-most occupied row). Adding widgets proportionally shrinks all rows; the grid never scrolls. If the grid is empty, reference_rows is used as the fallback row count.
  • fixed_rows: a fixed number of rows (set by reference_rows) always fills the viewport height, giving each widget a stable share of the screen across different resolutions. Content placed beyond reference_rows scrolls as normal.
reference_rows is consulted only when vertical_sizing is "fixed_rows" (and as the empty-grid fallback for "fit"). It has no effect in "pitch" mode. Similarly, row_height is only meaningful in "pitch" mode — in "fit" and "fixed_rows" the effective row height is derived from the viewport.

Playground Widgets (Components)

Just like Workflow Components, Playground widgets rely on interfaces to define their behavior. However, they generally pertain to user-facing interactions. The shape of each component’s position field depends on the layout type.

Free-Form Component

position.x and position.y are pixel coordinates on the canvas (negative values are valid — they correspond to panning offsets). Widget size is read from the width / height ports.

Grid Component

In a grid playground, every component’s position field carries grid-unit coordinates and dimensions: Constraint: position.x + position.width must not exceed layout.columns. Violations are rejected with invalid_component_position. Grid components do not carry width / height ports — widget size is derived from the grid units and the playground’s row_height / column width.