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

# Apply Session Graph Mutations

Apply a batch of mutations to a graph session object.

## **POST** `/revisions/:id/data/command` (Command: `apply_session_graph_mutations`)

Mutations are applied atomically in the order listed. Optimistic concurrency is supported per element
via `if_rev`.

### Request Body

| Parameter    | Type            | Required | Description                                                     |
| :----------- | :-------------- | :------- | :-------------------------------------------------------------- |
| `engine`     | string          | Yes      | Must be `workflow_blobhub`.                                     |
| `command`    | string          | Yes      | Must be `apply_session_graph_mutations`.                        |
| `session_id` | string          | Yes      | The ID of the session that owns the graph envelope.             |
| `alias`      | string          | Yes      | Alias of the graph session object.                              |
| `operations` | array of object | Yes      | Ordered list of mutation operations. See operation types below. |

#### Mutation Operation Types

Each entry in `operations` is an object with an `op` discriminator and op-specific fields:

| `op`                  | Required fields                      | Optional fields                 | Description                                                                                                                                                                               |
| :-------------------- | :----------------------------------- | :------------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `add_vertex`          | `labels` (non-empty)                 | `element_id`, `props`, `if_rev` | Create a new vertex. `labels` is required and must contain at least one label (labels are immutable afterward). `element_id` defaults to a server-generated id; `props` defaults to `{}`. |
| `add_edge`            | `label` (string), `from_id`, `to_id` | `element_id`, `props`, `if_rev` | Create a new directed edge. `label` is the relationship type and is required.                                                                                                             |
| `set_vertex_props`    | `element_id`, `props` (object)       | `if_rev`                        | Merge `props` into an existing vertex (shallow merge — keys are added/replaced).                                                                                                          |
| `set_edge_props`      | `element_id`, `props` (object)       | `if_rev`                        | Merge `props` into an existing edge.                                                                                                                                                      |
| `remove_vertex_props` | `element_id`, `keys` (string\[])     | `if_rev`                        | Remove the listed prop keys from an existing vertex.                                                                                                                                      |
| `remove_edge_props`   | `element_id`, `keys` (string\[])     | `if_rev`                        | Remove the listed prop keys from an existing edge.                                                                                                                                        |
| `delete_vertex`       | `element_id`                         | `if_rev`                        | Delete a vertex. Also cascades — all incident edges are removed atomically.                                                                                                               |
| `delete_edge`         | `element_id`                         | `if_rev`                        | Delete a single edge.                                                                                                                                                                     |

`add_vertex` requires a non-empty `labels` list. Labels are set only at creation and are immutable afterward, so there are no label-mutation operations (`set_labels`, `add_labels`, `remove_labels` do not exist).

Every operation may optionally include `if_rev` (integer). If present, the server checks that the
current `rev` of the element matches `if_rev` before applying the operation. A mismatch aborts the
entire batch and returns `graph_mutation_conflict` (409).

### Response

| Parameter  | Type            | Description                                                                                                                                                  |
| :--------- | :-------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `elements` | array of object | The current state of every upserted element in this batch (deleted elements are not included).                                                               |
| `changes`  | array of object | Change records — one per affected element. Each entry has `op` (`"upsert"` or `"delete"`), `element_id`, and `type`. `rev` is included for `upsert` entries. |

### Errors

* `invalid_graph_envelope` — the alias does not exist or its `value.type` is not `"graph"`.
* `invalid_vertex_labels` — an `add_vertex` op omitted `labels` or supplied only empty/whitespace labels; a vertex must be created with at least one non-empty label.
* `graph_element_too_large` — a single element's serialized props exceed the server-side size cap.
* `graph_mutation_too_large` — the total serialized size of the mutation batch exceeds the cap.
* `graph_mutation_conflict` (409) — an `if_rev` check failed; the batch was not applied.

### Example

<CodeGroup>
  ```json Request theme={null}
  {
    "engine": "workflow_blobhub",
    "command": "apply_session_graph_mutations",
    "session_id": "sess_001",
    "alias": "task_graph",
    "operations": [
      {
        "op": "add_vertex",
        "element_id": "task:1",
        "labels": ["task"],
        "props": { "title": "Research", "status": "open" }
      },
      {
        "op": "add_vertex",
        "element_id": "task:2",
        "labels": ["task"],
        "props": { "title": "Write report", "status": "open" }
      },
      {
        "op": "add_edge",
        "element_id": "e:1",
        "label": "depends_on",
        "from_id": "task:2",
        "to_id": "task:1",
        "props": {}
      },
      {
        "op": "set_vertex_props",
        "element_id": "task:1",
        "if_rev": 1,
        "props": { "status": "in_progress" }
      }
    ]
  }
  ```

  ```json Response theme={null}
  {
    "elements": [
      {
        "element_id": "task:1",
        "type": "vertex",
        "labels": ["task"],
        "props": { "title": "Research", "status": "in_progress" },
        "rev": 2,
        "created_at": "2026-06-06T10:00:00.000000+00:00",
        "updated_at": "2026-06-06T10:00:01.000000+00:00",
        "user_id": "usr_001"
      },
      {
        "element_id": "task:2",
        "type": "vertex",
        "labels": ["task"],
        "props": { "title": "Write report", "status": "open" },
        "rev": 1,
        "created_at": "2026-06-06T10:00:00.000000+00:00",
        "updated_at": "2026-06-06T10:00:00.000000+00:00",
        "user_id": "usr_001"
      },
      {
        "element_id": "e:1",
        "type": "edge",
        "label": "depends_on",
        "from_id": "task:2",
        "to_id": "task:1",
        "props": {},
        "rev": 1,
        "created_at": "2026-06-06T10:00:00.000000+00:00",
        "updated_at": "2026-06-06T10:00:00.000000+00:00",
        "user_id": "usr_001"
      }
    ],
    "changes": [
      { "op": "upsert", "element_id": "task:1", "type": "vertex", "rev": 1 },
      { "op": "upsert", "element_id": "task:2", "type": "vertex", "rev": 1 },
      { "op": "upsert", "element_id": "e:1",    "type": "edge",   "rev": 1 },
      { "op": "upsert", "element_id": "task:1", "type": "vertex", "rev": 2 }
    ]
  }
  ```
</CodeGroup>

### See also

* [Graph session object](/blob-types/workflow/session-objects/graph/introduction) — envelope shape and element schema.
* [Query Session Graph](/blob-types/workflow/operations/query-session-graph) — traverse the graph with a query AST.
* [List Session Graph Elements](/blob-types/workflow/operations/list-session-graph-elements) — paginate all elements.
* [List Session Graph Neighbors](/blob-types/workflow/operations/list-session-graph-neighbors) — fetch neighbors of a set of vertices.
* [Get Session Graph Element](/blob-types/workflow/operations/get-session-graph-element) — fetch a single element.
* [Get Session Graph Elements](/blob-types/workflow/operations/get-session-graph-elements) — fetch multiple elements by id.
* [`session_graph_changed` event](/blob-types/workflow/workflows/session-events) — real-time delta broadcast after each mutation batch.
