Data safety
Play Data safety answers
Your answers for the AdHedge SDK in Play Console's Data safety form.
Does the SDK collect or share user data?
Yes.
Data types
| Play category | Collected | Shared | Ephemeral | Required | Purposes |
|---|---|---|---|---|---|
| Device or other IDs | Yes | No | No | Yes | Fraud prevention, security, and compliance; Analytics |
| App activity: in-app actions | Yes | No | No | Yes | Fraud prevention, security, and compliance; Analytics |
| App info and performance: diagnostics | Yes | No | No | Yes | Fraud prevention, security, and compliance; Analytics |
| Device or other IDs: Advertising ID (blocking mode with AppsFlyer or Adjust only) | Yes | No | Yes | Yes | Advertising or marketing; Analytics |
| Location: approximate location | Yes | No | No | Yes | Fraud prevention, security, and compliance; Analytics |
- Device or other IDs: a random install ID, the Play App Set ID, and the IP address our server sees on each request. No Android ID.
- Advertising ID, blocking mode with AppsFlyer or Adjust only: the advertising ID is sent only for blocking-mode delivery to your own AppsFlyer or Adjust account, and never stored. The SDK sends it once per verified install, only when your app already declares
com.google.android.gms.permission.AD_ID. Our server forwards it in memory, server to server, to that account, which needs it for Google Ads postbacks. It is never logged or joined to install data, and it is skipped when the user deleted the ID or limited ad tracking. Apps on Firebase only, or not in blocking mode, send no advertising ID. - Play form answer for the advertising ID: Device or other IDs, collected yes, shared no, processed ephemerally yes, purposes Advertising or marketing and Analytics. Your attribution SDK already requires this row. Add Advertising or marketing as a purpose if it isn't there.
- App activity: tap counts and session length on the install day, the delay to the first touch, and whether the app was opened again the day after install. Every field is listed under Behavior.
- App info and performance: installer, install times, build, signing certificate hash, install referrer, debug flags, emulator and root checks, network type, battery, time since boot, and the Play Integrity token. Every field is listed under Fields the SDK sends.
- Approximate location: the country our server derives from the IP address of each request, stored with the install. The SDK reads no location, and precise location is never collected.
Fields the SDK sends
App and install, Install facts and Device checks are sent once per install. A field is empty when the Android version can't provide it. None of these need a permission. Behavior is the one group that is not sent once per install: it is batched, and its own table says when each field is sent.
App and install
| Field | What it is | Android source |
|---|---|---|
| Install ID | A random ID the SDK creates once. Built from no device identifier. | UUID in SharedPreferences |
| Play App Set ID | Scoped to your developer account. Our server hashes it on receipt and never stores it raw. | AppSetIdClient |
| Package name | Your app's package. | Context.getPackageName |
| Signing certificate hash | SHA-256 of your app's signing certificate. | PackageInfo.signingInfo |
| First install time | When your app was first installed on the device. | PackageInfo.firstInstallTime |
| Last update time | When your app was last updated. | PackageInfo.lastUpdateTime |
| App version code | The running build. | PackageInfo.getLongVersionCode |
| SDK version | The AdHedge SDK version. | SDK constant |
| Android API level | The device's Android version. | Build.VERSION.SDK_INT |
| Config version | Which SDK settings were in effect. | SDK config |
| Existing-user flag | Whether your app was installed before the SDK. | Install and update times |
| Request hash | SHA-256 of these fields. Ties them to the Play Integrity token. | Computed by the SDK |
Install facts
| Field | What it is | Android source |
|---|---|---|
| Installer package | The app store or package that installed your app. Empty for a sideload. | installingPackageName |
| Package that started the install | Android 11 and up. | initiatingPackageName |
| Install source type | Store, local file, downloaded file or other. Android 13 and up. | packageSource |
| Play Install Referrer string | Exactly as Play returns it, up to 1,024 bytes. Holds the ad click ID when Play has one. The only free-text field. | installReferrer |
| Referrer click time | When the store listing was opened from a click. | referrerClickTimestampSeconds |
| Install start time | When the Play download began. | installBeginTimestampSeconds |
| App version at install | Your app version when it was first installed. | installVersion |
| Referrer availability | Whether Play could return a referrer. | InstallReferrerClient response |
| Debuggable build flag | Whether this build is debuggable. | FLAG_DEBUGGABLE |
| USB debugging setting | Whether USB debugging is on. Read-only. | Settings.Global.ADB_ENABLED |
| Test-keys build | Whether the system image is signed with test keys. | Build.TAGS |
| Work profile | Whether the app runs in a managed work profile. Android 11 and up. | isManagedProfile |
Device checks
| Field | What it is | Android source |
|---|---|---|
| Emulator build markers | Which of 8 fixed build-string patterns match. | Build.* |
| Root markers | Which of 4 fixed file-path and system-property checks match. No app lookups. | File and property checks |
| Network transport type | Wi-Fi, cellular, Ethernet, other or none. No SSID, BSSID or IP address. | NetworkCapabilities |
| VPN active | Whether traffic goes through a VPN. | TRANSPORT_VPN |
| Proxy set | Whether a system HTTP proxy is set. | http.proxyHost |
| Battery level | Percent, 0 to 100. | ACTION_BATTERY_CHANGED |
| Charging state | Whether the device is charging. | ACTION_BATTERY_CHANGED |
| Time since boot | Milliseconds since the device started. | SystemClock.elapsedRealtime |
| Sensor count | How many sensors the device reports. No sensor readings. | SensorManager.getSensorList |
| SIM state | Absent, ready, unknown or other. No number, carrier or country. | TelephonyManager.getSimState |
| Phone type | None, GSM, CDMA, SIP or other. | TelephonyManager.getPhoneType |
Play purpose for every field in this table: Fraud prevention, security, and compliance. Why each group is collected:
- Emulator build markers, root markers: which of a fixed list of patterns matched, as true or false. An install verified on an emulator or a rooted device is the oldest form of install fraud. The build strings and file paths themselves stay on the device, and the SDK reads no list of installed apps.
- Battery level, charging state, time since boot: read once, when the install is first seen. Racked devices report the same battery level, charging state and uptime across hundreds of installs an hour; a real phone does not. All three change by the minute and identify no one.
- Sensor count: how many sensors the device reports, as a number. Emulated devices report a handful where a phone reports dozens. No sensor readings are collected.
- SIM state, phone type: two Android enum values that separate a phone from a rack of SIM-less hardware. No phone number, carrier, SIM country or subscriber ID.
- Network transport type, VPN active, proxy set: how this request reached us. Install traffic routed to look like another country is a fraud signal your reports can't show. No SSID or BSSID.
Why these are diagnostics under App info and performance: every one is a point-in-time value about the device's state at one install, none is a persistent identifier, and none is joined across apps. The Play App Set ID is hashed on receipt, and the install record as a whole is still declared under Device or other IDs, because Google treats a server-side device record as a device identifier whatever fields compose it.
How long they are kept: these signals 90 days, the install and its country 13 months. The IP address is kept 30 days and the network prefix 13 months, and the full address is never stored past that.
Behavior
This is the App activity group. It is the only group not sent with the install record: events are batched on the device, at most 20 of them, held at most 7 days, and posted on the SDK's background thread. Kept 90 days, like the rest of the signals. The collector runs only while tier 4 is on in the app's SDK config.
| Field | What it is | Android source | Sent | Kept |
|---|---|---|---|---|
| Taps in a session | How many touches the session had, as a number. No coordinates, no view, no content. | Window.Callback, ACTION_DOWN count | Per session | 90 days |
| Session length | How long the session lasted, in milliseconds. Tap interval variance is derived on our side from these pairs. | ActivityLifecycleCallbacks | Per session | 90 days |
| First-touch delay | Milliseconds from process start to the first touch after install. | SystemClock.elapsedRealtime | Once | 90 days |
| Next-day return | That the app was opened again on the day after the install day. One flag. No session count. | Install day + 1, on device | Once | 90 days |
| Event time | The device clock when the event happened. Our server also records when it arrived. | System.currentTimeMillis | Per event | 90 days |
| Conversion adapter result | Which adapter fired the conversion and whether the vendor SDK accepted the call. | Adapter return value | Per fire | 90 days |
| Late referrer | The Play Install Referrer fields above, when Play returned them after the install record was already sent. | InstallReferrerClient | At most once | 90 days |
Play purposes for this table: Fraud prevention, security, and compliance; Analytics. Why it is collected: a racked device that installs, opens once and never touches the screen looks identical to a real install in every network report. Counts and durations separate the two. Touch coordinates, view IDs, screen names and text input are never read, so the events carry nothing that could identify a person or reconstruct what they did.
How taps are counted: the SDK registers one Application.ActivityLifecycleCallbacks and wraps each Activity's Window.Callback. No listener is attached to your views, and no accessibility service is used. On the dispatch path the wrapper increments an int when the action is ACTION_DOWN and calls through to the callback that was there before, with no allocation and no I/O. A measured per-event figure on reference devices is not published yet. Mechanism and cost in full: docs.
Seen by our server
The SDK doesn't send these. Our server reads them from each request.
| Field | What it is | Kept |
|---|---|---|
| IP address | The address each request comes from. | 30 days |
| Network prefix | The IP address with its host part removed. | 13 months |
| Network operator | The network the request came from and whether it is a hosting provider. Derived from the IP address. | 13 months |
| Country | Derived from the IP address and stored with the install. | 13 months |
Purposes
Fraud prevention, security, and compliance. Analytics. The advertising ID row adds Advertising or marketing. Never personalization.
Shared
No. AdHedge processes the data on your behalf as a service provider, and Google does not count that as sharing. We don't sell it, link it across apps, or join it to personal data. The advertising ID goes only to your own AppsFlyer or Adjust account, on your instruction, and is never stored or joined to install data.
Handling
- Encrypted in transit: yes.
- Deletion: from your dashboard or API, within 30 days of a request.
- Retention: signals and events 90 days. IP address 30 days, network prefix and operator 13 months. Installs and their country 13 months.
- Optional collection: none for the install record. The advertising ID follows the user's ad settings.
Never collected
- Android ID, Firebase installation ID
- IMEI, serial, MAC address, SSID
- Phone number, carrier, SIM country, contacts, SMS, call logs
- Precise location
- Installed app lists
- Touch coordinates, screen content, text input, names, email
Permissions: INTERNET and ACCESS_NETWORK_STATE only.
Play Integrity
One token per install, under a Cloud project linked to your app. No tracking across apps.