DPDP and GDPR Side by Side: Tagging Rules for Indian SaaS
Serving both Indian and EU users? How the DPDP Act and GDPR differ on consent, and what that means for your tag setup.
A SaaS company headquartered in Bengaluru with customers in Pune, Berlin, and Amsterdam has two privacy regimes pointed at the same GTM container. India's Digital Personal Data Protection Act governs the domestic users. GDPR, plus the ePrivacy rules that actually control cookie placement, governs the European ones. Both apply to the same website, often to the same page, sometimes within the same session if someone travels.
Most teams discover this after they've already built for one of them. The usual pattern: GDPR came first because an enterprise customer asked, so there's a banner and a Consent Mode setup tuned for Europe, and then DPDP arrives and someone proposes a second container. Don't do that. One container, one CMP, region-scoped rules, and a consent model that satisfies the stricter requirement on each dimension. What follows is implementation guidance for practitioners, not legal advice, and the specifics of what your organization must do belong to your counsel and your DPO.
Two regimes, one tag stack
The instinct to fork is understandable and wrong. Two containers means two sets of tags, two places to make every future change, and a snippet-level routing decision that has to be right on every page template. You'll get it wrong on a landing page someone built in a hurry, and you won't find out for months.
The workable architecture is one container, one CMP, and rule groups scoped by geography inside the CMP. The container's tags carry consent conditions expressed in Consent Mode's vocabulary. The CMP decides what the consent state is for a given visitor based on where they are. GTM enforces it identically everywhere.
This works because Consent Mode's signals are regime-agnostic. ad_storage means the same thing whether the visitor is in Chennai or Copenhagen. What differs is the default value, whether an affirmative action is required to change it, and what your notice said. All three are CMP configuration, not container configuration.
Where the two laws agree
More than the discourse suggests. Both are consent-forward regimes built on the same basic structure: an individual with rights, an organization accountable for processing, and a requirement that consent be a real choice rather than a formality.
Both require consent that is free, specific, informed, and given by clear affirmative action. Pre-ticked boxes fail under both. A banner where Accept is a bright button and Reject is grey text at the bottom fails the "free" test under both, and regulators in Europe have said so repeatedly.
Both require notice before the processing starts, in language a normal person can read. Both require that withdrawal be possible and that the organization act on it. Both treat children's data as a separate, stricter category. Both hold you responsible for what your processors do, which in tagging terms means the ad platform's behavior is your problem, not theirs.
Practically, this means a well-built GDPR setup gets you most of the way to a DPDP-ready one. The gaps are specific and worth knowing precisely.
Where they meaningfully diverge
The biggest divergence for anyone doing marketing analytics: GDPR gives you legitimate interest as a lawful basis under Article 6(1)(f), subject to a balancing test. DPDP does not have an equivalent. It has a defined set of legitimate uses, and that set is a closed list covering things like data a person voluntarily provided for a specified purpose, employment purposes, medical emergencies, and state functions. There is no general-purpose balancing test you can argue your way into for advertising or behavioural analytics.
Before you conclude GDPR is looser here, remember that legitimate interest was never much help for tagging. The ePrivacy Directive requires consent to store or access information on a user's device, regardless of your Article 6 basis. It might cover what you do with the data after collection; it does not let you drop a cookie without asking. For the specific act of firing a tag that writes storage, both regimes land in the same place.
| Dimension | GDPR (plus ePrivacy) | DPDP | Build for |
|---|---|---|---|
| Basis for analytics or ad storage | Consent, via ePrivacy, regardless of Article 6 basis | Consent; no general legitimate interest equivalent | Consent, both regions |
| Notice | Article 13 disclosures at collection | Itemised notice with the specific personal data and purpose | Itemised, purpose-linked notice |
| Language of notice | Clear and plain language | Option to access the notice in listed Indian languages | Language switcher in the CMP |
| Withdrawal | As easy as giving consent | As easy as giving consent, stated explicitly | Same-click withdrawal, persistent entry point |
| Child threshold | 16, member states may lower to 13 | 18, with verifiable parental consent | The higher bar where you serve both |
| Rights available | Access, rectification, erasure, restriction, portability, objection | Access summary, correction, erasure, grievance redressal, nomination | A process that covers the union of both |
The withdrawal point is the one implementations fail most often. Both regimes say withdrawal must be as easy as the grant. If accepting takes one click on a banner and withdrawing takes finding a link in the footer, opening a preference centre, toggling five categories, and clicking Save, you have failed a requirement that a regulator can test in thirty seconds from a browser.
Fix it with a persistent, visible re-entry point: a small floating control or a footer link that opens the CMP modal directly, with a one-click Reject All inside. Then verify the click actually revokes, by watching for the consent update call with denied values and confirming the cookies clear.
One CMP with geo rule groups
Every serious CMP supports geolocation-driven rule sets, though they use different names for the concept. You define a group of regions, attach a configuration to it, and the CMP resolves a visitor's region server-side or from an IP lookup before rendering.
A structure that covers an Indian SaaS company serving Europe:
- EEA, UK, and Switzerland. Opt-in. Nothing non-essential fires before an affirmative action. Reject All has equal visual weight to Accept All. Full purpose and vendor disclosure.
- India. Opt-in. Notice itemised by purpose, with a language option. Same denied-by-default posture, plus a clearly identified grievance contact.
- Rest of world. Your policy choice, and increasingly the sensible default is to run the same opt-in model everywhere rather than maintain a third behavior.
Two things to get right in the CMP. Set the geolocation source to something reliable: an edge function or CDN header beats a client-side IP lookup, which adds latency and can be wrong behind a VPN. And have the CMP write the same consent signal names regardless of region, so your tags never need to know which regime applied.
Store the consent record with enough detail to be evidence: a timestamp, the regime that applied, the notice version shown, and the per-purpose decision. When someone asks in eighteen months whether a specific user consented to advertising cookies, "our banner was compliant" is not an answer. A record is.
Consent Mode defaults per region
Consent Mode v2 gives you seven signals, and the region parameter lets you declare different defaults for different places in the same snippet. Multiple default calls are allowed; a region-scoped one takes precedence over a global one for visitors in that region.
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
// Global fallback: deny by default everywhere.
gtag('consent', 'default', {
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
analytics_storage: 'denied',
functionality_storage: 'granted',
security_storage: 'granted',
wait_for_update: 500
});
// Region-scoped: same posture, longer wait where the
// notice is longer and decisions take a moment more.
gtag('consent', 'default', {
region: ['IN'],
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
analytics_storage: 'denied',
wait_for_update: 800
});
</script>
Put this above the GTM container snippet in the document head. Below it and tags can fire before the defaults register, which is exactly the failure the whole mechanism exists to prevent.
Then enforce it in the container. Under Admin, Container Settings, enable additional consent checks, and set per-tag consent requirements under each tag's Advanced Settings. A Google Ads conversion tag requires ad_storage and ad_user_data. A GA4 event tag requires analytics_storage. A chat widget or session recorder requires functionality_storage at minimum, and if it records inputs it belongs behind analytics or a dedicated category.
Advanced mode, where tags still load and send cookieless pings under denial, is what makes conversion modeling possible. Whether it's appropriate under both regimes is a question for your counsel, because the ping still transmits data. Have that conversation before you flip the setting.
Children, and why tagging cares
DPDP sets the threshold at eighteen and requires verifiable consent from a parent or lawful guardian below it. It also restricts tracking, behavioural monitoring, and targeted advertising directed at children. GDPR sets the digital services threshold at sixteen, with member states permitted to lower it to thirteen.
For a B2B SaaS product this feels academic until you look at your traffic. Free tools, calculators, templates, and educational content pull in students. If any part of your site plausibly attracts under-eighteens, the tagging consequence is concrete: no behavioural advertising tags, no remarketing audiences, no cross-context profiling for that group.
The mechanism is usually a self-declared age gate on the flows that need it, feeding a data layer value that drives a blocking trigger on advertising tags. It's imperfect, and it's meaningfully better than nothing. Where you genuinely serve minors, the requirement escalates to verifiable parental consent, which is a product problem rather than a tagging one.
Rights requests and your analytics data
A request arrives. Someone wants to know what you hold, or wants it deleted. Your CRM and product database are the obvious targets, and analytics is the one people forget until an auditor asks.
Work through it destination by destination:
- GA4. Admin, then Data Deletion Requests, for property-scoped deletion. For a specific individual, the User Deletion API takes a
userIdor client ID and removes the associated data. Aggregated reports already computed are not recalculated, which is a limitation you should be able to explain rather than one you should hide. - Google Ads. Remove the user from customer match lists, and if you uploaded offline conversions keyed to a hashed identifier, submit the corresponding removal.
- Meta. The Delete User Data endpoint accepts a hashed identifier and removes the associated records.
- Your warehouse. Usually the hardest, because raw event data gets copied into staging tables, dbt models, and analyst extracts. Keep a documented map of where user-level identifiers land, or the deletion will be partial and you won't know it.
- The server-side container's logs. If your tagging server writes request logs with IPs or user IDs, they're in scope. Set a retention window measured in days and stick to it.
Build this map before the first request arrives. GDPR gives you a month to respond, and DPDP expects a response within the timeframe set out in the rules made under it. Neither leaves room for a two-week archaeology project.
One practical shortcut: set GA4 event data retention to the shortest window your reporting can tolerate, under Admin, Data Settings, Data Retention. Data you don't hold is data you don't have to find, export, or delete.
A quarterly audit that proves it
Consent setups decay. Someone adds a tag without a consent condition. A CMP update resets a category mapping. A developer moves the container snippet during a template refactor and the defaults now load after it. None of these announce themselves.
Run this every quarter, region by region, and write down the result with a date and a name attached:
- Open the site in a clean profile with a VPN endpoint in each region you have a rule group for. Record what fires before any interaction, using the network tab filtered to your known endpoints.
- Reject everything. Reload, browse three pages, and confirm no advertising or analytics requests leave the browser. Check for cookies written despite the denial.
- Accept everything. Confirm the expected tags fire and the consent update carries granted values for the right signals.
- Withdraw consent through your persistent entry point. Count the clicks. If it's more than it took to accept, that's a finding.
- Confirm cookies are actually cleared on withdrawal, rather than only the banner state changing.
- Export the container and list every tag with no consent condition. Each one needs a justification or a fix.
- Read the notice text against what the tags actually do. If the banner says analytics only and a remarketing tag fires in that category, the banner is wrong.
Step seven is the one that catches real problems. Categories drift: a tag gets added to "Analytics" because that's where the person putting it in thought it belonged, and now your notice describes something narrower than what's happening.
Keep the evidence
Compliance in tagging is mostly a documentation problem wearing a technical costume. The container will be configured correctly or it won't, and that part is a day's work. What takes discipline is being able to show, months later, what the configuration was, who checked it, and what the user was told at the moment they clicked.
Keep the dated container exports, the consent records with notice versions, and the quarterly audit results in one place your legal team can reach without asking you. Build once for the stricter requirement on each dimension, verify quarterly, and both regimes end up satisfied by the same stack.