Understanding how major social media platforms handle your data is essential for developers building privacy-conscious applications. This guide compares privacy policies and data practices across the major platforms in 2026, with practical code examples for data portability and API access.
Data Collection Practices Overview
Each platform collects different categories of data with varying retention periods. Here’s a practical breakdown:
| Platform | Primary Data Collected | Retention | Data Export |
|---|---|---|---|
| X (Twitter) | Posts, interactions, location, device | 18 months inactive | Full archive |
| Meta (FB/IG) | Posts, messages, location, ads, biometric | Indefinite | Download all |
| Profile, connections, activity, ads | 3 years inactive | Limited export | |
| TikTok | Videos, interactions, device, clipboard | Variable | Request form |
| Mastodon | Posts, following, muting | Instance-dependent | JSON export |
API Access for Developers
Modern social platforms provide official APIs with varying access levels. Here’s how to work with them programmatically.
X (Twitter) API v2
X’s API requires OAuth 2.0 for most operations. Here’s a practical authentication flow:
import requests
from urllib.parse import urlencode
# X API v2 OAuth 2.0 PKCE flow
CLIENT_ID = "your_client_id"
REDIRECT_URI = "https://yourapp.com/callback"
# Step 1: Generate code verifier and challenge
import base64
import hashlib
import secrets
code_verifier = secrets.token_urlsafe(64)
code_challenge = base64.urlsafe_b64encode(
hashlib.sha256(code_verifier.encode()).digest()
).decode().rstrip("=")
# Step 2: Build authorization URL
auth_params = {
"response_type": "code",
"client_id": CLIENT_ID,
"redirect_uri": REDIRECT_URI,
"scope": "tweet.read users.read follows.read",
"state": secrets.token_hex(16),
"code_challenge": code_challenge,
"code_challenge_method": "S256"
}
auth_url = f"https://twitter.com/i/oauth2/authorize?{urlencode(auth_params)}"
# Step 3: Exchange code for token
token_response = requests.post(
"https://api.twitter.com/2/oauth2/token",
data={
"grant_type": "authorization_code",
"code": "authorization_code",
"redirect_uri": REDIRECT_URI,
"client_id": CLIENT_ID,
"code_verifier": code_verifier
}
)
access_token = token_response.json()["access_token"]
X’s API now limits free tier to 1,500 tweets per month, making it challenging for archival projects.
Meta Graph API
Meta’s API requires App Review for most permissions. Here’s a basic setup:
// Meta Graph API - Basic authentication check
const MetaAuth = {
accessToken: process.env.META_ACCESS_TOKEN,
appId: process.env.META_APP_ID,
async getUserData() {
const response = await fetch(
`https://graph.facebook.com/v18.0/me?fields=id,name,email&access_token=${this.accessToken}`
);
return response.json();
},
async exportInstagramData() {
// Request data download via official tool
const response = await fetch(
`https://graph.facebook.com/v18.0/${this.userId}/data_deletion_requests`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
platform: "instagram",
method: "delete"
})
}
);
return response.json();
}
};
Meta requires the pages_show_list and pages_read_engagement permissions for public page data.
Data Portability Tools
For power users managing multiple platforms, these tools help consolidate data exports.
Platform-Specific Export Commands
# X (Twitter) - Request full archive
# Requires OAuth - use browser dev tools to capture the download link
# LinkedIn - Data export via settings
# Navigate: Settings > Data privacy > Get copy of your data
# Mastodon - Built-in JSON export
curl -H "Authorization: Bearer $MASTODON_TOKEN" \
"https://mastodon.social/api/v1/export" -d "export_type=archive"
Cross-Platform Export Script
#!/usr/bin/env python3
"""Social media data export aggregator"""
import json
import os
from datetime import datetime
class SocialExport:
def __init__(self, output_dir="~/social-exports"):
self.output_dir = os.path.expanduser(output_dir)
os.makedirs(self.output_dir, exist_ok=True)
def export_to_json(self, platform, data):
"""Save platform data as timestamped JSON"""
timestamp = datetime.now().strftime("%Y%m%d")
filename = f"{platform}_{timestamp}.json"
filepath = os.path.join(self.output_dir, filename)
with open(filepath, "w") as f:
json.dump(data, f, indent=2, default=str)
print(f"Exported {platform} data to {filepath}")
return filepath
def create_manifest(self, exports):
"""Create a manifest of all exports"""
manifest = {
"generated": datetime.now().isoformat(),
"platforms": list(exports.keys()),
"files": exports
}
with open(os.path.join(self.output_dir, "manifest.json"), "w") as f:
json.dump(manifest, f, indent=2)
return manifest
# Usage example
exporter = SocialExport()
exports = {}
# Add exports from each platform as you collect them
exporter.create_manifest(exports)
Privacy-Focused Alternatives
For developers building privacy-conscious applications, consider these platforms with better data practices.
Fediverse (Mastodon, Lemmy, Pixelfed)
The federated network offers genuine data portability:
- ActivityPub protocol enables cross-instance following
- JSON-native data format throughout
- No algorithmic amplification by default
- Instance-specific moderation policies
// Mastodon API - Fetch home timeline with pagination
async function fetchHomeTimeline(maxId = null) {
const params = new URLSearchParams({
limit: 40,
...(maxId && { max_id: maxId })
});
const response = await fetch(
`https://mastodon.social/api/v1/timelines/home?${params}`,
{
headers: {
"Authorization": `Bearer ${process.env.MASTODON_TOKEN}`
}
}
);
return response.json();
}
Bluesky (AT Protocol)
Bluesky’s AT Protocol provides strong data portability:
- DID-based identity without platform lock-in
- RSK (repo storage) enables account migration
- Labeler services for content moderation
- JSON-LD data structures
// Bluesky ATP SDK - Session management
import { AtpAgent } from "@atproto/api";
const agent = new AtpAgent({ service: "https://bsky.social" });
async function login(identifier: string, password: string) {
await agent.login({ identifier, password });
// Session includes DID and access/refresh tokens
return {
did: agent.session?.did,
handle: agent.session?.handle,
accessToken: agent.session?.accessJwt,
refreshToken: agent.session?.refreshJwt
};
}
Key Privacy Considerations for Developers
Data Minimization Strategies
When building applications that interact with social platforms:
- Request minimum scopes — Only ask for permissions you need
- Cache strategically — Store only necessary data locally
- Handle tokens securely — Use environment variables, never commit secrets
# .env.example - Never commit this file
TWITTER_CLIENT_ID=your_client_id
TWITTER_CLIENT_SECRET=your_client_secret
MASTODON_TOKEN=your_mastodon_token
BLUESKY_PASSWORD=your_password
Compliance Tools
# GDPR/CCPA data request automation
import requests
from datetime import datetime
class PrivacyRequestHandler:
PLATFORM_ENDPOINTS = {
"twitter": "https://api.twitter.com/2/users/me/archive",
"facebook": "https://www.facebook.com/help/contact/180237885820906",
"linkedin": "https://www.linkedin.com/help/linkedin/ask/TS-privacy",
}
def request_deletion(self, platform, user_id):
"""Submit GDPR deletion request"""
if platform not in self.PLATFORM_ENDPOINTS:
raise ValueError(f"Unsupported platform: {platform}")
response = requests.post(
self.PLATFORM_ENDPOINTS[platform],
data={"id": user_id, "delete": "true"}
)
return {
"platform": platform,
"requested": datetime.now().isoformat(),
"status": response.status_code
}
Practical Recommendations
For developers and power users in 2026:
- Audit your connected apps quarterly across all platforms
- Enable two-factor authentication with hardware keys where supported
- Use data export tools to maintain backups outside platform ecosystems
- Consider fediverse alternatives for new community building
- Review privacy settings as platforms regularly update their policies
The social media landscape continues evolving. Staying informed about data practices helps you make better architectural decisions and protect your users’ privacy.
Built by theluckystrike — More at zovo.one