Deeplinkly

Glossary/iOS platform and privacy

IDFV

Definition

The IDFV, or Identifier for Vendor, is a UUID that iOS gives an app to identify the device it is running on, scoped so that every app from the same vendor receives the same value and apps from any other vendor receive a different one.

The IDFV is the identifier people reach for when ATT denies them the IDFA, and it is the wrong tool for that job — not because using it is prohibited, but because its scope makes the click-to-install join arithmetically impossible. It is genuinely useful for something else: recognising the same device across your own portfolio with no permission prompt at all. The two facts that catch teams out are that it can legitimately return nil, and that it is per-device rather than per-user.

Reading it, and the nil you have to handle

The full read path, including the documented nil
import UIKit

/// Returns the IDFV, or nil if iOS cannot supply one yet.
///
/// Apple documents exactly one case where a valid installation gets nil:
/// the device has been restarted and not yet unlocked. The value becomes
/// available after first unlock, so this must not be cached as "no IDFV".
func vendorIdentifier() -> UUID? {
    return UIDevice.current.identifierForVendor
}

/// What most code actually wants: a value, or a retry.
func vendorIdentifierWhenReady(completion: @escaping (UUID) -> Void) {
    if let id = UIDevice.current.identifierForVendor {
        completion(id)
        return
    }
    // Pre-first-unlock. A background launch can land here.
    NotificationCenter.default.addObserver(
        forName: UIApplication.protectedDataDidBecomeAvailableNotification,
        object: nil,
        queue: .main
    ) { _ in
        if let id = UIDevice.current.identifierForVendor {
            completion(id)
        }
    }
}

nil is not the same as the zeroed IDFA

The IDFA returns 00000000-0000-0000-0000-000000000000 when you lack permission. The IDFV has no permission to lack — when it returns nil it means *not yet*, and the usual cause is a background launch before first unlock. Code that writes a placeholder string in that branch creates a phantom device that every affected install then shares.

No permission prompt is involved. The IDFV is available whatever the user answered to App Tracking Transparency, because ATT governs tracking a user across apps and websites owned by *other* companies, and the IDFV cannot do that by construction. This is the whole reason it is useful and the whole reason it cannot replace the IDFA.

What "vendor" means, precisely

Vendor is not your Apple Developer account in the general case. For an app installed from the App Store, Apple derives the vendor from App Store data. For anything else — a development build, TestFlight in some configurations, an enterprise distribution — it is computed from the bundle identifier: the first two components of a reverse-DNS bundle ID, or the entire bundle ID if it has fewer than three components.

How the bundle identifier determines which apps share an IDFV.
Bundle IDs on the deviceDerived vendorSame IDFV?
com.example.shop + com.example.walletcom.exampleYes
com.example.shop + com.example.shop.clipcom.exampleYes
com.example.shop + io.example.shopcom.example / io.exampleNo
com.example.shop + com.partner.appcom.example / com.partnerNo
myapp (two components or fewer)myapp in fullOnly itself

The consequence for App Clips is useful: a clip whose bundle ID sits under the same two leading components as the full app reads the same IDFV, which gives you a permission-free way to recognise that the clip and the app are on one device. The consequence for attribution is fatal: the publisher app that showed the ad has a different vendor prefix, so it computes a different UUID for the same hardware, and there is nothing to join on.

What resets the value, and what does not.
EventIDFV after the event
Delete one of your apps, others remainUnchanged
Delete all apps from that vendor, then reinstallNew value
App update, including a new version from the storeUnchanged
User resets the advertising identifier in SettingsUnchanged
Device restore from backup to the same deviceUnchanged
Restore that backup onto a different deviceNew value

The single-app case is a reinstall detector, not a device ID

If you ship exactly one app, "delete all apps from the vendor" is just "delete the app". The IDFV then changes on every uninstall-reinstall cycle, which makes it a poor primary key for lifetime metrics and a decent signal for *this is a fresh install of a device we have seen before* only if some other app of yours survives.

What it can be used for, and the Android analogue

The IDFV answers one question well: is this the same device as before, within my own apps, without asking anyone's permission. That covers install deduplication, device-scoped session and crash grouping, abuse and multi-account detection, and carrying state between a clip and its full app. It does not answer who the user is — one person with an iPhone and an iPad has two IDFVs, which is why cross-device attribution needs a login identity rather than any device identifier.

The three device-scoped identifiers, side by side.
IDFA (iOS)IDFV (iOS)App Set ID (Android)
ScopeWhole deviceOne vendor's appsOne developer's apps
Needs user permissionYes, via ATTNoNo
Visible to an ad networkYes, if authorisedNoNo
Usable for ad measurementYesNoPolicy-prohibited
Resets onUser action in SettingsRemoving all vendor appsUninstall, or ~13 months idle
Time-based expiryNoneNoneYes

The App Set ID is the closest Android equivalent and the comparison is worth internalising, because the two differ in a way that breaks naive cross-platform code: the App Set ID can expire on a timer even if nothing is uninstalled, and Google's policy forbids using it for advertising measurement or personalisation at all. The IDFV has no timer and no equivalent prohibition — it simply cannot reach across vendors, so the prohibition is unnecessary.

For deep linking the IDFV is a supporting signal, never the mechanism. Routing an installed app comes from the Universal Link payload, and matching a deferred deep link comes from a first-party click identifier you generated and can recognise. If a vendor proposes the IDFV as the way they will match your installs after an ATT denial, ask them to explain how their SDK inside a publisher app reads your vendor's UUID. It cannot, and the answer will tell you what they are really doing — see fingerprint attribution for the technique that question usually uncovers.

iOS SDK documentation

Our iOS SDK uses the IDFV for first-party device recognition and never presents it as an attribution identifier. The documentation lists every signal it reads and what each one is used for, so you can audit the device identity your attribution actually depends on.

Open the ios sdk documentation

Frequently asked questions

What is the IDFV on iOS?
The IDFV, or Identifier for Vendor, is a UUID that iOS returns from UIDevice.current.identifierForVendor to identify the device an app is running on. Every app from the same vendor on that device receives an identical value, and apps from any other vendor receive a completely different one, so it recognises a device within one company's portfolio and nowhere else.
Does the IDFV require ATT permission?
No. App Tracking Transparency governs tracking a user across apps and websites owned by other companies, and the IDFV cannot do that because each vendor computes a different value for the same device. It is therefore readable regardless of whether the user allowed or denied tracking, which is exactly why it is useful for first-party device recognition and useless for advertising attribution.
Why does identifierForVendor return nil?
Apple documents one case for a valid installation: the device has been restarted and not yet unlocked, so the value is not available yet. A background launch can hit this. The correct handling is to retry after first unlock rather than caching a placeholder, because writing a stand-in string makes every affected install share one phantom device identity in your analytics.
When does the IDFV change?
It changes when every app from that vendor is removed from the device and one is then reinstalled. Updating an app, deleting one app while others from the same vendor remain, or restoring a backup onto the same device all leave it unchanged. Restoring a backup onto a different device produces a new value, because the identifier is scoped to the hardware as well as the vendor.
Can the IDFV be used for ad attribution instead of the IDFA?
No, and the reason is arithmetic rather than policy. Attribution requires the publisher app that showed the ad and the advertiser app that recorded the install to observe the same identifier, but those apps have different vendor prefixes and therefore receive different UUIDs for one physical device. There is nothing to join on, so no amount of permission would make the match possible.

Related terms

  • IDFAThe IDFA, or Identifier for Advertisers, is a resettable per-device UUID that iOS provides to apps for advertising measurement, and which is only readable when the user has granted App Tracking Transparency permission.
  • App Tracking Transparency (ATT)App Tracking Transparency is the iOS framework that requires an app to obtain explicit user permission before accessing the device's advertising identifier or otherwise tracking that user across apps and websites owned by other companies.
  • App Set IDThe App Set ID is an Android identifier consistent across all apps published by the same developer on one device, provided for analytics and fraud prevention and barred by Google Play policy from any advertising use.
  • Bundle IdentifierA bundle identifier is the reverse-DNS string, such as com.example.shop, that uniquely identifies an iOS app to the operating system and the App Store.
  • Cross-device attributionCross-device attribution is the practice of crediting a conversion that happens on one device to an advertising touch that happened on a different device belonging to the same person, which requires an identity that both devices share.