Delete personal data
Erase a person's personal data on request without losing your revenue history.
An erasure removes everything Voidhash holds that identifies a person, for example to honor a GDPR or CCPA deletion request, while their purchases and revenue stay recorded anonymously. You can request one from Studio, the API, the CLI or the MCP server. It cannot be undone.
What is deleted and what is kept
An erasure covers the person and every profile merged into them, such as the anonymous profile they used before signing in.
| Deleted | Kept, without anything that identifies the person |
|---|---|
| Name, email and attributes | Purchases, subscriptions and the access they grant |
| Every distinct ID and the links between them | Revenue events, so revenue, MRR and subscription reports don't change |
| Events, push devices, cohort memberships, unfinished checkouts and feature flag targeting that names them | Store transaction and subscription IDs, which identify the purchase, not the person |
| Their identifiers in webhook delivery history, stored store payloads and sent push notifications |
Kept records stay attached to an anonymous person ID, so renewals, refunds and cancellations of a subscription they still pay for keep being recorded. Afterwards the person no longer appears in Studio or the API. If your app identifies the same user ID again, Voidhash starts a new, empty person.
On a website, also call reset() in the visitor's browser so later events don't carry the erased
distinct ID. See Privacy.
Request an erasure
You need permission to delete people in the project, which team admins and owners have.
Open the person in People and click Delete person data, then confirm. Studio shows the progress and returns to the people list when the erasure finishes.
Send the person's distinct ID or Voidhash person ID in the body, with a secret key. Publishable keys are rejected.
curl https://api.voidhash.com/api/v1/projects/$VOIDHASH_PROJECT_ID/erasures \
-H "Authorization: Bearer $VOIDHASH_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{ "distinctId": "user_123" }'With the Node.js library:
import { createVoidhashSdk } from "@voidhash/node";
const voidhash = createVoidhashSdk({ secretKey: process.env.VOIDHASH_SECRET_KEY! });
const erasure = await voidhash.persons.createErasure({
payload: { distinctId: "user_123" },
});voidhash person erase user_123The argument is the person's email, distinct ID or person ID. The CLI asks you to type the email or
distinct ID to confirm (--yes skips this), then waits up to 60 seconds for the erasure to
finish. --no-wait returns as soon as it is requested.
Ask your agent to erase the person. erase_person first reports what will be erased and kept, and
changes nothing until you confirm. get_person_erasure reports progress after that.
Put identifiers in the body, never in the URL: a distinct ID can be an email address.
Track progress
The API answers every request with 202 Accepted and the erasure:
{
"id": "person_erasure_...",
"projectId": "proj_...",
"status": "queued",
"personId": "person_...",
"requestedAt": "2026-10-14T10:00:00.000Z",
"completedAt": null
}| Status | Meaning |
|---|---|
queued | Accepted; it finishes on its own. |
in_progress | Running; it finishes on its own. |
completed | The personal data is gone. |
failed | It stopped. Request it again to retry the same erasure. |
Most erasures finish within minutes. Poll GET /api/v1/projects/{projectId}/erasures/{erasureId}
or subscribe to the person.deleted webhook, which fires when the erasure completes.
- Repeats are safe. Requesting the same person again returns the same erasure, and restarts it
if it
failed. - Unknown people. A request that matches nobody returns an erasure that is
completedat once, withpersonIdset tonull. Every request is recorded in the audit log either way. - Late events. A day after completion, Voidhash erases once more to remove events the person's devices captured before the erasure but delivered later, for example from an offline queue. Events your app sends after the erasure belong to the new person and are kept.
Keep your own systems in sync
Voidhash only erases the data it holds. If your backend stores the same person, subscribe a
webhook endpoint to person.deleted and delete your copy when it arrives. The event
carries personId, erasureId and erasedAt, but no distinct ID, email or name, so store the
Voidhash person ID next to your own record.
Next steps
Something wrong or missing on this page? Tell us by email or on Discord.