Core operations
Forget a user
Erase every memory and fact held for one end user in the key's project, memories, extracted facts, and graph edges, in a single authenticated call.
When one of your end users exercises their right to erasure, you need to
remove everything Korely holds about them: raw memory text, vector
embeddings, entity graph edges, and bi-temporal facts. A single
DELETE /v1/users/{end_user}/memories call does all of
this atomically. Memories and facts are physically deleted, superseded
facts included, so nothing can be read back afterwards. The response
includes an audit_id you can store as proof that the erasure
was performed.
Wire this call directly into your own /delete-account flow. No secondary cleanup step is needed on the Korely side: one HTTP request per project erases every memory and fact Korely holds for that user in that project from the live database, which is the technical step of an Article 17 request. The audit record, the access trail and delivered webhooks keep a keyed pseudonym of the end user instead of the id. Encrypted nightly backups keep a copy for up to 35 days, after which it expires.
flowchart LR A([Your delete-account flow]) -->|DELETE /v1/users/end_user/memories| K[Korely] K --> M[Purge memory text<br/>+ embeddings] K --> G[Remove graph edges] K --> F[Delete all facts<br/>current and superseded] K --> AU[Emit audit_id] AU --> R([Return receipt]) M -.-> R G -.-> R F -.-> R
Request
Endpoint: DELETE /v1/users/{end_user}/memories. SDK: korely.delete_all(user_id=...).
| Parameter | Type | Required | Description |
|---|---|---|---|
end_user | string (path) | Required | The user_id you use when writing memories. Identifies the data subject whose data will be erased. Must match the value passed to add() for that user. |
Authorization | header | Required | Bearer kor_live_..., your agent API key: a key with the memories:write scope, from the project that holds the user's memories. |
Example
from korely_memory import Korely
korely = Korely(api_key="kor_live_...")
result = korely.delete_all(user_id="customer-4812")
print(result.user_id) # customer-4812print(result.memories_deleted) # 47print(result.facts_deleted) # 12print(result.audit_id) # aud_5f0c...e8f, store this in your erasure recordsResponse
{ "user_id": "customer-4812", "memories_deleted": 47, "facts_deleted": 12, "erasure": "permanent", "audit_id": "aud_5f0c2d9e8b7a4c1d9e3f6a2b1c0d4e8f"}| Field | Type | Description |
|---|---|---|
user_id | string | The end user that was erased, echoed back for confirmation. |
memories_deleted | integer | Number of memory records purged (text and embeddings removed). |
facts_deleted | integer | Number of facts physically deleted, superseded ones included. |
erasure | string | Always permanent: the rows are physically deleted from the live database and cannot be read back. |
audit_id | string | The id of the erasure receipt, which you can attach to your own erasure record: aud_ and 32 hex characters. The audit log records the same erasure as an erase event, without this id. |
Errors
Every error response carries code (stable, branch on it) and
message (for a person), plus detail, kept for older
clients: a sentence, an object with the code, the message and any figures such
as limit and used, or on a validation 422 the list of
fields that failed. Note there is no 404
for an unknown user, forget is idempotent and returns 200 with zero counts (see Notes below).
| Status | Code | When it happens |
|---|---|---|
401 | invalid_key | The Authorization header is missing, malformed, or the key has been revoked. Message: Invalid or missing API key: ..., then what is wrong. |
403 | forbidden | The key lacks memories:write. Message: API key missing required scope(s): memories:write. |
429 | rate_limit_exceeded | Too many requests in the current minute, hour or day for your plan. The response carries Retry-After (integer seconds). A forget call does not count against the monthly write or query quota. |
Notes
- Idempotent. If the user has no memories, the call succeeds and returns the same response shape with counts of zero and a fresh
audit_id. An unknown end user returns200with zero counts and a freshaudit_id. An id over 255 characters, one with a NUL byte, or one already erased (anerased:pseudonym) is a422, and a key confined to other end users gets403. It is safe to call from a delete-account handler without a pre-flight existence check. - Scoped to the key's project. The call erases the end user across every
agent_idin the project the key belongs to. If you keep the same end user in several projects, call it once per project, with that project's key. - Names declared elsewhere. If the person has no memory or fact left in any other project of your account, the names declared for them there (Declare a name) are removed too. A namesake, the same id in another project with memories of its own, keeps everything and is not counted as erased.
- Facts are deleted, not invalidated. Erasure is a different operation from the bi-temporal supersede: every fact about the end user is removed, including superseded ones, and
include_invalidatedcannot bring them back. The audit record keeps the counts and a keyed pseudonym of youruser_id, never the erased content (theeraseevent in the audit log is still found withGET /v1/audit?user_id=and the same id), so you can evidence the erasure (Article 5(2)). - Rate-limit behaviour. The endpoint does not count against the monthly write or query quota, so an erasure request never fails because a quota is spent. It is subject to the per-minute, per-hour and per-day rate limits of your plan; that 429 carries a
Retry-Afterheader (integer seconds). - Store the
audit_id. Theaud_-prefixed receipt is your proof of erasure. Attach it to your internal erasure record alongside the timestamp of the HTTP response.
Related
- Add a memory, write the first memories for a user.
- Get context, retrieve relevant memories and facts before a forget to audit what will be erased.
- List users, enumerate all
end_useridentifiers in the key's project to build a deletion queue. - API reference, full endpoint contract, request/response schemas, and OpenAPI spec.