Skip to content

Delete a user

Erase a user from Truememory on your app's instruction — memory in every scope, threads, uploads, identity, traces — and prove it was done.

Updated View as Markdown

When a user asks your app to delete their account, this is the one call that removes them from Truememory. Your app owns the relationship with the user and decides when their data goes; Truememory holds what grew out of what you sent it — the memories it extracted, chat threads, uploads, the identity record it keeps for the user — and erases all of it on your instruction. In privacy-law terms your app is the controller and Truememory the processor; this endpoint is how the controller’s “delete” reaches the processor.

It is broader than clear: clear empties one memory scope (one user × one agent, or one namespace), while this erases the person — memory in every agent scope, chat threads and their checkpoints, queued background work, uploaded knowledge packs, minds they own, their identity record and tokens, and their traces in observability.

DELETE https://your-tie-host/users/{user_id}
Authorization: Bearer $APP_TOKEN
Content-Type: application/json

{ "reason": "gdpr_art17", "callback_url": "https://your-app/hooks/truememory" }
Field In Required Description
user_id path Yes The Truememory user UUID (the user_id your other calls return). Service callers may send X-On-Behalf-Of or X-External-User-Id instead, as long as it matches the path (see Service accounts).
reason body No Free text for the service logs, e.g. gdpr_art17.
callback_url body No Receives one POST with the outcome (payload below).
include_linked body No Also erase the Mindvalley-linked namespace. Default false: that data belongs to a different controller.
dry_run query No true returns the row counts and memory scopes a deletion would remove, and writes nothing. It does not cover identity, checkpoints, traces or files.

The caller must be an app token or an admin; user tokens are refused.

What happens

The request does two things and answers at once. It marks the user deleted and starts the user’s deletion job. From the mark on, any request that reaches Truememory with the user’s ID token, or names them in X-On-Behalf-Of or X-External-User-Id, answers 410 USER_DELETED, and work that was already queued for the user is dropped instead of run.

The job runs on Truememory’s maintenance workers, normally within seconds: it removes the identity-provider account and revokes its tokens, then empties every store — threads and their checkpoints, queued work, memory in every scope, member records in shared graphs, owned resources, uploaded files, traces, caches. It is one job per user, so a second DELETE by path while it runs is a no-op and answers 202 again. While the id is still blocked (until the deletion completed, plus one hour), a DELETE for a completed user answers 202 with status: completed and starts nothing; after that hour the same call starts a new deletion. A request that names the deleted user in X-On-Behalf-Of or X-External-User-Id is refused with 410 before it reaches this route, so address a deleted user by the path alone. A store that cannot be verified clean makes the job run again, up to three times with growing pauses; if it still fails, the status is failed and a new DELETE starts a new job.

Think of it like a ticket in a durable job queue with the user’s id as the ticket number: the request only files the ticket, the worker does the work and retries it, and the same number cannot be filed twice while it is open. Where the comparison breaks down: there is no “cancel”. Once the user is marked deleted the data cannot be restored, even while the job is still running.

Response 202 as soon as the ticket is filed:

{
  "user_id": "22c78ed6-…",
  "status": "accepted",
  "requested_at": "2026-10-09T09:26:11Z",
  "completed_at": null
}

The user is locked out of Truememory when this response arrives. Watch the status for completed before you tell the user their data is gone, or let the callback tell you.

Check the status

GET https://your-tie-host/users/{user_id}/deletion
Authorization: Bearer $APP_TOKEN

status is running while the job works, completed once every store is clean, and failed when the job ended without completing — call DELETE again and a new job starts. Any app token or an admin may call it. It answers 404 when no deletion was ever requested for that user, and keeps answering afterwards, so you can show the completion as proof of erasure later. What was removed per store is in Truememory’s service logs, not in this response. Requests made by an admin also leave a row in the admin audit trail.

If you passed callback_url, Truememory also sends one POST to it with the outcome (none if the job could not be started):

{ "event": "user.deletion", "user_id": "22c78ed6-…", "status": "completed", "completed_at": "2026-10-09T09:26:14.265080+00:00" }

The callback is best-effort and is not retried; the status endpoint is the source of truth.

What happens afterwards:

  • The id is blocked until the deletion completed, plus one hour. Any request that names the user — a still-valid ID token, X-On-Behalf-Of, X-External-User-Id — answers 410 USER_DELETED. The hour covers an ID token issued before the delete; after it the same external id registers again as a fresh, empty user, and nothing of the old user comes back. If your app wants a waiting period before the same person can return, that is your rule to keep: Truememory does not hold the id longer. Langfuse deletes traces asynchronously on its side, so a trace can be visible there for up to about 15 minutes after completed.
  • The user still counts. Truememory keeps the user’s row in its identity table with every personal field emptied, so “how many users did we ever have” stays answerable. Nothing on that row can name a person.
  • Backups and logs expire on their own schedules. Truememory does not restore deleted users; the retention windows are documented in the processing agreement.
Navigation

Type to search…

↑↓ navigate↵ selectEsc close