Skip to content

Export & import

Move a user's entire knowledge graph — account migration, backup, and data portability.

Updated View as Markdown

Memory is something a user accumulates over time — facts, preferences, relationships, and context that an agent has learned about them. There are three common reasons to move that memory around:

  • Account migration — a user is switching to a new account and wants to take their memory with them
  • Backup — capture a snapshot now so you can restore if something goes wrong later
  • Data portability — give the user a copy of what Truememory has learned about them (useful for GDPR-style “export my data” requests)

The export endpoint produces a single JSON document. The import endpoint consumes that same document and writes it into the caller’s graph. Both sides span every agent scope for the user in one call — you do not loop per-agent.

Think of it like git clone for a user’s knowledge graph: one command pulls the whole repository, one command pushes it back somewhere else. Where this metaphor breaks down: embeddings (the vector representations Graphiti uses for semantic search) are not re-generated automatically on export, and they are rebuilt asynchronously on import — so searches against freshly imported data can return empty for a few minutes while the backfill runs.

Export Memory

GET https://your-tie-host/memories/export
Authorization: Bearer $TOKEN
Parameter In Required Description
include_episodes query No Include raw :Episodic nodes (conversation chunks the graph was extracted from). Defaults to false — episodes are much larger than the extracted graph and contain raw PII.
include_expired query No Include edges the user previously deleted (soft-deleted via expired_at). Defaults to false. Useful for full archival; skip for normal use.
include_embeddings query No Include the vector embeddings on nodes and edges. Defaults to false. Embeddings are regeneratable and inflate payload size roughly 10x.

Response:

{
  "schema_version": "1",
  "exported_at": "2026-04-20T08:15:42.123456+00:00",
  "source_user_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "counts": {
    "entity_nodes": 142,
    "entity_edges": 389,
    "episodes": 0
  },
  "entity_nodes": [
    {
      "uuid": "n-abc",
      "labels": ["User"],
      "properties": {
        "name": "Alice",
        "summary": "Senior engineer at Mindvalley",
        "created_at": "2026-01-12T09:00:00+00:00"
      }
    }
  ],
  "entity_edges": [
    {
      "uuid": "e-xyz",
      "type": "RELATES_TO",
      "source_uuid": "n-abc",
      "target_uuid": "n-def",
      "properties": {
        "fact": "Alice works at Mindvalley",
        "valid_at": "2026-01-12T09:00:00+00:00"
      }
    }
  ],
  "episodes": []
}

Each envelope field:

  • schema_version — envelope format version. The import endpoint only accepts "1" today.
  • source_user_id — the user the export was taken from. Import uses this to rewrite scoping on the target user.
  • counts — record totals, mirrored by the lengths of the arrays below.
  • entity_nodes — extracted entities (people, places, projects, topics) with their attributes.
  • entity_edges — facts connecting two entities. fact is the human-readable statement; source_uuid / target_uuid reference entries in entity_nodes.
  • episodes — raw conversation chunks, populated only when include_episodes=true.

Size cap: exports above 50,000 total records return 413 Payload Too Large. If you hit this, export per-agent (?agent_id=...) is not currently supported on /memories/export — contact the Truememory team to raise the cap.

Import Memory

Accept an exported envelope and write it into the caller’s graph. Intended for the same account (migration, restore) or across accounts (data transfer between users).

POST https://your-tie-host/memories/import
Authorization: Bearer $TOKEN
Content-Type: application/json

Request body — a JSON envelope produced by GET /memories/export. Unchanged envelopes can be re-sent; see the idempotency note below.

Response (202 Accepted):

{
  "status": "processing",
  "import_id": "b7a1c3ef9e5c4d80b6ab1b3b5b5c2c9d",
  "nodes_written": 142,
  "edges_written": 387,
  "episodes_written": 0,
  "edges_skipped": ["e-orphaned-1", "e-orphaned-2"]
}

Response fields:

  • import_id — pass to GET /memories/import/{import_id} to poll for embedding regeneration status.
  • nodes_written / edges_written / episodes_written — counts of records freshly created in the target graph. Records whose UUID already exists are skipped (see below).
  • edges_skipped — UUIDs of edges whose source_uuid or target_uuid did not match any node in the target graph. These are dropped silently; fix the source export or ignore them.

Scoping — what happens to group_id. Memory in Truememory is scoped by group_id, which looks like {user_id}_{agent_id}. On import, the envelope’s source_user_id is stripped from every record’s group_id and the caller’s user ID is substituted. The agent suffix (e.g. __shared__, chatbot) is preserved. A record originally under source-user_chatbot becomes caller-user_chatbot in the target graph.

Idempotency — skip-if-exists by UUID. Import is safe to re-run. Any node, edge, or episode whose UUID already exists in the target graph is left untouched — nothing is overwritten, and no duplicates are created. This means:

  • Re-sending the same envelope produces nodes_written: 0 on the second call.
  • Facts the user has accumulated since the export are not clobbered.
  • There is no partial-state concern: a crashed import can be retried safely.

Error cases:

Status When
400 schema_version is unsupported, source_user_id is missing, or the envelope is malformed
413 Total records exceed the import cap (50,000)
501 The memory backend is disabled for this deployment

Check Import Status

Poll the status of an async import. Useful for showing a progress indicator or gating the UI until semantic search is ready.

GET https://your-tie-host/memories/import/{import_id}
Authorization: Bearer $TOKEN

Response:

{
  "import_id": "b7a1c3ef9e5c4d80b6ab1b3b5b5c2c9d",
  "status": "ready",
  "nodes_written": 142,
  "edges_written": 387,
  "episodes_written": 0,
  "nodes_embedded": 142,
  "edges_embedded": 387,
  "edges_skipped_count": 2,
  "started_at": "2026-04-20T08:15:42.123456+00:00",
  "finished_at": "2026-04-20T08:18:07.456789+00:00",
  "error": null
}

Status values:

  • processing — the embedding backfill is still running. Search will miss freshly imported data.
  • ready — backfill complete, semantic search fully covers the imported records.
  • failed — backfill hit an error. Inspect error for details. The graph records themselves are still written; only embeddings are missing. Contact support or re-trigger by importing the same envelope again (idempotent).

nodes_embedded and edges_embedded count only records from this import, not pre-existing records in the user’s graph. They will stop incrementing once status is ready or failed.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close