> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kiwifs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Canvas

> List, read, write, patch, query, and auto-layout .canvas.json files.

Base path: `http://localhost:3333/api/kiwi`.

Canvas paths must end with **`.canvas.json`**.

## List canvases

```http theme={null}
GET /canvases
```

```json theme={null}
{ "canvases": ["maps/site.canvas.json", "research/ideas.canvas.json"] }
```

## Read canvas

```http theme={null}
GET /canvas?path=maps/site.canvas.json
```

Returns the raw JSON document with `Content-Type: application/json`.

## Write canvas

```http theme={null}
PUT /canvas?path=maps/site.canvas.json
Content-Type: application/json
```

Body must parse as JSON with **`nodes`** and **`edges`** arrays (empty arrays are allowed). Invalid JSON returns **`400`**.

## Patch canvas

Apply a batch of atomic operations without replacing the full document. If any operation fails, the whole batch is rejected.

```http theme={null}
PATCH /canvas?path=maps/site.canvas.json
Content-Type: application/json
```

```json theme={null}
{
  "operations": [
    { "op": "add_node", "node": { "id": "n1", "type": "file", "x": 0, "y": 0, "data": { "path": "concepts/auth.md" } } },
    { "op": "update_node", "id": "n1", "node": { "x": 120 } },
    { "op": "remove_node", "id": "n2" },
    { "op": "add_edge", "edge": { "id": "e1", "fromNode": "n1", "toNode": "n3" } },
    { "op": "update_edge", "id": "e1", "edge": { "label": "depends on" } },
    { "op": "remove_edge", "id": "e1" }
  ]
}
```

Supported `op` values: `add_node`, `update_node`, `remove_node`, `add_edge`, `update_edge`, `remove_edge`.

<ResponseField name="nodes_added" type="integer">Nodes inserted.</ResponseField>
<ResponseField name="nodes_updated" type="integer">Nodes merged in place.</ResponseField>
<ResponseField name="nodes_removed" type="integer">Nodes deleted (connected edges removed too).</ResponseField>
<ResponseField name="edges_added" type="integer">Edges inserted.</ResponseField>
<ResponseField name="edges_updated" type="integer">Edges merged in place.</ResponseField>
<ResponseField name="edges_removed" type="integer">Edges deleted.</ResponseField>

## Delete canvas

```http theme={null}
DELETE /canvas?path=maps/site.canvas.json
```

## Query canvas nodes

```http theme={null}
GET /canvas/query?path=maps/site.canvas.json&q=auth&type=file&connected=n1&nodes_only=true
```

<ParamField query="path" type="string" required>
  Canvas file path.
</ParamField>

<ParamField query="q" type="string">
  Filter nodes by label or metadata text.
</ParamField>

<ParamField query="type" type="string">
  Filter by node type.
</ParamField>

<ParamField query="connected" type="string">
  Return nodes connected to the given node ID.
</ParamField>

<ParamField query="nodes_only" type="boolean" default="false">
  Return only nodes.
</ParamField>

<ParamField query="edges_only" type="boolean" default="false">
  Return only edges.
</ParamField>

## Auto-layout

Reposition existing nodes in a canvas using a layout algorithm. This operates on the current canvas content only — it does not generate new nodes from the wiki-link graph (use `POST /canvas/generate` for that).

```http theme={null}
POST /canvas/auto-layout?path=maps/site.canvas.json
Content-Type: application/json
```

```json theme={null}
{ "layout": "dot" }
```

<ParamField query="path" type="string" required>
  Canvas file to update in place.
</ParamField>

<ParamField body="layout" type="string" default="dot">
  Graphviz engine: `dot`, `neato`, `fdp`, or `circo`.
</ParamField>

## Generate from link graph

```http theme={null}
POST /canvas/generate
Content-Type: application/json
```

```json theme={null}
{
  "path": "auto/graph.canvas.json",
  "layout": "hierarchical",
  "folder": "concepts/",
  "colorize": true
}
```

* `path` — output file; default `canvas.canvas.json`. A `.canvas.json` suffix is added if missing.
* `layout` — `hierarchical` (default), `radial`, `force`, or `circular`.
* `folder` — optional prefix; only edges whose endpoints live under this folder are included.
* `colorize` — boolean, default `true`.

Returns **`503`** if the link index is unavailable.

<Note>
  `POST /canvas/generate` and `PATCH /canvas` are REST-only. MCP exposes `kiwi_canvas_list`, `kiwi_canvas_read`, and `kiwi_canvas_write` — not generate or patch.
</Note>

## MCP parity

`kiwi_canvas_list`, `kiwi_canvas_read`, `kiwi_canvas_write` — see [MCP](/concepts/mcp).
