twin memory

Versions

Every version of one added item, oldest first, and when and why it went. Behind the write key, because it holds what was edited away.

POST /v1/memory/versionsAuth: write key

Adding an item again with the same id and other words, title, author, about, metadata or expiry is an edit. Reuse an id only to fix the same statement; when something changes, add a new item. Search only shows the newest copy. Versions keeps each copy memory took, whole, until the item goes. A retry of the same item is not a new version. Makes no model call. See Versions and edits.

When the item is forgotten or expires, every version is erased with it. One line stays: when it went and why, with no word of what it said. Adding the same id again after that starts its versions again, after that line.

Headers

Authorizationstringrequired

Bearer tm_…. The key must read and write: a read key is refused, because versions hold text the end user has since changed.

X-Twin-Accountstringrequired

The end user the item was added for. See End users.

X-Request-Idstring

Your id for this request, echoed on the response.

Body

idstringrequired

The item's id, as you gave it to add. 1 to 512 characters.

Response

idstring
The id as sent.
statestring

live, expired, forgotten, or unknown for an id memory never took.

historyobject[]

Oldest first. A version is {event: "version", at, version, item}: when memory took it, its number, and the item as it was held (id, kind, text, title, at, author, session, about, metadata, expires, each where set). role is not shown. A tombstone is {event: "gone", at, why}, where why is forgotten or expired.

Errors

400bad request

X-Twin-Account is missing or not a usable id.

401unauthorized

The bearer is not a key this service issued.

403forbidden

this key reads; writing takes a key that writes.

422invalid

An empty id.

503unavailable

At capacity, or this end user is being rebuilt. Retry after Retry-After seconds.

Request
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" }'
200 OK, after one edit
{
  "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" }
      }
    }
  ]
}
200 OK, after forget
{
  "id": "pref-diet",
  "state": "forgotten",
  "history": [{ "event": "gone", "at": "2026-10-21T10:23:40.619860+00:00", "why": "forgotten" }]
}
200 OK, an id memory never took
{ "id": "nope", "state": "unknown", "history": [] }