Apple's stack: three moving parts
Apple's compliance stack for state age-assurance laws has three pieces: the
Declared Age Range API (developer.apple.com/documentation/declaredagerange),
the API you call to ask the OS for a signal about the current user's age; the
Significant Change API, under the PermissionKit framework
(developer.apple.com/documentation/PermissionKit/SignificantAppUpdateTopic), which you
call when your app undergoes a change significant enough to require fresh parental consent; and
App Store server-side plumbing -- a new AppStore.ageRatingCode property in StoreKit,
plus App Store Server Notifications that tell your backend when a parent revokes consent for a
minor's access to your app.
Platform requirement: the Declared Age Range API needs iOS, iPadOS, or macOS 26 or later, and Apple's own forum threads confirm the iOS 26 SDK (Xcode 26+) is required to use it at all.
What Declared Age Range actually returns
There is no fixed, OS-provided age-category enum. You call
AgeRangeService.shared.requestAgeRange(ageGates:in:) (UIKit/AppKit) or the SwiftUI
environment value @Environment(\.requestAgeRange) -- and you supply the age
thresholds yourself, as up to three integer "age gates" (Apple's own sample uses
13, 15, 18; gates must be at least two years apart or the call throws
AgeRangeService.Error.invalidRequest). The system returns bounds around the gates you
supplied, not a fixed category, and the call requires the
com.apple.developer.declared-age-range entitlement, enabled via the Declared Age
Range capability in Xcode.
What comes back is a Response enum with two cases -- .sharing(AgeRange)
or .declinedSharing. The AgeRange struct has a nullable
lowerBound and upperBound (an Int? pair marking the gates
the person falls between), an ageRangeDeclaration describing how the age was
established -- the current, non-deprecated cases are .selfDeclared,
.guardianDeclared, and .confirmed (a scrutinized method, e.g. a credit
card or government ID, undifferentiated at this level; six older cases like
.paymentChecked and .governmentIDChecked are deprecated in Apple's own
reference docs and shouldn't drive new logic) -- and an activeParentalControls option
set describing parental controls active on the device, worth checking before enabling any
minor-facing feature even after a successful age-range share.
Two more properties are called independently, not part of the age-range response:
isEligibleForAgeFeatures (iOS/iPadOS/macOS 26.2+) tells you whether
age assurance is legally required for this person/region at all, and
requiredRegulatoryFeatures (iOS/iPadOS/macOS 26.4+, a higher floor
-- don't assume they ship together) tells you which specific obligations apply, e.g.
.declaredAgeRangeRequired or .significantAppChangeRequiresParentalConsent.
Apple's own sample derives an app-level outcome from all of this with four cases:
.minor (route to parental consent), .verifiedAdult (adult,
.confirmed declaration — may still need significant-change acknowledgment),
.unverifiedAdult (adult without a .confirmed declaration —
Apple's own sample blocks access pending verification), and .declinedSharing
(mandatory in some regulated regions, optional in others). Build your gating logic around this
four-case model, not a simpler three-state guess.
Significant Change API: the part most developers miss
This isn't a one-time integration -- it's a trigger you re-evaluate every release. Per Apple's own developer-news language, a change in your app's age rating is automatically treated as a significant change under Texas's law. Beyond that specific automatic trigger, Apple states plainly that it's the developer's responsibility to determine when a change is significant enough to require fresh parental consent -- Apple doesn't hand you an exhaustive checklist. Treat any change that would plausibly change a parent's original consent decision (new social/chat features, new purchase mechanics, new data collection, a rating bump) as a candidate, and document your reasoning for each release.
Mechanically: you call the API to present a system-level dialog requesting guardian re-approval, and Apple can restrict the minor's access until consent is obtained. Consent withdrawal works differently -- you configure your backend to receive an App Store Server Notification when a parent revokes access, rather than polling for it, and your app should block the relevant feature (or launching entirely) on that device when the notification arrives.
Google Play Age Signals API
Google's equivalent is currently beta: a runtime interface that lets your Android app retrieve an age-related signal for the current user directly from Google Play, on devices running Android 6.0 (API level 23) or higher. Google's documented default age bands are 0–12, 13–15, 16–17, and 18+ -- though Google's docs note you can receive custom ranges depending on region/regulatory requirements, so don't hard-code gating logic to exactly four bands everywhere.
The integration flow, per Google's own docs, is four steps: request access to the API for your
app; request the signal itself, which as of the latest release is an explicit two-call pattern
-- call requestAgeSignalsAccess() to trigger the Play in-app prompt, then
checkAgeSignals() to actually receive it (Google's release notes flag this as a
change from an earlier single-call version, so older sample code you find online may be
pre-migration -- check the current use-age-signals-api doc page for the live
signature); receive the response via AgeSignalsResult plus
@AgeSignalsVerificationStatus / @AgeSignalsErrorCode annotations for
handling outcomes and failures; and use the information strictly per Google Play's terms, covered
below. Key classes: AgeSignalsManager, AgeSignalsManagerFactory,
AgeSignalsRequest/.Builder, AgeSignalsResult/.Builder,
AgeSignalsException, and Google's own provided test double,
FakeAgeSignalsManager.
Regional rollout: don't assume every user gets a signal
This determines whether you'll actually get a signal back today. Per Google's own release messaging: Brazil went live March 17, 2026 (tied to Brazil's Digital ECA law); Texas is live for new accounts created after May 28, 2026 (tied to Texas SB 2420); Australia and Canada were rolling out by mid-August 2026; and Google has stated a target of worldwide availability by the end of 2026. If you call this API for a user outside a live region today, expect no signal or an explicit "not available" error code rather than a stale or default value -- build your fallback path around that, don't assume the API silently degrades to "assume adult."
Google's usage restriction is a hard constraint, not a guideline
Per Google's own documentation, the signal may be used only to deliver age-appropriate content/experiences and to meet compliance obligations in regulated regions. It may not be used for advertising, marketing, user profiling, analytics, or any purpose outside age-appropriate gating. Google's docs state that violating this can result in API access termination and app suspension or takedown from Google Play. If your analytics or ad-tech vendor ingests every signal your app touches by default, you need an explicit exception carved out for this one -- audit every downstream consumer of the signal in your codebase, not just the code path that calls the API. You must also accurately complete Play's Data Safety section to reflect that you use this API.
Side by side: what you actually build for each platform
| Apple | Google Play | |
|---|---|---|
| API name | Declared Age Range API + Significant Change API (PermissionKit) | Play Age Signals API (beta) |
| Minimum OS | iOS/iPadOS/macOS 26 (26.2+ and 26.4+ for two specific properties) | Android 6.0 / API level 23 |
| Age representation | Bounds around developer-supplied gates, not a fixed category | Default bands 0–12/13–15/16–17/18+, region-dependent custom ranges possible |
| Call pattern | Single call, four-case outcome model (Apple's own recommended pattern) | Two-call pattern: requestAgeSignalsAccess() then checkAgeSignals() |
| Consent withdrawal | App Store Server Notification to your backend; app must block on receipt | Not documented as a separate mechanic in the current API surface |
| Usage restriction | Governed by App Store policy and the significant-change obligations above | Age-appropriate gating and compliance only — explicitly not for ads/marketing/analytics, enforced by Play ToS |
A practical build checklist
- Confirm your app's minimum OS targets support each API (iOS/iPadOS/macOS 26+, with 26.2+/26.4+
for two specific Apple properties; Android API 23+) and add Apple's
com.apple.developer.declared-age-rangeentitlement in Xcode. - On Apple: call
isEligibleForAgeFeaturesandrequiredRegulatoryFeaturesfirst, choose yourageGatesdeliberately (≥2 years apart), then callrequestAgeRangeand handle all four outcome cases -- don't branch on the deprecated fine-grainedageRangeDeclarationcases. - On Apple: identify every user-facing change in your release pipeline that plausibly needs the Significant Change API, document why each release did or didn't trigger it, and wire up (and actually test in sandbox) App Store Server Notifications for consent withdrawal.
- On Google: confirm your region is live per the rollout table above before treating a missing
signal as an integration bug, call
requestAgeSignalsAccess()beforecheckAgeSignals(), and handle the fullAgeSignalsResultoutcome space including error codes. - On Google: audit every downstream consumer of the signal (analytics, ad SDKs, feature flags) against the usage restriction above, and update your Play Data Safety section accordingly.
- On both platforms: re-check each vendor's current documentation before you ship -- both APIs have already changed method signatures or outcome models once since their initial release.
The documentation-lag lesson applies here too
Apple's own developer documentation is authoritative for what these APIs do and how to call them -- that part is current and reliable. It is not authoritative for when a given state's law takes effect: Apple's own Utah/Louisiana developer-news post is dated February 25, 2026 and still shows both states' pre-amendment dates, months after both were delayed by a year. Cross-check any state deadline against the state's own text or a current law-firm tracker, not against a developer-news post's publish date -- see our companion state-by-state guide for the corrected dates and the full re-verification method.
Sources checked directly for this article: developer.apple.com's Declared Age Range and PermissionKit/SignificantAppUpdateTopic reference documentation, Apple's implementing-age-assurance-and-permissions sample, and Apple developer-news posts dated Oct 8, 2025, Nov 4, 2025, Dec 23, 2025, Feb 25, 2026, and Jun 3, 2026; developer.android.com's Play Age Signals documentation and release notes.