Age-Based Consent
This page provides context on how to implement an age-based consent solution for the OneTrust Roku SDK.
Overview
This feature is available as of 202608.1.0 and above.
Age-Based Consent in the Roku SDK enables automatic consent enforcement based on a user’s age range.
Administrators configure age-range groups in the OneTrust admin console and associate them with specific purposes or purpose groups. The SDK uses this configuration, along with the age range provided by your application, to enforce consent behavior at runtime.
When a user falls within a restricted age range:
- Consent for associated purposes is automatically denied.
- The corresponding purpose toggles in the Preference Center are hidden.
This ensures that age-based restrictions are consistently applied without requiring additional UI logic in the app.
How It Works
At a high level:
- Your app provides the user’s age range.
- The SDK sends this data to the OneTrust server.
- The server determines consent restrictions based on your settings in the admin console.
- The SDK enforces those restrictions in the UI and APIs.
What’s Changing
SDK Updates
- New delegate method to provide the user’s age range.
- New data model:
ProfileAgeRangewith lower and upper bounds. - Automatic consent restriction based on age overlap.
- Age-range changes are logged to the server using the
AGEGATE_RANGEinteraction.
Server (CMP API) Updates
- Accepts and stores user age-range data.
- Enforces restrictions by setting
consentToggleStatus = -1for restricted purposes. - Maintains enforcement across devices for the same user profile.
Implementation
1. roAssociativeArray: ProfileAgeRange
roAssociativeArray: ProfileAgeRangeProfileAgeRange represents a user’s age range.
| Property | Description |
|---|---|
lowerBound | Optional minimum age. |
upperBound | Optional maximum age. |
profileAgeRange = {
lowerBound: integer // Optional (omit if 0 or not applicable)
upperBound: integer // Optional (omit for open-ended ranges)
}Roku validates these values during initialization. All bounds must be greater than or equal to 0. When both
lowerBoundandupperBoundare specified,lowerBoundmust be less than or equal toupperBound.
Sample Code
m.OTsdk.OTCustomConfigurator.getProfileAgeRange.callback = { lowerBound: 13, upperBound: 17 } // 13–17
m.OTsdk.OTCustomConfigurator.getProfileAgeRange.callback = { lowerBound: 18, upperBound: invalid } // 18+
m.OTsdk.OTCustomConfigurator.getProfileAgeRange.callback = { lowerBound: invalid, upperBound: 12 } // 0–12At least one bound is required. Both values cannot be invalid.
2. Observer: getProfileAgeRange
getProfileAgeRangeRegister this optional observer in the appropriate interface before calling startSDK.
The SDK calls it automatically:
- During
startSDK. - When
checkAndLogConsentis called.
Sample Code
m.OTsdk.OTCustomConfigurator.getProfileAgeRange.observeField("request", "onAgeRangeRequest")
' AgeGate: SDK requests the app for the profile age range
function onAgeRangeRequest(event as object)
requestData = event.getData()
' AgeGate: Register your age range before calling startSDK “setProfileAgeRange” to true
m.OTsdk.OTCustomConfigurator.getProfileAgeRange.setProfileAgeRange = true
profileId = ""
if requestData <> invalid and requestData.profileId <> invalid then profileId = requestData.profileId
if profileId = "test1"
m.OTsdk.OTCustomConfigurator.getProfileAgeRange.callback = { lowerBound: 0, upperBound: 4 }
else if profileId = "test2"
m.OTsdk.OTCustomConfigurator.getProfileAgeRange.callback = { lowerBound: 9, upperBound: 10 }
else
m.OTsdk.OTCustomConfigurator.getProfileAgeRange.callback = { lowerBound: 0, upperBound: 4 }
end if
end functionParameters
profileIdidentifies the current user or profile session.callbackreturns a validProfileAgeRange.
Notes
- The observer supports asynchronous operations, including network calls, database lookups, and user prompts.
- If the observer is not implemented or an invalid value is returned:
- No age range is set.
- The server may still enforce restrictions based on previously stored data. See Cross-Device Behavior.
Public APIs
checkAndLogConsent
checkAndLogConsentTriggers age-range validation and logs consent if the value has changed.
Use this method when the user’s age range may have changed after SDK initialization, such as after:
- User profile updates.
- Account switching.
- User login or re-authentication.
m.OTsdk.eventlistener.observeField("AGE_GATE.checkAndLogConsentCallBack", "eventlistener")
m.OTsdk.callFunc("AppPermissionType", "AGE_GATE.checkAndLogConsent")When invoked, the SDK:
- Calls the
getProfileAgeRangeobserver to retrieve the latest age range. - Compares the value with the previously stored range.
- If the value has changed:
- Updates local storage.
- Logs the new value to the CMP API using the
AGEGATE_RANGEinteraction type.
- If the value is unchanged, takes no action.
When to Call
Call this API whenever the user’s age range may be updated:
- After profile updates that include age or date-of-birth changes.
- After account switching or user re-authentication.
Note: You do not need to call this method during
startSDK. The SDK automatically performs this check during initialization.
getConsentStatus
getConsentStatusReturns the consent status for a purpose group.
val status = m.OTsdk.callFunc("getConsentStatusForGroupID", "C0005")Returns:
1= consent given.0= consent denied, including age restrictions.-1= invalid or unknown purpose group ID.
Age Gate Impact
The API automatically returns 0 for any purpose linked to a restricted age range. No additional code is required.
updatePurposeConsent
updatePurposeConsentUpdates the consent value for a purpose group programmatically.
m.OTsdk.callFunc("updatePurposeConsent", "C0005", true)With Age-Based Consent-supported SDKs:
- The SDK prevents consent from being enabled for age-restricted purposes.
- Any attempt to set consent to
trueis silently ignored.
Without Age-Based Consent-supported SDKs, including older SDKs:
- The update may succeed locally.
- The CMP API overrides the value to
0(denied) during the next sync.
Behavior Changes
Preference Center
Restricted Users
If a user’s age range overlaps with a configured restricted age group:
- The consent toggle for associated purposes is hidden (
consentToggleStatus: -1). - Consent is automatically set to
0(denied). - The user cannot provide consent for those purposes.
Non-Restricted Users
If the user’s age range does not overlap with any restricted age group:
- All consent toggles remain visible and interactive.
- Standard consent behavior applies.
Age-Range Overlap Logic
A user is considered restricted if their age range shares any intersection with a restricted age group. Partial overlap also results in restriction.
Logic
restricted = (user.lowerBound <= group.upperBound) &&
(user.upperBound >= group.lowerBound)Examples
Restricted age group: 0–15
| User Age Range | Result | Reason |
|---|---|---|
[0, 18] | Restricted | Possible overlap, such as age 14. |
[14, 16] | Restricted | Overlaps with ages 14–15. |
[10, 12] | Restricted | Fully within the restricted range. |
[18, 25] | Not Restricted | No overlap. |
[18, null] | Not Restricted | Open-ended range starting at 18 does not intersect. |
Cross-Device Behavior (Authenticated Consent)
For environments with Cross-Device Consent or Authenticated Consent enabled, age-based restrictions are enforced server-side and persist across devices.
How It Works
Once a user’s age range is logged for a profile from any device:
- The CMP API server stores the age range.
- All subsequent consent responses for that profile enforce the same restrictions.
- Enforcement applies across:
- Devices.
- Sessions.
- SDK versions.
SDKs with Age-Range Support (Recommended)
These SDKs provide complete enforcement and is strongly recommended.
- The server returns
consentToggleStatus: -1for restricted purposes. - The SDK:
- Hides restricted toggles in the UI.
- Prevents consent from being enabled through public APIs, such as
updatePurposeConsent.
- Enforcement is applied at both levels:
- UI level: the toggle is hidden.
- API level: updates are blocked.
SDKs Without Age-Range Support (Older SDK Versions)
Note: This section applies to Authenticated Consent-enabled environments where server-side enforcement is active.
For SDKs that support the CMP API (Next-Generation SDKs) but do not include Age-Based Consent logic:
- The server continues to send
consentToggleStatus: -1for restricted purposes. - The SDK:
- Correctly hides toggles in the Preference Center, keeping the UI consistent.
- Does not enforce age restrictions at the API level.
Behavior Differences
updatePurposeConsentmay still allow local updates for restricted purposes.- These updates are not authoritative.
- The CMP API server overrides consent to
0(denied) during the next sync. - The toggle remains hidden in the UI regardless of local changes.
Result
- Users cannot bypass restrictions through the UI.
- Temporary local inconsistencies may occur if consent is updated programmatically.
- The server ensures that the final persisted state is always compliant.
Legacy SDKs Without CMP API
Note: This section applies only to Authenticated Consent scenarios where server-side enforcement is required.
This behavior applies to legacy SDKs that:
- Use the legacy mobile-data API flow, before the CMP API.
- Include legacy Web SDKs.
- Include CTV SDKs that have not yet migrated to the CMP API.
Behavior Differences
- These SDKs do not support
consentToggleStatus: -1. - As a result:
- Consent toggles may remain visible in the UI.
- Users may be able to enable consent locally.
- When consent is synchronized with the server:
- The CMP API overrides the value to
0(denied) for restricted purposes. - Any locally enabled state is not persisted.
- The CMP API overrides the value to
Result
- Users may temporarily see consent toggled ON on the device.
- After the next server sync, the toggle reflects the correct OFF (denied) state.
Anonymous-to-Known User Consent Transfer
When a user transitions from an anonymous session to an authenticated (known) user, the SDK transfers consent using the SYNC_PROFILE interaction.
With Age-Based Consent enabled, this process includes additional safeguards to ensure that age-based restrictions are correctly enforced.
Default Behavior Without Age-Based Consent
- The user provides consent during an anonymous session.
- The user authenticates or logs in.
- The SDK invokes
handleAuthenticatedConsent, sending aSYNC_PROFILErequest to the CMP API. - The CMP API compares:
- Anonymous consent.
- Stored preferences for the known profile.
- The most recent consent value is applied for each purpose.
Behavior with Age-Based Consent
When processing a SYNC_PROFILE request, the CMP API checks whether the known profile already has an associated age range.
If the known profile has an age range:
- Consent for Age-Based Consent-linked purposes is not transferred, regardless of recency.
- The server preserves the existing age-restricted consent state.
- Consent for non-linked purposes continues to follow standard behavior; the latest value wins.
If the known profile does not have an age range:
- All consent transfers normally; the latest value wins.
- Age-based restrictions are not applied until an age range is provided.
Important: The anonymous user’s age range is not carried over to the known profile, even if the anonymous session included age-range data. This is because:
- Age range is identity-specific and may not apply across users, such as on shared devices.
- The authenticated profile must provide its own age range.
- Enforcement relies on the age range returned through the
getProfileAgeRangedelegate.
Implementation Guidance
To ensure proper enforcement:
- Implement
getProfileAgeRangefor authenticated users. This is recommended. - Optionally implement it for anonymous users if age data is collected before login.
- When a user authenticates:
- The SDK calls
getProfileAgeRangewith the new profile ID. - Your app should return the correct age range for that user.
- The SDK calls
If the age range differs from the previous session, the SDK:
- Detects the change.
- Logs it using the
AGEGATE_RANGEinteraction.
Example Flow
- An anonymous user aged 14–17 provides consent; Age Gate restricts linked purposes.
- The user logs in as
[email protected]. - The SDK calls
handleAuthenticatedConsent, and aSYNC_PROFILErequest is sent. - The CMP API evaluates the known profile:
- Age 14–17: restrictions remain; consent for linked purposes is not transferred.
- Age 18–25: no restriction; consent transfers normally.
- No age range: all consent transfers; restrictions are applied only after an age range is provided.
- The SDK calls
getProfileAgeRange("[email protected]"); the app provides the age range, and the SDK stores and logs it.
Recommendation
To ensure consistent and reliable behavior across devices:
- Upgrade all applications to the latest CMP API-enabled SDK with Age-Based Consent support.
This enables:
- Full UI enforcement, including hidden toggles.
- Full API enforcement (restricted updates blocked).
- Elimination of temporary consent inconsistencies.
- Correct handling of anonymous-to-known user consent transfer.
End-to-End Flow
- An administrator configures restricted age groups in the OneTrust Admin Console and links purposes or purpose groups to them.
- The app sets the
OTCustomConfiguratordelegate with thegetProfileAgeRangeimplementation. - The app calls
startSDK. - The SDK internally calls
getProfileAgeRangeto request the user’s age range from the app. - If the app provides a range:
- The SDK stores it locally.
- The SDK logs the age range to the CMP API server with an
AGEGATE_RANGEconsent interaction. - The server stores the age range for the profile and enforces restrictions in subsequent responses.
- The SDK hides toggles for restricted purposes in the Preference Center.
- If the app returns
nilbecause the age is unknown:- The SDK does not send an age range to the server.
- The server checks whether an age range already exists for the profile from a prior interaction or another device.
- If an age range is found, the server still enforces age-based restrictions.
- If no age range exists anywhere, no restrictions are applied.
- When the user’s age changes, such as after a profile update or account switch:
- The app calls
AppPermissionType.ageGate.checkAndLogConsent. - The SDK re-invokes the delegate and compares the new range with the stored range.
- If the range changed, the SDK updates local storage and logs the change to the server.
- The Preference Center reflects the updated restriction state.
- The app calls
Important Notes
The App Must Provide the Age Range
The SDK does not determine the user’s age. Your app must supply it using internal data, such as a user profile, registration information, or date of birth.
No System-Level APIs
The SDK does not use system-level platform APIs. It requires the app user’s age, not the device owner’s age.
Existing Age Gate UI Is Unchanged
showConsentUI and getAgeGatePromptValue() are unaffected and operate independently.
Consistent API Naming
APIs are aligned across platforms, including:
ProfileAgeRangegetProfileAgeRangecheckAndLogConsentgetConsentStatusupdatePurposeConsent
Updated about 3 hours ago
