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

# Graph

> Direct access to the substrate: read nodes, edges and domains, and mutate them with a full audit trail.

## What this family does

The graph family is what makes Exo composable rather than a black box. Six read routes let you walk the substrate directly. Seven write routes let you edit a memory, assert a relation, forget content, restore it, and record that one belief replaced another.

Every mutation is audited, every deletion is a tombstone with a recovery window, and every developer-asserted edge is capped so organic evidence outranks it. Freedom over the substrate is the point; the guardrails are what stop that freedom corrupting the graph.

## Routes

| Method   | Path                                                                         | Scope           | What it does                       |
| -------- | ---------------------------------------------------------------------------- | --------------- | ---------------------------------- |
| `GET`    | [`/v1/graph/domains`](/api-reference/graph/list-graph-domains)               | `read`          | List graph domains                 |
| `GET`    | [`/v1/graph/domains/{id}`](/api-reference/graph/get-graph-domain)            | `read`          | Get a graph domain                 |
| `GET`    | [`/v1/graph/edges`](/api-reference/graph/list-graph-edges)                   | `read`          | List graph edges                   |
| `POST`   | [`/v1/graph/edges`](/api-reference/graph/assert-edge)                        | `graph:write`   | Assert an edge                     |
| `DELETE` | [`/v1/graph/edges/{edge_id}`](/api-reference/graph/remove-edge)              | `memory:forget` | Remove (tombstone) an edge         |
| `GET`    | [`/v1/graph/edges/{edge_id}`](/api-reference/graph/get-graph-edge)           | `read`          | Get a graph edge                   |
| `GET`    | [`/v1/graph/nodes`](/api-reference/graph/list-graph-nodes)                   | `read`          | List graph nodes                   |
| `DELETE` | [`/v1/graph/nodes/{node_id}`](/api-reference/graph/forget-node)              | `memory:forget` | Forget (tombstone) a node          |
| `GET`    | [`/v1/graph/nodes/{node_id}`](/api-reference/graph/get-graph-node)           | `read`          | Get a graph node                   |
| `PATCH`  | [`/v1/graph/nodes/{node_id}`](/api-reference/graph/edit-node)                | `graph:write`   | Edit a node                        |
| `GET`    | [`/v1/graph/nodes/{node_id}/history`](/api-reference/graph/get-node-history) | `graph:write`   | Get a node's belief + edit history |
| `POST`   | [`/v1/graph/nodes/{node_id}/supersede`](/api-reference/graph/supersede-node) | `graph:write`   | Supersede a belief                 |
| `POST`   | [`/v1/graph/nodes/{node_id}/undelete`](/api-reference/graph/undelete-node)   | `graph:write`   | Restore a forgotten node           |

## Headers that apply here

Neither header is declared as an OpenAPI parameter, so neither appears in the generated schema tables.

* **`X-Exo-Subject`** selects which subject the call acts for on the subject-aware routes above. Omit it to act as the key owner. See [Subjects](/api-reference/subjects).
* **`Idempotency-Key`** makes a retry safe on `POST /v1/graph/edges`, `POST /v1/graph/nodes/{node_id}/supersede`, `POST /v1/graph/nodes/{node_id}/undelete`. See [Idempotency](/platform/idempotency).

## The shape of a call

Record that a belief was replaced.

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  curl -X POST https://api.get-exo.com/v1/graph/nodes/ingest:4a1e88f0-9c2d-4f31-b7a0-5e6c1d820b93:7d3c9b1e04a2/supersede \
    -H "X-Exo-API-Key: $EXO_KEY" \
    -H "Content-Type: application/json" \
    -d '{"content": "Pricing is seat plus usage.", "reason": "Q3 pricing review"}'
  ```

  ```python Python theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  import httpx

  response = httpx.post(
      "https://api.get-exo.com/v1/graph/nodes/ingest:4a1e88f0-9c2d-4f31-b7a0-5e6c1d820b93:7d3c9b1e04a2/supersede",
      headers={"X-Exo-API-Key": EXO_KEY},
      json={"content": "Pricing is seat plus usage.", "reason": "Q3 pricing review"},
  )
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  const response = await fetch(
    "https://api.get-exo.com/v1/graph/nodes/ingest:4a1e88f0-9c2d-4f31-b7a0-5e6c1d820b93:7d3c9b1e04a2/supersede",
    {
      method: "POST",
      headers: {
        "X-Exo-API-Key": process.env.EXO_KEY!,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ content: "Pricing is seat plus usage.", reason: "Q3 pricing review" }),
    },
  );
  ```
</CodeGroup>

The response:

```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
{
  "oldNodeId": "ingest:4a1e88f0-9c2d-4f31-b7a0-5e6c1d820b93:7d3c9b1e04a2",
  "newNodeId": "ingest:4a1e88f0-9c2d-4f31-b7a0-5e6c1d820b93:91c7d0e35b4f",
  "edgeId": "ingest:4a1e88f0-9c2d-4f31-b7a0-5e6c1d820b93:7d3c9b1e04a2_ingest:4a1e88f0-9c2d-4f31-b7a0-5e6c1d820b93:91c7d0e35b4f_superseded_by",
  "created": true,
  "newAuthority": 0.9
}
```

## Traps

**Reads and writes need different scopes.** Reads take `read`. Mutations take `graph:write`. The two erasure verbs, forgetting a node and removing an edge, take `memory:forget`. A `write` key holds all of them; a key minted with `graph:write` alone can edit but cannot destroy.

**Forget erases content, undelete does not restore it.** The node's chunks are destroyed, which is what removes it from search and retrieval. The node row survives as a tombstone for 30 days so its graph position can be restored. Content erasure is intentional and permanent.

**Asserted edges are capped at 0.4.** Weight and confidence on `POST /v1/graph/edges` are limited, so a leaked key cannot inject a dominating edge into the identity graph.

**Edge ownership is proven by both endpoints.** Edges carry no reliable owner, so removing one requires the effective subject to own the source node and the target node.

**Node history sits behind `graph:write`.** It is a read, but it exposes the mutation record, so it follows the mutation family rather than plain `read`.

## Related

<Columns cols={2}>
  <Card title="API reference" icon="book-open" href="/api-reference/overview">
    Base URL, authentication, and the conventions every route shares.
  </Card>

  <Card title="Errors" icon="circle-alert" href="/platform/errors">
    The problem envelope and the full code catalogue.
  </Card>
</Columns>
