AgeSafety
Use platform age signals to verify user age and supervision status
Beta API Notice
The underlying platform APIs are currently in beta and may change before January 1, 2026. During the beta period, Play Age Signals may return
API_NOT_AVAILABLEor throw exceptions on some devices. Always handle these cases gracefully and provide conservative fallbacks for age-gated flows.
AgeSafety exposes system-provided age signals and supervision state so you can determine whether a user is a minor, whether their account is supervised (Family Link / Screen Time), and whether parental approval is required for significant app changes or feature enablement.
The plugin intentionally passes through platform signals (it does not collect or send identifiable data itself). Use the plugin to gate UI, require parental confirmation, or disable features for underage users.
Why use AgeSafety?
- Compliance made simple: Meet platform requirements for age-appropriate content
- User safety first: Protect minors with proper age verification
- Parental controls: Respect existing family supervision settings
- Unified approach: One API works across both Android and iOS platforms
Before you start
Prerequisites
- A Median.co app with JavaScript Bridge enabled
- Target SDK support for Play Age Signals (Android) and Declared Age Range (iOS)
- Understanding of your app's age-restricted content and features
Developer DemoTest your implementation using our developer demo page at https://median.dev/age-safety
When to use this plugin
AgeSafety is essential for apps that need to:
| Use Case | Example |
|---|---|
| Content filtering | Social media apps are blocking mature content for minors |
| Purchase flows | E-commerce apps restricting age-restricted products |
| Account creation | Apps requiring parental consent for users under 13 |
| Feature gating | Gaming apps are disabling in-app purchases or communications for supervised accounts |
| Compliance | Any app handling personal data from minors |
Key concepts
The following terms will help you implement AgeSafety effectively:
Age bounds
Platforms return age ranges (like 13–17) rather than exact ages. Both bounds are inclusive, meaning a user with bounds 13–17 could be 13, 17, or anywhere in between.
Verification strength
- Strong verification: High-confidence signals from payment verification or government ID checks
- Weak verification: Self-declared ages or other lower-confidence methods
Account supervision
- Supervised account: The user's device or account is under parental supervision (Family Link on Android, Screen Time on iOS)
- Supervisor approval required: The platform indicates that significant app changes need parent/guardian approval
Note
The plugin only surfaces signals; it doesn't collect or transmit personal information.
Privacy and security
- The plugin surfaces system-provided signals only. It does not log or transmit personally-identifying information.
- Follow platform rules: do not use Play Age Signals for advertising purposes (per Play's terms).
TypeScript types
enum VerificationMethod { PAYMENT, GOVERNMENT_ID, SELF_DECLARED, OTHER, NONE, UNKNOWN }
interface AgeSignalsOptions { ageGates?: number[] }
interface AgeSignalsResponse {
ageLowerBound?: number;
ageUpperBound?: number;
strongVerification: boolean;
verificationMethod?: VerificationMethod; // iOS Only
supervisedAccount: boolean;
supervisorApprovalRequired: boolean;
}
interface AgeRequirementResponse extends AgeSignalsResponse { allowed: boolean }
Quick start
Get up and running with AgeSafety in three steps:
- Get age signals
const resp = await median.ageSafety.getAgeSignals({ ageGates: [13, 17, 21] });- Check the minimum age requirement
const resp = await median.ageSafety.requireMinimumAge(requiredAge);
if (resp.allowed) {
// show content
} else {
// show age-gated message
}- Handle errors
try {
// Age check logic here
} catch (err) {
console.error('Age safety check failed', err);
}Implementation guide
Core methods
getAgeSignals
Retrieve age and supervision signals from the platform.
// Using promises
const resp = await median.ageSafety.getAgeSignals({ ageGates: [13, 17, 21] });
console.log('Age signals:', resp);
// Using callback methods
median.ageSafety.getAgeSignals({ ageGates: [13, 17] }, function (resp) {
console.log('Age signals callback:', resp);
}, function (err) {
console.error('AgeSafety error (callback)', err);
});Return value (resolved Promise/success callback) is an AgeSignalsResponse.
requireMinimumAge
A convenience helper that checks whether the user meets a numeric minimum age.
async function checkMinimumAge(requiredAge) {
// Async/await style
try {
const resp = await median.ageSafety.requireMinimumAge(requiredAge);
if (resp.allowed) {
// show content
} else {
// show age-gated message
}
} catch (err) {
console.error('Age safety check failed', err);
}
}
checkMinimumAge(13);
// Callback style
median.ageSafety.requireMinimumAge(18, function (resp) {
console.log('requireMinimumAge', resp.allowed);
}, function (err) {
console.error(err);
});AgeRequirementResponse.allowed is computed as ageLowerBound >= requiredAge when age bounds are available. If bounds are missing, allowed may be false, and an app-level conservative policy should apply.
Code example
Gate a purchase flow
This example demonstrates how to verify a user's age before allowing a purchase, handle supervised accounts that require parental approval, and fall back when age signals are unavailable.
async function attemptPurchase() {
try {
const resp = await Median.ageSafety.getAgeSignals({ ageGates: [18] });
if (resp.ageLowerBound >= 18) {
// proceed with purchase
} else if (resp.supervisorApprovalRequired) {
// show parent approval flow
} else {
// block purchase and show message
}
} catch (err) {
// fallback: conservative block or soft-check
console.error('Age check failed', err);
}
}Error handling
Error codes
| Error Code | Description |
|---|---|
| NOT_SUPPORTED | Device or OS does not support age signals, or Play Age Signals/entitlement missing |
| API_ERROR | Underlying platform API threw an exception |
| USER_DENIED | User denied permission (iOS system prompt), or the signal is unavailable due to user action |
Important
When signals return
UNKNOWN,ageLowerBound/ageUpperBoundmay be omitted. Design your UI to apply a conservative default (e.g., block age-restricted content) when verification is not available.
Updated 1 day ago