Handling erasure requests
Answer a user's request to be forgotten, such as under the GDPR right to erasure, and keep a receipt of what was removed.
When a user asks you to erase what they told your product, you need to find what to erase, erase every copy, and keep a record that you did. twin memory gives you one call for the erasure and a receipt for the record.
This page describes what the API does. It is not legal advice about what a request requires of you.
1. Decide what to erase
| The user asks to erase | Call |
|---|---|
| One message, document or note | forget with items: the ids you gave at add |
| A whole conversation | forget with sessions: the session ids |
| Everything | Delete the end user in the console, or forget every session and item |
forget also takes events (ev_… ids) and threads (th_… ids), as search and status return them. Each
list holds at most 500 ids, and one request may mix them.
2. Look before you erase
Check what the memory holds, so you can confirm it is gone afterwards.
grepfor a phrase the user named, such as an address or a phone number.lineageof an item id lists what it became: its passages, the facts read from it and the lines of the core page built from those. That is exactly what a forget of it removes.searchwith the user's own words.
3. Forget
curl https://api.twinmemory.dev/v1/memory/forget \
-H "Authorization: Bearer $TWIN_MEMORY_API_KEY" \
-H "X-Twin-Account: user_42" \
-H "Content-Type: application/json" \
-d '{ "items": ["pref-diet"], "sessions": ["onboarding"] }'Forget takes the write key. Its cost grows with the size of the user's memory, because the rest of the memory is rebuilt without what went. Give it a longer timeout than a search.
4. Keep the receipt
The answer counts every table before and after, and what went from each layer:
{
"events": 1,
"threads_emptied": 1,
"ledger": 1,
"records": 0,
"assertions": 0,
"versions": 2,
"log_emptied": true,
"tables": {
"events": { "before": 4, "after": 3 },
"passages": { "before": 3, "after": 2 },
"passages_fts": { "before": 3, "after": 2 },
"files": { "before": 18, "after": 19 }
},
"inbox": 0,
"queue": 0
}This receipt is shortened; the forget reference lists every field. Store it with the request, the date and the end user id. It is your record of what was removed.
Two things to know when you read it:
filescan rise. The record of the erasure is itself written, and pages built from the rest of the memory are written again.queueisnullwhen the queue could not be reached. The erasure of the stored memory stands. Call forget again to clear copies still waiting.
When nothing matched, the receipt is {"events": 0, "inbox": 0, "queue": 0}.
5. What happens to late copies
An item can still be on its way in when you forget it, for example from a retry. The id of every erased event is kept, without its content, so a copy that arrives later is not landed. If you add the same item again on purpose, that lifts it.
Deleted rows are not left readable in the database file: freed pages are zeroed, and the write-ahead log is
emptied when it can be (log_emptied).
6. Confirm
statusof an erased item id answersunknown.versionsof it answers"state": "forgotten", with one line saying when, and no word of what it said.grepandsearchfor the same words no longer return it.
Erase a user whole
In the console, open End users, find the user and delete them. Their memory is deleted as a whole, and anything still waiting for them in the queue is removed. A later add for the same id starts an empty memory.
What this does not cover
- Copies in your own systems: your database, your logs, your analytics.
- Text you sent to a model provider in prompts built from memory. Their retention is set by your agreement with them.
- Encryption at rest with your own key Soon.