---
title: "Deleting data"
description: "Remove memories from a user's knowledge graph — one fact, one topic, or everything — and know exactly what each delete does and does not remove."
---

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

# Deleting data

The knowledge graph stores memories at three levels: **edges** (one fact each), **nodes** (an entity — a person, habit, or topic — that facts connect to), and **episodes** (the raw ingested source text). Deletion works at matching levels, and each level has a different blast radius. This page covers all of them, including what each delete deliberately leaves behind.

| You want to | Use | Removes |
|-------------|-----|---------|
| Remove one incorrect fact | [Delete an edge](#delete-an-edge) | That edge, both stores |
| Remove a whole topic ("forget my ex") | [Delete a node](#delete-a-node) | The node and every edge touching it, both stores |
| Remove everything for a user or a namespace | [Clear all memories](#clear-all-memories) | Edges, nodes, **and episodes** — full erase |
| Erase a user entirely (GDPR / CCPA request) | [Delete a user](/authentication/delete-user/) | Memory in every scope, threads, identity, uploads, traces — the account is gone. An account operation, documented under Authentication |

All deletes are **hard deletes** — the data is removed from the graph database and the search overlay, not flagged. There is no undo. (System-side fact *invalidation* — when a new fact contradicts an old one — is a separate, soft mechanism and is not affected by anything on this page.)

## Delete an edge

One edge carries one fact. Deleting the edge deletes the fact.

```bash
DELETE https://your-tie-host/memories/{agent_id}/edges/{edge_id}
Authorization: Bearer $TOKEN
```

| Parameter | In | Required | Description |
|-----------|------|----------|-------------|
| `edge_id` | path | Yes | The edge UUID — `facts[].id` in the [Memory Timeline](/memory/building-uis/#memory-timeline) response |
| `graph_id` | query | No | Delete from a [graph namespace](/memory/graph-namespacing/) instead of the user's memory. Service token required; `agent_id` is ignored. |

**Response:**

```json
{
  "status": "deleted",
  "edge_id": "edge-abc123"
}
```

Deleting an edge never deletes the nodes at either end. A node whose last live edge is deleted stays in the graph but disappears from the timeline (entities with zero live edges are not rendered).

The lookup is scoped to the calling user, not to `agent_id` — you don't need to know which agent produced the fact, and one user can never delete another user's data.

:::note[This route replaces `DELETE /memories/{agent_id}/{memory_id}`]
The old route deleted edges too, but its path didn't say so. It is now **deprecated** — it keeps working unchanged, but new code should call `/edges/{edge_id}`. Same scoping, same cascade; the response names the field `edge_id` instead of `memory_id`.
:::

## Delete a node

Deletes an entity and **every edge connected to it, in both directions** — the card-level "forget this topic" operation. One call, atomic, instead of a client-side loop over the entity's facts.

```bash
DELETE https://your-tie-host/memories/{agent_id}/nodes/{node_id}
Authorization: Bearer $TOKEN
```

| Parameter | In | Required | Description |
|-----------|------|----------|-------------|
| `node_id` | path | Yes | The node UUID — the top-level `id` of a [Memory Timeline](/memory/building-uis/#memory-timeline) item |
| `graph_id` | query | No | Delete from a [graph namespace](/memory/graph-namespacing/) instead of the user's memory. Service token required; `agent_id` is ignored. |

**Response:**

```json
{
  "status": "deleted",
  "node_id": "node-def456",
  "facts_deleted": 7
}
```

`facts_deleted` counts the removed edges — log it so deletions are verifiable. The node's search-overlay row (name, summary, embedding) is removed along with the edge rows, so nothing about the entity keeps surfacing in retrieval.

**Error cases:**

| Status | Code | When |
|--------|------|------|
| `404` | `MEMORY_NOT_FOUND` | The node UUID is not in the requested scope |
| `422` | `MEMORY_NODE_PROTECTED` | The node is structural and can never be deleted |

Three kinds of node are **protected** and always return `422`:

- The user's own `User` node — it anchors every relationship in the graph.
- `Topic` nodes — abstract subject areas ("fitness", "AI") used for organization.
- `Value` nodes — taxonomy scaffolding, not memories.

:::caution[Shared facts disappear from other cards]
An edge belongs to *two* nodes. "Fauzaan runs with Maya" hangs off both the **Running** node and the **Maya** node. Deleting Running removes that edge from Maya's card too, and Maya's `fact_count` drops. This is inherent to graph deletion — surface it in your UX if users will notice.
:::

## Clear all memories

Erases everything in one scope — a user+agent pair, or a whole [graph namespace](/memory/graph-namespacing/): edges, nodes, **and episodic source content**, from both stores. This is the one true erase and the right backend for a "delete all memories" button or a data-removal request.

```bash
POST https://your-tie-host/memories/{agent_id}/clear
Authorization: Bearer $TOKEN
```

| Parameter | In | Required | Description |
|-----------|------|----------|-------------|
| `graph_id` | query | No | Empty a [graph namespace](/memory/graph-namespacing/) instead of the user's memory. Service token required; `agent_id` is ignored. |

**Response:**

```json
{
  "status": "cleared",
  "scope": "user",
  "deleted_count": 42
}
```

`scope` names what was actually cleared — `"user"` for a pair, or `"graph"` plus a `graph_id` field for a namespace — so a caller can verify the blast radius before trusting a `deleted_count`. A clear of an already-empty scope succeeds with `deleted_count: 0`.

## What edge and node deletes do NOT remove

Edge and node deletes remove *derived* knowledge. They deliberately do **not** touch **episodes** — the raw source text (chat exchanges, ingested documents) the knowledge was extracted from. Two consequences worth designing for:

1. **The source remains stored.** If your product's delete must also erase the underlying record, use `clear` (everything) or delete the source conversation through your own retention flow. Per-episode deletion is not currently exposed.
2. **Deleted knowledge can be re-learned.** If a later conversation or ingest states the same information again, extraction recreates the entity and its facts. For conversational input this is expected (a user who re-tells you about their cat wants the cat remembered). For **batch ingestion this is a trap**: pushing a cumulative summary through [`POST /memories/graph`](/memory/add-data/) every day restates old information and resurrects whatever the user deleted, usually within a day. Ingest deltas — only what's new — and deletions stick.

:::note[Where the IDs come from]
One [Memory Timeline](/memory/building-uis/#memory-timeline) response carries everything the delete routes need: each item's top-level `id` is the node UUID, and each entry in its `facts[]` array carries the edge UUID. Treat both as opaque strings — list them, show them, send them back.
:::

Source: https://truememory-docs.mvstg.com/memory/deleting-data/index.mdx
