Operations

DSP defines 17 typed operations for mutating scenes. Operations are sent in batches via the applyOps endpoint.

For recommended operational behavior when using these operations from an AI agent, see How AI Agents Should Use Zindex.

This page defines the canonical request shape for every operation. All field names match the authoritative TypeScript types and JSON Schema. When examples elsewhere are abbreviated, this page is the source of truth.

Node operations

createNode

Create a new node element.

{
  "op": "createNode",
  "id": "my-node",
  "nodeType": "service",
  "shape": "roundedRect",
  "label": "API Gateway",
  "layout": {
    "mode": "absolute",
    "x": 50, "y": 100,
    "width": 180, "height": 70
  }
}

Required: id, nodeType, shape, layout (optional when scene has layoutStrategy)

Optional: label, name, style, ports, icon, zIndex, locked, visible

The icon field accepts a semantic key (lucide:database, lucide:server, etc.) or a URL. See Element Types: Icons for the full list of built-in icons.

updateNode

Update properties of an existing node.

{
  "op": "updateNode",
  "id": "my-node",
  "label": "Updated Label",
  "shape": "ellipse"
}

Required: id

Optional: any property from createNode except id

deleteElement

Remove any element from the scene.

{ "op": "deleteElement", "id": "my-node" }

Required: id

moveElement

Move an element by a relative delta.

{ "op": "moveElement", "id": "my-node", "delta": { "dx": 50, "dy": -20 } }

Required: id, delta (with dx and dy)

resizeElement

Change an element’s dimensions.

{ "op": "resizeElement", "id": "my-node", "size": { "width": 250, "height": 100 } }

Required: id, size (with width and height)

Optional: anchor ("top", "right", "bottom", "left")

Edge operations

createEdge

Create a connection between two elements (typically nodes; frame and group IDs are also valid targets - see Edges to a group as a whole).

{
  "op": "createEdge",
  "id": "e1",
  "from": { "elementId": "node-a" },
  "to": { "elementId": "node-b" },
  "label": "connects to",
  "router": "straight"
}

Required: id, from, to

Optional: label, router ("straight", "orthogonal", "curved", "polyline"), style, endpoints, waypoints

Optional: edgeType - family-specific edge type (e.g. "workflow.sequenceFlow", "er.relationship")

updateEdge

Update properties of an existing edge.

{
  "op": "updateEdge",
  "id": "e1",
  "label": "new label",
  "router": "orthogonal"
}

Required: id

Optional: any property from createEdge except id

Style and text

setStyle

Apply a named style or inline style overrides to an element.

{ "op": "setStyle", "id": "my-node", "style": "highlight" }

Or with inline overrides:

{ "op": "setStyle", "id": "my-node", "styleOverride": { "fill": "#ff0000", "strokeWidth": 2 } }

Required: id

Optional: style (named style token), styleOverride (inline StyleValue object)

setText

Set the text content of a node or text element. Optionally update text styling at the same time.

{ "op": "setText", "id": "my-node", "text": "New Label" }

With textStyle:

{
  "op": "setText",
  "id": "my-node",
  "text": "Centered Label",
  "textStyle": { "wrap": true, "align": "center", "verticalAlign": "middle" }
}

Required: id, text

Optional: textStyle - an object with any combination of:

When textStyle is provided, it is merged with the element’s existing textStyle. Only the fields you include are updated; omitted fields keep their current values. This works on both node and text elements.

Grouping

groupElements

Group multiple elements together.

{
  "op": "groupElements",
  "id": "group-1",
  "children": ["node-a", "node-b", "e1"]
}

Required: id, children

Optional: title, style, layout

ungroupElements

Dissolve a group, releasing its children.

{ "op": "ungroupElements", "id": "group-1" }

Required: id

createFrame

Create a visual frame container.

{
  "op": "createFrame",
  "id": "frame-1",
  "title": "Backend Services",
  "children": ["api", "db"],
  "layout": { "mode": "absolute", "x": 20, "y": 20, "width": 500, "height": 300 }
}

Required: id, children, layout

Optional: title, style

Optional: containerType ("generic", "pool", "lane", "subprocess", "partition", "package", "boundary"), laneDirection ("horizontal", "vertical")

Constraints

addConstraint

Add a spatial constraint.

{
  "op": "addConstraint",
  "constraint": {
    "type": "align",
    "axis": "y",
    "elements": ["node-a", "node-b", "node-c"]
  }
}

Required: constraint (object with type and type-specific fields)

Axis values: "x", "y"

See Constraints for all constraint types and their fields.

removeConstraint

Remove a constraint by its ID.

{ "op": "removeConstraint", "id": "c1" }

Required: id

Layout

autoLayout

Trigger automatic layout computation. When used, this sets layoutStrategy on the scene, enabling automatic positioning for nodes that omit their layout field.

{ "op": "autoLayout", "elements": ["node-a", "node-b", "node-c"] }

Optional: elements (subset to lay out), strategy ("constraintAware", "grid", "hierarchical", "flow", "forceDirected"), scope ("scene", "selection"), writeBack

Note: For scenes created with layoutStrategy at the document level, the engine automatically positions nodes without layout. The autoLayout operation can also be used to re-run layout on demand or apply it to a subset of elements.

normalizeScene

Re-normalize the entire scene (recompute defaults, resolve layout).

{ "op": "normalizeScene" }

Optional: recomputeLayout, recomputeEdgePaths, applyDefaults, generateDiagnostics

updateScene

Update scene-level metadata (title, palette, styles registry, layoutStrategy, diagramFamily, canvas) on an existing scene. Fields set to null are removed; unspecified fields are left unchanged. Styles are merged additively; canvas is partially merged.

{
  "op": "updateScene",
  "title": "Updated Architecture",
  "palette": { "nodeFill": "#003366", "edgeStroke": "#004488" },
  "styles": { "highlight": { "fill": "#ffcc00", "stroke": "#cc9900" } },
  "layoutStrategy": { "algorithm": "hierarchical", "direction": "LR" },
  "diagramFamily": "architecture",
  "canvas": { "width": 1400, "height": 800 }
}

Optional: title, palette (or null to remove), styles (merged additively with the existing registry), layoutStrategy (or null to remove), diagramFamily (or null to remove), canvas (partially merged - omitted fields keep current values).

All fields are optional - include only the metadata you want to change. Omitted fields are preserved. Use this operation to modify scene-wide settings without recreating the scene or touching elements.

Operation envelope

Operations are sent in an envelope with metadata:

{
  "schemaVersion": "0.1",
  "sceneId": "my-scene",
  "baseRevision": 1,
  "transactionMode": "allOrNothing",
  "ops": [ ... ]
}

Transaction modes: