GDPR Article 20: The Right to Data Portability — SaaS Developer Implementation Guide (2026)
Post #878 in the sota.io EU Cyber Compliance Series
GDPR Article 20 is the only data subject right that creates an active technical obligation to build an export system. While the right of access (Art.15) can be satisfied with a human-readable PDF, the right to data portability requires a structured, commonly used, machine-readable format — and it can include a direct transfer to a third-party controller the data subject names.
For SaaS developers, this is not a legal edge case. If your platform processes personal data based on consent or a contract, and does so through automated means, you are already within scope. An EU data subject can request their data at any time. You have 30 days to deliver a machine-readable export. If they ask you to transmit it directly to another service, you must comply where technically feasible.
This guide covers the full Article 20 framework, the boundary between portable and non-portable data, technical format requirements, the CLOUD Act exposure problem for portability requests involving US-hosted infrastructure, and the intersection with the 2026 EU Data Act switching obligations.
Article 20 in Full
GDPR Article 20(1):
"The data subject shall have the right to receive the personal data concerning him or her, which he or she has provided to a controller, in a structured, commonly used and machine-readable format and have the right to transmit those data to another controller without hindrance from the controller to which the personal data have been provided."
GDPR Article 20(2):
"In exercising his or her right to data portability pursuant to paragraph 1, the data subject shall have the right to have the personal data transmitted directly from one controller to another, where technically feasible."
GDPR Article 20(3):
"The exercise of the right referred to in paragraph 1 of this Article shall be without prejudice to Article 17. That right shall not apply to processing necessary for the performance of a task carried out in the public interest or in the exercise of official authority vested in the controller."
GDPR Article 20(4):
"The right referred to in paragraph 1 shall not adversely affect the rights and freedoms of others."
The Three Cumulative Conditions
Article 20 applies only when all three conditions are met simultaneously. If any condition fails, the right to portability does not apply — though the right of access under Art.15 may still apply.
Condition 1: The Processing Is Based on Consent (Art.6(1)(a)) or Contract (Art.6(1)(b))
Portability does not apply to processing based on:
- Legitimate interests (Art.6(1)(f)) — the most common lawful basis for B2B analytics
- Legal obligation (Art.6(1)(c)) — compliance-driven retention is not portable
- Public interest (Art.6(1)(e)) — excluded by Art.20(3)
- Vital interests (Art.6(1)(d)) — emergency processing is not portable
For SaaS platforms, portability is most likely triggered by:
- User account data (processed under contract — the subscription or ToS)
- Usage data explicitly consented to (e.g., analytics you asked consent for)
- Health or financial data processed under explicit consent (Art.9(2)(a))
The EDPB's Guidelines 05/2019 on data portability confirm: contract basis includes pre-contractual steps — so onboarding data collected before a formal agreement can also be portable.
Condition 2: Processing Is Carried Out by Automated Means
Manual filing systems — paper records, unstructured notes — are outside scope. This condition is easily satisfied by any modern SaaS platform, since virtually all processing uses automated means.
The condition excludes edge cases like a contractor's handwritten project notes about a client. Those notes are personal data but not portable under Art.20.
Condition 3: The Data Was "Provided by" the Data Subject
This is the most important and most misunderstood condition. Only data provided by the data subject is portable. The EDPB draws a clear distinction:
| Category | Portable? | Examples |
|---|---|---|
| Provided data | ✅ Yes | Name, email, postal address, date of birth, account settings, uploaded files, photos, messages, explicitly submitted preferences |
| Observed data | ✅ Yes (EDPB considers this "provided") | Activity logs, location history, browsing behavior, transaction history, search queries |
| Inferred/derived data | ❌ No | Risk scores, credit ratings, AI-generated recommendations, behavioural profiles, engagement scores |
The EDPB's Guidelines explicitly include observed data (data generated by the data subject's activity on the platform) as portable, even though the data subject did not actively "submit" it. The rationale: the subject's use of the service generates this data, and they have a legitimate interest in taking it elsewhere.
Inferred and derived data are categorically excluded. A creditworthiness score derived from the subject's payment history is not portable — it is intellectual property of the processor. A personalised content ranking model trained on the subject's behaviour is not portable. The input data may be portable; the derived output is not.
The 30-Day Response Deadline
Article 12(3) applies to all Chapter III rights including Art.20: you must respond within one month of receipt of the request. One 30-day extension is permitted for complex requests, but you must notify the data subject within the initial month that an extension is being taken.
The clock starts when the request is received — not when you verify identity, not when you begin processing. Identity verification time is part of the 30 days.
Practical implication: If identity verification takes 3 business days and data assembly takes 5 business days, you still have ample time — but the process must be automated enough to consistently meet this deadline at scale.
Machine-Readable Format Requirements
The GDPR does not mandate a specific format. The requirement is "structured, commonly used and machine-readable." The EDPB's Guidelines 05/2019 clarify what this means in practice:
Formats That Satisfy the Requirement
JSON (JavaScript Object Notation) — The EDPB explicitly cites JSON as a suitable format. It is structured, machine-readable, human-legible, and universally supported. For most SaaS data exports, JSON is the recommended choice.
CSV (Comma-Separated Values) — Suitable for tabular data. CSV exports satisfy Art.20 for structured records (transaction history, event logs, preference tables). Limitations: no native support for nested structures, no schema enforcement.
XML — Acceptable, though verbose. Used in financial services and healthcare contexts where existing XML schemas (HL7, ISO 20022) provide interoperability.
Open formats specific to your domain — A calendar export in iCal (.ics), a contact export in vCard (.vcf), or a health record in HL7 FHIR JSON are all appropriate where the data type warrants a domain-specific format.
Formats That Do Not Satisfy the Requirement
PDF — A PDF is not machine-readable in the Art.20 sense. It is not structured in a way that another system can programmatically consume. A PDF export satisfies Art.15 but not Art.20.
Proprietary binary formats — Exports that require vendor software to open do not satisfy the "commonly used" requirement.
Screenshots or visual representations — Not acceptable.
What the Export Must Include
The EDPB recommends that portability exports include:
- Data in the portable categories (provided + observed data matching the legal basis)
- Metadata describing the data structure (a schema or README helps but is not required)
- A cover note confirming what is and is not included, and why
You are not required to include third-party data. If a user's message thread contains messages from other users, you must assess whether including those messages affects third parties' rights under Art.20(4). Standard practice: include the requesting user's own messages and metadata; omit or redact other users' content.
Direct Controller-to-Controller Transfer (Art.20(2))
Article 20(2) creates an obligation to transmit data directly to another controller when the data subject requests it and when this is technically feasible. This is the most demanding technical aspect of Art.20.
"Technically feasible" is not a high bar — it does not mean you must build a universal API. It means: if there is a standardised API or protocol for the receiving system that you can implement, you should. If the receiving controller has no machine-readable intake mechanism, you are not required to build one for them.
Practical approach for SaaS platforms:
-
Build a machine-readable export endpoint — A
/api/v1/data-exportendpoint that returns JSON is the foundation. The data subject can then forward this to any controller. -
Support common receiving systems — If you operate in a domain with established interchange formats (financial: Open Banking; health: FHIR; social: ActivityPub), consider supporting direct export to those ecosystems.
-
Honour direct-transfer requests on a best-efforts basis — If a user provides you with an API endpoint from another controller, and that endpoint is publicly documented, a direct transfer is technically feasible and you should implement it.
-
Document infeasibility when applicable — If direct transfer is not feasible, document why and inform the data subject so they can download and upload manually.
The CLOUD Act Problem for Portability Exports
Here is the intersection that most SaaS legal teams have not analyzed: when you process EU data subjects' data on US-owned infrastructure (AWS, Azure, GCP, Snowflake, etc.), a portability export does not cleanse that data's legal status.
The CLOUD Act (Clarifying Lawful Overseas Use of Data Act, 2018) allows US law enforcement to compel US cloud providers to disclose data stored anywhere in the world, including within the EU. When a data subject requests a portability export, the exported data:
- Is still stored on the original US-cloud infrastructure during generation
- Is transmitted through US-cloud network infrastructure
- May be temporarily cached or logged in US-cloud systems during export
The CLOUD Act exposure exists throughout the portability lifecycle, not just at rest. A GDPR-compliant export (timely, machine-readable, complete) can simultaneously be a US law enforcement access point.
For EU SaaS developers, this creates a dual compliance gap:
- GDPR Art.20: Satisfied — the data was exported in the correct format within 30 days
- GDPR Art.46/Art.48: Potentially violated — the act of exporting data through US infrastructure constitutes a data transfer that may require appropriate safeguards
The EDPB's position (enforced in the Schrems II decision and reinforced by subsequent transfer impact assessments) is that the export pipeline itself must be assessed for transfer risks — not just the at-rest storage.
EU-native hosting eliminates this risk. If the portability export is generated, transmitted, and delivered entirely within EU infrastructure not subject to US jurisdiction, there is no CLOUD Act exposure in the export pipeline. The data subject receives their data without it having touched a system accessible to US government compulsion orders.
Art.20 and the EU Data Act (2023/2854)
The EU Data Act, applicable from September 2025, adds a parallel layer of switching obligations for cloud services. While GDPR Art.20 is about individual data subject rights, the EU Data Act Chapter VI imposes obligations on cloud service providers to enable portability at the service level.
Key distinctions:
| Dimension | GDPR Art.20 | EU Data Act Ch.VI |
|---|---|---|
| Trigger | Individual data subject request | Customer (B2B or B2C) switching to a different cloud service |
| Scope | Personal data only | All customer data, not limited to personal data |
| Format | Structured, machine-readable | Structured, commonly used, interoperable |
| Deadline | 30 days | 30 days for data export; longer for functional portability |
| Enforceable by | Individual data subjects, DPAs | Customers, national authorities |
| Fee | Must be free (Art.20 + EDPB) | No excessive fees (Data Act Art.23) |
If your SaaS platform is also a cloud service (as most modern SaaS is), you face both obligations simultaneously. A well-designed portability export system that satisfies EU Data Act Chapter VI will also satisfy GDPR Art.20 for personal data — these are complementary, not contradictory.
Practical Implementation: GDPR Art.20 Portability Toolkit
Below is a Python toolkit for building and auditing your Art.20 compliance posture.
#!/usr/bin/env python3
"""
GDPR Article 20 — Data Portability Compliance Toolkit
Assesses portability scope, generates export manifest, validates format.
"""
from dataclasses import dataclass, field
from typing import Optional
from enum import Enum
import json
from datetime import datetime
class LegalBasis(Enum):
CONSENT = "Art.6(1)(a) — Consent"
CONTRACT = "Art.6(1)(b) — Contract"
LEGAL_OBLIGATION = "Art.6(1)(c) — Legal Obligation"
VITAL_INTERESTS = "Art.6(1)(d) — Vital Interests"
PUBLIC_TASK = "Art.6(1)(e) — Public Task"
LEGITIMATE_INTERESTS = "Art.6(1)(f) — Legitimate Interests"
class DataCategory(Enum):
PROVIDED = "provided" # Actively submitted by data subject
OBSERVED = "observed" # Generated by subject's activity
INFERRED = "inferred" # Derived/calculated by controller
THIRD_PARTY = "third_party" # From other data subjects
@dataclass
class ProcessingActivity:
name: str
legal_basis: LegalBasis
automated: bool
data_categories: list[DataCategory]
retention_days: int
cloud_provider: str = "EU-native"
description: str = ""
@property
def portability_applicable(self) -> bool:
"""Art.20 applies only to consent/contract + automated + provided/observed."""
basis_ok = self.legal_basis in (LegalBasis.CONSENT, LegalBasis.CONTRACT)
return basis_ok and self.automated
@property
def portable_categories(self) -> list[DataCategory]:
if not self.portability_applicable:
return []
return [c for c in self.data_categories
if c in (DataCategory.PROVIDED, DataCategory.OBSERVED)]
@property
def non_portable_categories(self) -> list[DataCategory]:
return [c for c in self.data_categories
if c not in (DataCategory.PROVIDED, DataCategory.OBSERVED)]
@property
def cloud_act_risk(self) -> str:
us_providers = {"aws", "azure", "gcp", "google", "amazon",
"microsoft", "snowflake", "cloudflare", "fastly"}
provider_lower = self.cloud_provider.lower()
if any(p in provider_lower for p in us_providers):
return "HIGH — US CLOUD ACT EXPOSURE IN EXPORT PIPELINE"
return "LOW — EU-native infrastructure"
@dataclass
class PortabilityRequest:
subject_id: str
request_date: datetime
processing_activities: list[ProcessingActivity] = field(default_factory=list)
direct_transfer_requested: bool = False
target_controller: Optional[str] = None
@property
def deadline(self) -> datetime:
from datetime import timedelta
return self.request_date + timedelta(days=30)
@property
def days_remaining(self) -> int:
delta = self.deadline - datetime.now()
return max(0, delta.days)
def generate_manifest(self) -> dict:
"""Generate portability export manifest for this request."""
portable_activities = [
a for a in self.processing_activities
if a.portability_applicable and a.portable_categories
]
excluded_activities = [
a for a in self.processing_activities
if not a.portability_applicable or not a.portable_categories
]
cloud_act_risks = [
a.name for a in portable_activities
if "HIGH" in a.cloud_act_risk
]
return {
"request_id": f"port-{self.subject_id}-{self.request_date.date()}",
"subject_id": self.subject_id,
"request_date": self.request_date.isoformat(),
"deadline": self.deadline.isoformat(),
"days_remaining": self.days_remaining,
"portable_scope": [
{
"activity": a.name,
"legal_basis": a.legal_basis.value,
"categories": [c.value for c in a.portable_categories],
"cloud_act_risk": a.cloud_act_risk,
}
for a in portable_activities
],
"excluded_scope": [
{
"activity": a.name,
"reason": "Legal basis not consent/contract"
if a.legal_basis not in (LegalBasis.CONSENT, LegalBasis.CONTRACT)
else "Only inferred/third-party data",
"categories": [c.value for c in a.non_portable_categories],
}
for a in excluded_activities
if not a.portability_applicable or not a.portable_categories
],
"direct_transfer": {
"requested": self.direct_transfer_requested,
"target_controller": self.target_controller,
"feasible": self.direct_transfer_requested and bool(self.target_controller),
},
"cloud_act_exposure": {
"activities_at_risk": cloud_act_risks,
"risk_level": "HIGH" if cloud_act_risks else "LOW",
"recommendation": (
"Migrate export pipeline to EU-native infrastructure to eliminate "
"CLOUD Act exposure during portability operations."
) if cloud_act_risks else "Export pipeline uses EU-native infrastructure.",
},
"format_requirements": {
"compliant_formats": ["JSON", "CSV", "XML", "iCal", "vCard", "HL7 FHIR JSON"],
"non_compliant": ["PDF", "proprietary binary", "screenshots"],
"recommended": "JSON with accompanying schema.json",
},
}
def generate_portability_checklist() -> list[dict]:
return [
{"id": "p01", "check": "Processing basis identified for each activity (consent vs contract vs other)"},
{"id": "p02", "check": "Portability scope defined: provided data + observed data only"},
{"id": "p03", "check": "Inferred/derived data explicitly excluded from portability scope"},
{"id": "p04", "check": "Export format is structured, machine-readable, commonly used (JSON/CSV)"},
{"id": "p05", "check": "30-day response deadline enforced in ticketing/workflow system"},
{"id": "p06", "check": "Identity verification process exists and fits within 30-day window"},
{"id": "p07", "check": "Automated export generation (not manual assembly) implemented"},
{"id": "p08", "check": "Direct controller-to-controller transfer capability assessed"},
{"id": "p09", "check": "Third-party data in exports assessed under Art.20(4) rights of others"},
{"id": "p10", "check": "Export cost is zero to data subject (EDPB Guidelines 05/2019)"},
{"id": "p11", "check": "Export endpoint documented in Privacy Notice and DSR portal"},
{"id": "p12", "check": "CLOUD Act exposure in export pipeline assessed for US-hosted infrastructure"},
{"id": "p13", "check": "EU Data Act Chapter VI obligations assessed alongside GDPR Art.20"},
{"id": "p14", "check": "Art.20 does not replace Art.17 erasure right — erasure after portability handled"},
{"id": "p15", "check": "DPA escalation path defined if portability technically infeasible"},
{"id": "p16", "check": "Extension notice template prepared for complex requests (Art.12(3))"},
{"id": "p17", "check": "Export includes metadata/schema describing data structure"},
{"id": "p18", "check": "Portability requests logged for Art.5(2) accountability compliance"},
{"id": "p19", "check": "Special category data (Art.9) explicit consent verified before portability"},
{"id": "p20", "check": "Portability response tested end-to-end with real request simulation"},
]
def assess_portability_readiness(
processing_activities: list[ProcessingActivity],
has_export_api: bool,
export_format: str,
response_automation_level: str,
cloud_provider: str,
) -> dict:
"""Assess overall Art.20 readiness."""
portable_count = sum(
1 for a in processing_activities
if a.portability_applicable and a.portable_categories
)
total = len(processing_activities)
us_cloud = any(
p in cloud_provider.lower()
for p in ["aws", "azure", "gcp", "google", "amazon", "microsoft"]
)
compliant_formats = {"json", "csv", "xml", "ical", "vcard", "fhir"}
format_ok = export_format.lower() in compliant_formats
automation_score = {
"fully_automated": 3,
"semi_automated": 2,
"manual": 1,
}.get(response_automation_level.lower(), 1)
readiness_score = 0
issues = []
if has_export_api:
readiness_score += 30
else:
issues.append("CRITICAL: No export API — Art.20 compliance requires machine-readable export")
if format_ok:
readiness_score += 25
else:
issues.append(f"CRITICAL: Export format '{export_format}' is not machine-readable under Art.20")
readiness_score += automation_score * 10
if not us_cloud:
readiness_score += 25
else:
issues.append(
"WARNING: US cloud provider — CLOUD Act exposure exists in portability export pipeline. "
"Consider EU-native infrastructure to eliminate this risk."
)
if portable_count > 0:
readiness_score += 10
return {
"readiness_score": min(100, readiness_score),
"portable_activities": portable_count,
"total_activities": total,
"issues": issues,
"recommendation": (
"Art.20 compliant" if readiness_score >= 75
else "Significant gaps — immediate remediation required"
if readiness_score < 40
else "Partial compliance — address listed issues within 30 days"
),
}
if __name__ == "__main__":
# Example: SaaS platform with account, analytics, and AI scoring
activities = [
ProcessingActivity(
name="User Account Data",
legal_basis=LegalBasis.CONTRACT,
automated=True,
data_categories=[DataCategory.PROVIDED, DataCategory.OBSERVED],
retention_days=365 * 3,
cloud_provider="Hetzner (EU)",
),
ProcessingActivity(
name="Usage Analytics",
legal_basis=LegalBasis.CONSENT,
automated=True,
data_categories=[DataCategory.OBSERVED],
retention_days=365,
cloud_provider="AWS eu-central-1",
),
ProcessingActivity(
name="Churn Risk Score",
legal_basis=LegalBasis.LEGITIMATE_INTERESTS,
automated=True,
data_categories=[DataCategory.INFERRED],
retention_days=90,
cloud_provider="AWS eu-central-1",
),
ProcessingActivity(
name="Compliance Audit Logs",
legal_basis=LegalBasis.LEGAL_OBLIGATION,
automated=True,
data_categories=[DataCategory.OBSERVED],
retention_days=365 * 7,
cloud_provider="Hetzner (EU)",
),
]
req = PortabilityRequest(
subject_id="user-42",
request_date=datetime.now(),
processing_activities=activities,
direct_transfer_requested=False,
)
manifest = req.generate_manifest()
print("=== PORTABILITY EXPORT MANIFEST ===")
print(json.dumps(manifest, indent=2))
print("\n=== READINESS ASSESSMENT ===")
assessment = assess_portability_readiness(
processing_activities=activities,
has_export_api=True,
export_format="json",
response_automation_level="semi_automated",
cloud_provider="AWS eu-central-1",
)
print(json.dumps(assessment, indent=2))
print("\n=== ART.20 COMPLIANCE CHECKLIST ===")
for item in generate_portability_checklist():
print(f" ☐ [{item['id']}] {item['check']}")
What the Toolkit Reveals
Running the example above produces a manifest showing:
- Portable activities: User Account Data (contract + automated + provided/observed) and Usage Analytics (consent + automated + observed)
- Excluded activities: Churn Risk Score (legitimate interests basis — not portable) and Compliance Audit Logs (legal obligation basis — not portable)
- CLOUD Act risk: Usage Analytics uses AWS infrastructure — CLOUD Act exposure exists in the export pipeline
- Readiness score: 75/100 — partial compliance, CLOUD Act gap identified
The churn risk score is explicitly excluded from portability even though it is derived from the subject's behaviour. Only the input data (observed usage analytics) is portable, not the derived output.
Key EDPB Guidance: What the Guidelines 05/2019 Add
The EDPB's Guidelines 05/2019 on the right to data portability add several practical clarifications beyond the Article 20 text:
On "provided by the data subject": The EDPB's broad interpretation includes observed data. The Guidelines state: "The notion 'provided by the data subject' should be interpreted broadly as covering both data 'knowingly and actively provided by the data subject' and 'observed data provided by the data subject by virtue of the use of the service or the device'."
On machine-readable format: "The right to data portability is an empowerment right. The controller must therefore make it easy for data subjects to use their data." Interoperability is an objective, not just compliance. Controllers should consider open formats and standards.
On the relationship with Art.17 erasure: The exercise of portability does not automatically trigger erasure. The data subject must make a separate erasure request if they want deletion. Many controllers assume that once a subject has received their data, they want it deleted — this assumption is legally incorrect.
On fees: Portability responses must be free of charge. Unlike the right of access where reasonable fees may be charged for manifestly excessive requests, portability has no fee exception under the EDPB's interpretation.
Art.20 and EU-Native Hosting
CLOUD Act exposure in portability pipelines is not theoretical. If a data subject's personal data is processed on AWS, Azure, or GCP — even in EU regions — a US court order under 18 U.S.C. § 2713 (the CLOUD Act) can compel disclosure of that data regardless of where it is stored.
During a portability export:
- The export is assembled from data stored on US-cloud infrastructure
- The assembled export is transmitted over US-cloud network infrastructure
- Temporary copies may be created in US-cloud memory during processing
All three steps create potential CLOUD Act access points. This is not a compliance failure under Art.20 (the export was timely and machine-readable), but it is a potential failure under Art.46 (the export pipeline itself constitutes a data transfer to a US-jurisdiction system).
EU-native hosting addresses this structurally. When the portability pipeline runs on Hetzner, Scaleway, OVHcloud, or sota.io — EU-incorporated providers with infrastructure exclusively under EU jurisdiction — the CLOUD Act does not reach the export pipeline. The data subject's portability right is fulfilled without creating a US law enforcement access point.
This is the compliance-complete position: Art.20 satisfied, Art.46 satisfied, CLOUD Act exposure eliminated.
25-Item Art.20 Readiness Checklist
| # | Check | Status |
|---|---|---|
| 1 | Portability scope mapped per processing activity | ☐ |
| 2 | Legal basis identified: consent or contract only triggers Art.20 | ☐ |
| 3 | Provided data catalogued (actively submitted fields) | ☐ |
| 4 | Observed data catalogued (activity logs, usage data) | ☐ |
| 5 | Inferred/derived data explicitly excluded from portability scope | ☐ |
| 6 | Machine-readable export format implemented (JSON preferred) | ☐ |
| 7 | PDF-only exports replaced or supplemented with structured formats | ☐ |
| 8 | 30-day response deadline automated in DSR workflow | ☐ |
| 9 | Identity verification process fits within 30-day window | ☐ |
| 10 | Extension notice template prepared for complex requests | ☐ |
| 11 | Export generation automated (not manually assembled) | ☐ |
| 12 | Direct controller-to-controller transfer feasibility assessed | ☐ |
| 13 | Third-party data in exports reviewed under Art.20(4) | ☐ |
| 14 | Special category data (Art.9) explicit consent verified | ☐ |
| 15 | Export provided free of charge | ☐ |
| 16 | Art.20 right documented in Privacy Notice | ☐ |
| 17 | DSR portal includes portability request option | ☐ |
| 18 | CLOUD Act exposure in export pipeline assessed | ☐ |
| 19 | EU Data Act Chapter VI obligations assessed in parallel | ☐ |
| 20 | Portability requests logged for Art.5(2) accountability | ☐ |
| 21 | Portability does not block separate Art.17 erasure request | ☐ |
| 22 | Export schema/metadata included with data package | ☐ |
| 23 | End-to-end portability test performed (real request simulation) | ☐ |
| 24 | DPA escalation path defined for infeasible direct transfers | ☐ |
| 25 | EU-native infrastructure used for export pipeline (eliminates CLOUD Act risk) | ☐ |
Summary
GDPR Article 20 creates a technical obligation that most SaaS platforms have not fully implemented. The requirement is precise: structured, machine-readable format, 30-day deadline, free of charge, scoped to consent/contract + automated processing + provided/observed data. Inferred data is excluded. Direct transfers are mandatory where technically feasible.
The CLOUD Act intersection is the gap that most compliance programs miss. A timely, correctly formatted portability export through US-cloud infrastructure is GDPR Art.20 compliant but potentially Art.46 non-compliant — because the export pipeline itself touches US-jurisdiction systems.
Building the portability pipeline on EU-native infrastructure closes both gaps simultaneously: Art.20 obligations are met, and the export pipeline is outside US jurisdictional reach.
sota.io is an EU-native PaaS — infrastructure, export pipelines, and data processing all within EU jurisdiction, with no US-parent company exposure.
EU-Native Hosting
Ready to move to EU-sovereign infrastructure?
sota.io is a German-hosted PaaS — no CLOUD Act exposure, no US jurisdiction, full GDPR compliance by design. Deploy your first app in minutes.