Consenti

Right to Erasure ("Right to Be Forgotten")

Almost every consent-related privacy law gives a visitor some form of right to have their data deleted — GDPR calls it the right to erasure (Article 17), CCPA/CPRA calls it the right to delete, LGPD, KVKK, POPIA, and the rest have their own names and article numbers for essentially the same idea. This guide covers how that right is implemented in Consenti end to end: the server-side erasure endpoint, the preference modal's "Forget me" button, and the events both sides fire so you can wire the parts of the flow that are legitimately your responsibility, not the CMP's.

What Consenti erases vs. what's your responsibility

A CMP only ever holds one narrow slice of a visitor's data: their consent record — which cookie/tracking categories they agreed to, when, and under which profile version. Consenti erases thatslice completely, instantly, and without friction, because it's the one thing the CMP can delete with full confidence and no risk of deleting the wrong person's data.

A full erasure request usually reaches further than that, though — into your CRM, analytics warehouse, order history, support tickets, and any third-party processor you pass data to. None of that is something a cookie-consent widget can see or safely touch, and regulators generally expect identity verification and a response window (GDPR gives you a month) before a broader erasure request is fulfilled — not an instant, unverified self-service delete.

So the split is deliberate:

  • Consenti erases its own consent record instantly, self-service, no verification.There's nothing to verify — a signed ownership cookie already proves the request came from the same browser that gave the consent in the first place.
  • Consenti fires events on both erasure paths (server-side consent:erased on the eventBus, client-side consenti:forgetMeRequested/consenti:forgotten on the widget) so your own backend and frontend code can hook in and run whatever broader, identity-verified erasure workflow your business actually needs — deleting the visitor from your CRM, DMP, or analytics platform, or kicking off a formal DSAR case if your data footprint requires one.
💡If your business only processes what the consent record itself tracks — no separate CRM row, no server-side user profile keyed to the visitor — the CMP-side erasure described below may already satisfy the regulation's requirement on its own. If you hold more data than that elsewhere, treat these events as the trigger for your own DSAR process, not as the whole answer.

The compliance mapping

Same right, different name and article number depending on the regulation. Every one of these maps onto the identical DELETE /consent/:visitorId endpoint described below:

RegulationWhere it's definedCompliance guide
GDPR (EU)Article 17 — Right to erasureGDPR guide
UK GDPRArt. 17, applies identically to EU GDPRUK GDPR guide
CCPA / CPRA (California)Right to deleteCCPA guide · CPRA guide
LGPD (Brazil)Art. 18 — Right to erasureLGPD guide
DPDPA (India)Section 12 — Erasure (Section 6 covers withdrawal)DPDPA guide
KVKK (Turkey)Article 7 — Right to request deletionKVKK guide
PIPEDA / Law 25 (Canada)Right to access and erasurePIPEDA guide
PDPA (Thailand)ErasurePDPA Thailand guide
APPI (Japan)ErasureAPPI guide
POPIA (South Africa)Section 24 — Erasure and accessPOPIA guide

Server-side: the erasure endpoint

http
DELETE /consenti/api/v1/consent/:visitorId

This deletes, for the given visitor ID:

  • Every entry in consent_records
  • Every entry in consent_history
  • The visitors record (IP hash, UA hash, geolocation)

The visitor ID itself is a random UUID with no PII embedded in it, and the request is ownership-verified — only the browser that originally submitted the consent (proven by a signed consenti_{visitorId} cookie) can erase it. The response also expires that ownership cookie.

Deletion fires a consent:erased event on the server-side eventBus — this is the hook for cascading the erasure into your own systems:

typescript
eventBus.on('consent:erased', ({ visitorId }) => {
  // Remove the visitor from your own DMP / analytics / CRM
  myDmpClient.deleteUser(visitorId)
})
🚨The audit_logstable is append-only by design — the erasure request itself is logged there and that log entry is retained as compliance evidence (most regulations, including GDPR Art. 17(3)(b), carve out an exception for records you're legally obligated to keep). Only the consent data itself is deleted, never the fact that an erasure happened.

Client-side: the preference modal's "Forget me" button

The widget doesn't expose this by default — a host developer has to opt in, because it's a destructive, one-way action that not every profile wants surfaced as a one-click button. There are two authoring steps, both in the dashboard.

1. Enable it on the UI Template

Open the profile's linked UI Template (Banners → UI Templates), go to the Preference Modal step, and check "Show 'Forget me' button" — right next to "Show locale switcher". This is a structural, per-template toggle (preferenceModal.showForgetMe), the same category as showClose or trapFocus — it controls whether the slot exists at all, shared by every profile that uses this template.

2. Author the button's label

Back in the profile editor's content step (Step 4, Preference Modal), a "Forget Me Button"section appears once the template flag above is on — author the button's label per locale, same pattern as the consent-receipt checkbox's label. Falls back to "Forget me" if left blank.

Runtime behavior

  • Rendered in the modal body, below the categories — only for visitors who already have a stored consent decision (widget.hasConsent()). A first-time visitor has nothing to erase yet, so the button doesn't render for them.
  • Clicking it asks for confirmation (the action is destructive and can't be undone), then calls widget.forgetMe() — see below.
  • After erasure, the banner (or age-gate, if the profile has one) re-prompts automatically, the same way reConsent() already behaves — the visitor is back to a no-consent state, so the compliance banner has to reappear.

Events

forgetMe() dispatches two widget events, mirroring the server's consent:erased:

EventFiredUse it for
consenti:forgetMeRequestedRight before the erasure call goes outKick off your own identity-verified erasure workflow in parallel
consenti:forgottenAfter the consent record is erased and the banner/age-gate has re-promptedConfirm-and-log, analytics, redirect to a "you've been forgotten" page
typescript
import type { ConsentEvent } from '@consenti/ui'

widget.on('forgetMeRequested', (data: ConsentEvent) => {
  // e.g. queue your own backend DSAR intake for this visitor
  fetch('/api/dsar/erasure-request', {
    method: 'POST',
    body: JSON.stringify({ visitorId: data.visitorId }),
  })
})

widget.on('forgotten', (data: ConsentEvent) => {
  console.log('Consent record erased for', data.visitorId, 'at', data.timestamp)
})

Other ways to trigger erasure

The preference modal button isn't the only way in — all three methods below are public and can be wired to a custom link anywhere on your site (a footer, an account/privacy-settings page):

MethodErases the recordRe-prompts banner/age-gateFires forget-me events
widget.deleteConsent()YesNoNo
widget.reConsent(resetAgeGate?)YesYesNo
widget.forgetMe(resetAgeGate?)YesYesYes

Use deleteConsent()if you're about to show your own custom UI next and don't want the banner popping up first. Use reConsent()for a plain "change my cookie settings" link that isn't framed as an erasure/rights request. Use forgetMe()whenever the action is user-facing as a right — a "Delete my data" or "Forget me" link — so the events are there for you to hook into.

html
<a href="#" id="delete-my-data">Delete my data</a>
<script>
  document.querySelector('#delete-my-data').addEventListener('click', (e) => {
    e.preventDefault()
    window.__consenti?.forgetMe()
  })
</script>

Frequently asked questions