Core operations
Delete a memory
Remove one memory by its id, so your agent no longer sees it or the facts only it stated.
By default a delete hides the memory: search and the lists of memories stop returning it, and nothing brings it back.
Its text and its embedding stay in Korely's
database until you erase it with erase=true.
A delete closes the facts only that memory stated. A closed fact is kept for history but left out of normal reads.
To answer an end user's request to erase their data, use
erase=true or Forget a user,
which erases all of one end user's memories. Encrypted backups keep a copy
for up to 35 days.
Quick start
You need Python 3.9 or later and an API key. Install the SDK:
pip install korely-memory
Replace kor_live_... with your key from
Quickstart: get a free API key. The key
needs the memories:write permission.
The script saves one memory for the end user customer-4812, then deletes it.
from korely_memory import Korelykorely = Korely(api_key="kor_live_...")memory = korely.add("The customer prefers to be contacted by email.", user_id="customer-4812")result = korely.delete(memory.id)print(result.status, result.facts_invalidated, result.audit_id) add() returns the new memory at once, with its
memory.id. The script prints three values: the status
forgotten, the count 0
and an audit id such as aud_3d0f9a21c4b84e6f8a7d5c3b2e1f0a9d.
The 0 counts the facts closed. Korely
extracts facts in the
background, usually about ten seconds after add(), so the
memory is deleted before any fact is written.
Terms
The Glossary defines the words used across the docs. This page adds three.
- Hide (the default delete): the memory leaves every read but stays in Korely's database. Its status is
forgotten. The Glossary calls this forgetting. - Erase:
erase=true(see Forget and erase) removes the memory and the facts only it stated, for good. Its status iserased. - Audit record: a row Korely writes for each delete, with the end user, memory id, fact count and time, never the text.
audit_idis its id, a receipt for your logs. The Audit log lists your API calls, not this record.
Reference
Request
Endpoint: DELETE /v1/memories/{id}. No request body.
| Parameter | Type | Notes |
|---|---|---|
Authorization | header | Required. Bearer kor_live_..., a key of the memory's project with the memories:write permission. |
id | string, path | Required. The id that add() returned. |
erase | boolean, query | Optional, default false. true erases for good. The SDKs do not send it: use the REST call. |
Example
For Node.js 18 or later, run
npm install korely-memory.
import { Korely } from "korely-memory";
const korely = new Korely({ apiKey: "kor_live_..." });
const result = await korely.delete("mem_8f2c1a4d9b3e47a6b05e2c7d1f3a9e84");
console.log(result.status, result.facts_invalidated, result.audit_id);Response
A hide answers 200:
{ "id": "mem_8f2c1a4d9b3e47a6b05e2c7d1f3a9e84", "status": "forgotten", "facts_invalidated": 2, "facts_reopened": 0, "audit_id": "aud_3d0f9a21c4b84e6f8a7d5c3b2e1f0a9d"}An erase also answers 200, with two more fields:
{ "id": "mem_8f2c1a4d9b3e47a6b05e2c7d1f3a9e84", "status": "erased", "erasure": "permanent", "facts_invalidated": 2, "facts_deleted": 2, "facts_reopened": 0, "audit_id": "aud_7b1e4c9a2d5f48e0a3c6b9d2f1e8a4c7"}| Field | Type | Description |
|---|---|---|
id | string | The memory's id. |
status | string | "forgotten" for a hide, or "erased" with erase=true. |
facts_invalidated | integer | Facts this delete closed. See Details when it is 0. |
facts_reopened | integer | Closed facts made true again as new facts. See Details. |
facts_deleted | integer | Erase only. Facts deleted for good that only this memory stated, closed ones included. |
erasure | string | Erase only. Always "permanent". |
audit_id | string | The audit record's id. |
After a delete
A hidden memory and its closed facts leave search results, context blocks and the other reads. A facts query can still return the facts if you ask for closed facts or for a date before the delete (Temporal facts: reading past dates).
Errors
| Status | Code | When it occurs |
|---|---|---|
401 | invalid_key | The header is missing or malformed, or the key is unknown, revoked or expired. |
403 | forbidden | The key lacks memories:write. |
404 | not_found | The id is wrong, or the memory is in another project or account, or this is a repeated delete. |
422 | invalid_request | erase is not a boolean. |
429 | rate_limit_exceeded | Past the rate limit. Wait as long as Retry-After says. |
503 | unavailable | Another change to the same records, such as an erasure under way, held this request too long. Retry when Retry-After says. |
Details
- When facts_invalidated is 0. The memory has no facts yet. Its facts were already closed. An erase follows an earlier hide. Or another memory states the same fact: if two memories both say "prefers email", deleting one keeps that fact open.
- Repeating a delete. A second plain delete, a second erase and an unknown id return
404. An erase after a plain delete works. After a lost response, a404on retry means the memory is gone or never existed. - A delete can make a closed fact true again. Say you saved "The plan costs 50 euro", then a wrong "The plan costs 80 euro", which closed the 50 euro fact. Deleting the 80 euro memory writes the 50 euro fact again as a new fact, counted in
facts_reopened. It stays closed if another memory says 80 euro, another value is open, or no live memory still says 50 euro. When the same fact was told to several agents of one end user, each agent gets its copy back andfacts_reopenedcounts every copy (since 1.0.8). The same holds for a fact that a past statement closed (“costs 55 now, it used to cost 50”): forgetting the memory that said it gives the 50 back (since 1.0.9; before, nothing was left open in that case). No model is asked on a delete, so in three cases the old fact comes back beside a newer one it contradicts, or a copy does not come back. A value filed under another relation: "I live in Paris", then "now I live in Zanzibar", and "relocated to Rome" stored as its own relation; forgetting the Zanzibar memory gives Paris back beside Rome. One place under two names in two agents: Paris told to agents a and b, while b also knows it as "Parigi" through its own alias; the two copies count as two values, so one stays closed. A fact told to more than about ten agents: a new value closes only the ten newest and the ten nearest copies, so the others were never closed and are not given back. In each case, close the stale fact yourself. - A fact you said is over stays over (since 1.0.14). Say "I live in Paris" was closed by "I live in Zanzibar". If you forget Paris (Forget a fact), correct it, or post it in the past tense (
"tense": "past"on Write a fact), deleting the Zanzibar memory afterwards no longer gives Paris back, andfacts_reopenedsays 0. Until 1.0.13 it could. A forget never moves an end later: with anaton or after the end the judge gave, the answer is stillalready_forgotten, with that end ininvalid_at. It counts as your word all the same, and so does a forget of a fact the judge had already closed. - A memory that said a fact is over keeps it closed while it says so (since 1.0.14). "I no longer live in Paris", or an edit of "I live in Paris" into a text that no longer says it, ends Paris in place. Korely now records that memory, and every later memory that says it again, as a reason the fact is closed. While one of them is live and still says it, deleting the Zanzibar memory gives nothing back. When all of them are forgotten, erased or edited so they no longer say it, and nothing else closes Paris, Paris is true again as a new fact. An edit that still says it, such as a fixed typo, keeps it. What the judgement of that statement closed (for example "I love Paris", beside "I no longer live in Paris") follows Paris.
- Known limits of 1.0.14. Facts that were ended in place before 1.0.14 have no record of who ended them, and Korely does not guess it, so a deletion treats them as it did until 1.0.13. Forget such a fact by hand to make it your word. A fact whose end was brought earlier still shows the fact that was to replace it in
invalidated_by, so readinvalid_atfor when it ended. A forget with anatahead loses that date if the value that closed the fact sooner goes: the fact stays closed from that value's start. A value posted by hand and then forgotten by hand keeps closed what it closed. One order of deletions can leave a fact closed for good: when two memories say Paris is over and only the first one's judgement closed "I love Paris", deleting the first and then the second gives Paris back but not "I love Paris". Post it again to make it true. - A delete during extraction. If you delete a memory while Korely is still extracting its facts, that is not an error. The write is discarded and not queued again (since 1.0.0). Since 1.0.2 a synchronous write over MCP no longer answers
500in that case. - What an erase removes. The text, summary and embedding, the facts only it stated, and the name aliases they alone taught Korely.
- No webhook. Neither a delete nor a reopened fact sends one. Refresh any copy outside Korely.
- Command line and AI assistants. The
korely delete <id>command only hides. The MCP server, which AI assistants such as Claude connect to, haskorely_forget_memory, which hides, or erases witheraseset.
Related
- Update a memory: correct a memory instead of deleting it.