# CanvasOperationPlan reference ## Required envelope Every request passed to `yedir_apply_canvas_operation` has this shape: ```json { "canvasId": "canvas UUID", "operationPlan": { "version": 1, "operationId": "stable unique ID", "operation": "create_text_node", "projectId": "same canvas UUID", "baseCanvasRevision": "updatedAt from yedir_get_canvas", "baseCanvasUpdatedAt": "updatedAt from yedir_get_canvas", "textContent": "Example" } } ``` `operationId` is the idempotency key. Keep it stable across retries of the same logical write. ## Operations | Operation | Required fields | Notes | | --- | --- | --- | | `create_agent_slot` | `slot` | `slotType` is `image`, `video`, or `ui-screen`. | | `create_text_node` | `textContent` | Optional `targetPosition` or placement fields. | | `fill_slot` | `targetSlotId`, `media` or `mediaItems` | Media type must match the slot. | | `insert_beside` | `anchorNodeId`, `media` or `mediaItems` | Preserves the source. | | `append_revision` | `sourceNodeIds`, `media` or `mediaItems` | Preferred for revised media. | | `replace_node_media` | target, media, `confirmed: true` | Destructive; require explicit confirmation. | | `add_annotation` | target and `textContent` or `annotations` | Annotation types: text-note, arrow-note, box, freehand, crop-box. | | `link_nodes` | at least two `targetNodeIds` | Optional `edgeType`. | | `move_nodes` | targets, `targetPosition`, `confirmed: true` | Require explicit confirmation. | | `delete_nodes` | targets, `confirmed: true` | Require explicit confirmation. | | `rename_node` | target and `textContent` | Changes the node title. | | `update_note` | target and `textContent` | Updates note content. | | `update_text` | target and `textContent` | Updates a text node. | Use `targetNodeIds` for mutations, `sourceNodeIds` for provenance, and `anchorNodeId` for relative placement. A request may reference at most 20 nodes or media items. ## Placement - `placement`: `right`, `left`, `below`, `above`, or `viewport-center`. - `placementStrategy`: `single`, `row`, `grid`, `overlay`, or `beside_each_source`. - `layoutStrategy`: `row`, `column`, or `grid`. - `spacing`: positive number up to 240. ## Media item ```json { "mediaItemId": "stable item ID", "type": "image", "url": "https://public-or-signed-media-url", "assetId": "optional UUID", "width": 1024, "height": 1024, "title": "Result", "prompt": "source prompt", "sourceNodeIds": ["source node ID"] } ``` Only HTTP and HTTPS media URLs are accepted.