Both stores ask what data your app collects, including data collected by the SDKs inside it. This page gives the answers for the Fingerly mobile SDKs, and the store rules that affect how you integrate them. React Native, Flutter and Lynx apps use the same native SDKs and collect nothing more, so the same answers apply.
What the mobile SDKs collect
- A random install ID the SDK creates and keeps on the device: in the Keychain on iOS, and in a file in your app's no-backup directory on Android. It is the only thing Fingerly recognises an app's device by.
- Device identifiers the operating system gives apps:
identifierForVendoron iOS, and a hash ofANDROID_IDon Android. Never the advertising identifier. - Device and app characteristics, used for integrity checks and the risk score, never to recognise the device: hardware, operating system, display, language and time zone settings, battery state, network type, and the integrity of the device and of your app. On Android, also the mobile network operator's name, the store that installed your app, and whether any app from a fixed list of root, hooking and cloning apps is installed.
- App activity: how many times your app has been launched, and how long ago it was installed.
- The IP address each request comes from. Fingerly derives the country, region, city and network from it. Coordinates are stored rounded to one decimal place, a city's reference point rather than the device's position.
- Your tag, the string you pass to
identify.
The SDKs never collect precise location, contacts, photos, messages, anything your users type, browsing history or advertising data, never send the names of other installed apps, and never show a permission prompt.
Apple: App Store
App Privacy details
In App Store Connect, under App Privacy, declare these data types for Fingerly. They match the privacy manifest the SDK ships.
| Data type | Collected | Linked to the user | Used for tracking | Purpose |
|---|---|---|---|---|
| Identifiers: Device ID | Yes: the install ID and identifierForVendor | Yes | No | App Functionality |
| Location: Coarse Location | Yes: country, region and city, derived from the IP address on the server | Yes | No | App Functionality |
| Usage Data: Product Interaction | Yes: launch count and install age | Yes | No | App Functionality |
| Other Data: Other Data Types | Yes: device and app characteristics and integrity indicators | Yes | No | App Functionality |
| Identifiers: User ID | Only if your tags contain a user or account ID | Yes | No | App Functionality |
Apple's App Functionality purpose includes preventing fraud and implementing security measures, which is what Fingerly is for.
The manifest declares every type as linked to the user. The install ID persists on the device, and most integrations store the request ID or the visitor ID with an account, as the use-case recipes do. Fingerly itself does not know who your users are.
Tracking and App Tracking Transparency
Answer No to tracking, and do not show an App Tracking Transparency prompt on Fingerly's account. The SDK does not track: its manifest sets NSPrivacyTracking to false and lists no tracking domains. Fingerly processes the data on your behalf, only to prevent fraud and keep your app secure. It does not combine it with other companies' data, the same device has a different visitor ID for every Fingerly customer, and nothing is used for advertising. Apple's definition of tracking excludes data used solely for fraud detection, fraud prevention or security on your behalf. This stays true only while your own use of the data stays within those purposes.
Privacy manifest
The iOS SDK ships a privacy manifest, PrivacyInfo.xcprivacy, in the Swift package's resources and in the Fingerly_Privacy resource bundle of the CocoaPods pod. Xcode includes it in your app's privacy report with nothing to do on your side. The React Native, Flutter and Lynx packages depend on the pod, so they bring it too.
| Key | What the manifest declares |
|---|---|
NSPrivacyTracking | false |
NSPrivacyTrackingDomains | None |
NSPrivacyCollectedDataTypes | Device ID, Coarse Location, Product Interaction and Other Data Types. Each is linked, not used for tracking, and collected for App Functionality. |
NSPrivacyAccessedAPITypes | File timestamp, reason C617.1, to read the creation date of your app's own container, sent as an age in whole days. |
File timestamps are the only required-reason API the SDK uses. It reads no boot time, system uptime or disk space, and nothing outside your app's container.
How the device is recognised
Apple's developer agreement does not allow data derived from a device to be used to identify it, and makes no exception for fraud prevention. So on iOS, and on Android too, Fingerly recognises a device only by the random install ID the SDK stores. The device signals are used to detect jailbreaks, simulators, instrumentation and device farms, never to identify a device or a user. A report without an install ID identifies nobody.
On iOS the install ID is kept in the Keychain, only on this device and never in a backup. It survives your app being deleted, so a reinstall on the same device keeps its visitor ID. Deleting the stored identity is the way to remove it.
Review guidelines
- Do not ship the SDK in Kids Category apps. Guideline 1.3 does not allow third-party analytics of this kind in them.
- Do not use the browser SDK inside a
WKWebViewin an iOS app. Apple treats reading browser properties there as fingerprinting. Call the iOS SDK from the native side instead, and send its request ID to your server with the action it protects. - Consent defaults to pending. Guideline 5.1.1(ii) asks apps to get consent before collecting user or usage data. The SDK collects and sends nothing until your app sets consent to
granted. See consent tools. - No private API. The SDK uses public frameworks only, so it adds nothing to your review.
Google Play
Data safety
In Play Console, under App content > Data safety, declare these data types for Fingerly:
| Data type | Collected | Shared | Purpose | What it covers |
|---|---|---|---|---|
| Location: Approximate location | Yes | No | Fraud prevention, security, and compliance | Country, region and city derived from the IP address on the server |
| Device or other IDs | Yes | No | Fraud prevention, security, and compliance | A random install ID, a hashed ANDROID_ID, the key attestation certificate chain |
| App activity: Installed apps | Yes | No | Fraud prevention, security, and compliance | Whether any of 17 named root, hooking or cloning apps is installed |
| App activity: App interactions | Yes | No | Fraud prevention, security, and compliance | Launch count, install age |
| App info and performance: Diagnostics | Yes | No | Fraud prevention, security, and compliance | Device model and OS, hardware, display, battery and thermal state, network transport, VPN and proxy, root, emulator, debugger and hooking indicators |
| Personal info: User IDs | Only if your tags contain a user or account ID | No | Fraud prevention, security, and compliance | Your tag |
The other questions
| Question | Answer for Fingerly |
|---|---|
| Is the data shared? | No. Fingerly is a service provider processing the data on your behalf, which Google does not count as sharing. |
| Is it processed ephemerally? | No. Identification events are kept for 30 days. See data retention. |
| Is collection required or optional? | Required if you load the SDK with consent granted. Optional if you keep the default, pending, and let users decline. See consent tools. |
| Is all data encrypted in transit? | Yes. The SDK sends everything to Fingerly over HTTPS. If you set a custom endpoint, it must be an https:// URL for this to stay true. |
| Can users request deletion? | Yes. Call deleteStoredIdentity on the device, and erase the visitor from your server with Erase a visitor. See account deletion and erasure. |
Package visibility
The SDK's manifest has a <queries> block naming 17 packages: root managers, hooking-framework managers and app cloners. It never requests QUERY_ALL_PACKAGES, so there is no declaration to make for it. No package name leaves the device: the report says only whether a root manager, a hooking manager or a cloning app is installed, and whether your app runs inside another app's data directory.
To leave a package out, remove its entry with the manifest merger in your app's own AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<queries>
<package android:name="com.applisto.appcloner" tools:node="remove" />
</queries>
</manifest>
The SDK then cannot see that package and reports it as not installed. The verdicts keep working on their other evidence.
Permissions
- The SDK's manifest declares only
INTERNETandACCESS_NETWORK_STATE. Both are granted at install time, so there is no prompt and no Permissions Declaration Form. - It uses no Google Play services and no advertising ID, so you do not need to declare the
AD_IDpermission for Fingerly.
Backups and reinstalls
The install record is a file in your app's noBackupFilesDir, so Auto Backup and device-to-device transfer never copy it, and there is nothing to add to your backup rules. It is removed when your app is uninstalled, so a reinstall starts with a new install ID and a new visitor ID. A record an earlier version of the SDK kept in shared preferences is moved there once, and the old preferences file deleted.
Families and consent
- Do not ship the SDK in apps directed at children, or in apps whose target audience includes children under the Families policy.
- Consent defaults to pending. Google Play's guidance on using SDKs safely asks that an SDK honour your app's consent decision. Nothing is collected, stored or sent until your consent tool sets consent to
GRANTED. See consent tools.
Account deletion and erasure
Both stores require an app that lets users create an account to let them delete it, and data protection law gives users the right to erasure. Every mobile SDK has a call that deletes the install record from the device:
fingerly.setConsent(.denied) // if nothing should be collected afterwards
try Fingerly.deleteStoredIdentity()
- It deletes the install ID the server recognises the device by, when it was first seen and the launch count. The next identification made with consent starts a new install ID, and nothing links it to the old one.
- It needs no client and no consent, sends nothing, and succeeds when there was no record.
- A call already running may write a fresh record once the delete returns. To stop collection as well, set consent to
deniedfirst. - On iOS it throws
StoredIdentityErrorwith the Keychain status if the Keychain refuses. On Android it returns whether no record remains; it is a small file delete, so call it off the main thread if StrictMode matters to you. The React Native and Lynx packages reject with aFingerlyError, and Flutter throws aFingerlyException.
Deleting the record on the device does not delete what Fingerly already holds. For that, keep the visitor_id your server receives with each identification, and when the user deletes their account, have your server call Erase a visitor with it. You can also erase a visitor from one of its events in the dashboard.
Your privacy policy
Both stores link to your privacy policy. Say that your app uses device identification from Fingerly to prevent fraud and keep accounts secure, what that involves, and how long the data is kept. See privacy and consent.