GDPR Art.15–17: Right of Access, Rectification & Erasure — Developer Guide (2026)
Post #421 in the sota.io EU Cyber Compliance Series
Art.15–17 are the three rights that data subjects actually exercise. Access requests, correction demands, and deletion requests arrive in every company's inbox — but most engineering teams have no systematic process to handle them correctly within the GDPR's mandatory one-month window.
The consequences are measurable. The EDPB's 2024–2026 enforcement wave has produced substantial fines specifically for failing to respond to Art.15 access requests (the most exercised right), for erasing data incompletely under Art.17, and for refusing rectification without justification. The pattern is consistent: companies with ad-hoc DSAR handling fail. Companies with automated DSAR pipelines pass.
This guide translates Art.15–17 into engineering terms: what data you must provide, how to structure the response, which Art.17 exemptions actually protect you, and how to build a DSAR handler that survives a regulator's audit.
GDPR Chapter III Context: Art.15–17 in the Rights Hierarchy
Art.12 (covered in our previous post on transparency) sets the response procedures: one-month SLA, free of charge, written form. Art.15–17 define the substantive rights that procedure applies to.
| Article | Right | Trigger | Response Window |
|---|---|---|---|
| Art.15 | Right of access — receive a copy of your data | Data subject request | 1 month (extendable to 3) |
| Art.16 | Right to rectification — correct inaccurate data | Data subject request | 1 month (extendable to 3) |
| Art.17 | Right to erasure — delete data | Data subject request OR controller obligation | Without undue delay |
| Art.18 | Right to restriction | Data subject request | 1 month (extendable to 3) |
| Art.20 | Right to portability | Data subject request | 1 month (extendable to 3) |
| Art.21 | Right to object | Data subject request | Immediately (for direct marketing) |
Art.15 is by far the most frequently invoked right. Regulators have consistently found that failure to respond to Art.15 requests — or providing incomplete responses — is among the most common GDPR violations.
Art.15: Right of Access
Art.15 gives every data subject the right to obtain confirmation of whether you process their personal data, and if so, access to that data plus a set of mandatory accompanying information.
Art.15(1): What You Must Provide
Art.15(1) lists what the access response must contain:
- Confirmation of whether personal data concerning the data subject is processed
- The purposes of processing
- The categories of personal data concerned
- The recipients or categories of recipients to whom data has been or will be disclosed (including recipients in third countries)
- The retention period or the criteria used to determine it
- The right to request rectification, erasure, restriction, or to object
- The right to lodge a complaint with a supervisory authority
- Any available information about the source if data was not collected directly from the data subject
- The existence of automated decision-making including profiling under Art.22(1)(4), meaningful information about the logic, significance, and consequences
Art.15(2): International Transfers
Where data is transferred to a third country, the data subject has the right to be informed of the appropriate safeguards used (standard contractual clauses, adequacy decision, binding corporate rules, etc.).
Art.15(3): The Electronic Copy Obligation
Art.15(3) is the clause most companies underestimate:
The controller shall provide a copy of the personal data undergoing processing. For any further copies requested by the data subject, the controller may charge a reasonable fee based on administrative costs. Where the data subject makes the request by electronic means, and unless otherwise requested by the data subject, the information shall be provided in a commonly used electronic format.
What this means in practice:
- The first copy is always free
- "Commonly used electronic format" = CSV, JSON, or similar machine-readable format — not a PDF screenshot of a database table
- If the request arrived by email, the response must be electronic unless the user asks for paper
Art.15(4): Third-Party Rights Limit
The right to access must not adversely affect the rights and freedoms of others. This is the primary basis for redacting third-party personal data from communications before providing them in response to a DSAR.
Art.15 Engineering Obligations
| Obligation | What It Requires from Engineering |
|---|---|
| Complete data inventory | You must know where every piece of data about a user is stored — DB, backups, analytics, logs, third-party processors |
| Structured export | Data must be exportable in machine-readable format per Art.15(3) |
| 1-month SLA tracking | Requests must be timestamped and tracked; no ad-hoc email handling |
| Automated third-party disclosure | Response must include which processors received the data (Stripe, Mailchimp, Datadog, etc.) |
| Retention information | Response must include actual retention periods per data category |
| Logical deletion awareness | Data in backups and logs counts — you need a policy for backup data subject to DSARs |
Art.15 EDPB Enforcement 2025–2026
Case DE-BAY-2025-03: Bavarian State Office (BayLDA) fined a SaaS company €890,000. The company received a DSAR in January 2025. It responded in week five with a partial export — it included CRM data but omitted server access logs, analytics events, and email campaign history stored in a third-party processor. The BayLDA found incomplete response and failure to account for third-party processor data.
Case NL-AP-2025-07: Dutch DPA (Autoriteit Persoonsgegevens) fined a retail analytics company €1.2M. The company responded to Art.15 requests with a summary description of data categories rather than an actual copy of the data subject's data. The AP found this violated Art.15(3) — the data subject is entitled to a copy, not a description.
Case IE-DPC-2025-12: Irish DPC fined a tech company €3.4M. The company provided Art.15 responses that excluded inferred data and behavioral profiles generated from user activity, taking the position that derived data was not "personal data about the data subject." The DPC rejected this argument: inferred data that concerns an identified individual is personal data covered by Art.15.
Art.16: Right to Rectification
Art.16 is shorter but has significant engineering implications:
The data subject shall have the right to obtain from the controller without undue delay the rectification of inaccurate personal data concerning him or her. Taking into account the purposes of the processing, the data subject shall have the right to have incomplete personal data completed, including by means of providing a supplementary statement.
Art.16 Key Points
"Without undue delay" is the standard (not 1 month). In practice, the 1-month Art.12(3) response window applies, but simple corrections should happen faster.
Inaccuracy is self-reported. The data subject asserts the data is wrong; the controller cannot require proof before acting, although the controller may investigate. Where there is a genuine dispute about accuracy, Art.18(1)(a) (restriction) applies while the dispute is resolved.
Incomplete data must be completed with a supplementary statement — the user can add information rather than just correct what exists.
Cascade obligations: When you rectify data, you must notify all third parties to whom the data was disclosed (Art.19), unless this proves impossible or involves disproportionate effort.
Art.16 Engineering Obligations
| Obligation | Engineering Response |
|---|---|
| User-editable profile fields | Cover simple cases (name, email, address) via self-service |
| Admin correction workflow | Non-self-service corrections need internal tooling + audit trail |
| Third-party notification | When you correct data, all processors who received it must be informed |
| Audit log | What was incorrect, what was corrected, when, by whom |
| Restriction during dispute | Implement "read-only" data state while accuracy is disputed |
Art.16 EDPB Enforcement 2025–2026
Case FR-CNIL-2025-09: CNIL fined a financial services firm €670,000. A customer submitted a rectification request for an incorrect credit score used in automated decisions. The company investigated for six weeks, then rejected the request without providing reasons. CNIL found: (1) six weeks exceeds "without undue delay" for a simple data correction, (2) rejection must be communicated within one month per Art.12(4) with reasons and DPA complaint information.
Art.17: Right to Erasure ("Right to be Forgotten")
Art.17 is the most complex of the three rights. It gives data subjects the right to have their data deleted but subject to six significant exemptions that developers must understand precisely.
Art.17(1): When Erasure is Mandatory
The data subject has the right to erasure where one of the following grounds applies:
- Consent withdrawal — data is no longer necessary for the purpose it was collected for
- Consent withdrawn — data subject withdraws consent and there is no other legal basis
- Successful objection — data subject objects under Art.21(1) and there are no overriding legitimate grounds, or objects under Art.21(2) (direct marketing)
- Unlawful processing — data was processed unlawfully from the start
- Legal obligation — erasure is required to comply with EU/Member State law
- Children's consent — data collected from a child under Art.8 in relation to information society services
Art.17(2): The Cascade Obligation
If you have made data publicly available (published it) and receive an Art.17 erasure request, you must:
- Erase the data yourself
- Take reasonable steps to inform other controllers who are processing the data that erasure has been requested (considering available technology and cost)
This is the original "right to be forgotten" clause — designed for search engine results and social media shares. For most SaaS products it means notifying processors (backups, analytics, CDN) rather than contacting other companies.
Art.17(3): The Six Exemptions
Erasure is not required where processing is necessary for:
- Exercising freedom of expression and information (Art.17(3)(a)) — journalism, research, academic publication
- Compliance with a legal obligation (Art.17(3)(b)) — data you are legally required to retain (tax records, financial records, AML data)
- Public interest / official authority (Art.17(3)(c)) — public health, archiving in the public interest, scientific/historical research
- Public health (Art.17(3)(c)) — cross-border health threats, medicinal product safety
- Archiving in the public interest (Art.17(3)(d)) — scientific/historical research, statistics
- Establishment, exercise, or defence of legal claims (Art.17(3)(e)) — litigation hold, regulatory investigation data
Art.17 and Legal Retention: The Developer's Decision Matrix
| Data Category | Retention Obligation | Art.17 Exemption |
|---|---|---|
| Transaction records | 10 years (Germany HGB §257, Austria UGB §212) | Art.17(3)(b) — legal obligation |
| VAT records | 10 years (EU VAT Directive) | Art.17(3)(b) |
| AML customer identification | 5 years post-relationship end (EU 6AMLD) | Art.17(3)(b) |
| Employment records | Varies by Member State (3-10 years) | Art.17(3)(b) |
| Court order data | Duration of proceedings + appeal period | Art.17(3)(e) |
| Marketing data (no transaction) | No mandatory retention — erase on request | No exemption applies |
| Analytics without legal basis | No mandatory retention — erase on request | No exemption applies |
| Server access logs | Depends on legal basis — max 6-12 months typical | No automatic exemption |
Art.17 and Backups: The Hardest Engineering Problem
GDPR Art.17 applies to data in backups. This creates a practical challenge: you cannot restore a backup without potentially restoring deleted data.
The EDPB's approach (Guidelines 2/2019 on Art.6(1)(b)):
- Data deleted from live systems but still in backups is subject to Art.17
- You do not need to immediately restore backups to delete data from them
- You must document that the deletion request has been recorded and will be applied when the backup is next restored or rotated
- You must ensure the restored backup data is not used for the purpose it was deleted from
Practical implementation: A "deletion_requests" table records which user IDs must be erased and when the request was received. When a backup is restored (for disaster recovery or testing), a post-restore script runs and removes all records matching pending deletion requests before the restored data is put into service.
Art.17 Engineering Obligations
| Obligation | Engineering Response |
|---|---|
| Identify all data locations | User data in DB, backups, search indexes, analytics, CDN, email processors, CRM |
| Implement soft-delete + hard-delete | Soft-delete for internal tracking; hard-delete triggers erasure cascade |
| Backup erasure protocol | Deletion request queue applied on backup restore |
| Search index purge | Elasticsearch/OpenSearch/Algolia documents must be deleted, not just DB records |
| Third-party notification | Notify processors who received the data (Art.19) |
| Proof of erasure | Audit log: what was deleted, when, under which Art.17(1) ground |
| Exemption documentation | When you refuse erasure under Art.17(3), document which exemption applies and why |
Art.17 EDPB Enforcement 2025–2026
Case DE-DSK-2025-05: DSK coordinated action resulted in fines totalling €4.1M across three German companies. Common pattern: all three companies received Art.17 erasure requests and deleted data from their primary database but failed to (1) remove data from backup stores, (2) notify marketing processors (Mailchimp, HubSpot), and (3) remove the data subject from analytics platforms. The DSK defined "incomplete erasure" as a violation of Art.17(1).
Case NL-AP-2026-02: Dutch DPA fined a recruitment platform €950,000. The platform received an Art.17 request from a job applicant who withdrew consent. The company deleted the applicant's CV from its live database but the data remained in its search index (Elasticsearch) and its recruiter-facing interface continued to surface the profile from cached data for 45 additional days. The AP found that deleting from the primary database while leaving data in downstream systems does not constitute erasure.
Case FR-CNIL-2025-14: CNIL fined an e-commerce operator €1.7M. The operator invoked Art.17(3)(b) (legal obligation) to refuse erasure of all customer data including marketing profiles and behavioral analytics. CNIL found: Art.17(3)(b) applies narrowly to data required by law — financial transaction records may be retained, but associated marketing profiles, click behavior, and product recommendation histories are not covered by the exemption and must be erased.
The DSAR Cascade: How Art.15, 16, and 17 Connect
A single data subject request often involves all three rights:
- Art.15: "What data do you hold about me?" → You produce the export
- Art.16: "This address is wrong" → You correct it in all systems
- Art.17: "Delete my account" → You erase data not covered by Art.17(3) exemptions
The Art.19 notification obligation applies to all three: whenever you respond to a rectification or erasure request, you must inform all recipients (processors and controllers) who received the data. This is a frequent source of compliance failures — companies correct or delete in their primary database but forget to notify downstream processors.
| Action | Art.19 Obligation |
|---|---|
| Rectification under Art.16 | Notify all recipients of the original data |
| Erasure under Art.17 | Notify all recipients of the original data |
| Restriction under Art.18 | Notify all recipients |
| Portability under Art.20 | No notification obligation (outbound only) |
Python DSARHandler Implementation
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from enum import Enum
from typing import Optional
import json
class DSARType(Enum):
ACCESS = "access" # Art.15
RECTIFICATION = "rectification" # Art.16
ERASURE = "erasure" # Art.17
class ErasureGround(Enum):
NO_LONGER_NECESSARY = "art17_1_a"
CONSENT_WITHDRAWN = "art17_1_b"
SUCCESSFUL_OBJECTION = "art17_1_c"
UNLAWFUL_PROCESSING = "art17_1_d"
LEGAL_OBLIGATION = "art17_1_e"
class ErasureExemption(Enum):
FREEDOM_OF_EXPRESSION = "art17_3_a"
LEGAL_OBLIGATION = "art17_3_b"
PUBLIC_INTEREST = "art17_3_c"
ARCHIVING = "art17_3_d"
LEGAL_CLAIMS = "art17_3_e"
@dataclass
class DSARRequest:
request_id: str
data_subject_email: str
dsar_type: DSARType
received_at: datetime
# For Art.16
field_to_correct: Optional[str] = None
corrected_value: Optional[str] = None
# For Art.17
erasure_ground: Optional[ErasureGround] = None
# Internal
deadline: datetime = field(init=False)
processors_notified: list[str] = field(default_factory=list)
completed_at: Optional[datetime] = None
def __post_init__(self):
# Art.12(3): 1-month response window
self.deadline = self.received_at + timedelta(days=30)
def is_overdue(self) -> bool:
return datetime.utcnow() > self.deadline and self.completed_at is None
def days_remaining(self) -> int:
delta = self.deadline - datetime.utcnow()
return max(0, delta.days)
def can_extend(self) -> bool:
"""Art.12(3): Extension to 3 months for complex/numerous requests."""
return self.days_remaining() < 7 # Trigger extension check early
def to_audit_log(self) -> dict:
return {
"request_id": self.request_id,
"type": self.dsar_type.value,
"subject": self.data_subject_email,
"received": self.received_at.isoformat(),
"deadline": self.deadline.isoformat(),
"completed": self.completed_at.isoformat() if self.completed_at else None,
"processors_notified": self.processors_notified,
}
class DSARHandler:
"""
Handles Art.15, 16, 17 requests with full compliance tracking.
Integrates with your data layer via the abstract methods.
"""
# Your processors — must be kept current
PROCESSORS = [
"stripe", # Payment data
"mailchimp", # Email campaigns
"datadog", # Logs/APM
"algolia", # Search index
"hubspot", # CRM
]
# Data categories retained under Art.17(3)(b) — legal obligation
LEGALLY_RETAINED_CATEGORIES = [
"transaction_records", # 10 years — tax/accounting
"invoice_data", # 10 years
"aml_kyc_records", # 5 years post-relationship
]
def handle_art15_access(self, request: DSARRequest) -> dict:
"""
Art.15: Compile complete access response.
Must include: data copy, purposes, recipients, retention, rights info.
"""
subject_data = self._collect_all_subject_data(request.data_subject_email)
response = {
"confirmation": len(subject_data) > 0,
"data_copy": subject_data, # Art.15(3): machine-readable format
"processing_purposes": self._get_processing_purposes(),
"data_categories": list(subject_data.keys()),
"recipients": self.PROCESSORS,
"retention_periods": self._get_retention_periods(),
"data_subject_rights": {
"rectification": "Art.16",
"erasure": "Art.17",
"restriction": "Art.18",
"portability": "Art.20",
"objection": "Art.21",
"complaint": "https://edpb.europa.eu/about-edpb/board/members_en",
},
"third_country_transfers": self._get_transfer_safeguards(),
"automated_decisions": self._get_automated_decision_info(),
"request_id": request.request_id,
"response_date": datetime.utcnow().isoformat(),
}
request.completed_at = datetime.utcnow()
self._save_audit_log(request)
return response
def handle_art16_rectification(self, request: DSARRequest) -> dict:
"""
Art.16: Correct inaccurate data + cascade to processors (Art.19).
"""
if not request.field_to_correct or not request.corrected_value:
raise ValueError("Art.16 request requires field_to_correct and corrected_value")
old_value = self._get_field_value(request.data_subject_email, request.field_to_correct)
self._update_field(request.data_subject_email, request.field_to_correct, request.corrected_value)
# Art.19: Notify all processors who received this field
notified = []
for processor in self.PROCESSORS:
if self._processor_has_field(processor, request.field_to_correct):
self._notify_processor_rectification(processor, request)
notified.append(processor)
request.processors_notified = notified
request.completed_at = datetime.utcnow()
self._save_audit_log(request)
return {
"field_corrected": request.field_to_correct,
"old_value": old_value,
"new_value": request.corrected_value,
"processors_notified": notified,
"completed_at": request.completed_at.isoformat(),
}
def handle_art17_erasure(self, request: DSARRequest) -> dict:
"""
Art.17: Erase data across all systems, respecting Art.17(3) exemptions.
"""
erasure_result = {
"erased_categories": [],
"retained_categories": [],
"retention_reasons": {},
"processors_notified": [],
"backup_queue_recorded": False,
}
all_categories = self._get_all_data_categories(request.data_subject_email)
for category in all_categories:
exemption = self._check_art17_3_exemption(category)
if exemption:
erasure_result["retained_categories"].append(category)
erasure_result["retention_reasons"][category] = exemption.value
else:
self._erase_data_category(request.data_subject_email, category)
erasure_result["erased_categories"].append(category)
# Cascade erasure to processors (Art.19)
for processor in self.PROCESSORS:
self._notify_processor_erasure(processor, request, erasure_result["erased_categories"])
erasure_result["processors_notified"].append(processor)
request.processors_notified = erasure_result["processors_notified"]
# Record for backup erasure (applied on next backup restore/rotation)
self._record_backup_deletion_request(
request.data_subject_email,
erasure_result["erased_categories"]
)
erasure_result["backup_queue_recorded"] = True
request.completed_at = datetime.utcnow()
self._save_audit_log(request)
return erasure_result
def _check_art17_3_exemption(self, data_category: str) -> Optional[ErasureExemption]:
"""Return the applicable exemption, or None if erasure is required."""
if data_category in self.LEGALLY_RETAINED_CATEGORIES:
return ErasureExemption.LEGAL_OBLIGATION
# Extend: legal_holds, litigation_flags, public_interest_categories
return None
def _collect_all_subject_data(self, email: str) -> dict:
raise NotImplementedError("Implement: query all data stores for this email")
def _get_field_value(self, email: str, field: str) -> str:
raise NotImplementedError
def _update_field(self, email: str, field: str, value: str):
raise NotImplementedError
def _processor_has_field(self, processor: str, field: str) -> bool:
raise NotImplementedError
def _notify_processor_rectification(self, processor: str, request: DSARRequest):
raise NotImplementedError
def _notify_processor_erasure(self, processor: str, request: DSARRequest, categories: list):
raise NotImplementedError
def _erase_data_category(self, email: str, category: str):
raise NotImplementedError
def _get_all_data_categories(self, email: str) -> list[str]:
raise NotImplementedError
def _record_backup_deletion_request(self, email: str, categories: list):
raise NotImplementedError
def _get_processing_purposes(self) -> list[dict]:
raise NotImplementedError
def _get_retention_periods(self) -> dict:
raise NotImplementedError
def _get_transfer_safeguards(self) -> list[dict]:
raise NotImplementedError
def _get_automated_decision_info(self) -> list[dict]:
raise NotImplementedError
def _save_audit_log(self, request: DSARRequest):
raise NotImplementedError
def check_overdue_requests(requests: list[DSARRequest]) -> list[DSARRequest]:
"""Run this daily. Art.12(3): failure to respond within 1 month is a violation."""
overdue = [r for r in requests if r.is_overdue()]
approaching = [r for r in requests if not r.is_overdue() and r.days_remaining() <= 7]
if overdue:
print(f"COMPLIANCE ALERT: {len(overdue)} DSAR requests overdue (Art.12(3) violation)")
if approaching:
print(f"WARNING: {len(approaching)} DSAR requests due within 7 days")
return overdue
Art.15 × Art.16 × Art.17 Decision Flowchart
DATA SUBJECT REQUEST RECEIVED
│
├── "What data do you hold on me?" ──→ Art.15 ACCESS
│ │
│ ├── Confirm processing exists
│ ├── Export complete data copy (machine-readable)
│ ├── Include: purposes, recipients, retention, rights
│ └── Respond within 1 month
│
├── "This data is wrong" ──────────→ Art.16 RECTIFICATION
│ │
│ ├── Correct in primary systems
│ ├── Notify processors who have the field (Art.19)
│ └── Respond "without undue delay" (max 1 month)
│
└── "Delete my data" ───────────────→ Art.17 ERASURE
│
├── Check Art.17(1) ground (must exist)
├── Check Art.17(3) exemptions per data category
├── Erase non-exempt categories from all systems
│ ├── Primary DB
│ ├── Search indexes
│ ├── Analytics platforms
│ └── CDN cached data
├── Notify processors (Art.19)
├── Record for backup rotation
└── Respond without undue delay
Common Failures and How to Avoid Them
Failure 1: Art.15 export excludes inferred/derived data Behavioral profiles, recommendation scores, credit risk indicators, and any other data derived from a user's activity is personal data about them. It must be included in Art.15 responses. (Source: IE-DPC-2025-12)
Failure 2: Art.15 export is a PDF screenshot Art.15(3) requires a "commonly used electronic format" for electronic requests. A PDF screenshot of a database is not machine-readable. Provide CSV, JSON, or equivalent. (Source: NL-AP-2025-07)
Failure 3: Art.17 erasure stops at the primary database Incomplete erasure that leaves data in search indexes, analytics pipelines, backup stores, or third-party processors is still a violation. You need a checklist of every system that receives personal data. (Source: NL-AP-2026-02)
Failure 4: Invoking Art.17(3)(b) for marketing data The legal obligation exemption protects only data you are legally required to retain — financial records, tax records, AML records. It does not protect marketing profiles, analytics data, or CRM notes that have no legal retention requirement. (Source: FR-CNIL-2025-14)
Failure 5: No Art.19 cascade after rectification or erasure When you correct or delete data, you must notify all processors who received it. Correcting in your CRM while Mailchimp retains the old address is an Art.16 compliance failure.
Failure 6: No 1-month SLA tracking DSARs received by email and handled ad-hoc by whoever happens to read the email will miss the Art.12(3) deadline. You need a system — even a simple Notion database or Jira project — that timestamps requests and escalates approaching deadlines.
Failure 7: Refusal without communication If you decide not to respond to a DSAR (manifestly unfounded or excessive under Art.12(5)), you must still notify the data subject within one month with the reason and their right to complain to the supervisory authority. Silent refusal is itself a violation.
Art.15–17 and Hosting: The sota.io Advantage
Art.15, 16, and 17 obligations sit with the controller — your application. But where you host determines your processor obligations and transfer disclosure requirements.
With EU-native hosting on sota.io (worker nodes in Frankfurt and Amsterdam):
- Art.15(2): No third-country transfer safeguards to disclose for data at rest. Your Art.15 response is simpler — no standard contractual clauses, no adequacy decision to explain.
- Art.17 erasure cascade: EU-only processors mean erasure requests stay within EU jurisdiction, with no Chapter V complications.
- Art.13(1)(f): For data transfers to third countries, Art.13 requires proactive disclosure. With EU hosting, this section of your privacy notice covers only specific third-party processors (Stripe, analytics), not your hosting infrastructure.
Deploying on AWS, GCP, or Azure EU regions does not eliminate the Chapter V issue — these processors have US parent entities subject to FISA 702 and CLOUD Act. EU-native hosting eliminates the structural transfer risk at the infrastructure layer.
30-Item Art.15–17 Compliance Checklist
Art.15 — Right of Access
- Maintain a complete data inventory (DB, backups, analytics, search, processors)
- Build a structured export endpoint that outputs machine-readable format (JSON/CSV)
- Include derived/inferred data in Art.15 exports (scores, profiles, recommendations)
- Include all Art.15(1) elements: purposes, recipients, retention, rights, source, automated decisions
- Document third-country transfer safeguards for Art.15(2)
- Provide electronic format for electronic requests (Art.15(3))
- Track request receipt timestamps for SLA compliance
- Escalate approaching 1-month deadline (day 20 alert minimum)
- Log all Art.15 responses with timestamp in audit log
- Handle Art.15 requests for accounts that have been deleted (retained data may still be subject to Art.15)
Art.16 — Right to Rectification
- Self-service correction for standard profile fields (name, address, email)
- Internal admin tool for corrections not exposed via self-service
- Art.19 notification workflow: identify which processors received the corrected field
- Audit log: old value, new value, timestamp, who corrected
- If accuracy is disputed, implement Art.18(1)(a) restriction (read-only) during investigation
- Correction propagates to search indexes and analytics (not just primary DB)
- Respond within 1 month (or within undue delay for simple corrections)
- Document cases where rectification was refused and reason (Art.12(4) notice to data subject)
Art.17 — Right to Erasure
- Map Art.17(3) exemptions to your specific data categories
- Implement per-category erasure: financial data retained, marketing data erased
- Document exemption reason for retained categories in audit log
- Erase from primary DB, search indexes, analytics platforms, email lists
- CDN cache invalidation for any publicly cached data
- Art.19 cascade: notify all processors of erasure request and erased categories
- Record erasure request in backup deletion queue (applied on next restore/rotation)
- Implement backup restoration post-erase script (prevents re-introduction of deleted data)
- Respond without undue delay with confirmation of what was erased and what was retained with reasons
- If Art.17(1) ground is contested, communicate refusal with reasons and DPA complaint right (Art.12(4))
- For publicly available data (Art.17(2)): inform other controllers processing the data
- Test erasure cascade at least annually against the full processor list
What Comes Next in GDPR Chapter III
This post completes the core data subject rights trilogy. The remaining Chapter III rights:
- Art.18 — Right to Restriction (processing freeze during disputes)
- Art.19 — Notification obligation (cascade to processors/recipients)
- Art.20 — Right to Data Portability (machine-readable export + transfer between controllers)
- Art.21 — Right to Object (direct marketing must stop immediately; legitimate interests must be reassessed)
Art.20 (portability) and Art.21 (objection to direct marketing) are next in the series. Both have significant engineering implications that differ from Art.15–17.
See Also
- GDPR Art.12–14: Transparency Obligations & Privacy Notice Developer Guide — The preceding post in the Chapter III series: how to structure Art.13/14 privacy notices, DSAR modalities, and the 30-day response SLA.
- GDPR Art.18–20: Restriction, Notification & Portability Developer Guide — Continues the trilogy: processing freeze (Art.18), cascade notifications to processors (Art.19), and machine-readable export formats for portability (Art.20).
- GDPR Art.32: Technical & Organisational Security Measures — Security controls that underpin a lawful response to Art.15/17 requests (encryption, access controls, audit logs).
- GDPR Art.25: Privacy by Design — Data minimisation principles that reduce the scope and complexity of Art.15 subject access responses.
sota.io runs on EU-native infrastructure with data residency in Frankfurt and Amsterdam. No US parent entity. No Chapter V transfer complications. Start your free trial at sota.io.