2026-04-19·15 min read·

GDPR Art.92–99 Final Provisions: Delegated Acts, ePrivacy Intersection & Entry into Force — Developer Guide (2026)

GDPR Articles 92–99 close the regulation: they grant the Commission power to issue delegated acts (Art.92), establish committee oversight (Art.93), repeal Directive 95/46/EC (Art.94), clarify the ePrivacy relationship (Art.95), honour pre-GDPR adequacy decisions (Art.96), require Commission reports (Art.97–98), and set the 24 May 2016 / 25 May 2018 timeline (Art.99). Understanding these provisions prevents compliance gaps when working with legacy systems, cookie infrastructure, and international data transfers.

Art.92 — Exercise of the Delegation

Art.92 grants the Commission power to adopt delegated acts supplementing the GDPR without returning to the full legislative procedure. The delegation is for a 5-year period from 24 May 2016 (renewable). The European Parliament or Council may revoke at any time.

Which delegated acts are possible under GDPR?

ReferenceSubject
Art.12(8)Standard icons for transparency
Art.43(8)Certification criteria accreditation requirements

In practice very few GDPR delegated acts have been issued — the Commission has relied on implementing acts (Art.93) for specifics like standard contractual clauses.

Developer relevance: Delegated acts have the force of law across the EU without transposition. If the Commission issues new icons (Art.12(8)), your privacy notices must update. Monitor EUR-Lex /legal-content/EN/TXT/?uri=OJ:L:* for delegated act publications.

Art.93 — Committee Procedure

Art.93 establishes examination procedure (Regulation (EU) 182/2011) for implementing acts — formally binding measures issued after a standing committee of Member State representatives votes.

Key implementing acts issued under GDPR:

YearActSubject
2021Commission Decision 2021/914/EUStandard Contractual Clauses (SCCs) for international transfers
2021Commission Implementing Decision 2021/915/EUSCCs controller-processor (Art.28)
2022Commission Implementing Decision 2022/254/EUUK adequacy (Art.45)
2023Commission Decision 2023/1795/EUUS Data Privacy Framework adequacy

Developer relevance: SCCs are implementing acts — legally binding templates you cannot modify substantively. When new SCCs replace old ones (the 2010 SCCs were superseded by the 2021 set), you must migrate DPAs by the stated deadline or face a transfer ban.

from datetime import date, timedelta
from dataclasses import dataclass
from typing import Optional

@dataclass
class SCCVersion:
    id: str
    issued: date
    effective: date
    deprecated_date: Optional[date]
    migration_deadline: Optional[date]

SCC_VERSIONS = [
    SCCVersion(
        id="2010/87/EU-controller-processor",
        issued=date(2010, 2, 5),
        effective=date(2010, 2, 15),
        deprecated_date=date(2021, 6, 27),
        migration_deadline=date(2022, 12, 27),
    ),
    SCCVersion(
        id="2021/914/EU-module-1-4",
        issued=date(2021, 6, 4),
        effective=date(2021, 6, 27),
        deprecated_date=None,
        migration_deadline=None,
    ),
]

def check_scc_compliance(scc_id: str, execution_date: date) -> dict:
    """Check if an SCC version is valid at a given date."""
    version = next((v for v in SCC_VERSIONS if v.id == scc_id), None)
    if not version:
        return {"valid": False, "reason": "Unknown SCC version"}
    
    if version.deprecated_date and execution_date > version.deprecated_date:
        if version.migration_deadline and execution_date > version.migration_deadline:
            return {
                "valid": False,
                "reason": f"Deprecated {version.deprecated_date}, migration deadline {version.migration_deadline} passed",
                "action": "Replace with 2021/914/EU SCCs immediately",
            }
    return {"valid": True, "version": version.id}

Art.94 — Repeal of Directive 95/46/EC

Art.94 formally repeals Directive 95/46/EC (the 1995 Data Protection Directive) with effect from 25 May 2018. References to the repealed Directive in other Union acts are construed as references to the GDPR.

What Directive 95/46 obligations ceased on 25 May 2018:

Obligation (D95/46)GDPR equivalentChange
Notification to DPA (Art.18)NoneRemoved — no more general notification
Prior checking by DPA (Art.20)DPIA (Art.35) + optional DPA consultation (Art.36)Risk-based, not blanket
Sensitive data "express consent" (Art.8)Explicit consent (Art.9(2)(a)) + 10 other basesMore lawful bases available
Safe Harbour (Commission Decision 2000/520/EU)Invalidated by Schrems I (2015), replaced by Privacy Shield (2016) → DPF (2023)Multiple changes

Legacy system audit pattern: If you inherited a system built before 2018, check for:

from enum import Enum

class LegacyRisk(Enum):
    NOTIFICATION_REGISTER = "DPA notification register — may still exist in old docs, no longer required"
    PRIOR_CHECKING = "Prior checking approval — no longer valid basis, replace with DPIA"
    SAFE_HARBOUR = "Safe Harbour transfer mechanism — invalid since 2015"
    PRIVACY_SHIELD = "Privacy Shield — invalid since Schrems II (2020)"
    CONSENT_BOXES_AMBIGUOUS = "Pre-ticked consent boxes — valid under D95/46, invalid under GDPR"
    PAPER_DSAR = "Paper-only DSAR process — GDPR requires response within 1 month, not 40 days"
    SENSITIVE_DATA_CONDITIONS = "Directive-era sensitive data conditions — verify against GDPR Art.9"

LEGACY_AUDIT_CHECKLIST = {
    "documentation": [
        "Old DPA registration certificates → archive only, delete DPA numbers from production systems",
        "Prior checking approvals → replace with DPIA documentation",
        "Consent forms without withdrawal mechanism → reissue",
    ],
    "technical": [
        "Transfer mechanisms → verify no Safe Harbour or Privacy Shield references in DPAs",
        "Consent records < 2018 → validity depends on method; audit samples",
        "Response time SLAs → update from 40-day to 1-month/30-day (GDPR Art.12(3))",
    ],
    "contractual": [
        "DPAs referencing D95/46 Art.17 → update to GDPR Art.28 template",
        "Old national law references (BDSG 2001, DPA 1998 UK) → check for superseded versions",
    ],
}

def audit_legacy_system(system_created_year: int) -> list[str]:
    """Generate legacy audit tasks for systems predating GDPR."""
    if system_created_year >= 2018:
        return []
    tasks = []
    if system_created_year < 2016:
        tasks.extend(LEGACY_AUDIT_CHECKLIST["documentation"])
    tasks.extend(LEGACY_AUDIT_CHECKLIST["technical"])
    tasks.extend(LEGACY_AUDIT_CHECKLIST["contractual"])
    return tasks

Art.95 — Relationship with Directive 2002/58/EC (ePrivacy)

Art.95 establishes that GDPR does not impose additional obligations on natural or legal persons where they are already subject to specific obligations with the same objective under Directive 2002/58/EC (ePrivacy Directive, also called "Cookie Directive"). This is the lex specialis rule.

The ePrivacy / GDPR layering:

ePrivacy Directive 2002/58/EC (national implementations)
├── Applies to: electronic communications — telecom operators, ISPs, OTT services
├── Specifically governs:
│   ├── Confidentiality of communications (Art.5)
│   ├── Traffic data retention and processing (Art.6)
│   ├── Location data (Art.9)
│   ├── Cookies and device access (Art.5(3))  ← KEY for web developers
│   ├── Spam/unsolicited commercial comms (Art.13)
│   └── Calling line identification (Art.8)
└── Lex specialis over GDPR for these topics WHERE obligations overlap

GDPR Regulation 2016/679
├── Applies to: all processing of personal data
├── Governs everything ePrivacy does NOT specifically cover
└── ePrivacy = Directive → national implementation varies (PECR UK, TTDSG DE, etc.)

The cookie consent question:

Cookie consent under Art.5(3) ePrivacy is governed by national ePrivacy law, not GDPR directly. However:

from dataclasses import dataclass

@dataclass
class CookieAnalysis:
    name: str
    vendor: str
    accesses_device: bool      # Triggers ePrivacy Art.5(3)
    processes_personal_data: bool  # Triggers GDPR
    category: str              # "strictly_necessary" | "functional" | "analytics" | "marketing"

def get_required_consent(cookie: CookieAnalysis) -> dict:
    """Determine which consent mechanisms are required."""
    result = {
        "eprivacy_consent_required": False,
        "gdpr_lawful_basis_required": False,
        "notes": [],
    }
    
    if cookie.accesses_device:
        if cookie.category == "strictly_necessary":
            result["notes"].append(
                "ePrivacy: strictly necessary exemption applies (Art.5(3) — 'sole purpose of carrying out transmission' or 'strictly necessary for service explicitly requested')"
            )
        else:
            result["eprivacy_consent_required"] = True
            result["notes"].append(
                "ePrivacy: prior consent required before setting cookie or accessing stored information"
            )
    
    if cookie.processes_personal_data:
        if cookie.category == "marketing":
            result["gdpr_lawful_basis_required"] = True
            result["notes"].append(
                "GDPR Art.6(1)(a): consent required — profiling/marketing cannot rely on legitimate interests (EDPB Guidelines 8/2020)"
            )
        elif cookie.category == "analytics":
            result["gdpr_lawful_basis_required"] = True
            result["notes"].append(
                "GDPR: legitimate interests possible for privacy-preserving analytics (Art.6(1)(f)) — document DPIA balancing test"
            )
    
    return result

# Examples
ga4 = CookieAnalysis("_ga", "Google Analytics 4", accesses_device=True, processes_personal_data=True, category="analytics")
session = CookieAnalysis("session_id", "own", accesses_device=True, processes_personal_data=True, category="strictly_necessary")

print(get_required_consent(ga4))
# {'eprivacy_consent_required': True, 'gdpr_lawful_basis_required': True, ...}
print(get_required_consent(session))
# {'eprivacy_consent_required': False, 'gdpr_lawful_basis_required': False, 'notes': ['ePrivacy: strictly necessary exemption...']}

National ePrivacy implementations that matter:

CountryNational lawNotable rule
GermanyTTDSG (2021)§25 = Art.5(3) implementation, stricter than many
FranceCNIL Guidelines (2020)Cookie walls generally prohibited
UKPECR (2003, amended)Now diverges post-Brexit; ICO guidance
NetherlandsTelecommunications ActCookie wall prohibition since 2012
SpainLSSICE + AEPD guidanceImplied consent rejected
ItalyGarante 2021 guidelinesCookie walls require genuine alternative

Coming: ePrivacy Regulation (proposed 2017, still not adopted as of 2026): would replace the Directive with a directly applicable Regulation, harmonising cookie rules across the EU. Until adopted, national divergence continues.

Art.96 — Relationship with Previously Concluded Agreements

Art.96 provides that international agreements concluded by Member States before the entry into force of GDPR (24 May 2016) remain valid, and Commission adequacy decisions adopted under Directive 95/46 remain in force until amended, replaced, or repealed.

Pre-GDPR adequacy decisions that carried over:

CountryD95/46 DecisionStatus under GDPR
Switzerland2000/518/ECCarried over; Commission announced new adequacy 2024
Canada (PIPEDA)2002/2/ECCarried over; PIPEDA modernisation in progress
Argentina2003/490/ECCarried over; under review
Guernsey2003/821/ECCarried over
Isle of Man2004/411/ECCarried over
Jersey2008/393/ECCarried over
Faroe Islands2010/146/EUCarried over
Andorra2010/625/EUCarried over
Israel2011/61/EUCarried over; under review
Uruguay2012/484/EUCarried over
New Zealand2013/65/EUCarried over

Commission adequacy decisions adopted under GDPR Art.45 (not Art.96 carry-over):

from datetime import date
from typing import Optional
from dataclasses import dataclass

@dataclass  
class AdequacyDecision:
    country: str
    decision_id: str
    basis: str  # "D95/46" or "GDPR_Art45"
    valid_from: date
    valid_until: Optional[date]
    notes: str

def is_transfer_adequate(country: str) -> dict:
    """Check if a country has a current adequacy decision for EU personal data transfers."""
    adequate_countries = {
        "CH": AdequacyDecision("Switzerland", "2000/518/EC", "D95/46", date(2000, 7, 26), None, "Renewed 2024"),
        "CA": AdequacyDecision("Canada", "2002/2/EC", "D95/46", date(2002, 1, 4), None, "PIPEDA only; private sector"),
        "AR": AdequacyDecision("Argentina", "2003/490/EC", "D95/46", date(2003, 7, 3), None, "Under review"),
        "GB": AdequacyDecision("UK", "2021/1772/EU", "GDPR_Art45", date(2021, 6, 28), date(2025, 6, 27), "4-year sunset, renewal decision pending"),
        "KR": AdequacyDecision("South Korea", "2021/1179/EU", "GDPR_Art45", date(2021, 12, 17), None, "PIPC framework"),
        "US": AdequacyDecision("USA", "2023/1795/EU", "GDPR_Art45", date(2023, 7, 10), None, "DPF — certified companies only; Schrems III pending"),
        "IL": AdequacyDecision("Israel", "2011/61/EU", "D95/46", date(2011, 1, 31), None, "Under review"),
        "NZ": AdequacyDecision("New Zealand", "2013/65/EU", "D95/46", date(2013, 1, 10), None, "Under review"),
        "JP": AdequacyDecision("Japan", "2019/419/EU", "GDPR_Art45", date(2019, 1, 23), None, "APPI amendment assessment"),
    }
    
    decision = adequate_countries.get(country)
    if not decision:
        return {"adequate": False, "action": "Use SCCs or BCRs — no adequacy decision"}
    
    today = date.today()
    if decision.valid_until and today > decision.valid_until:
        return {"adequate": False, "reason": f"Adequacy expired {decision.valid_until}", "action": "Check for renewal decision; use SCCs as fallback"}
    
    return {
        "adequate": True,
        "decision": decision.decision_id,
        "notes": decision.notes,
    }

# Practical: check before routing personal data
for country in ["US", "CH", "AU", "IN", "BR"]:
    print(f"{country}: {is_transfer_adequate(country)}")

Key developer note on US/DPF: The DPF only covers certified companies. Before transferring personal data to a US vendor, verify they are on the DPF certification list. The DPF has also been challenged (Schrems III was filed in 2023). Maintain SCC fallback clauses in all US-vendor DPAs.

Art.97 — Commission Reports

Art.97 requires the Commission to submit reports to the European Parliament and Council every 4 years on the evaluation and review of the GDPR, covering:

Reports issued:

Developer relevance: Reports flag upcoming changes. The 2020 report flagged certification (Art.42) as underused — subsequent SA certification schemes followed. The 2024 report flagged AI Act / GDPR alignment — watch for Commission guidance on LLM training data, automated decision-making under Art.22, and biometrics.

Art.98 requires the Commission to review all other Union acts protecting personal data and to propose legislative amendments where necessary.

Acts reviewed and updated post-GDPR:

Acts with GDPR intersection that developers encounter:

ActWhat it governsIntersection with GDPR
AI Act (2024)High-risk AI systemsArt.22 automated decisions + profiling; DPIA required for Art.35 AI systems
Digital Markets Act (2022)Gatekeeper platformsDMA consent rules layer on top of GDPR consent
NIS2 Directive (2022)Cybersecurity incident reportingSimultaneous GDPR Art.33 + NIS2 incident notification
Digital Services Act (2022)Online platforms contentRisk assessments complement DPIAs
Data Act (2023)Non-personal IoT dataIntersection where IoT data can become personal
Data Governance Act (2022)Data intermediaries, sharingConsent for data altruism (Art.2(16) GA) complements GDPR consent
from dataclasses import dataclass
from typing import Optional

@dataclass
class EUActIntersection:
    act: str
    applies_to: str
    gdpr_articles_affected: list[str]
    compliance_note: str

EU_ACT_MATRIX = [
    EUActIntersection(
        act="AI Act 2024",
        applies_to="High-risk AI systems (Annex III)",
        gdpr_articles_affected=["Art.22", "Art.35"],
        compliance_note="DPIA required before deploying high-risk AI; automated decisions under Art.22 need human review mechanism",
    ),
    EUActIntersection(
        act="NIS2 2022/2555",
        applies_to="Essential/important entities (energy, health, digital infra)",
        gdpr_articles_affected=["Art.33", "Art.34"],
        compliance_note="Dual notification: NIS2 24h early warning + GDPR 72h breach notification — draft joint notification template",
    ),
    EUActIntersection(
        act="DMA 2022/1925",
        applies_to="Gatekeeper platforms (€7.5B+ turnover, 45M+ EU users)",
        gdpr_articles_affected=["Art.6", "Art.7"],
        compliance_note="DMA Art.5(2) bans combining data across services without explicit consent — stricter than GDPR legitimate interests",
    ),
    EUActIntersection(
        act="Data Act 2023",
        applies_to="Connected device manufacturers, related services",
        gdpr_articles_affected=["Art.4(1)", "Art.89"],
        compliance_note="IoT-generated data that relates to an identified person = personal data; GDPR applies",
    ),
]

def get_compliance_stack(system_type: str) -> list[EUActIntersection]:
    """Get applicable EU act intersections for a given system type."""
    mapping = {
        "ai_recommendation": ["AI Act 2024", "DMA 2022/1925"],
        "iot_device": ["Data Act 2023", "NIS2 2022/2555"],
        "platform": ["DMA 2022/1925", "DSA 2022/2065"],
        "saas_b2b": ["NIS2 2022/2555"],
    }
    act_names = mapping.get(system_type, [])
    return [a for a in EU_ACT_MATRIX if a.act in act_names]

Art.99 — Entry into Force and Application

Art.99 is the final article. It establishes two key dates:

DateEvent
24 May 2016Entry into force (20 days after publication in OJ L 119, 4 May 2016)
25 May 2018Application (2-year transition period; Art.99(2))

The 2-year window (May 2016–May 2018) gave organisations time to:

  1. Map all personal data processing (Art.30 records)
  2. Implement consent mechanisms (Art.7)
  3. Update privacy notices (Art.13/14)
  4. Appoint DPOs where required (Art.37)
  5. Establish breach notification procedures (Art.33/34)
  6. Update processor contracts (Art.28)
  7. Implement privacy by design (Art.25)

The May 25, 2018 cliff: Organisations that had relied on "legitimate interests" under D95/46 had to re-document their lawful basis under GDPR's specific Art.6(1) framework. A simple D95/46 "processing is necessary for our business" was insufficient; Art.6(1)(f) requires a documented balancing test.

from datetime import date, timedelta

GDPR_ENTRY_INTO_FORCE = date(2016, 5, 24)
GDPR_APPLICATION = date(2018, 5, 25)

class GDPRTimeline:
    """Timeline reference for GDPR compliance planning."""
    
    @staticmethod
    def years_in_force() -> float:
        """How many years GDPR has been in force."""
        return (date.today() - GDPR_APPLICATION).days / 365.25
    
    @staticmethod
    def was_compliant_by_application(implementation_date: date) -> bool:
        return implementation_date <= GDPR_APPLICATION
    
    @staticmethod
    def data_collected_pre_gdpr_requires_review(collection_date: date) -> bool:
        """Data collected before GDPR application needs lawful basis review."""
        return collection_date < GDPR_APPLICATION
    
    @staticmethod
    def consent_collected_pre_gdpr_valid(consent_date: date, method: str) -> dict:
        """
        Assess whether pre-GDPR consent is still valid.
        
        Under GDPR recital 171: pre-GDPR consent that meets GDPR standards remains valid.
        Consent that was merely "opt-out" or based on pre-ticked boxes is invalid.
        """
        if consent_date >= GDPR_APPLICATION:
            return {"valid": True, "basis": "Collected under GDPR"}
        
        valid_methods = ["double_opt_in", "explicit_opt_in_clear_purpose"]
        if method in valid_methods:
            return {
                "valid": True,
                "basis": "Pre-GDPR consent valid if it meets GDPR standard (Recital 171)",
                "action": "Document that consent method meets Art.7 standard; retain proof",
            }
        return {
            "valid": False,
            "basis": "Pre-GDPR consent method insufficient",
            "action": "Re-request consent under GDPR standard or establish alternative lawful basis",
        }

# Audit pre-GDPR user database
timeline = GDPRTimeline()
print(f"GDPR in application for: {timeline.years_in_force():.1f} years")

old_newsletter_signup = date(2016, 3, 15)
method = "pre_ticked_box"
print(timeline.consent_collected_pre_gdpr_valid(old_newsletter_signup, method))
# valid: False — must re-request

Full GDPR Chapter Overview: What's Where

With Art.99, the GDPR closes. Here is a developer-oriented map:

ChapterArticlesCore topicKey developer obligation
I1–4Scope + definitionsIs your system in scope? "Personal data" definition
II5–11Principles + lawful basisArt.5 principles, Art.6 lawful basis
III12–23Data subject rightsDSAR handling, Art.17 erasure, Art.20 portability
IV24–43Controller/ProcessorDPO (Art.37), DPIA (Art.35), PbD (Art.25), DPA (Art.28)
V44–49International transfersSCCs, adequacy, BCRs, derogations
VI50–59SA independence/tasksOne-stop-shop, Art.55 competence
VII60–76SA cooperation/EDPBArt.60 cooperation, Art.65 binding decisions
VIII77–84Remedies + finesArt.83 tiered fines (2%/4%), Art.82 compensation
IX85–91Special situationsJournalism, employment, religious orgs
X92–99Final provisionsePrivacy Art.95, transition Art.94, Art.99 timeline

sota.io Positioning: EU-Only Stack Simplifies This

Art.95 ePrivacy complexity illustrates why infrastructure jurisdiction matters. With a US-based PaaS:

With sota.io's German-hosted infrastructure:

GDPR Compliance Checklist — Art.92-99 Final Provisions

See Also