DSAR data-mapping checklist for analytics stacks

last verified · against GDPR/CCPA texts + GA4 & Adobe privacy APIs as of 2026-07

DSAR checklist for analytics stacks: identifier-to-system map, GA4 and Adobe deletion APIs, statutory deadlines, and verification steps for erasure requests.

What this is

A Data Subject Access Request (DSAR) is a person exercising their legal right to access, delete, or port the personal data you hold — and your analytics stack is in scope. This checklist maps the identifiers an analytics stack actually stores to the system-specific deletion mechanism for each, with the statutory clocks and the API calls.

Statutory clocks

Regulation Deadline Extension Fee
GDPR (Art. 12(3)) “without undue delay and in any event within one month of receipt” “by two further months where necessary”, informing the person within the first month Free unless “manifestly unfounded or excessive” (Art. 12(5))
CCPA/CPRA 45 calendar days +45 days (90 total) with notice to the consumer Free, same excessive-request carve-out

The rights most relevant here: access (GDPR Art. 15), erasure (Art. 17), portability (Art. 20). Under both regimes you must verify the requester’s identity first — and information collected for verification “can only use that information for this verification purpose” (California AG).

Identifier map — what the stack stores and where

Identifier Lives in Deletion surface
GA4 client ID _ga cookie (“used to distinguish users”, 2-year default) Admin API submitUserDeletion with clientId
GA4 session state _ga_<container-id> cookie Deleted with the client ID’s data
GA4 User-ID Your auth system, sent as user_id submitUserDeletion with userId
Firebase app instance ID App install submitUserDeletion with appInstanceId
User-provided data (email/phone) Enhanced conversions / user_data submitUserDeletion with userProvidedData (normalized; “one email address or one phone number”)
Adobe ECID Legacy AMCV_* cookie; Web SDK kndctr cookie Privacy Service job, namespace ECID
CRM ID / email in Adobe identityMap namespaces Privacy Service job, standard or custom namespace
BigQuery export rows Your GA4 export dataset Your own SQL — no Google tool deletes here for you
sGTM / collection logs Your Cloud Run / Worker logs Your own log retention and deletion
Consent records Your CMP The CMP vendor’s own DSAR tooling

The map is the deliverable: for each row, record where the identifier is minted, which systems it propagates to, and who owns the deletion. A DSAR answered from this table takes minutes; one answered from memory takes the whole deadline.

GA4 deletion surfaces

Per-user deletion — Admin API. POST https://analyticsadmin.googleapis.com/v1alpha/properties/PROPERTY_ID:submitUserDeletion with exactly one of userId, clientId, appInstanceId, or userProvidedData (a union field). Requires OAuth scope https://www.googleapis.com/auth/analytics.edit. The response’s deletionRequestTime “marks the moment for which all visitor data before this point should be deleted”. Processing time is not documented — flagged rather than guessed.

Field-level cleanup — Data-deletion requests. In Admin → Data collection and modification → Data deletion request. Five types: delete all parameters on all events; all registered parameters on selected events; selected parameters on all events; selected parameters on selected events; selected user properties.

Data-deletion request fact Value
Preview / cancellation window 7 days (Editor role can cancel)
Active requests per property Maximum 12
Processing time “between 7 and 63 days”
Minimum data age “more than 12 days old”
What happens to values Replaced with “(data deleted)”; events still count in metrics
Out of scope Numeric parameters; auto-collected fields like age, browser, country

The data-deletion documentation does not address the BigQuery export — treat exported data as entirely your own deletion responsibility, and pair every GA4 deletion with a DELETE against the export dataset.

Adobe deletion surfaces

One Privacy Service job can fan out across products via the include array:

Product include value
Adobe Analytics analytics
Audience Manager audienceManager
AEP Profile store profileService
AEP data lake aepDataLake
Target target
Customer Attributes CRS
Journey Optimizer cjm
Marketo Engage marketo
Identity Service identity
Campaign / Advertising campaign / adCloud
privacy-job.sh
curl -X POST https://platform.adobe.io/data/core/privacy/jobs \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'x-api-key: {API_KEY}' \
-H 'x-gw-ims-org-id: {ORG_ID}' \
-H 'Content-Type: application/json' \
-d '{
"companyContexts": [{ "namespace": "imsOrgID", "value": "{ORG_ID}" }],
"users": [{
"key": "request-2026-0042",
"action": ["access", "delete"],
"userIDs": [
{ "namespace": "email", "value": "person@example.com", "type": "standard" },
{ "namespace": "ECID", "value": "44363657679975868102", "type": "standard", "isDeletedClientSide": false }
]
}],
"include": ["analytics", "profileService", "identity"],
"regulation": "gdpr"
}'

regulation takes the code for the applicable law (gdpr and ccpa are the ones verified here; the Privacy Service appendix lists the full set).

Adobe Analytics only honors labels. Privacy jobs act on report-suite variables according to their data governance labels — unlabeled variables are invisible to the workflow:

Label Meaning
ID-DEVICE / ID-PERSON Field identifies a device / an authenticated person for privacy requests
DEL-DEVICE / DEL-PERSON Anonymize the field when the request carries a matching device / person ID
ACC-ALL / ACC-PERSON Include in every access request / only when the hit is confidently the data subject’s
I1 / I2 Directly identifies a person / identifies in combination with other data
S1 / S2 Precise / broad geolocation sensitivity

Request workflow

  1. Verify identity — before touching any system; keep verification data solely for that purpose.
  2. Start the clock — log the receipt date; GDPR gives one month, CCPA 45 days.
  3. Resolve identifiers — from the map above: cookies named in the request, CRM lookup for email → User-ID/CRM ID, ECID if supplied.
  4. Submit per system — GA4 submitUserDeletion per identifier; one Adobe privacy job covering all products in include.
  5. Sweep your own stores — BigQuery export, sGTM logs, data warehouse copies. No vendor API reaches these.
  6. Record completion — job IDs, deletionRequestTime, SQL run, dates — this is your accountability evidence.

Gotchas

  1. Deleting the cookie deletes nothing. Cause: the _ga or kndctr cookie is only the identifier’s carrier; the data sits server-side. Fix: run the deletion APIs with the identifier value, not just a consent banner cleanup.
  2. GA4 deletion “done” but the warehouse still has the person. Cause: neither the Admin API nor UI deletion requests are documented to touch the BigQuery export. Fix: pair every request with DML against analytics_* tables.
  3. Adobe delete job returns complete, data still visible. Cause: the variables holding personal data carry no DEL-DEVICE/DEL-PERSON labels, so the job had nothing to act on. Fix: label variables in Data Governance before you need them — labeling is the prerequisite, not part of the request.
  4. A GA4 field-level request sits pending for weeks. Cause: documented behavior — 7-day preview, then “between 7 and 63 days” processing, and data must be “more than 12 days old”. Fix: respond to the requester with the statutory letter first; don’t wait for processing to finish.
  5. One person, many identifiers, partial deletion. Cause: GA4’s API takes exactly one identifier per call (union field). A person with three devices has at least three client IDs. Fix: resolve all identifiers from your CRM/BigQuery before submitting, and submit one call each.
  6. The 13th GA4 deletion request fails. Cause: “a maximum of 12 … active requests per property at any one time.” Fix: batch fields into fewer requests; queue the rest until earlier ones complete.

Quick recipes

GA4 per-user deletion:

ga4-user-deletion.sh
curl -X POST \
"https://analyticsadmin.googleapis.com/v1alpha/properties/123456:submitUserDeletion" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{ "clientId": "123456.7654321" }'
# response: { "deletionRequestTime": "2026-07-20T00:00:00Z" }

BigQuery export sweep for the same person:

bq-dsar-delete.sql
DELETE FROM `project.analytics_123456.events_*`
WHERE user_pseudo_id = '123456.7654321';
DELETE FROM `project.analytics_123456.events_*`
WHERE user_id = 'crm-42';

Find every client ID a known user has touched (device fan-out):

bq-find-ids.sql
SELECT DISTINCT user_pseudo_id
FROM `project.analytics_123456.events_*`
WHERE user_id = 'crm-42';

Sources

Read on 2026-07-19:

Flagged rather than guessed: processing-time guarantees for GA4 submitUserDeletion and for Adobe privacy jobs are not stated in the pages above; the CCPA regulations’ separate acknowledgment-of-receipt timing is not covered here; CMP deletion mechanics vary by vendor. This is an implementation reference, not legal advice.

Changelog

  • — Initial version, verified against GDPR/CCPA texts, Google, and Adobe documentation.

dataLayer

0 events · 0 sent

    • home /
      writing /writing
      guides /guides
      work /#work
      about /about
      colophon /colophon
      toggle analyst mode ctrl+.
      print session receipt /#receipt