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 |
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
- Verify identity — before touching any system; keep verification data solely for that purpose.
- Start the clock — log the receipt date; GDPR gives one month, CCPA 45 days.
- Resolve identifiers — from the map above: cookies named in the request, CRM lookup for email → User-ID/CRM ID, ECID if supplied.
- Submit per system — GA4
submitUserDeletionper identifier; one Adobe privacy job covering all products ininclude. - Sweep your own stores — BigQuery export, sGTM logs, data warehouse copies. No vendor API reaches these.
- Record completion — job IDs,
deletionRequestTime, SQL run, dates — this is your accountability evidence.
Gotchas
- Deleting the cookie deletes nothing. Cause: the
_gaorkndctrcookie 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. - 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. - Adobe delete job returns complete, data still visible. Cause: the
variables holding personal data carry no
DEL-DEVICE/DEL-PERSONlabels, 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. - 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.
- 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.
- 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:
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:
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):
SELECT DISTINCT user_pseudo_idFROM `project.analytics_123456.events_*`WHERE user_id = 'crm-42';Related
- Hub: Privacy & consent guides
- Consent Mode v2 reference
- GA4 limits reference card (retention settings)
Sources
Read on 2026-07-19:
- GDPR Art. 12 (Regulation (EU) 2016/679; deadlines and fees)
- California AG — CCPA (45-day deadline, verification)
- GA4 data-deletion requests
- Admin API submitUserDeletion
- Google Analytics cookies
- Privacy Service jobs API
- Privacy Service appendix — product values
- Adobe Analytics privacy labels
- Adobe Analytics privacy workflow
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.