CCPA Compliance Requirements for Online Businesses: California Privacy Law Guide 2026
CCPA requires California businesses to disclose what data they collect, allow users to delete and opt-out, avoid selling data without explicit consent, and respond to data access requests within 45 days. You must comply if you handle California residents’ data and meet revenue or data thresholds, implementing privacy policies, opt-out mechanisms, and data request processes. The CPRA (2023 successor) adds more consumer rights including data correction and algorithm opt-out, increasing compliance complexity and potential penalties for non-compliance.
Who Must Comply?
CCPA applies to for-profit businesses that meet any of these thresholds:
- Annual gross revenue exceeding $25 million
- Buy, sell, or share personal information of 100,000+ consumers annually
- Derive 50% or more of annual revenue from selling personal information
If your online business meets any of these criteria, you must comply with CCPA requirements. The law defines “personal information” broadly—it includes identifiers, commercial information, internet activity, geolocation data, and professional information.
Consumer Rights Under CCPA
California residents have five primary rights you must support:
- Right to Know — Consumers can request what personal data you collect and how it’s used
- Right to Delete — Consumers can request deletion of their personal data
- Right to Opt-Out — Consumers can opt out of the sale or sharing of their data
- Right to Correct — Consumers can request correction of inaccurate data
- Right to Limit — Consumers can limit use of sensitive personal information
Implementing Consumer Rights in Your Application
Building a Data Subject Access Request (DSAR) Handler
Your application needs an endpoint to handle consumer requests. Here’s a practical implementation:
from flask import request, jsonify
from functools import wraps
def handle_dsar_request(func):
"""Decorator for CCPA data subject access request handling"""
@wraps(func)
def wrapper(*args, **kwargs):
# Verify consumer identity before processing
consumer_id = request.headers.get('X-Consumer-Identifier')
if not consumer_id:
return jsonify({'error': 'Identity verification required'}), 401
return func(*args, **kwargs)
return wrapper
@app.route('/api/ccpa/request', methods=['POST'])
@handle_dsar_request
def submit_ccpa_request():
data = request.get_json()
request_type = data.get('type') # know, delete, correct, limit
valid_types = ['know', 'delete', 'correct', 'opt-out', 'limit']
if request_type not in valid_types:
return jsonify({'error': 'Invalid request type'}), 400
# Queue request for processing
dsar_queue.push({
'consumer_id': get_current_consumer_id(),
'request_type': request_type,
'request_date': datetime.utcnow(),
'status': 'pending'
})
return jsonify({
'message': 'Request received',
'request_id': generate_request_id(),
'timeline': '45 days to fulfill'
}), 202
Implementing Data Deletion
The right to delete requires removing all personal information from your systems:
// Data deletion handler for MongoDB
async function handleDataDeletion(consumerId) {
const deletionTasks = [
// Remove from users collection
db.users.deleteOne({ consumerId }),
// Remove from analytics (if applicable)
db.analytics.deleteMany({ consumerId }),
// Remove from session data
db.sessions.deleteMany({ consumerId }),
// Remove from logs (consider retention policies)
db.logs.deleteMany({ consumerId, timestamp: { $lt: getDeletionCutoff() } })
];
const results = await Promise.allSettled(deletionTasks);
const failed = results.filter(r => r.status === 'rejected');
if (failed.length > 0) {
await logDeletionFailure(consumerId, failed);
}
return {
deleted: results.filter(r => r.status === 'fulfilled').length,
failed: failed.length
};
}
Privacy Notice Requirements
Your privacy policy must contain specific elements. Update your policy to include:
- Categories of personal information collected
- Purposes for which information is used
- Categories of third parties with whom data is shared
- Consumer rights and how to exercise them
- Specific disclosures about sensitive personal information
<!-- Cookie consent banner with CCPA compliance -->
<div id="cookie-consent" class="ccpa-banner" style="display:none;">
<p>We collect personal information to improve our services.
California residents have the right to opt-out of data sales.</p>
<button onclick="acceptCookies()">Accept</button>
<button onclick="showDoNotSell()">Do Not Sell My Personal Information</button>
</div>
<script>
function showDoNotSell() {
// Display opt-out mechanism
fetch('/api/ccpa/opt-out', { method: 'POST' })
.then(() => {
document.getElementById('cookie-consent').innerHTML =
'<p>Your opt-out preference has been recorded.</p>';
});
}
</script>
Technical Safeguards for Data Protection
Data Minimization
Collect only what you need. Review your data models:
# Before: Collecting excessive data
class User:
name = StringField()
email = StringField()
phone = StringField()
ssn = StringField() # Often unnecessary
browsing_history = ListField() # Massive data collection
precise_location = GeoPointField() # Sensitive data
# After: Minimal necessary data
class User:
email = StringField() # Required for account
display_name = StringField() # Optional, user-provided
# Remove SSN unless specifically required
# Remove or anonymize browsing history
# Use ZIP code instead of precise location
Encryption and Access Controls
Implement encryption at rest and in transit:
from cryptography.fernet import Fernet
import hashlib
class DataProtection:
def __init__(self):
self.cipher = Fernet(settings.ENCRYPTION_KEY)
def encrypt_pii(self, data):
"""Encrypt personally identifiable information"""
return self.cipher.encrypt(data.encode()).decode()
def pseudonymize(self, data):
"""Replace identifiers with pseudonyms"""
return hashlib.sha256(
f"{data}{settings.SALT}".encode()
).hexdigest()[:16]
def anonymize_location(self, lat, lon):
"""Reduce location precision to ~1 mile"""
return {
'lat': round(lat, 1),
'lon': round(lon, 1)
}
Sale of Personal Information
If you sell data, you must:
- Include a “Do Not Sell My Personal Information” link on your homepage
- Respect opt-out signals from browsers (Global Privacy Control)
- Provide clear opt-out mechanisms
// Check for GPC (Global Privacy Control) signal
function checkGPCSignal() {
const gpcSignal = navigator.globalPrivacyControl;
if (gpcSignal === true) {
// Immediately halt data sale
disableDataSale();
return true;
}
return false;
}
// Opt-out endpoint
app.post('/api/ccpa/opt-out', async (req, res) => {
const consumerId = await verifyConsumer(req);
await db.consumers.updateOne(
{ _id: consumerId },
{
$set: {
'privacy.preferences.optOutOfSale': true,
'privacy.preferences.updatedAt': new Date()
}
}
);
// Disable all downstream data sharing
await disableThirdPartySharing(consumerId);
res.json({ status: 'opt-out-recorded' });
});
Record Keeping and Compliance Evidence
Maintain logs demonstrating compliance:
import logging
from datetime import datetime
class CCPAComplianceLogger:
"""Audit trail for CCPA compliance"""
def log_request_received(self, request_id, request_type, consumer_id):
logging.info(f"CCPA Request: {request_id} | Type: {request_type} | "
f"Consumer: {consumer_id[:8]}... | Date: {datetime.utcnow()}")
def log_request_fulfilled(self, request_id, data_returned):
logging.info(f"CCPA Fulfilled: {request_id} | "
f"Data categories: {list(data_returned.keys())}")
def log_deletion_completed(self, request_id, consumer_id, systems_affected):
logging.info(f"CCPA Deletion: {request_id} | "
f"Consumer: {consumer_id[:8]}... | Systems: {systems_affected}")
Non-Compliance Consequences
Failure to comply can result in:
- Civil penalties up to $2,500 per violation
- $7,500 for intentional violations
- Private right of action for data breaches ($100-$750 per consumer per incident)
Getting Started
To achieve CCPA compliance:
- Audit your data — Map what you collect, where it’s stored, and who accesses it
- Update privacy notices — Ensure clear disclosure of data practices
- Build request handlers — Implement endpoints for all consumer rights
- Configure opt-out mechanisms — Add GPC support and do-not-sell links
- Implement safeguards — Apply encryption, access controls, and data minimization
- Establish audit logging — Document compliance efforts
The regulations continue evolving. Monitor updates from the California Privacy Protection Agency (CPPA) and consult legal counsel for specific business guidance.
Related Articles
- Ccpa Compliance Requirements For Online Businesses
- Enterprise Privacy Compliance Tool Comparison for GDPR.
- Children’s Privacy Compliance: COPPA Requirements
- China Real Name Registration Requirements How Online Identit
- Privacy Audit Checklist for Small Businesses
Built by theluckystrike — More at zovo.one