---
description: Capacitor plugin for the Google Play Age Signals API. Retrieve age assurance signals to gate sensitive content and comply with platform regulations.
title: Capacitor Age Signals Plugin for Android & iOS - Capawesome
image: https://capawesome.io/docs/assets/images/social/sdks/capacitor/age-signals.png
---

<!doctype html> 

[Skip to content ](#capacitor-age-signals-plugin) 

[📲 Introducing **Build Sharing** — get your builds onto testers' devices with a link & QR code. No account required. ](/blog/share-mobile-app-builds-with-testers/) 

* [ SDKs ](/docs/sdks/)
* [ iOS ](#ios)
* [ Configuration ](#configuration)
* [ Usage ](#usage)
* [ API ](#api)
* [ Enums ](#enums)
* [ Testing ](#testing)
* [ FAQ ](#faq)
* [ Related Plugins ](#related-plugins)
* [ Newsletter ](#newsletter)
* [ Changelog ](#changelog)
* [ License ](#license)
* [ Alarm ](/docs/sdks/capacitor/alarm/)
* [ Android Battery Optimization ](/docs/sdks/capacitor/android-battery-optimization/)
* [ Android Dark Mode Support ](/docs/sdks/capacitor/android-dark-mode-support/)
* [ Android Edge-to-Edge Support ](/docs/sdks/capacitor/android-edge-to-edge-support/)
* [ Android Foreground Service ](/docs/sdks/capacitor/android-foreground-service/)
* [ Android Intent Launcher ](/docs/sdks/capacitor/android-intent-launcher/)
* [ Android SMS Retriever ](/docs/sdks/capacitor/android-sms-retriever/)
* [ App Icon ](/docs/sdks/capacitor/app-icon/)
* [ App Integrity ](/docs/sdks/capacitor/app-integrity/)
* [ App Language ](/docs/sdks/capacitor/app-language/)
* [ App Launcher ](/docs/sdks/capacitor/app-launcher/)
* [ App Review ](/docs/sdks/capacitor/app-review/)
* [ App Shortcuts ](/docs/sdks/capacitor/app-shortcuts/)
* [ App Tracking Transparency ](/docs/sdks/capacitor/app-tracking-transparency/)
* [ App Update ](/docs/sdks/capacitor/app-update/)
* [ Apple Sign-In ](/docs/sdks/capacitor/apple-sign-in/)
* [ Asset Manager ](/docs/sdks/capacitor/asset-manager/)
* [ Audio Player ](/docs/sdks/capacitor/audio-player/)
* [ Audio Recorder ](/docs/sdks/capacitor/audio-recorder/)
* [ Audio Session ](/docs/sdks/capacitor/audio-session/)
* [ Background Geolocation ](/docs/sdks/capacitor/background-geolocation/)
* [ Background Task ](/docs/sdks/capacitor/background-task/)
* [ Badge ](/docs/sdks/capacitor/badge/)
* [ Barcode Scanner ](/docs/sdks/capacitor/barcode-scanner/)
* [ Barometer ](/docs/sdks/capacitor/barometer/)
* [ Battery ](/docs/sdks/capacitor/battery/)
* [ Biometrics ](/docs/sdks/capacitor/biometrics/)
* [ Bluetooth Low Energy ](/docs/sdks/capacitor/bluetooth-low-energy/)
* [ Calendar ](/docs/sdks/capacitor/calendar/)
* [ Clipboard ](/docs/sdks/capacitor/clipboard/)
* [ Cloudinary ](/docs/sdks/capacitor/cloudinary/)
* [ Compass ](/docs/sdks/capacitor/compass/)
* [ Contacts ](/docs/sdks/capacitor/contacts/)
* [ Crisp ](/docs/sdks/capacitor/crisp/)
* [ Datetime Picker ](/docs/sdks/capacitor/datetime-picker/)
* [ Device Info ](/docs/sdks/capacitor/device-info/)
* [ Dialog ](/docs/sdks/capacitor/dialog/)
* [ Document Scanner ](/docs/sdks/capacitor/document-scanner/)
* [ Electron ](/docs/sdks/capacitor/electron/)
* [ Exif ](/docs/sdks/capacitor/exif/)
* [ Facebook Sign-In ](/docs/sdks/capacitor/facebook-sign-in/)
* [ File Compressor ](/docs/sdks/capacitor/file-compressor/)
* [ File Manager ](/docs/sdks/capacitor/file-manager/)
* [ File Opener ](/docs/sdks/capacitor/file-opener/)
* [ File Picker ](/docs/sdks/capacitor/file-picker/)
* [ File Transfer ](/docs/sdks/capacitor/file-transfer/)
* [ Firebase ](/docs/sdks/capacitor/firebase/)
* [ Formbricks ](/docs/sdks/capacitor/formbricks/)
* [ Geocoder ](/docs/sdks/capacitor/geocoder/)
* [ Geofences ](/docs/sdks/capacitor/geofences/)
* [ Google Sign-In ](/docs/sdks/capacitor/google-sign-in/)
* [ Grafana Faro ](/docs/sdks/capacitor/grafana-faro/)
* [ Gyroscope ](/docs/sdks/capacitor/gyroscope/)
* [ Haptics ](/docs/sdks/capacitor/haptics/)
* [ Health ](/docs/sdks/capacitor/health/)
* [ Home Indicator ](/docs/sdks/capacitor/home-indicator/)
* [ In-App Browser ](/docs/sdks/capacitor/in-app-browser/)
* [ Install Referrer ](/docs/sdks/capacitor/install-referrer/)
* [ Intercom ](/docs/sdks/capacitor/intercom/)
* [ Intune ](/docs/sdks/capacitor/intune/)
* [ Keep Awake ](/docs/sdks/capacitor/keep-awake/)
* [ libSQL ](/docs/sdks/capacitor/libsql/)
* [ Light Sensor ](/docs/sdks/capacitor/light-sensor/)
* [ Live Update ](/docs/sdks/capacitor/live-update/)
* [ LLM ](/docs/sdks/capacitor/llm/)
* [ Localization ](/docs/sdks/capacitor/localization/)
* [ Mail Composer ](/docs/sdks/capacitor/mail-composer/)
* [ Managed Configurations ](/docs/sdks/capacitor/managed-configurations/)
* [ MapLibre ](/docs/sdks/capacitor/maplibre/)
* [ Maps Launcher ](/docs/sdks/capacitor/maps-launcher/)
* [ Media Session ](/docs/sdks/capacitor/media-session/)
* [ ML Kit ](/docs/sdks/capacitor/mlkit/)
* [ Navigation Bar ](/docs/sdks/capacitor/navigation-bar/)
* [ Network ](/docs/sdks/capacitor/network/)
* [ NFC ](/docs/sdks/capacitor/nfc/)
* [ Node.js ](/docs/sdks/capacitor/nodejs/)
* [ OAuth ](/docs/sdks/capacitor/oauth/)
* [ Passkeys ](/docs/sdks/capacitor/passkeys/)
* [ Password Autofill ](/docs/sdks/capacitor/password-autofill/)
* [ PDF Generator ](/docs/sdks/capacitor/pdf-generator/)
* [ PDF Viewer ](/docs/sdks/capacitor/pdf-viewer/)
* [ Pedometer ](/docs/sdks/capacitor/pedometer/)
* [ Permissions ](/docs/sdks/capacitor/permissions/)
* [ Phone Dialer ](/docs/sdks/capacitor/phone-dialer/)
* [ Photo Editor ](/docs/sdks/capacitor/photo-editor/)
* [ Photo Manipulator ](/docs/sdks/capacitor/photo-manipulator/)
* [ PixLive ](/docs/sdks/capacitor/pixlive/)
* [ PostHog ](/docs/sdks/capacitor/posthog/)
* [ Printer ](/docs/sdks/capacitor/printer/)
* [ Privacy Screen ](/docs/sdks/capacitor/privacy-screen/)
* [ Proximity Sensor ](/docs/sdks/capacitor/proximity-sensor/)
* [ Purchases ](/docs/sdks/capacitor/purchases/)
* [ RealtimeKit ](/docs/sdks/capacitor/realtimekit/)
* [ Root Detection ](/docs/sdks/capacitor/root-detection/)
* [ Screen Brightness ](/docs/sdks/capacitor/screen-brightness/)
* [ Screen Orientation ](/docs/sdks/capacitor/screen-orientation/)
* [ Screen Reader ](/docs/sdks/capacitor/screen-reader/)
* [ Screenshot ](/docs/sdks/capacitor/screenshot/)
* [ Secure Preferences ](/docs/sdks/capacitor/secure-preferences/)
* [ Settings Launcher ](/docs/sdks/capacitor/settings-launcher/)
* [ Shake ](/docs/sdks/capacitor/shake/)
* [ Silent Mode ](/docs/sdks/capacitor/silent-mode/)
* [ SIM ](/docs/sdks/capacitor/sim/)
* [ SMS Composer ](/docs/sdks/capacitor/sms-composer/)
* [ Speech Recognition ](/docs/sdks/capacitor/speech-recognition/)
* [ Speech Synthesis ](/docs/sdks/capacitor/speech-synthesis/)
* [ Share Target ](/docs/sdks/capacitor/share-target/)
* [ Square Mobile Payments ](/docs/sdks/capacitor/square-mobile-payments/)
* [ SQLite ](/docs/sdks/capacitor/sqlite/)
* [ Superwall ](/docs/sdks/capacitor/superwall/)
* [ System WebView ](/docs/sdks/capacitor/system-webview/)
* [ Tauri ](/docs/sdks/capacitor/tauri/)
* [ Text Interaction ](/docs/sdks/capacitor/text-interaction/)
* [ Text Zoom ](/docs/sdks/capacitor/text-zoom/)
* [ Thermal State ](/docs/sdks/capacitor/thermal-state/)
* [ Toast ](/docs/sdks/capacitor/toast/)
* [ Torch ](/docs/sdks/capacitor/torch/)
* [ Vault ](/docs/sdks/capacitor/vault/)
* [ Volume ](/docs/sdks/capacitor/volume/)
* [ Wallet ](/docs/sdks/capacitor/wallet/)
* [ Watch ](/docs/sdks/capacitor/watch/)
* [ Wifi ](/docs/sdks/capacitor/wifi/)
* [ YouTube Player ](/docs/sdks/capacitor/youtube-player/)
* [ Zip ](/docs/sdks/capacitor/zip/)
* [ Cordova ](/docs/sdks/cordova/)
* [ Cloud ](/docs/cloud/)
* [ Integrations ](/docs/cloud/live-updates/integrations/)
* Concepts
* Reference
* [ Troubleshooting ](/docs/cloud/live-updates/troubleshooting/)
* [ FAQ ](/docs/cloud/live-updates/faq/)
* [ Native Builds ](/docs/cloud/native-builds/)
* [ Set Up Environments ](/docs/cloud/native-builds/environments/)
* [ Set Up Native Configurations ](/docs/cloud/native-builds/native-configurations/)
* [ Auto-Increment Build Numbers ](/docs/cloud/native-builds/auto-incrementing-build-numbers/)
* [ Configure the Web Build Script ](/docs/cloud/native-builds/web-build-script/)
* [ Build from a Monorepo ](/docs/cloud/native-builds/monorepo/)
* [ Use pnpm, Yarn, or bun ](/docs/cloud/native-builds/package-managers/)
* [ Install Private npm Packages ](/docs/cloud/native-builds/npm-private-registry/)
* [ Override the Java Version ](/docs/cloud/native-builds/override-java-version/)
* [ Custom iOS Provisioning Profiles ](/docs/cloud/native-builds/custom-ios-provisioning-profiles/)
* [ Build without Git ](/docs/cloud/native-builds/build-without-git/)
* [ Access Git Behind a Firewall ](/docs/cloud/native-builds/firewall-access/)
* [ Integrations ](/docs/cloud/native-builds/integrations/)
* Reference
* [ Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [ FAQ ](/docs/cloud/native-builds/faq/)
* [ App Store Publishing ](/docs/cloud/app-store-publishing/)
* [ Submit a Build ](/docs/cloud/app-store-publishing/submit-a-build/)
* [ Submit Automatically After a Build ](/docs/cloud/app-store-publishing/submit-automatically/)
* [ Troubleshooting ](/docs/cloud/app-store-publishing/troubleshooting/)
* [ FAQ ](/docs/cloud/app-store-publishing/faq/)
* [ Automations ](/docs/cloud/automations/)
* [ Reference ](/docs/cloud/automations/reference/)
* [ Troubleshooting ](/docs/cloud/automations/troubleshooting/)
* [ FAQ ](/docs/cloud/automations/faq/)
* [ Assist ](/docs/cloud/assist/)
* [ CLI ](/docs/cloud/cli/)
* APIs and SDKs
* [ Webhooks ](/docs/cloud/webhooks/)
* [ Integrations ](/docs/cloud/integrations/)
* Notifications
* Account
* [ Organization ](/docs/cloud/organizations/)
* [ Two-Factor Enforcement ](/docs/cloud/organizations/two-factor-authentication/)
* [ Network Restrictions ](/docs/cloud/organizations/network-restrictions/)
* [ Audit Logs ](/docs/cloud/organizations/audit-logs/)
* [ Billing ](/docs/cloud/organizations/billing/)
* [ License Keys ](/docs/cloud/license-keys/)
* [ AI ](/docs/ai/)
* [ Insiders ](/docs/insiders/)
* [ Billing & Plans ](/docs/insiders/billing-and-plans/)
* [ FAQ ](/docs/insiders/faq/)
* [ License ](https://capawesome.io/legal/eula/)
* [ Support ](/docs/support/)
* [ Contributing ](/docs/contributing/)
* Contributing code
* [ Code of Conduct ](/docs/contributing/code-of-conduct/)
* [ Questions ](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#creating-a-discussion)
* [ Blog ](/blog/)
* Categories

* [ iOS ](#ios)
* [ Configuration ](#configuration)
* [ Usage ](#usage)
* [ API ](#api)
* [ Enums ](#enums)
* [ Testing ](#testing)
* [ FAQ ](#faq)
* [ Related Plugins ](#related-plugins)
* [ Newsletter ](#newsletter)
* [ Changelog ](#changelog)
* [ License ](#license)

Build and Ship Mobile Apps Faster

Cloud builds, OTA live updates, and automated store releases — everything your mobile team needs in one platform.

[Start for free ](https://console.cloud.capawesome.io/?utm%5Fsource=docs&utm%5Fmedium=sidebar%5Fcta&utm%5Fcampaign=docs%5Fcta) [See our plans ](https://capawesome.io/pricing/?utm%5Fsource=docs&utm%5Fmedium=sidebar%5Fcta&utm%5Fcampaign=docs%5Fcta) 

# Capacitor Age Signals Plugin[¶](#capacitor-age-signals-plugin "Permanent link")

Capacitor plugin to use the [Play Age Signals API](https://developer.android.com/google/play/age-signals/overview) (Android) and [DeclaredAgeRange](https://developer.apple.com/documentation/declaredagerange/) (iOS) to request age signals about the user.

[ ![Deliver Live Updates to your Capacitor app with Capawesome Cloud](../../../assets/external/cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.69628c3f.png) ](https://cloud.capawesome.io/) 

## Features[¶](#features "Permanent link")

The Capacitor Age Signals plugin is one of the most complete age assurance solutions for Capacitor apps. Here are some of the key features:

* 🖥️ **Cross-platform**: Supports Android and iOS.
* 🔍 **Age Verification**: Request user age signals using Play Age Signals API (Android) and DeclaredAgeRange (iOS).
* 👨‍👩‍👧‍👦 **Parental Controls**: Support for supervised accounts with parental approval status.
* 🧪 **Testing Support**: Built-in `FakeAgeSignalsManager` integration for testing different age verification scenarios (Android).
* 🌍 **Compliance Ready**: Built for US state age verification requirements (effective January 1, 2026).
* 🤝 **Compatibility**: Works alongside the [App Integrity](https://capawesome.io/docs/sdks/capacitor/app-integrity/) and [Root Detection](https://capawesome.io/docs/sdks/capacitor/root-detection/) plugins.
* 📦 **CocoaPods & SPM**: Supports CocoaPods and Swift Package Manager for iOS.
* 🔁 **Up-to-date**: Always supports the latest Capacitor version.

Missing a feature? Just [open an issue](https://github.com/capawesome-team/capacitor-plugins/issues) and we'll take a look!

## Use Cases[¶](#use-cases "Permanent link")

The Age Signals plugin is typically used to comply with age verification requirements and to tailor the app experience to the user's age, for example:

* **Age-gated content**: Restrict access to mature or sensitive content based on the user's verification status and age range.
* **Regulatory compliance**: Meet US state age verification requirements by requesting age signals from Google Play and Apple's DeclaredAgeRange API.
* **Parental supervision**: Detect supervised accounts and react to pending or denied parental approvals.
* **Regional eligibility checks**: Use `getRegulatoryRequirements()` on iOS to determine whether the user is in a region with additional age-related obligations.
* **Automated testing**: Simulate different age verification scenarios in your Android tests using the built-in fake manager.

## Compatibility[¶](#compatibility "Permanent link")

| Plugin Version | Capacitor Version | Status         |
| -------------- | ----------------- | -------------- |
| 0.3.x          | \>=8.x.x          | Active support |
| 0.2.x          | 7.x.x             | Deprecated     |

## Installation[¶](#installation "Permanent link")

You can use our **AI-Assisted Setup** to install the plugin. Add the [Capawesome Skills](https://github.com/capawesome-team/skills) to your AI tool using the following command:

`[](#%5F%5Fcodelineno-0-1)npx skills add capawesome-team/skills --skill capacitor-plugins
`

Then use the following prompt:

`` [](#%5F%5Fcodelineno-1-1) Use the `capacitor-plugins` skill from `capawesome-team/skills` to install the `@capawesome/capacitor-age-signals` plugin in my project.
 ``

If you prefer **Manual Setup**, install the plugin by running the following commands and follow the platform-specific instructions below:

`[](#%5F%5Fcodelineno-2-1)npm install @capawesome/capacitor-age-signals
[](#%5F%5Fcodelineno-2-2)npx cap sync
`

### Android[¶](#android "Permanent link")

#### Variables[¶](#variables "Permanent link")

If needed, you can define the following project variable in your app's `variables.gradle` file to change the default version of the dependency:

* `$androidPlayAgeSignalsVersion` version of `com.google.android.play:age-signals` (default: `0.0.4`)

This can be useful if you encounter dependency conflicts with other plugins in your project.

**Note**: The `FakeAgeSignalsManager` testing API is included in the main `age-signals` library, so no additional dependency is required for testing.

### iOS[¶](#ios "Permanent link")

#### Entitlements[¶](#entitlements "Permanent link")

To use the DeclaredAgeRange API, you must enable the `com.apple.developer.declared-age-range` entitlement in your app's entitlements file by adding the following key:

`[](#%5F%5Fcodelineno-3-1)<key>com.apple.developer.declared-age-range</key>
[](#%5F%5Fcodelineno-3-2)<true/>
`

Check out the [Apple documentation](https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.contacts.notes) for more information.

## Configuration[¶](#configuration "Permanent link")

No configuration required for this plugin.

## Usage[¶](#usage "Permanent link")

The following examples show how to request the user's age range and how to react to the regulatory requirements that apply to the user.

### Request the user's age range[¶](#request-the-users-age-range "Permanent link")

Call `requestAgeRange(...)` to ask the user to share their age range. The status tells you whether the age range was shared, and the `ageRange` property contains the bounds:

`[](#%5F%5Fcodelineno-4-1)import { AgeRangeStatus, AgeSignals } from '@capawesome/capacitor-age-signals';
[](#%5F%5Fcodelineno-4-2)
[](#%5F%5Fcodelineno-4-3)const requestAgeRange = async () => {
[](#%5F%5Fcodelineno-4-4)  const result = await AgeSignals.requestAgeRange();
[](#%5F%5Fcodelineno-4-5)  if (result.status !== AgeRangeStatus.Shared) {
[](#%5F%5Fcodelineno-4-6)    console.log('The user has not shared their age range:', result.status);
[](#%5F%5Fcodelineno-4-7)    return;
[](#%5F%5Fcodelineno-4-8)  }
[](#%5F%5Fcodelineno-4-9)  console.log('Lower Bound:', result.ageRange?.lowerBound);
[](#%5F%5Fcodelineno-4-10)  console.log('Upper Bound:', result.ageRange?.upperBound);
[](#%5F%5Fcodelineno-4-11)};
`

On Android, a status of `VERIFICATION_REQUIRED` means the user must resolve their status in the Google Play Store before an age range can be shared.

### Read the age range without prompting[¶](#read-the-age-range-without-prompting "Permanent link")

Call `getAgeRange()` to read the age range again without showing a prompt. This is useful to poll for a `significantChange` status that moves from `PENDING` to `APPROVED`. Only available on Android:

`[](#%5F%5Fcodelineno-5-1)import { AgeSignals } from '@capawesome/capacitor-age-signals';
[](#%5F%5Fcodelineno-5-2)
[](#%5F%5Fcodelineno-5-3)const getAgeRange = async () => {
[](#%5F%5Fcodelineno-5-4)  const result = await AgeSignals.getAgeRange();
[](#%5F%5Fcodelineno-5-5)  console.log('Significant Change:', result.significantChange?.status);
[](#%5F%5Fcodelineno-5-6)};
`

### Check the regulatory requirements[¶](#check-the-regulatory-requirements "Permanent link")

Check whether the user is in a region and account state that requires age assurance, and which regulatory features your app must support. Only available on iOS:

`[](#%5F%5Fcodelineno-6-1)import {
[](#%5F%5Fcodelineno-6-2)  AgeSignals,
[](#%5F%5Fcodelineno-6-3)  RegulatoryFeature,
[](#%5F%5Fcodelineno-6-4)} from '@capawesome/capacitor-age-signals';
[](#%5F%5Fcodelineno-6-5)
[](#%5F%5Fcodelineno-6-6)const getRegulatoryRequirements = async () => {
[](#%5F%5Fcodelineno-6-7)  const result = await AgeSignals.getRegulatoryRequirements();
[](#%5F%5Fcodelineno-6-8)  if (
[](#%5F%5Fcodelineno-6-9)    result.regulatoryFeatures.includes(
[](#%5F%5Fcodelineno-6-10)      RegulatoryFeature.SignificantAppChangeRequiresAdultNotification,
[](#%5F%5Fcodelineno-6-11)    )
[](#%5F%5Fcodelineno-6-12)  ) {
[](#%5F%5Fcodelineno-6-13)    await AgeSignals.showSignificantUpdateAcknowledgment({
[](#%5F%5Fcodelineno-6-14)      updateDescription: 'This app now supports direct messages between users.',
[](#%5F%5Fcodelineno-6-15)    });
[](#%5F%5Fcodelineno-6-16)  }
[](#%5F%5Fcodelineno-6-17)};
`

## API[¶](#api "Permanent link")

* [getAgeRange()](#getagerange)
* [getRegulatoryRequirements()](#getregulatoryrequirements)
* [isAvailable()](#isavailable)
* [requestAgeRange(...)](#requestagerange)
* [setNextAgeSignalsAccessResult(...)](#setnextagesignalsaccessresult)
* [setNextAgeSignalsException(...)](#setnextagesignalsexception)
* [setNextAgeSignalsResult(...)](#setnextagesignalsresult)
* [setNextRequestAgeSignalsAccessException(...)](#setnextrequestagesignalsaccessexception)
* [setUseFakeManager(...)](#setusefakemanager)
* [showSignificantUpdateAcknowledgment(...)](#showsignificantupdateacknowledgment)
* [Interfaces](#interfaces)
* [Enums](#enums)

### getAgeRange()[¶](#getagerange "Permanent link")

`[](#%5F%5Fcodelineno-7-1)getAgeRange() => Promise<GetAgeRangeResult>
`

Get the age range that the user has already shared with the app.

This method never shows a system prompt. Call `requestAgeRange(...)` first and only call this method if the returned status was `SHARED`.

Use this method to poll for changes (for example a `significantChange`status that moves from `PENDING` to `APPROVED`) without prompting the user again.

Only available on Android.

**Returns:** `Promise<[GetAgeRangeResult](#getagerangeresult)>`

**Since:** 0.5.0

---

### getRegulatoryRequirements()[¶](#getregulatoryrequirements "Permanent link")

`[](#%5F%5Fcodelineno-8-1)getRegulatoryRequirements() => Promise<GetRegulatoryRequirementsResult>
`

Get the regulatory requirements that apply to the current user.

Call this method before starting any age assurance flow to find out whether the user is in a region and account state where age assurance applies at all.

Only available on iOS (26.2+).

**Returns:** `Promise<[GetRegulatoryRequirementsResult](#getregulatoryrequirementsresult)>`

**Since:** 0.5.0

---

### isAvailable()[¶](#isavailable "Permanent link")

`[](#%5F%5Fcodelineno-9-1)isAvailable() => Promise<IsAvailableResult>
`

Check whether age signals are available on this device.

On **Android**, this checks whether the Google Play Store is installed. On **iOS**, this checks whether the device runs iOS 26.0 or later.

A result of `true` does not guarantee that an age range can be retrieved. Always handle the errors of the other methods as well.

**Returns:** `Promise<[IsAvailableResult](#isavailableresult)>`

**Since:** 0.5.0

---

### requestAgeRange(...)[¶](#requestagerange "Permanent link")

`[](#%5F%5Fcodelineno-10-1)requestAgeRange(options?: RequestAgeRangeOptions | undefined) => Promise<RequestAgeRangeResult>
`

Ask the user to share their age range with the app.

This method may show a system prompt. The system caches the decision of the user, so subsequent calls may resolve without any user interaction.

On **Android**, the prompt is only shown to unsupervised users who have chosen to be asked before sharing. It is not shown in regions where age verification is mandatory. In that case the status is `VERIFICATION_REQUIRED` and the user must resolve their status in the Google Play Store. Google Play also suppresses the prompt after the user has dismissed or declined it a few times. On **iOS**, the prompt is not shown in regions where age assurance is mandatory. In that case the age range is shared without user interaction.

| Param       | Type                                              |
| ----------- | ------------------------------------------------- |
| **options** | [RequestAgeRangeOptions](#requestagerangeoptions) |

**Returns:** `Promise<[RequestAgeRangeResult](#requestagerangeresult)>`

**Since:** 0.5.0

---

### setNextAgeSignalsAccessResult(...)[¶](#setnextagesignalsaccessresult "Permanent link")

`[](#%5F%5Fcodelineno-11-1)setNextAgeSignalsAccessResult(options: SetNextAgeSignalsAccessResultOptions) => Promise<void>
`

Set the next access result to be returned by the fake manager.

Only available on Android.

| Param       | Type                                                                          |
| ----------- | ----------------------------------------------------------------------------- |
| **options** | [SetNextAgeSignalsAccessResultOptions](#setnextagesignalsaccessresultoptions) |

**Since:** 0.5.0

---

### setNextAgeSignalsException(...)[¶](#setnextagesignalsexception "Permanent link")

`[](#%5F%5Fcodelineno-12-1)setNextAgeSignalsException(options: SetNextAgeSignalsExceptionOptions) => Promise<void>
`

Set the next error to be thrown by the fake manager when the age range is read.

Only available on Android.

| Param       | Type                                                                    |
| ----------- | ----------------------------------------------------------------------- |
| **options** | [SetNextAgeSignalsExceptionOptions](#setnextagesignalsexceptionoptions) |

**Since:** 0.3.1

---

### setNextAgeSignalsResult(...)[¶](#setnextagesignalsresult "Permanent link")

`[](#%5F%5Fcodelineno-13-1)setNextAgeSignalsResult(options: SetNextAgeSignalsResultOptions) => Promise<void>
`

Set the next age range result to be returned by the fake manager.

Only available on Android.

| Param       | Type                                                              |
| ----------- | ----------------------------------------------------------------- |
| **options** | [SetNextAgeSignalsResultOptions](#setnextagesignalsresultoptions) |

**Since:** 0.3.1

---

### setNextRequestAgeSignalsAccessException(...)[¶](#setnextrequestagesignalsaccessexception "Permanent link")

`[](#%5F%5Fcodelineno-14-1)setNextRequestAgeSignalsAccessException(options: SetNextRequestAgeSignalsAccessExceptionOptions) => Promise<void>
`

Set the next error to be thrown by the fake manager when access to the age range is requested.

Only available on Android.

| Param       | Type                                                                                              |
| ----------- | ------------------------------------------------------------------------------------------------- |
| **options** | [SetNextRequestAgeSignalsAccessExceptionOptions](#setnextrequestagesignalsaccessexceptionoptions) |

**Since:** 0.5.0

---

### setUseFakeManager(...)[¶](#setusefakemanager "Permanent link")

`[](#%5F%5Fcodelineno-15-1)setUseFakeManager(options: SetUseFakeManagerOptions) => Promise<void>
`

Enable or disable the fake manager for testing.

The fake manager is only available in debuggable builds. In release builds this method rejects with `FAKE_MANAGER_NOT_ALLOWED`, because it would otherwise allow age signals to be forged from the web layer.

Only available on Android.

| Param       | Type                                                  |
| ----------- | ----------------------------------------------------- |
| **options** | [SetUseFakeManagerOptions](#setusefakemanageroptions) |

**Since:** 0.3.1

---

### showSignificantUpdateAcknowledgment(...)[¶](#showsignificantupdateacknowledgment "Permanent link")

`[](#%5F%5Fcodelineno-16-1)showSignificantUpdateAcknowledgment(options: ShowSignificantUpdateAcknowledgmentOptions) => Promise<void>
`

Show a system interface that lets the user acknowledge a significant change to the app.

Only call this method if `getRegulatoryRequirements()` returned `SIGNIFICANT_APP_CHANGE_REQUIRES_ADULT_NOTIFICATION`.

Only available on iOS (26.4+).

| Param       | Type                                                                                      |
| ----------- | ----------------------------------------------------------------------------------------- |
| **options** | [ShowSignificantUpdateAcknowledgmentOptions](#showsignificantupdateacknowledgmentoptions) |

**Since:** 0.5.0

---

### Interfaces[¶](#interfaces "Permanent link")

#### GetAgeRangeResult[¶](#getagerangeresult "Permanent link")

| Prop                  | Type                                    | Description                                                                                                                                                                                                                                                                                                                                                                                                    | Since |
| --------------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **ageRange**          | [AgeRange](#agerange)                   | The age range that the user has shared with the app. undefined if the user has not shared their age range.                                                                                                                                                                                                                                                                                                     | 0.5.0 |
| **installId**         | string                                  | An ID assigned to supervised user installs by Google Play, used for the purposes of notifying you of revoked app approval. Only available on Android.                                                                                                                                                                                                                                                          | 0.5.0 |
| **significantChange** | [SignificantChange](#significantchange) | The parental approval state for the significant changes of the app. Significant changes are declared in the Google Play Console. Google Play then asks the parent or guardian of a supervised user to approve them. undefined if the user is not supervised, if no significant change has been declared yet or if significant changes do not apply in the jurisdiction of the user. Only available on Android. | 0.5.0 |

#### AgeRange[¶](#agerange "Permanent link")

| Prop                       | Type                                        | Description                                                                                                                                                                   | Since |
| -------------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **activeParentalControls** | ParentalControl\[\]                         | The parental controls that are active for the user. Only available on iOS.                                                                                                    | 0.5.0 |
| **ageRangeDeclaration**    | [AgeRangeDeclaration](#agerangedeclaration) | How the age range was declared. The more granular values are only returned in some regions. undefined if the system does not provide this information. Only available on iOS. | 0.5.0 |
| **ageRangeSource**         | [AgeRangeSource](#agerangesource)           | How the age range was established. undefined if the system does not provide this information. Only available on Android.                                                      | 0.5.0 |
| **lowerBound**             | number                                      | The (inclusive) lower bound of the age range. undefined if the user is below the lowest requested age gate.                                                                   | 0.5.0 |
| **upperBound**             | number                                      | The (inclusive) upper bound of the age range. undefined if the user meets or exceeds the highest requested age gate.                                                          | 0.5.0 |

#### SignificantChange[¶](#significantchange "Permanent link")

| Prop             | Type                                                | Description                                                                                                                                                                                                                     | Since |
| ---------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **approvalDate** | string                                              | The effective date of the most recently approved significant change, in ISO 8601 format. All significant changes with an earlier effective date are approved as well. undefined if no significant change has been approved yet. | 0.5.0 |
| **status**       | [SignificantChangeStatus](#significantchangestatus) | The parental approval state for the most recent significant change.                                                                                                                                                             | 0.5.0 |

#### GetRegulatoryRequirementsResult[¶](#getregulatoryrequirementsresult "Permanent link")

| Prop                     | Type                  | Description                                                                                                          | Since |
| ------------------------ | --------------------- | -------------------------------------------------------------------------------------------------------------------- | ----- |
| **ageAssuranceRequired** | boolean               | Whether the user must share their age range because of a law or regulation that applies to their region and account. | 0.5.0 |
| **regulatoryFeatures**   | RegulatoryFeature\[\] | The regulatory features that the app must support for this user. Empty on iOS versions below 26.4.                   | 0.5.0 |

#### IsAvailableResult[¶](#isavailableresult "Permanent link")

| Prop          | Type    | Description                                       | Since |
| ------------- | ------- | ------------------------------------------------- | ----- |
| **available** | boolean | Whether age signals are available on this device. | 0.5.0 |

#### RequestAgeRangeResult[¶](#requestagerangeresult "Permanent link")

| Prop                  | Type                                    | Description                                                                                                                                                                                                                                                                                                                                                                                                    | Since |
| --------------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **ageRange**          | [AgeRange](#agerange)                   | The age range that the user has shared with the app. undefined if the status is not SHARED.                                                                                                                                                                                                                                                                                                                    | 0.5.0 |
| **installId**         | string                                  | An ID assigned to supervised user installs by Google Play, used for the purposes of notifying you of revoked app approval. Only available on Android.                                                                                                                                                                                                                                                          | 0.5.0 |
| **significantChange** | [SignificantChange](#significantchange) | The parental approval state for the significant changes of the app. Significant changes are declared in the Google Play Console. Google Play then asks the parent or guardian of a supervised user to approve them. undefined if the user is not supervised, if no significant change has been declared yet or if significant changes do not apply in the jurisdiction of the user. Only available on Android. | 0.5.0 |
| **status**            | [AgeRangeStatus](#agerangestatus)       | Whether the user has shared their age range with the app.                                                                                                                                                                                                                                                                                                                                                      | 0.5.0 |

#### RequestAgeRangeOptions[¶](#requestagerangeoptions "Permanent link")

| Prop         | Type       | Description                                                                                                                                                                                                                                                                                                                                          | Default        | Since |
| ------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ----- |
| **ageGates** | number\[\] | The age thresholds that are relevant for the app. The provided array must contain at least 1 and at most 3 ages. The ages must be sorted in ascending order and must be at least two years apart from each other. The system may ignore these thresholds and return a different age range if a law or regulation requires it. Only available on iOS. | \[13, 15, 18\] | 0.5.0 |

#### SetNextAgeSignalsAccessResultOptions[¶](#setnextagesignalsaccessresultoptions "Permanent link")

| Prop       | Type                              | Description                                    | Since |
| ---------- | --------------------------------- | ---------------------------------------------- | ----- |
| **status** | [AgeRangeStatus](#agerangestatus) | The status to be returned by the fake manager. | 0.5.0 |

#### SetNextAgeSignalsExceptionOptions[¶](#setnextagesignalsexceptionoptions "Permanent link")

| Prop          | Type                    | Description                                                                                                        | Since |
| ------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------ | ----- |
| **errorCode** | [ErrorCode](#errorcode) | The error code to be thrown by the fake manager. Only the error codes that are available on Android are supported. | 0.3.1 |

#### SetNextAgeSignalsResultOptions[¶](#setnextagesignalsresultoptions "Permanent link")

| Prop                              | Type                                                | Description                                                                              | Since |
| --------------------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------------------- | ----- |
| **ageLower**                      | number                                              | The (inclusive) lower bound of the age range.                                            | 0.3.1 |
| **ageRangeSource**                | [AgeRangeSource](#agerangesource)                   | How the age range was established.                                                       | 0.5.0 |
| **ageUpper**                      | number                                              | The (inclusive) upper bound of the age range.                                            | 0.3.1 |
| **installId**                     | string                                              | An ID assigned to supervised user installs by Google Play.                               | 0.3.1 |
| **significantChangeApprovalDate** | string                                              | The effective date of the most recently approved significant change, in ISO 8601 format. | 0.5.0 |
| **significantChangeStatus**       | [SignificantChangeStatus](#significantchangestatus) | The parental approval state for the most recent significant change.                      | 0.5.0 |

#### SetNextRequestAgeSignalsAccessExceptionOptions[¶](#setnextrequestagesignalsaccessexceptionoptions "Permanent link")

| Prop          | Type                    | Description                                                                                                        | Since |
| ------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------ | ----- |
| **errorCode** | [ErrorCode](#errorcode) | The error code to be thrown by the fake manager. Only the error codes that are available on Android are supported. | 0.5.0 |

#### SetUseFakeManagerOptions[¶](#setusefakemanageroptions "Permanent link")

| Prop        | Type    | Description                                  | Default | Since |
| ----------- | ------- | -------------------------------------------- | ------- | ----- |
| **useFake** | boolean | Whether to use the fake manager for testing. | false   | 0.3.1 |

#### ShowSignificantUpdateAcknowledgmentOptions[¶](#showsignificantupdateacknowledgmentoptions "Permanent link")

| Prop                  | Type   | Description                                                                              | Since |
| --------------------- | ------ | ---------------------------------------------------------------------------------------- | ----- |
| **updateDescription** | string | A short description of what has changed in the app and why the user must acknowledge it. | 0.5.0 |

### Enums[¶](#enums "Permanent link")

#### ParentalControl[¶](#parentalcontrol "Permanent link")

| Members                 | Value                   | Description                                                | Since |
| ----------------------- | ----------------------- | ---------------------------------------------------------- | ----- |
| **CommunicationLimits** | 'COMMUNICATION\_LIMITS' | The system limits the communication features for the user. | 0.5.0 |

#### AgeRangeDeclaration[¶](#agerangedeclaration "Permanent link")

| Members                          | Value                                  | Description                                                                                                           | Since |
| -------------------------------- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ----- |
| **CheckedByOtherMethod**         | 'CHECKED\_BY\_OTHER\_METHOD'           | The user set their own age range using an unspecified method. Only available on iOS (26.2+).                          | 0.5.0 |
| **Confirmed**                    | 'CONFIRMED'                            | The age range was set using a scrutinized method, like a credit card or government ID. Only available on iOS (26.5+). | 0.4.0 |
| **GovernmentIdChecked**          | 'GOVERNMENT\_ID\_CHECKED'              | The user set their own age range using a government ID. Only available on iOS (26.2+).                                | 0.5.0 |
| **GuardianCheckedByOtherMethod** | 'GUARDIAN\_CHECKED\_BY\_OTHER\_METHOD' | A parent or guardian set the age range using an unspecified method. Only available on iOS (26.2+).                    | 0.5.0 |
| **GuardianDeclared**             | 'GUARDIAN\_DECLARED'                   | A parent or guardian declared the age range without external verification.                                            | 0.4.0 |
| **GuardianGovernmentIdChecked**  | 'GUARDIAN\_GOVERNMENT\_ID\_CHECKED'    | A parent or guardian set the age range using a government ID. Only available on iOS (26.2+).                          | 0.5.0 |
| **GuardianPaymentChecked**       | 'GUARDIAN\_PAYMENT\_CHECKED'           | A parent or guardian set the age range using a payment method, like a credit card. Only available on iOS (26.2+).     | 0.5.0 |
| **PaymentChecked**               | 'PAYMENT\_CHECKED'                     | The user set their own age range using a payment method, like a credit card. Only available on iOS (26.2+).           | 0.5.0 |
| **SelfDeclared**                 | 'SELF\_DECLARED'                       | The user declared their own age range without external verification.                                                  | 0.4.0 |

#### AgeRangeSource[¶](#agerangesource "Permanent link")

| Members   | Value     | Description                                                                                                               | Since |
| --------- | --------- | ------------------------------------------------------------------------------------------------------------------------- | ----- |
| **TierA** | 'TIER\_A' | The user has self-declared their age.                                                                                     | 0.5.0 |
| **TierB** | 'TIER\_B' | The age of the user is managed by a parent or guardian.                                                                   | 0.5.0 |
| **TierC** | 'TIER\_C' | The age of the user was assessed using a credit card, an email address, a selfie assessment, a government ID or a tax ID. | 0.5.0 |
| **TierD** | 'TIER\_D' | The age of the user was checked using a combination of a government ID and a selfie assessment, or using a digital ID.    | 0.5.0 |

#### SignificantChangeStatus[¶](#significantchangestatus "Permanent link")

| Members      | Value      | Description                                                                                               | Since |
| ------------ | ---------- | --------------------------------------------------------------------------------------------------------- | ----- |
| **Approved** | 'APPROVED' | The parent or guardian has approved the most recent significant change and all prior significant changes. | 0.5.0 |
| **Declined** | 'DECLINED' | The parent or guardian has declined one or more significant changes.                                      | 0.5.0 |
| **Pending**  | 'PENDING'  | The parent or guardian has not yet approved one or more significant changes.                              | 0.5.0 |

#### RegulatoryFeature[¶](#regulatoryfeature "Permanent link")

| Members                                           | Value                                                     | Description                                                                                                                                                                        | Since |
| ------------------------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **DeclaredAgeRangeRequired**                      | 'DECLARED\_AGE\_RANGE\_REQUIRED'                          | The user must share their age range with the app.                                                                                                                                  | 0.5.0 |
| **SignificantAppChangeRequiresAdultNotification** | 'SIGNIFICANT\_APP\_CHANGE\_REQUIRES\_ADULT\_NOTIFICATION' | An adult user must acknowledge a significant change of the app. Use showSignificantUpdateAcknowledgment(...) to show the system interface for the acknowledgment.                  | 0.5.0 |
| **SignificantAppChangeRequiresParentalConsent**   | 'SIGNIFICANT\_APP\_CHANGE\_REQUIRES\_PARENTAL\_CONSENT'   | A parent or guardian must consent to a significant change of the app. This plugin does not implement the consent flow. Use Apple's PermissionKit framework to request the consent. | 0.5.0 |

#### AgeRangeStatus[¶](#agerangestatus "Permanent link")

| Members                  | Value                    | Description                                                                                                                                                                              | Since |
| ------------------------ | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **NotShared**            | 'NOT\_SHARED'            | The user has not shared their age range with the app.                                                                                                                                    | 0.5.0 |
| **Shared**               | 'SHARED'                 | The user has shared their age range with the app.                                                                                                                                        | 0.5.0 |
| **Unspecified**          | 'UNSPECIFIED'            | The system did not specify whether the user has shared their age range. Treat this value like NOT\_SHARED. Google Play does not document when it is returned. Only available on Android. | 0.5.0 |
| **VerificationRequired** | 'VERIFICATION\_REQUIRED' | The user must verify their age in the Google Play Store before the age range can be shared. Only available on Android.                                                                   | 0.5.0 |

#### ErrorCode[¶](#errorcode "Permanent link")

| Members                            | Value                                | Description                                                                                                                                                                                 | Since |
| ---------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **ApiNotAvailable**                | 'API\_NOT\_AVAILABLE'                | The age signals API is not available. On **Android**, the Play Store app version installed on the device might be old. On **iOS**, the system was unable to share the age range.            | 0.0.1 |
| **AppNotOwned**                    | 'APP\_NOT\_OWNED'                    | The app was not installed by Google Play. Only available on Android.                                                                                                                        | 0.0.1 |
| **CannotBindToService**            | 'CANNOT\_BIND\_TO\_SERVICE'          | Binding to the service in the Play Store has failed. This can be due to having an old Play Store version installed on the device or device memory is overloaded. Only available on Android. | 0.0.1 |
| **ClientTransientError**           | 'CLIENT\_TRANSIENT\_ERROR'           | There was a transient error in the client device. Only available on Android.                                                                                                                | 0.0.1 |
| **FakeManagerNotAllowed**          | 'FAKE\_MANAGER\_NOT\_ALLOWED'        | The fake manager is not available, because the app is not debuggable. Only available on Android.                                                                                            | 0.5.0 |
| **FakeManagerNotEnabled**          | 'FAKE\_MANAGER\_NOT\_ENABLED'        | The fake manager is not enabled. Only available on Android.                                                                                                                                 | 0.5.0 |
| **InternalError**                  | 'INTERNAL\_ERROR'                    | Unknown internal error. Only available on Android.                                                                                                                                          | 0.0.1 |
| **InvalidRequest**                 | 'INVALID\_REQUEST'                   | The request contains invalid parameters. On **iOS**, this is also returned if the requested age gates are rejected by the system.                                                           | 0.5.0 |
| **NetworkError**                   | 'NETWORK\_ERROR'                     | No available network is found. Only available on Android.                                                                                                                                   | 0.0.1 |
| **NotSupported**                   | 'NOT\_SUPPORTED'                     | Age signals are not supported on this device.                                                                                                                                               | 0.5.0 |
| **PlayServicesNotFound**           | 'PLAY\_SERVICES\_NOT\_FOUND'         | Play Services is not available or its version is too old. Only available on Android.                                                                                                        | 0.0.1 |
| **PlayServicesVersionOutdated**    | 'PLAY\_SERVICES\_VERSION\_OUTDATED'  | Play Services needs to be updated. Only available on Android.                                                                                                                               | 0.0.1 |
| **PlayStoreNotFound**              | 'PLAY\_STORE\_NOT\_FOUND'            | No Play Store app is found on the device. Only available on Android.                                                                                                                        | 0.0.1 |
| **PlayStoreVersionOutdated**       | 'PLAY\_STORE\_VERSION\_OUTDATED'     | The Play Store app needs to be updated. Only available on Android.                                                                                                                          | 0.0.1 |
| **PresentationContextUnavailable** | 'PRESENTATION\_CONTEXT\_UNAVAILABLE' | No view controller was found to present the system interface. Only available on iOS.                                                                                                        | 0.5.0 |
| **SdkVersionOutdated**             | 'SDK\_VERSION\_OUTDATED'             | The Age Signals SDK version is outdated. Only available on Android.                                                                                                                         | 0.4.0 |

## Testing[¶](#testing "Permanent link")

The plugin includes support for the `FakeAgeSignalsManager` API on Android, which allows you to simulate different age signals scenarios in your tests without requiring live responses from Google Play.

### Android Testing[¶](#android-testing "Permanent link")

**Important**: The fake manager is only available if your app is debuggable. In release builds, `setUseFakeManager(...)` rejects with `FAKE_MANAGER_NOT_ALLOWED`, because it would otherwise allow age signals to be forged from the web layer.

**Important**: Due to a known issue in versions 0.0.1 and 0.0.2 of the Age Signals API, you may encounter a `java.lang.VerifyError` when calling the builder method of `AgeSignalsResult` in unit tests. As a workaround, run your tests as Android instrumented tests within the `androidTest` source set.

#### Example: Testing a Self-Declared Adult User[¶](#example-testing-a-self-declared-adult-user "Permanent link")

`[](#%5F%5Fcodelineno-17-1)import {
[](#%5F%5Fcodelineno-17-2)  AgeRangeSource,
[](#%5F%5Fcodelineno-17-3)  AgeRangeStatus,
[](#%5F%5Fcodelineno-17-4)  AgeSignals,
[](#%5F%5Fcodelineno-17-5)} from '@capawesome/capacitor-age-signals';
[](#%5F%5Fcodelineno-17-6)
[](#%5F%5Fcodelineno-17-7)// Enable the fake manager
[](#%5F%5Fcodelineno-17-8)await AgeSignals.setUseFakeManager({ useFake: true });
[](#%5F%5Fcodelineno-17-9)
[](#%5F%5Fcodelineno-17-10)// The user agrees to share their age range
[](#%5F%5Fcodelineno-17-11)await AgeSignals.setNextAgeSignalsAccessResult({
[](#%5F%5Fcodelineno-17-12)  status: AgeRangeStatus.Shared,
[](#%5F%5Fcodelineno-17-13)});
[](#%5F%5Fcodelineno-17-14)
[](#%5F%5Fcodelineno-17-15)// Set up an adult user
[](#%5F%5Fcodelineno-17-16)await AgeSignals.setNextAgeSignalsResult({
[](#%5F%5Fcodelineno-17-17)  ageLower: 18,
[](#%5F%5Fcodelineno-17-18)  ageRangeSource: AgeRangeSource.TierA,
[](#%5F%5Fcodelineno-17-19)});
[](#%5F%5Fcodelineno-17-20)
[](#%5F%5Fcodelineno-17-21)const result = await AgeSignals.requestAgeRange();
[](#%5F%5Fcodelineno-17-22)console.log(result.status); // 'SHARED'
[](#%5F%5Fcodelineno-17-23)console.log(result.ageRange?.lowerBound); // 18
`

#### Example: Testing a Supervised User (13-17 years old)[¶](#example-testing-a-supervised-user-13-17-years-old "Permanent link")

`[](#%5F%5Fcodelineno-18-1)import {
[](#%5F%5Fcodelineno-18-2)  AgeRangeSource,
[](#%5F%5Fcodelineno-18-3)  AgeRangeStatus,
[](#%5F%5Fcodelineno-18-4)  AgeSignals,
[](#%5F%5Fcodelineno-18-5)} from '@capawesome/capacitor-age-signals';
[](#%5F%5Fcodelineno-18-6)
[](#%5F%5Fcodelineno-18-7)await AgeSignals.setUseFakeManager({ useFake: true });
[](#%5F%5Fcodelineno-18-8)
[](#%5F%5Fcodelineno-18-9)await AgeSignals.setNextAgeSignalsAccessResult({
[](#%5F%5Fcodelineno-18-10)  status: AgeRangeStatus.Shared,
[](#%5F%5Fcodelineno-18-11)});
[](#%5F%5Fcodelineno-18-12)
[](#%5F%5Fcodelineno-18-13)await AgeSignals.setNextAgeSignalsResult({
[](#%5F%5Fcodelineno-18-14)  ageLower: 13,
[](#%5F%5Fcodelineno-18-15)  ageUpper: 17,
[](#%5F%5Fcodelineno-18-16)  ageRangeSource: AgeRangeSource.TierB,
[](#%5F%5Fcodelineno-18-17)  installId: 'fake_install_id',
[](#%5F%5Fcodelineno-18-18)});
[](#%5F%5Fcodelineno-18-19)
[](#%5F%5Fcodelineno-18-20)const result = await AgeSignals.requestAgeRange();
[](#%5F%5Fcodelineno-18-21)console.log(result.ageRange?.lowerBound); // 13
[](#%5F%5Fcodelineno-18-22)console.log(result.ageRange?.upperBound); // 17
[](#%5F%5Fcodelineno-18-23)console.log(result.installId); // 'fake_install_id'
`

#### Example: Testing Parental Approval Scenarios[¶](#example-testing-parental-approval-scenarios "Permanent link")

`[](#%5F%5Fcodelineno-19-1)import {
[](#%5F%5Fcodelineno-19-2)  AgeRangeSource,
[](#%5F%5Fcodelineno-19-3)  AgeRangeStatus,
[](#%5F%5Fcodelineno-19-4)  AgeSignals,
[](#%5F%5Fcodelineno-19-5)  SignificantChangeStatus,
[](#%5F%5Fcodelineno-19-6)} from '@capawesome/capacitor-age-signals';
[](#%5F%5Fcodelineno-19-7)
[](#%5F%5Fcodelineno-19-8)await AgeSignals.setUseFakeManager({ useFake: true });
[](#%5F%5Fcodelineno-19-9)
[](#%5F%5Fcodelineno-19-10)await AgeSignals.setNextAgeSignalsAccessResult({
[](#%5F%5Fcodelineno-19-11)  status: AgeRangeStatus.Shared,
[](#%5F%5Fcodelineno-19-12)});
[](#%5F%5Fcodelineno-19-13)
[](#%5F%5Fcodelineno-19-14)// Test pending approval
[](#%5F%5Fcodelineno-19-15)await AgeSignals.setNextAgeSignalsResult({
[](#%5F%5Fcodelineno-19-16)  ageLower: 13,
[](#%5F%5Fcodelineno-19-17)  ageUpper: 17,
[](#%5F%5Fcodelineno-19-18)  ageRangeSource: AgeRangeSource.TierB,
[](#%5F%5Fcodelineno-19-19)  significantChangeApprovalDate: '2026-02-01T00:00:00.000Z',
[](#%5F%5Fcodelineno-19-20)  significantChangeStatus: SignificantChangeStatus.Pending,
[](#%5F%5Fcodelineno-19-21)});
[](#%5F%5Fcodelineno-19-22)
[](#%5F%5Fcodelineno-19-23)const result = await AgeSignals.requestAgeRange();
[](#%5F%5Fcodelineno-19-24)console.log(result.significantChange?.status); // 'PENDING'
[](#%5F%5Fcodelineno-19-25)console.log(result.significantChange?.approvalDate); // '2026-02-01T00:00:00.000Z'
`

#### Example: Testing a User Who Must Verify Their Age[¶](#example-testing-a-user-who-must-verify-their-age "Permanent link")

`[](#%5F%5Fcodelineno-20-1)import { AgeRangeStatus, AgeSignals } from '@capawesome/capacitor-age-signals';
[](#%5F%5Fcodelineno-20-2)
[](#%5F%5Fcodelineno-20-3)await AgeSignals.setUseFakeManager({ useFake: true });
[](#%5F%5Fcodelineno-20-4)
[](#%5F%5Fcodelineno-20-5)await AgeSignals.setNextAgeSignalsAccessResult({
[](#%5F%5Fcodelineno-20-6)  status: AgeRangeStatus.VerificationRequired,
[](#%5F%5Fcodelineno-20-7)});
[](#%5F%5Fcodelineno-20-8)
[](#%5F%5Fcodelineno-20-9)const result = await AgeSignals.requestAgeRange();
[](#%5F%5Fcodelineno-20-10)console.log(result.status); // 'VERIFICATION_REQUIRED'
[](#%5F%5Fcodelineno-20-11)console.log(result.ageRange); // undefined
`

#### Example: Testing Error Scenarios[¶](#example-testing-error-scenarios "Permanent link")

`[](#%5F%5Fcodelineno-21-1)import { AgeSignals, ErrorCode } from '@capawesome/capacitor-age-signals';
[](#%5F%5Fcodelineno-21-2)
[](#%5F%5Fcodelineno-21-3)await AgeSignals.setUseFakeManager({ useFake: true });
[](#%5F%5Fcodelineno-21-4)
[](#%5F%5Fcodelineno-21-5)// Simulate a network error while access is requested
[](#%5F%5Fcodelineno-21-6)await AgeSignals.setNextRequestAgeSignalsAccessException({
[](#%5F%5Fcodelineno-21-7)  errorCode: ErrorCode.NetworkError,
[](#%5F%5Fcodelineno-21-8)});
[](#%5F%5Fcodelineno-21-9)
[](#%5F%5Fcodelineno-21-10)try {
[](#%5F%5Fcodelineno-21-11)  await AgeSignals.requestAgeRange();
[](#%5F%5Fcodelineno-21-12)} catch (error) {
[](#%5F%5Fcodelineno-21-13)  console.log('Caught network error:', error);
[](#%5F%5Fcodelineno-21-14)}
[](#%5F%5Fcodelineno-21-15)
[](#%5F%5Fcodelineno-21-16)// Simulate a network error while the age range is read
[](#%5F%5Fcodelineno-21-17)await AgeSignals.setNextAgeSignalsException({
[](#%5F%5Fcodelineno-21-18)  errorCode: ErrorCode.NetworkError,
[](#%5F%5Fcodelineno-21-19)});
[](#%5F%5Fcodelineno-21-20)
[](#%5F%5Fcodelineno-21-21)try {
[](#%5F%5Fcodelineno-21-22)  await AgeSignals.getAgeRange();
[](#%5F%5Fcodelineno-21-23)} catch (error) {
[](#%5F%5Fcodelineno-21-24)  console.log('Caught network error:', error);
[](#%5F%5Fcodelineno-21-25)}
`

#### Disabling the Fake Manager[¶](#disabling-the-fake-manager "Permanent link")

`[](#%5F%5Fcodelineno-22-1)import { AgeSignals } from '@capawesome/capacitor-age-signals';
[](#%5F%5Fcodelineno-22-2)
[](#%5F%5Fcodelineno-22-3)// Switch back to the production manager
[](#%5F%5Fcodelineno-22-4)await AgeSignals.setUseFakeManager({ useFake: false });
[](#%5F%5Fcodelineno-22-5)
[](#%5F%5Fcodelineno-22-6)// This will now use the real Age Signals API
[](#%5F%5Fcodelineno-22-7)const result = await AgeSignals.requestAgeRange();
`

## FAQ[¶](#faq "Permanent link")

### Which age verification APIs does this plugin use?[¶](#which-age-verification-apis-does-this-plugin-use "Permanent link")

On Android, the plugin uses the [Play Age Signals API](https://developer.android.com/google/play/age-signals/overview) to request age signals from Google Play. On iOS, it uses Apple's [DeclaredAgeRange](https://developer.apple.com/documentation/declaredagerange/) framework, which requires the `com.apple.developer.declared-age-range` entitlement (see [Installation](#installation)).

### What do the different statuses mean?[¶](#what-do-the-different-statuses-mean "Permanent link")

The `status` property tells you whether the user shared their age range. `SHARED` means an age range is available, `NOT_SHARED` means the user declined or is not in an applicable region, and `VERIFICATION_REQUIRED` (Android only) means the user must resolve their status in the Google Play Store first.

### How do the Android age range sources map to the iOS age range declarations?[¶](#how-do-the-android-age-range-sources-map-to-the-ios-age-range-declarations "Permanent link")

Android reports how an age was established as a tier, while iOS reports a declaration method. They do not map one to one, so both values are exposed as separate properties. The following table shows the closest equivalents:

| Android | iOS                                                                                                            |
| ------- | -------------------------------------------------------------------------------------------------------------- |
| TIER\_A | SELF\_DECLARED                                                                                                 |
| TIER\_B | GUARDIAN\_DECLARED                                                                                             |
| TIER\_C | PAYMENT\_CHECKED, CHECKED\_BY\_OTHER\_METHOD, GUARDIAN\_PAYMENT\_CHECKED, GUARDIAN\_CHECKED\_BY\_OTHER\_METHOD |
| TIER\_D | GOVERNMENT\_ID\_CHECKED, GUARDIAN\_GOVERNMENT\_ID\_CHECKED                                                     |

On iOS 26.5 and later, the more granular declarations may be replaced by `CONFIRMED`, which covers both `TIER_C` and `TIER_D`.

### How can I test different age verification scenarios?[¶](#how-can-i-test-different-age-verification-scenarios "Permanent link")

On Android, the plugin integrates the `FakeAgeSignalsManager` API, which lets you simulate age signals without live responses from Google Play. Enable it with `setUseFakeManager(...)` and set the next results or exceptions with `setNextAgeSignalsAccessResult(...)`, `setNextAgeSignalsResult(...)`, `setNextRequestAgeSignalsAccessException(...)` and `setNextAgeSignalsException(...)`. The fake manager is only available if your app is debuggable. See the [Testing](#testing) section for complete examples.

### Why do I get a VerifyError in my Android unit tests?[¶](#why-do-i-get-a-verifyerror-in-my-android-unit-tests "Permanent link")

Due to a known issue in versions 0.0.1 and 0.0.2 of the Age Signals API, calling the builder method of `AgeSignalsResult` in unit tests may throw a `java.lang.VerifyError`. As a workaround, run your tests as Android instrumented tests within the `androidTest` source set.

### Why does the plugin reject with an error like API\_NOT\_AVAILABLE or APP\_NOT\_OWNED?[¶](#why-does-the-plugin-reject-with-an-error-like-api%5Fnot%5Favailable-or-app%5Fnot%5Fowned "Permanent link")

The Play Age Signals API requires an up-to-date Play Store app and Play Services on the device, so errors like `API_NOT_AVAILABLE`, `PLAY_STORE_VERSION_OUTDATED`, or `PLAY_SERVICES_NOT_FOUND` usually indicate outdated or missing Google Play components. The `APP_NOT_OWNED` error means the app was not installed by Google Play. Check the `ErrorCode` enum in the [API](#api) section for the full list of error codes.

### Can I use this plugin with Ionic, React, Vue or Angular?[¶](#can-i-use-this-plugin-with-ionic-react-vue-or-angular "Permanent link")

Yes, the plugin is framework-agnostic. It works in any Capacitor app regardless of the web framework, including Ionic with Angular, React, or Vue, as well as plain JavaScript projects.

## Related Plugins[¶](#related-plugins "Permanent link")

* [App Integrity](https://capawesome.io/docs/sdks/capacitor/app-integrity/): Verify app and device integrity using the Play Integrity API and App Attest.
* [App Tracking Transparency](https://capawesome.io/docs/sdks/capacitor/app-tracking-transparency/): Request user authorization via Apple's App Tracking Transparency framework.
* [Root Detection](https://capawesome.io/docs/sdks/capacitor/root-detection/): Detect rooted and jailbroken devices.

## Newsletter[¶](#newsletter "Permanent link")

Stay up to date with the latest news and updates about the Capawesome, Capacitor, and Ionic ecosystem by subscribing to our [Capawesome Newsletter](https://cloud.capawesome.io/newsletter/).

## Changelog[¶](#changelog "Permanent link")

See [CHANGELOG.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/age-signals/CHANGELOG.md).

## License[¶](#license "Permanent link")

See [LICENSE](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/age-signals/LICENSE).

July 8, 2026 

Back to top

```json
{"@context": "https://schema.org", "@graph": [{"@type": "TechArticle", "@id": "https://capawesome.io/docs/sdks/capacitor/age-signals/#article", "headline": "Capacitor Age Signals Plugin for Android & iOS", "name": "Capacitor Age Signals Plugin for Android & iOS", "description": "Capacitor plugin for the Google Play Age Signals API. Retrieve age assurance signals to gate sensitive content and comply with platform regulations.", "inLanguage": "en", "url": "https://capawesome.io/docs/sdks/capacitor/age-signals/", "mainEntityOfPage": "https://capawesome.io/docs/sdks/capacitor/age-signals/", "author": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "publisher": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "about": {"@id": "https://capawesome.io/docs/sdks/capacitor/age-signals/#software"}}, {"@type": "SoftwareSourceCode", "@id": "https://capawesome.io/docs/sdks/capacitor/age-signals/#software", "name": "Capacitor Age Signals Plugin for Android & iOS", "description": "Capacitor plugin for the Google Play Age Signals API. Retrieve age assurance signals to gate sensitive content and comply with platform regulations.", "url": "https://capawesome.io/docs/sdks/capacitor/age-signals/", "programmingLanguage": "TypeScript", "runtimePlatform": "Capacitor", "codeRepository": "https://github.com/capawesome-team", "author": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "publisher": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}}]}
{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "Which age verification APIs does this plugin use?", "acceptedAnswer": {"@type": "Answer", "text": "On Android, the plugin uses the Play Age Signals API to request age signals from Google Play. On iOS, it uses Apple's DeclaredAgeRange framework, which requires the com.apple.developer.declared-age-range entitlement (see Installation)."}}, {"@type": "Question", "name": "What do the different statuses mean?", "acceptedAnswer": {"@type": "Answer", "text": "The status property tells you whether the user shared their age range. SHARED means an age range is available, NOT_SHARED means the user declined or is not in an applicable region, and VERIFICATION_REQUIRED (Android only) means the user must resolve their status in the Google Play Store first."}}, {"@type": "Question", "name": "How do the Android age range sources map to the iOS age range declarations?", "acceptedAnswer": {"@type": "Answer", "text": "Android reports how an age was established as a tier, while iOS reports a declaration method. They do not map one to one, so both values are exposed as separate properties. The following table shows the closest equivalents: Android iOS TIER_A SELF_DECLARED TIER_B GUARDIAN_DECLARED TIER_C PAYMENT_CHECKED, CHECKED_BY_OTHER_METHOD, GUARDIAN_PAYMENT_CHECKED, GUARDIAN_CHECKED_BY_OTHER_METHOD TIER_D GOVERNMENT_ID_CHECKED, GUARDIAN_GOVERNMENT_ID_CHECKED On iOS 26.5 and later, the more granular declarations may be replaced by CONFIRMED, which covers both TIER_C and TIER_D."}}, {"@type": "Question", "name": "How can I test different age verification scenarios?", "acceptedAnswer": {"@type": "Answer", "text": "On Android, the plugin integrates the FakeAgeSignalsManager API, which lets you simulate age signals without live responses from Google Play. Enable it with setUseFakeManager(...) and set the next results or exceptions with setNextAgeSignalsAccessResult(...), setNextAgeSignalsResult(...), setNextRequestAgeSignalsAccessException(...) and setNextAgeSignalsException(...). The fake manager is only available if your app is debuggable. See the Testing section for complete examples."}}, {"@type": "Question", "name": "Why do I get a VerifyError in my Android unit tests?", "acceptedAnswer": {"@type": "Answer", "text": "Due to a known issue in versions 0.0.1 and 0.0.2 of the Age Signals API, calling the builder method of AgeSignalsResult in unit tests may throw a java.lang.VerifyError. As a workaround, run your tests as Android instrumented tests within the androidTest source set."}}, {"@type": "Question", "name": "Why does the plugin reject with an error like API_NOT_AVAILABLE or APP_NOT_OWNED?", "acceptedAnswer": {"@type": "Answer", "text": "The Play Age Signals API requires an up-to-date Play Store app and Play Services on the device, so errors like API_NOT_AVAILABLE, PLAY_STORE_VERSION_OUTDATED, or PLAY_SERVICES_NOT_FOUND usually indicate outdated or missing Google Play components. The APP_NOT_OWNED error means the app was not installed by Google Play. Check the ErrorCode enum in the API section for the full list of error codes."}}, {"@type": "Question", "name": "Can I use this plugin with Ionic, React, Vue or Angular?", "acceptedAnswer": {"@type": "Answer", "text": "Yes, the plugin is framework-agnostic. It works in any Capacitor app regardless of the web framework, including Ionic with Angular, React, or Vue, as well as plain JavaScript projects."}}], "url": "https://capawesome.io/docs/sdks/capacitor/age-signals/"}
```
