Versions & edits
Sending an item again with the same id edits it, and every version memory took is kept for your backend until the item goes.
There is no separate update call. To edit an item, add it again with the same id and the new
content. Memory replaces what it holds and keeps the earlier copy as a version.
An edit is for fixing the same statement, such as a typo or a mistake. When something changes, such as a new
address or a new plan, add a new item with a new id instead: memory keeps both, each with the day it was said,
and shows them newest first. An edit keeps the item's first date, so an edit used for a change loses the earlier
value and dates the new one too early.
Sending an id again replaces its text. Its about, metadata, expires and author stay as they were
unless the request sends them; send null to clear one.
What makes a version
A new version is taken whenever what lands differs from what memory holds for that id:
- new
text - a new
titleorauthor - other
abouttags ormetadata - a new
expires, ornullwhere there was one
The item's time does not change on an edit: once memory holds an item, its at is fixed. To move it in time,
forget it and add it again.
Sending exactly the same item again, such as a retry, makes no version.
What an edit does
- The stored copy is replaced, and the conversation it belongs to is filed again, so search finds the new words and no longer finds the old ones.
- Records read from the old words are read again from the new ones when the conversation is next read.
- Models never see earlier versions.
read,lsand every search show only what the item says now.
Read an item's versions
/v1/memory/versions returns every version of one item, oldest first, and its state now.
It takes a read and write key, because it returns text that was edited away. Do not give that key to a
model.
curl https://api.twinmemory.dev/v1/memory/versions \
-H "Authorization: Bearer $TWIN_MEMORY_API_KEY" \
-H "X-Twin-Account: user_42" \
-H "Content-Type: application/json" \
-d '{ "id": "pref-diet" }'After the note pref-diet was added, then sent again with new text:
{
"id": "pref-diet",
"state": "live",
"history": [
{
"event": "version",
"at": "2026-10-21T10:23:40.598077+00:00",
"version": 1,
"item": {
"id": "pref-diet",
"kind": "note",
"text": "Alice is vegetarian and allergic to peanuts.",
"at": "2026-10-02T12:00:00+00:00",
"metadata": { "source": "crm" }
}
},
{
"event": "version",
"at": "2026-10-21T10:23:40.600223+00:00",
"version": 2,
"item": {
"id": "pref-diet",
"kind": "note",
"text": "Alice is vegan and allergic to peanuts.",
"at": "2026-10-02T12:00:00+00:00",
"metadata": { "source": "crm" }
}
}
]
}aton a version is when memory took it.item.atis the item's own time.itemshows what memory held, in the shapeaddtakes. Aroleis kept only as the kind of author, so it may not appear as you sent it.
States
state | Meaning |
|---|---|
live | The item is held. The last version is what it says now. |
expired | Its expires time has passed. |
forgotten | It was erased by forget. |
unknown | Memory never took an item by this id. history is empty. |
When the item goes
When an item is forgotten or expires, every version goes with it. One line stays, saying when it went and why, with nothing of what it said:
{
"id": "pref-diet",
"state": "forgotten",
"history": [{ "event": "gone", "at": "2026-10-21T10:23:40.619860+00:00", "why": "forgotten" }]
}If you add the same id again after that, its versions start again after that line.
Versions are kept only for items you add. They are not a backup: the forget receipt
counts the versions it erased under versions.
Related
- Items: what makes an item's identity.
- Expiry: moving or lifting an expiry is an edit.
- Versions reference.