Skip to content

GDPR endpoints

The query API exposes two site-scoped companion endpoints for subject data. Both require an administrator or an admin-scoped API key. They do not replace the complete managed Article 15 access or Article 17 erasure workflow across the Vault, identity mappings, regional customer membership, and every affected site.

Hosted customers should request the complete managed subject workflow. Use the endpoints below for the site-scoped analytics leg and its audit receipt.

POST /sites/:siteId/gdpr/export
Authorization: Bearer <admin-token-or-admin-api-key>
Content-Type: application/json

Body with exactly one of subject.anon_id or subject.user_id:

{ "subject": { "user_id": "u_42" } }
{ "subject": { "anon_id": "anon_abc123" } }

Supplying both is 400 invalid_subject. Body cap: 16 KB.

Response (200):

{
"site_id": "site_marketing",
"subject": { "user_id": "u_42" },
"counts": {
"events": 12,
"sessions": 3,
"user_profiles": 1,
"identity_links": 2
},
"events": [/* full row dumps */],
"sessions": [/* … */],
"user_profiles": [/* … */],
"identity_links": [/* … */]
}

The response contains the entire matching row contents from these four site-scoped hot-storage tables, including the events.raw JSONB wire payload. It is not a complete cross-service Article 15 export.

POST /sites/:siteId/gdpr/delete
Authorization: Bearer <admin-token-or-admin-api-key>
Content-Type: application/json

Same subject body shape:

{ "subject": { "user_id": "u_42" } }

Response (200):

{
"site_id": "site_marketing",
"subject": { "user_id": "u_42" },
"counts": {
"events": 12,
"sessions": 3,
"user_profiles": 1,
"identity_links": 2,
"replay_chunks": 1,
"eligible_pageviews": 2,
"integration_jobs": 1,
"integration_object_links": 1,
"integration_crm_unmatched_deals": 0
}
}

Behaviour:

  • Hard-deletes matching site-scoped analytics, replay metadata, eligible pageviews, and linked Integration Hub records inside one transaction.
  • Idempotent. Replaying against an already-purged subject returns zero counts (still 200).
  • Recorded in the audit log with the actor and the SHA-256-truncated subject id.
  • Does not itself erase Vault ciphertext, redact identity mappings, or clear and regenerate customer account membership.
TableCovered?Notes
eventsYesEvery row with the matching anon_id or user_id.
sessionsYesEvery session for the subject.
user_profilesYesThe profile row, if user_id was supplied or resolves through identity_links.
identity_linksYesAll anon ↔ user mappings touching the subject.
replay_chunksYesReplay metadata directly associated with the matching anonymous subject.
eligible_pageviewsYesEligible pageview rows reached through the subject’s site sessions.
Integration Hub recordsYesSubject-linked jobs, CRM unmatched records, and object links for the site’s workspace.
Vault ciphertext and key materialNoThe managed Vault workflow owns cryptographic identity erasure.
Customer account membershipNoThe managed workflow clears regional membership and regenerates affected reviews after the Vault signal resolves.
audit_logNoAudit rows are append-only; the subject id in the audit row is SHA-256-truncated rather than stored verbatim, so erasing the subject does not require deleting audit history.
dlqPartialDLQ rows tagged with the subject id are deleted; rows where the subject is buried in the payload JSON are not (the operator must inspect manually if dlq retention is long).
BackupsNoThe platform does not delete from your database backups. Operator policy: rotate backups within the GDPR-mandated window, or document the policy in your DPIA.

The site-scoped endpoints resolve subjects in two ways:

  • user_id: joins identity_links to find every anon_id ever bound to the user, then deletes across the union.
  • anon_id: direct match on the anon_id column.

If a single human ever appeared as both an anon and a known user, supplying user_id is the right choice because it picks up their pre-identification trail through identity_links.

Both endpoints are O(rows-per-subject), and delete runs inside one transaction. The API responds only after that site-scoped transaction commits. These endpoints are not on the ingestion hot path.

Every gdpr.export and gdpr.delete call is recorded in audit_log with the actor (admin or api_key id) and a SHA-256-truncated copy of the subject id. The truncation prevents the audit row from being its own GDPR violation while still leaving an audit trail.

This page is technical documentation. It is not legal advice. Your DPIA, the legal basis for processing, the retention policy, and the rest of the GDPR surface are operator responsibilities. leadmaps provides the mechanism; you supply the policy.