n8n + n8n: GDPR Deletion Request — Automated Multi-System Purge

A GDPR erasure request (Article 17, "right to be forgotten") gives you a legal clock: 30 days to fully delete a person's data from every system you control. For most teams, that means a Slack ping, a

n8n + n8n: GDPR Deletion Request — Automated Multi-System Purge

A GDPR erasure request (Article 17, "right to be forgotten") gives you a legal clock: 30 days to fully delete a person's data from every system you control. For most teams, that means a Slack ping, a scramble to remember where the contact lives, a manual delete in HubSpot, another in Stripe, a third in Notion — and a hand-typed confirmation email that may or may not get sent. Miss one system, and you're technically non-compliant. Miss the deadline, and fines run up to €20M or 4% of global turnover. This article shows you how to collapse that entire scramble into a single n8n workflow that purges the contact from HubSpot, Stripe, and Notion, then emails a compliance confirmation — every time, on the record.

Why manual GDPR deletion breaks at scale

The problem isn't the delete itself — it's the coordination. Customer data spreads across your CRM, your billing processor, your internal wiki, your email tool, and half a dozen SaaS apps nobody remembers subscribing to. When a deletion request arrives, three things go wrong:

  • Incomplete purge. Someone deletes the HubSpot contact but forgets the Stripe customer object, which still holds name, email, and billing address. The record survives, and you're non-compliant without knowing it.
  • No audit trail. GDPR regulators expect you to demonstrate compliance. "I'm pretty sure Maria deleted it in March" is not evidence. Without a timestamped log of what was purged where, you can't prove you honored the request.
  • Blown SLAs. Manual requests sit in an inbox. The 30-day window quietly closes while the ticket waits behind higher-priority work.

As your contact volume grows, each request becomes a small forensic investigation. That doesn't scale, and it exposes you to exactly the risk the regulation was written to punish.

The solution: one trigger, a fan-out purge, one confirmation

The workflow follows a simple, auditable shape. A deletion request enters through a single entry point. n8n normalizes the identifier (usually an email address), looks up the matching record in each system, deletes it, logs the result, and sends a confirmation to the data subject and your compliance inbox. If any system fails to delete, the workflow flags it instead of silently passing.

The core node chain looks like this:

  • Webhook (or Gmail/IMAP trigger) — receives the request with the subject's email.
  • Set — normalizes the email (lowercase, trim) into a single clean field used downstream.
  • HubSpot — search contact by email → delete (GDPR-permanent).
  • Stripe — find customer by email → delete customer object.
  • Notion — query database for the person's page → archive/delete.
  • Merge / Set — collect each system's result into one audit record.
  • Email / Gmail — send compliance confirmation.

Because n8n runs each branch and captures the response, you get a structured, per-execution record of exactly what happened — the audit trail regulators want, generated automatically.

Step-by-step setup in n8n

1. The trigger. Add a Webhook node set to POST with a path like /gdpr-delete. Point your privacy form, help desk, or "delete my data" button at it. The payload only needs one field: { "email": "person@example.com" }. Prefer email intake? Use a Gmail Trigger filtered to a privacy@yourdomain label and parse the sender or body instead.

2. Normalize the identifier. Add a Set node. Create a field email with the expression {{ $json.email.toLowerCase().trim() }}. Every downstream lookup keys off this one clean value, so a stray capital letter never causes a missed match.

3. Purge HubSpot. Add a HubSpot node. First operation: Contact → Search, filter email equals {{ $json.email }}, to resolve the contact ID. Chain a second HubSpot node: Contact → Delete using that ID. HubSpot's delete is a soft archive by default; for true GDPR erasure use their GDPR-delete endpoint via an HTTP Request node (POST /crm/v3/objects/contacts/{id}/gdpr-delete) with your private-app token — this permanently scrubs the record and blocks re-import of the same email.

4. Purge Stripe. Add a Stripe node (or HTTP Request to api.stripe.com). Operation: list customers filtered by email to get the cus_xxx ID, then Customer → Delete. Deleting the Stripe customer removes PII from the customer object while preserving the immutable transaction records Stripe must retain for tax and anti-fraud law — an important nuance: you erase the person, not the legally-required financial ledger.

5. Purge Notion. Add a Notion node. Operation: Database → Get Many with a filter where your email property equals {{ $json.email }}. Pass the returned page_id to a second Notion node set to Database Page → Archive. Archiving removes it from views and the API surface; if your data map treats archive as insufficient, follow with a block-level delete.

6. Build the audit record. Feed all three branches into a Merge node (mode: Combine) or a final Set node that assembles a single object: email, hubspot_status, stripe_status, notion_status, and {{ $now }} as the completion timestamp. Optionally append this to a Google Sheet or a dedicated Notion "Erasure Log" database so you have a durable, exportable compliance ledger.

7. Send the confirmation. Add a Gmail or Send Email node. Send to the data subject: "Your data has been deleted from our systems as of {{ $now }}." BCC your privacy@ inbox so compliance has a copy. Wrap the send in an IF node that only fires when all three statuses read success — otherwise route to an alert branch that pings your team to intervene manually.

Handling partial failures and edge cases

Real systems return errors. On each API node, open Settings and enable Continue On Fail so one dead system doesn't abort the whole purge — you want the other two to complete, and you want the failure recorded, not swallowed. Then use an IF or Switch node to inspect each result: if HubSpot succeeded but Stripe threw a 404 ("no such customer"), that's actually fine — it means the person was never in Stripe. Treat "not found" as success; treat "not authorized" or "timeout" as a real failure that needs a retry.

Add a No Operation / error branch that writes any hard failure to your log with the system name and error message, then sends an internal alert. This turns a silent compliance gap into a visible, actionable task — the single most important safety property of the whole workflow.

The payoff for busy teams

Once this is live, a deletion request stops being a project. The measurable benefits:

  • Provable compliance. Every request produces a timestamped, per-system audit record — the evidence a regulator or DPO actually asks for.
  • Zero missed systems. The fan-out hits HubSpot, Stripe, and Notion every time, in the same order, with no reliance on human memory.
  • SLA safety. Requests are handled in seconds, not days, so the 30-day window is never in play.
  • Frictionless scaling. Ten requests a month or ten a day costs the same operational effort: none.
  • Extensible. Add Intercom, Mailchimp, or your data warehouse by dropping in one more search-then-delete branch — the pattern doesn't change.

Common pitfalls to avoid

Soft-delete masquerading as erasure. Many APIs "delete" by archiving. HubSpot's standard delete and Notion's archive both keep data recoverable. For GDPR, confirm each system's delete is permanent — use HubSpot's dedicated GDPR-delete endpoint, and verify your Notion retention policy.

Over-deleting legally-required data. Don't nuke Stripe charge or invoice records — tax and anti-money-laundering law requires you to retain them. Delete the customer PII object, not the transaction ledger. GDPR's right to erasure yields to other legal retention obligations.

No identity verification. Anyone who knows an email could trigger a deletion. For a public-facing form, add a confirmation-link step (double opt-in) or manual approval gate before the purge fires, so you don't delete a real customer on a malicious request.

Case-sensitive lookups. Person@Example.com and person@example.com are the same human but may not match in a case-sensitive filter. The normalization Set node in step 2 exists precisely to prevent a "successful" run that silently deleted nothing.

Trusting the confirmation email as proof of success. Gate the confirmation behind an all-systems-success check. An email that says "we deleted your data" when Stripe actually failed is worse than no email at all — it's a false compliance record.

GDPR Deletion Request — Automated Multi-System Purge
PRONTO PARA USAR

Ja construimos isso pra voce

Nao comece do zero. O GDPR Deletion Request — Automated Multi-System Purge e um workflow n8n pronto para instalar — conecta suas ferramentas em minutos, sem codigo.

Instalar por $49 →