COPPA Compliance
Learn how to comply with US children's privacy laws (COPPA) when showing ads to kids under 13.
What is COPPA?
The Children's Online Privacy Protection Act (COPPA) is a US federal law that protects the privacy of children under 13 years old. Key requirements:
- Parental Consent: Must obtain verifiable parental consent before collecting data
- Data Minimization: Only collect necessary information
- No Behavioral Ads: Cannot serve personalized/targeted ads to children
- Security: Must protect collected information
- Transparency: Must have clear privacy policy
Does COPPA Apply to Your App?
You MUST comply if:
- ✅ Your app/game is directed at children under 13
- ✅ Your app has "mixed audience" and you knowingly collect data from kids
- ✅ You're a service provider (ad network) serving ads to child-directed apps
"Child-Directed" Means:
- Primary audience is children under 13
- Subject matter appeals to children (toys, games, cartoons)
- Uses child-oriented characters or activities
- Language targeted at children
- Marketed to children
How BZZE Ads Handles COPPA
The SDK provides built-in COPPA support. Here's how it works:
| What Happens | Regular Mode | COPPA Mode |
|---|---|---|
| Personalized Ads | ✅ Allowed | ❌ Blocked |
| Contextual Ads | ✅ Allowed | ✅ Allowed |
| User Tracking | ✅ Allowed | ❌ Blocked |
| Data Collection | Standard | Minimal (session only) |
| Analytics | Full tracking | Aggregated only |
Implementation Guide
Option 1: Child-Directed App (All Users Are Kids)
If your entire app is directed at children under 13:
// Initialize with COPPA mode enabled for ALL users
RewardedAd.init({
appId: "YOUR_APP_ID",
apiKey: "YOUR_API_KEY",
userId: "user_123",
// Mark ALL traffic as child-directed
coppaCompliant: true,
isChildDirected: true,
onReward: function(reward) {
grantCoins(100);
}
});
Option 2: Mixed Audience (Age Gate Required)
If your app has both kids and adults, implement an age gate:
// Show age gate on first launch
async function showAgeGate() {
const birthYear = await promptUserBirthYear();
const age = new Date().getFullYear() - birthYear;
const isChild = age < 13;
// Store result
localStorage.setItem('isChild', isChild);
return isChild;
}
// Initialize SDK based on age
async function initializeAds() {
const isChild = localStorage.getItem('isChild') === 'true';
RewardedAd.init({
appId: "YOUR_APP_ID",
apiKey: "YOUR_API_KEY",
userId: "user_123",
// Enable COPPA only for kids
coppaCompliant: true,
isChildDirected: isChild,
onReward: function(reward) {
grantCoins(100);
}
});
}
initializeAds();
Option 3: Age Gate with Parental Consent
If you need to collect data from children (requires parental consent):
async function handleChildUser() {
const age = await getAgeFromAgeGate();
if (age < 13) {
// Show parental consent form
const hasParentalConsent = await showParentalConsentForm();
if (!hasParentalConsent) {
// Cannot show ads without consent
return false;
}
// Initialize with COPPA mode
RewardedAd.init({
appId: "YOUR_APP_ID",
apiKey: "YOUR_API_KEY",
userId: "user_123",
coppaCompliant: true,
isChildDirected: true,
onReward: function(reward) {
grantCoins(100);
}
});
return true;
} else {
// Adult user - normal mode
RewardedAd.init({
appId: "YOUR_APP_ID",
apiKey: "YOUR_API_KEY",
userId: "user_123",
coppaCompliant: false,
onReward: function(reward) {
grantCoins(100);
}
});
return true;
}
}
Age Gate Best Practices
1. Simple Age Input
function showAgeGateUI() {
const ageGateHTML = `
Welcome!
Please enter your birth year to continue:
`;
document.body.innerHTML = ageGateHTML;
}
function submitAge() {
const birthYear = parseInt(document.getElementById('birthYear').value);
const age = new Date().getFullYear() - birthYear;
if (isNaN(age) || age < 0 || age > 120) {
alert('Please enter a valid year');
return;
}
const isChild = age < 13;
localStorage.setItem('userAge', age);
localStorage.setItem('isChild', isChild);
// Initialize game
initializeGame();
}
2. Neutral Wording
Complete Example
// Complete COPPA-compliant implementation
class COPPAManager {
constructor() {
this.isChild = null;
}
async checkAge() {
// Check if we already know the age
const storedAge = localStorage.getItem('userAge');
if (storedAge) {
this.isChild = parseInt(storedAge) < 13;
return this.isChild;
}
// Show age gate
const birthYear = await this.showAgeGate();
const age = new Date().getFullYear() - birthYear;
// Store age
localStorage.setItem('userAge', age);
this.isChild = age < 13;
return this.isChild;
}
showAgeGate() {
return new Promise((resolve) => {
// Show your age gate UI
// Resolve with birth year when user submits
const birthYear = prompt('Enter your birth year (YYYY):');
resolve(parseInt(birthYear));
});
}
initializeAds() {
RewardedAd.init({
appId: "YOUR_APP_ID",
apiKey: "YOUR_API_KEY",
userId: "user_" + Math.random().toString(36).substr(2, 9),
// COPPA compliance
coppaCompliant: true,
isChildDirected: this.isChild,
onReward: function(reward) {
console.log('Reward granted!');
grantCoins(100);
},
onError: function(error) {
console.error('Ad error:', error);
}
});
}
}
// Usage
const coppaManager = new COPPAManager();
async function startGame() {
await coppaManager.checkAge();
coppaManager.initializeAds();
// Start your game
}
What Data is Collected in COPPA Mode?
| Data Type | Regular Mode | COPPA Mode |
|---|---|---|
| Session ID | ✅ Collected | ✅ Collected (required) |
| App ID | ✅ Collected | ✅ Collected (required) |
| User ID | ✅ Collected | ⚠️ Should be anonymous |
| IP Address | ✅ Collected | ❌ Not stored |
| Device ID | ✅ Collected | ❌ Not collected |
| Location | ✅ Collected | ❌ Not collected |
| Cookies | ✅ Used | ❌ Not used |
Compliance Checklist
- ☑️ Implement age gate for mixed audience apps
- ☑️ Set
coppaCompliant: truein SDK - ☑️ Set
isChildDirected: truefor child users - ☑️ Use anonymous user IDs (no email, name, etc.)
- ☑️ Update privacy policy to mention COPPA
- ☑️ Do NOT collect personal information from kids
- ☑️ Test with COPPA mode enabled
- ☑️ Monitor compliance regularly
Testing COPPA Mode
// Test COPPA mode
RewardedAd.enableDebug();
RewardedAd.init({
appId: "YOUR_APP_ID",
apiKey: "YOUR_API_KEY",
userId: "test_child_user",
coppaCompliant: true,
isChildDirected: true
});
// Check SDK info
const info = RewardedAd.getInfo();
console.log('COPPA Mode:', info.config.isChildDirected);
// Show ad and verify non-personalized
RewardedAd.showAd();
Best Practices
- Implement age gate with neutral wording
- Enable COPPA mode for all child users
- Use anonymous user IDs for children
- Show only contextual (non-personalized) ads
- Update privacy policy clearly
- Test thoroughly with COPPA enabled
- Consult with legal counsel
- Collect email, name, or personal info from kids
- Use leading age gate questions
- Show personalized ads to children
- Track children across apps/websites
- Store cookies for child users
- Share children's data with third parties
- Assume compliance without legal review
Common Mistakes
1. Not Implementing Age Gate
❌ Wrong: Assuming all users are adults
✅ Right: Implement age verification for mixed audiences
2. Using Leading Questions
❌ Wrong: "Are you 13 or older?"
✅ Right: "What is your birth year?"
3. Not Enabling COPPA Mode
❌ Wrong: Only updating privacy policy
✅ Right: Set isChildDirected: true in SDK