Updating, superseding and deleting
Choose between updating a memory in place, superseding it with a newer one, or deleting it, and understand what each does.
Information changes. Agent Memory lets you change a memory in three different ways; picking the right one keeps history and dependent information correct.
| Situation | Use | What happens? |
|---|---|---|
| The text of the same information is wrong or incomplete | Update (update_memory, PUT /v1/memory/{id}) | The content changes in place; a new revision is created; the validity time does not change. |
| New information invalidates the old | Supersede (add_memory supersedes=…, supersede_memory) | The old memory is not deleted; it is marked as superseded and hidden from default searches. |
| The information should never be kept | Delete (delete_memory, DELETE /v1/memory/{id}) | The content is redacted and derived copies are cleaned up. |
Update
# 1) Read the current version
curl -s "$API/v1/memory/$ID?workspaceId=$WS" -H "Authorization: Bearer $KEY" # ... "version": 1465395 ...
# 2) Send the version with If-Match
curl -s -i -X PUT "$API/v1/memory/$ID" \
-H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -H 'If-Match: "1465395"' \
-d "{\"workspaceId\":\"$WS\",\"content\":\"Customer meetings are held on Wednesdays\"}"
# HTTP/1.1 200 OK
# ETag: "1466771"
# {"id":"…","version":1466771}- If you send
If-Matchand the memory changed in the meantime, the write is not applied:412 precondition_failedwithcurrentVersionin the response. Re-read the memory and try again. - Without
If-Match, the last writer wins. - The content is scanned as on write and re-embedded; an
UPDATEis written to history, anupdaterow to the change feed, and anupdatewebhook event is emitted. - MCP:
update_memory(memoryId, content, version?); take theversionvalue from theget_memoryoutput. - Only the content is updated. Type, visibility, tags and time fields are not changed by an update (to widen visibility, see Identity and access).
Supersede
If a new decision or correction invalidates an older memory, say so explicitly:
- While writing:
add_memory(content=…, type="decision", supersedes="<old-id>"). The new memory is written and the old one is immediately treated as superseded. If the target is not visible or is already superseded, nothing is written and the response says why. - For two existing memories:
supersede_memory(memoryId="<old>", supersededBy="<new>")— for example, when the user says which of two conflicting corrections is valid.
On the superseded memory:
supersededAtis stamped and the validity interval is closed (validTo);- a
REPLACESrelationship is added from the new memory to the old one; - memories derived from the old memory are flagged for review (
reviewState: "stale"); - the memory is hidden from default searches; it is visible with
includeSuperseded: true, andexplain_memoryshows the chain.
If the superseding memory is deleted, the old memory becomes valid again (unless another live memory supersedes it).
During consolidation the system also performs some supersessions itself (a very similar new decision supersedes the old one; a correction supersedes the decision it contradicts); ambiguous cases are left as open contradictions. See Consolidation, episodes and procedures.
There is no separate REST endpoint for explicit superseding; use the MCP tools for that (for REST clients, consolidation's automatic rules apply).
Delete
curl -s -o /dev/null -w '%{http_code}\n' -X DELETE "$API/v1/memory/$ID?workspaceId=$WS" \
-H "Authorization: Bearer $KEY"| Response | Meaning |
|---|---|
204 | Deleted; derived copies were cleaned up too. |
202 {"cleanup":"pending"} | The memory was redacted; cleanup of derived copies will be retried in the background. |
409 deletion_blocked_by_active_dependents | Live memories are derived from this one. Check the blockingDependents list in the response; to delete deliberately, add ?cascade=true. |
404 | The memory doesn't exist or isn't visible to you. |
403 | You lack permission (delete permission, ownership, or it is a tenant-wide rule). |
The SDKs return these as deleted, pending, blocked, not_found, forbidden.
What does a delete do?
- The deletion is first written to a central erasure ledger (so it can be re-applied after a restore from backup; it contains no content).
- In the same operation the memory is redacted: content, summary and embeddings are cleared, and the memory moves to the deleted state.
- Derived copies are cleaned up: the copy in the run layer, the related line in the user profile, the run summary, episode events and sentences with the same content, mentions in procedures and abstractions, revisions, and history rows containing values.
- If
cascade=truewas given, dependent memories are not deleted but markedstale; thedeleterow in the change feed lists the marked ones.
Track the status:
curl -s "$API/v1/memory/$ID/erasure?workspaceId=$WS" -H "Authorization: Bearer $KEY"
# {"memoryId":"…","status":"complete","attempts":0,"erasedAt":"…"}status: none (no deletion), pending (cleanup in progress), complete, dead (retries exhausted; operator intervention required).
Things to know
- Entity names extracted from the deleted memory's content, the episode summary the memory appears in, and the dependent memories' own text are not cleaned up by a single-memory delete. To fully remove a person's or project's data, use the project/organization deletion flows. See Data management.
- There is no single endpoint for bulk deletion by end user (e.g. "delete everything belonging to this
userId"). - Tenant-wide rules cannot be deleted from a workspace connection.
Related pages
Search and context compilation
Retrieve a compiled, prompt-ready context for a task, together with a receipt of exactly what was delivered.
Consolidation, episodes and procedures
How consolidation turns a run's memories into episodes, facts and procedures, resolves contradictions, and learns from repeated success.