Your paid campaign is live, installs are coming in, and your analytics dashboard shows a wall of "unknown source." The root cause is almost always a broken or missing device ID pipeline — wrong ID type, missing permissions, or an MMP expecting a format your code isn't sending.
Knowing how to know device ID — which type to retrieve, how to retrieve it programmatically, and how it behaves over time — is the foundational skill for fixing attribution and reducing CAC. Privacy changes across iOS and Android have accelerated device ID fragmentation in 2025, making this question more complex and more urgent than it has ever been. This guide covers every major ID type, their formats with real examples, working code snippets, and the privacy constraints you need to build around.
What Is a Device ID and Why Does It Matter for Mobile Attribution?
Device ID Defined: A Technical Baseline
A device ID is a string identifier — generated at the hardware, OS, or app layer — that uniquely identifies a device or a user session within a specific scope. The scope matters: some IDs are global across all apps, others are scoped to a single vendor or app install.
Device IDs are the connective tissue between an ad click and an install event. Without a reliable ID to match the two, your attribution model is guessing.
Why Device IDs Are Central to Attribution Accuracy
Device ID tracking is a cornerstone of mobile advertising, enabling advertisers to monitor user behavior and measure ad performance across apps while navigating privacy compliance (Source: Algorix). When a user clicks an ad, the network appends an ID to the click URL. When the app opens post-install, your SDK reads the same ID from the device and sends it to your MMP for matching.
If those two IDs don't match — wrong type, missing value, or a reset in between — the install is attributed to "organic" and your paid CAC looks worse than it is.
The Cost of Getting Device ID Wrong
Misattributed installs corrupt your ROAS data, cause you to over-invest in underperforming channels, and make it impossible to suppress re-acquisition spend for existing users. At scale, this is not a measurement inconvenience — it directly inflates CAC.
What Does a Device ID Look Like? Formats and Real Examples
A device ID is a structured alphanumeric string, typically formatted as a UUID (Universally Unique Identifier) or a numeric sequence, depending on the ID type. Most advertising IDs follow the 8-4-4-4-12 UUID pattern: 32 hexadecimal characters split into five groups by hyphens, totalling 36 characters including hyphens. Hardware-level IDs like IMEI use a different numeric format with no hyphens.
IDFA Format (iOS Advertising Identifier)
Format: 8-4-4-4-12 UUID (hexadecimal, uppercase)
Example: A1B2C3D4-E5F6-7890-ABCD-EF1234567890
The first group (8 chars) is a random time-based component. The version and variant bits sit in the third and fourth groups. When ATT consent is denied, IDFA returns 00000000-0000-0000-0000-000000000000.
GAID Format (Google Advertising ID)
Format: 8-4-4-4-12 UUID (hexadecimal, lowercase)
Example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
Structurally identical to IDFA but lowercased by convention. When the user opts out, GAID returns all zeros in the same format.
UUID / Vendor ID Format
Format: 8-4-4-4-12 UUID (hexadecimal)
Example: B3D4E5F6-1234-5678-90AB-CDEF12345678
Apple's identifierForVendor follows the same UUID structure. The value is consistent across all apps from the same vendor on a given device, but changes on app reinstall if no other vendor app remains installed.
IMEI Format
Format: 15-digit decimal number (no hyphens)
Example: 490154203237518
Structured as TAC (8 digits, Type Allocation Code identifying manufacturer and model) + serial number (6 digits) + check digit (1 digit, Luhn algorithm). Direct IMEI access is restricted or prohibited on both iOS and modern Android.
IMSI Format
Format: Up to 15-digit decimal number
Example: 310150123456789
Structured as MCC (3 digits, country code) + MNC (2–3 digits, network code) + MSIN (subscriber number). App-level IMSI access requires carrier agreement and is not available through standard SDKs.
| ID Type | Format | Length | Resettable |
|---|---|---|---|
| IDFA | UUID (uppercase) | 36 chars | Yes (user) |
| GAID | UUID (lowercase) | 36 chars | Yes (user) |
| Vendor UUID | UUID | 36 chars | Conditional |
| IMEI | Decimal numeric | 15 digits | No |
| IMSI | Decimal numeric | Up to 15 digits | No |

Types of Device IDs: Which One Should You Use?
IDFA: The iOS Advertising Standard (and Its ATT Limitations)
IDFA is the canonical cross-app advertising identifier on iOS, but it is consent-gated since iOS 14.5 via the App Tracking Transparency (ATT) framework. If the user denies the ATT prompt, you receive a zeroed-out string — not null, not an error, just zeros.
Average ATT opt-in rates sit well below 50% in most categories, which means IDFA alone covers a minority of your iOS user base.
GAID: Android's Advertising Identifier
GAID is Google's equivalent on Android and is available without an upfront consent prompt, though users can opt out in device settings. It is the primary attribution ID for Android campaigns and is supported by all major MMPs.
GAID availability is tied to Google Play Services, so it is unavailable on AOSP builds, Huawei devices with HMS, and some regional Android variants.
UUID and Vendor ID: App-Scoped Persistent IDs
Apple's identifierForVendor and randomly generated UUIDs stored in the Keychain are app-scoped alternatives when IDFA is unavailable. They are not cross-app identifiers, so they cannot be used for cross-network attribution — but they are reliable for cohort analysis within your own product.
A common mistake in production: relying on identifierForVendor alone without a Keychain-backed fallback. If the user deletes all apps from your vendor, the ID resets on reinstall — causing duplicate user records and inflated install counts (Source: Developer Community).
IMEI and IMSI: Hardware-Level IDs and When Not to Use Them
Do not use IMEI or IMSI for attribution in new implementations. iOS has never exposed IMEI to apps. Android restricted programmatic IMEI access in Android 10 (API 29), requiring READ_PRIVILEGED_PHONE_STATE — a permission unavailable to third-party apps. Using these IDs also creates significant GDPR exposure.
Fingerprinting and Probabilistic IDs: The Privacy-Compliant Fallback
Probabilistic fingerprinting — matching installs using IP address, user agent, screen resolution, and install timestamp — is a fallback for users where no advertising ID is available. It is inherently less accurate than deterministic ID matching and is restricted under Apple's ATT guidelines if used without user consent on iOS.
Quick decision framework:
- Use IDFA when: ATT consent is granted and you need cross-app iOS attribution.
- Use GAID when: Targeting Android users on Google Play devices.
- Use Vendor UUID when: Doing within-app cohort analysis or A/B testing without cross-app scope.
How to Find the Device ID Programmatically: Code Snippets by Platform
How to Check Device ID on iOS: IDFA and Vendor ID (Swift)
Request ATT permission before attempting IDFA retrieval. Calling advertisingIdentifier without the prompt returns zeros regardless.
import AppTrackingTransparency
import AdSupport
func requestIDFA() {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
print("IDFA: \(idfa)")
default:
let vendorID = UIDevice.current.identifierForVendor?.uuidString ?? "unavailable"
print("Vendor ID fallback: \(vendorID)")
}
}
}Add NSUserTrackingUsageDescription to your Info.plist or the ATT prompt will crash at runtime.
How to Check Device ID on Android: GAID and Android ID (Kotlin)
GAID retrieval is asynchronous via the Advertising ID client API. Never call it on the main thread.
import com.google.android.gms.ads.identifier.AdvertisingIdClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
suspend fun getAdvertisingId(context: Context): String {
return withContext(Dispatchers.IO) {
try {
val info = AdvertisingIdClient.getAdvertisingIdInfo(context)
if (info.isLimitAdTrackingEnabled) {
// Fall back to Android ID
Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
} else {
info.id ?: "unavailable"
}
} catch (e: Exception) {
Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
}
}
}ANDROID_ID has been scoped per app signature since Android 8.0 (Oreo). It is no longer a global device identifier — two apps from different developers will read different ANDROID_ID values on the same device.
Retrieving Device ID via Attribution SDK
Most attribution SDKs expose a device ID retrieval method directly, abstracting platform differences behind a unified API call:
val deviceId = AttributionSDK.getInstance().getDeviceId()
If you are integrating with a mobile measurement partner, Deeplinkly's attribution SDK abstracts ID retrieval across platforms — handling IDFA, GAID, and Vendor UUID collection with a single initialisation call, with built-in ATT prompt management for iOS. Setup takes under 30 minutes and device ID data surfaces directly in your attribution dashboard, without writing the fallback logic manually.
Handling Null and Restricted ID States
Three states require explicit handling in your code:
- ATT denied on iOS: advertisingIdentifier returns 00000000-0000-0000-0000-000000000000. Check for this string explicitly and route to your Vendor ID fallback.
- GAID opted out: isLimitAdTrackingEnabled returns true. Fall back to ANDROID_ID and flag the record as non-addressable for retargeting.
- No advertising ID available: Emulators without Google Play Services, Huawei HMS devices, and certain Android Go builds will throw an exception on GAID retrieval. Always wrap in try/catch and have a UUID fallback ready.
Device ID Persistence, Resets, and What Changes Over Time
Which Device IDs Persist Across App Reinstalls?
| ID Type | Persists After Reinstall |
|---|---|
| IDFA | Yes (until user resets) |
| GAID | Yes (until user resets) |
| Vendor UUID | Conditional (resets if no other vendor app installed) |
| Keychain UUID | Yes (if written to Keychain before uninstall) |
| ANDROID_ID | Yes (scoped per app signature, stable across reinstalls) |
| IMEI | Yes (hardware-bound) |
What Triggers a Device ID Reset?
IDFA and GAID reset when the user manually resets their advertising ID in device settings — a deliberate privacy action. Factory resets regenerate all software-based IDs. Vendor UUID resets on reinstall if no sibling vendor app is present on the device.
Keychain-backed UUIDs on iOS survive reinstalls and even device backups, making them the most persistent app-layer identifier available without advertising consent.
Building Resilient Attribution With ID Fallback Chains
Build your attribution logic around a priority chain, not a single ID. A practical order: IDFA → GAID → Vendor UUID → Keychain UUID → probabilistic fingerprint. Each tier activates only when the tier above returns null or a zeroed value.
This architecture handles consent changes, user resets, and platform restrictions without dropping attribution events.
Privacy, Security, and Compliance Considerations for Device IDs
GDPR and CCPA: Is a Device ID Personal Data?
Yes — advertising IDs (IDFA and GAID) are personal data under GDPR. The European Data Protection Board has confirmed that identifiers used to track individuals across apps constitute personal data and require a lawful basis for processing, typically explicit consent. Under CCPA, advertising IDs fall within the definition of personal information and are subject to opt-out rights.
This has a direct implementation consequence: you must collect and store device IDs only after establishing a valid consent signal, and you must be able to delete them on request.
Apple ATT Framework: Consent-Gated IDFA Access
ATT makes IDFA access binary — the user either grants permission or you receive zeros. There is no partial access. Your ATT prompt timing and messaging directly affect your consent rate, and a low consent rate has a direct impact on your attributable install volume.
Google Privacy Sandbox and the Future of GAID
Google's Privacy Sandbox initiative for Android is progressing toward replacing GAID with privacy-preserving APIs. The timeline has shifted multiple times, but the direction is clear: direct advertising ID access will eventually be deprecated in favour of aggregated cohort-based signals.
Device IDs are commonly passed between attribution systems as query parameters in click tracking URLs — for example, ?idfa=XXXX&gaid=YYYY. Understanding what is a query parameter in this context is practical: it is a key-value pair appended to a URL that allows the MMP's server to read the device identifier at click time and later match it against the install postback. What is query parameter usage in attribution? It is the mechanism that connects an ad network click to a specific device, and it is where ID format consistency matters most — a lowercase GAID in the click URL that doesn't match an uppercase value in the postback will break attribution.
Storing Device IDs Securely in Your Backend
Never store raw advertising IDs in plaintext logs. Hash IDs (SHA-256 minimum) before storing, and store the hash alongside a salted version to prevent rainbow table attacks. Restrict access to ID storage to services that explicitly require it, and implement a deletion pipeline that can remove all records associated with a given ID on user request.
Handle device ID compliance without building it yourself.
Deeplinkly collects, hashes, and manages device IDs across iOS and Android with built-in consent handling — so your attribution stays accurate and your privacy posture stays clean.
How to Know Device ID: Troubleshooting Common Retrieval Issues
IDFA Returning Zeros: ATT Not Requested or Denied
- Problem:
advertisingIdentifierreturns00000000-0000-0000-0000-000000000000. - Likely Cause: The ATT prompt was never shown, the user denied it, or
NSUserTrackingUsageDescriptionis missing fromInfo.plist. - Fix: Confirm the ATT request is called before any ID retrieval. Check for the zeroed string explicitly in code and route to the Vendor UUID fallback. Verify
Info.plistcontains a non-empty usage description string.
GAID Returning Null on Android Emulator
- Problem: GAID retrieval throws an exception or returns null in the emulator.
- Likely Cause: The emulator image does not include Google Play Services, which is required for the Advertising ID client.
- Fix: Use an emulator image that includes the Play Store. Alternatively, wrap retrieval in a try/catch and return
ANDROID_IDas the fallback — this is the correct production pattern regardless.
Duplicate Device IDs Across Users
- Problem: Multiple distinct users share the same device ID in your analytics.
- Likely Cause: Some ID implementations are not unique across all environments — shared devices, enterprise MDM scenarios, or incorrect Keychain sharing groups can return the same identifier for multiple users (Source: Developer Community).
- Fix: Never use device ID as a user identity primary key. Use it only for attribution matching. Assign a separate, server-generated user ID at account creation and store the device-to-user mapping server-side.
Device ID Mismatch Between SDK and Dashboard
- Problem: The device ID logged in your app differs from what appears in your MMP dashboard.
- Likely Cause: Format normalisation differences — one system sends lowercase UUID, the other stores uppercase — or clock skew causing the wrong session's ID to be sent in the postback.
- Fix: Normalise all IDs to lowercase before transmission. Confirm your SDK version matches the MMP's current spec. Add device ID to your debug logging at both the click and install event to trace the mismatch point.
Frequently Asked Questions
What does a device ID look like?
A device ID is typically a UUID string in 8-4-4-4-12 format: 32 hexadecimal characters separated by hyphens, totalling 36 characters — for example, A1B2C3D4-E5F6-7890-ABCD-EF1234567890. Hardware IDs like IMEI are 15-digit decimal numbers with no hyphens. When advertising IDs are unavailable or opted out, they return a zeroed UUID: 00000000-0000-0000-0000-000000000000.
How do you find a device ID?
On iOS, retrieve IDFA via ASIdentifierManager.shared().advertisingIdentifier after requesting ATT permission, or use UIDevice.current.identifierForVendor for a consent-free vendor-scoped ID. On Android, call AdvertisingIdClient.getAdvertisingIdInfo(context) asynchronously for GAID, or read Settings.Secure.ANDROID_ID as a fallback. Most MMPs expose a unified method that handles platform detection and fallback logic automatically, which is the recommended approach for attribution use cases.
Is device ID the same as IMEI?
No. IMEI is one specific type of hardware-level device ID, but "device ID" is a general term covering multiple identifier types: IDFA, GAID, Vendor UUID, ANDROID_ID, IMEI, and IMSI. IMEI is hardware-bound and never changes, but it is inaccessible to third-party apps on iOS and requires privileged permissions on Android 10 and above. For mobile attribution, IDFA and GAID are the relevant identifiers — not IMEI.
How do I see my iPhone device ID?
In Settings, go to General > About — your device serial number is listed there, but IDFA is not exposed in the UI since iOS 14. Programmatically, retrieve it in Swift with: let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString. This requires ATT authorisation first. For the Vendor ID (no consent required), use UIDevice.current.identifierForVendor?.uuidString. If you are testing attribution, check your MMP's SDK debug logs — they will output the active device ID after initialisation.
Build the ID pipeline that doesn't drop installs.
Understanding device ID types is the foundation. Building the fallback chain — IDFA, GAID, Vendor UUID, Keychain UUID — is what actually keeps your attribution accurate when consent rates fluctuate and platform rules shift. Developers who build ID-resilient pipelines now will have a structural CAC advantage as advertising ID access continues to narrow.