The demise of Apple's IDFA in iOS 14 is causing many people to ask the question: what is SKAdNetwork?

IDFA, the identifier that has made ad personalization possible on iPhones and iPads for years, will effectively be killed off in iOS 14 when iOS will start asking users if they want to be tracked by individual apps.

It is expected that the majority of users will choose the "Ask App Not To Track" option, which will prevent an app from extracting the user's IDFA value (the anonymous and user-resettable advertising identifier tied to a user's device). This means no more user tracking, audience targeting or conversion tracking. Or does it?

Apple threw advertisers and the ad tech industry a bone and released a way to enable app install and conversion tracking in iOS 14. Apple actually released version 1.0 of SKAdNetwork back in March 2018 with iOS 11.3 as a privacy-compliant method of app install conversion tracking, which we should of all saw as a harbinger of doom.

That doom has arrived, but do not fret! This article will give you an overview of SKAdNetwork 2.0 and how it works to track app installs and other conversion actions.

This is not a comprehensive technical guide on how to exactly implement SKAdNetwork 2.0, for that I will refer you to Apple's own SKAdNetwork documentation. Use this post to gain a quick understanding of how SKAdNetwork works from a high-level.

The Involved Parties

There are three entities involved in SKAdNetwork

  1. Ad networks - The platform that will deliver ads and report app installs and conversions
  2. Source app - The app displaying the ad from the ad network
  3. Advertised apps - The app being advertised and aiming to be installed by the user

The Process

Apple provided the following handy graphic to outline the process of conversion tracking. I have added labels to add context to each step.

  1. The Ad Network provides a "signed" ad
  2. The ad network calls the loadProduct() method that includes required advertising key values to facilitate install or conversion tracking
  3. The user taps the ad which will display the app store product view of the advertised app
  4. App is launched and the advertised app calls one of two methods that provide info necessary for attribution and conversion tracking
  5. Apple calls a postback URL provided by the ad network that signals a successful app install or conversion.

The above is a high level overview of each step of the process. To understand all the individual pieces, it's easiest to break it down by the individual responsibilities of the participating entities.

Ad Network

The ad network is the entity or platform that will provide signed ads for the advertised apps that are displayed in the source app. Each responsibility of the ad network is below.

1. Register as an ad network with Apple

Apple requires all ad networks utilizing SKAdNetwork to request an Ad Network ID. Any publisher displaying SKAdNetwork enabled ads from the ad network must include this ID in their app's configuration file (Info.plist).

The ad network will have to create a cryptographic private / public key pair (Apple provides step by step instructions to do this in Mac Terminal) in order to generate the signatures that will be sent along with SKAdnetwork compatible ads. So a "signature" in this sense is a digital or cryptographic signature, generated using the created private key. The signature is used by Apple to verify the entity signing the ads is the expected ad network.

The ad network will need to provide their public key to Apple during registration for verifying signatures. Apple will use this public key to verify that it's paired private key was used to sign ads from the expected ad network.

The final step of registration will be to provide a URL at which to receive install validation postback requests where the customer’s devices will send install notifications and a conversion values. Apple will sign these postback calls using their private key and the network is expected to verify postbacks using Apple's public key.

2. Provide signed ads to the source app

When an ad is loaded by an app (or ad network SDK) they must call the loadProduct() method and provide a signature along with this method. The signature is generated by combining the following values:

Ad Network Version

The version of the ad network API being used.

Ad Network Identifier

The identifier you received from Apple after registering as an ad network.

Ad Network Campaign Identifier

An integer between 1-100 that represents a campaign within the ad network's platform.

iTunes Item Identifier

The App Store ID of the advertised app.

Ad Network Nonce

A unique UUID value generated by the Ad Network for each ad impression. A nonce is a value typically used in cryptography to ensure a hash is unique.

Ad Network Source App Store Identifier

The App Store ID of the app displaying the ad.

Timestamp

Timestamp generated near the time of the ad impression.

These values must be combined into a UTF-8 string with an invisible separator (‘\u2063’) between them, in the exact order shown in the example below:

version + '\u2063' + ad-network-id + '\u2063' + campaign-id + '\u2063' + itunes-item-id + '\u2063' + nonce + '\u2063' + source-app-id + '\u2063' + timestamp

And signed using the private key created in step 1 (using the Elliptic Curve Digital Signature Algorithm (ECDSA) with a SHA-256 hash, if you were wondering!).

Lastly, you must encode the resulting binary value into a Base64 string that will result in something similar below:

MEQCIEQlmZRNfYzKBSE8QnhLTIHZZZWCFgZpRqRxHss65KoFAiAJgJKjdrWdkLUOCCjuEx2RmFS7daRzSVZRVZ8RyMyUXg==

This will be the key value used along with all the other required keys (see "source app" section below) when calling the loadProduct() method. If a user installs and launches the advertised app, the ad network will receive a postback at the URL they provided during registration.

3. Verify Postbacks

The ad network will receive JSON at the postback URL provided. See the example below:

{  
    "version" : "2.0",
    "ad-network-id" : "com.example",
    "campaign-id" : 42,
    "transaction-id" : "6aafb7a5-0170-41b5-bbe4-fe71dedf1e28",
    "app-id" : 525463029,
    "attribution-signature" : "MDYCGQCsQ4y8d4BlYU9b8Qb9BPWPi+ixk\/OiRysCGQDZZ8fpJnuqs9my8iSQVbJO\/oU1AXUROYU=",
    "redownload": 1,
    "source-app-id": 1234567891,
    "conversion-value": 20
}

The definition of each value is below:

Version

The version of the ad network API being used.

Ad Network Identifier

The identifier you received from Apple after registering as an ad network.

Transaction ID

A unique value for each validation used to deduplicate install validation messages.

Campaign ID

The campaign ID provided when displaying an ad. Should match the key value used when calling loadProduct() and the value in the ad network signature.

App ID

The App Store ID of the advertised app.

Attribution Signature

Apple's signature that will be used to verify the postback.

Redownload

Boolean that indicates if the app is being reinstalled. 1 for reinstall 0 for first-time install.

Source App ID

The App Store ID of the source app that displayed the ad.

Conversion Value

A 6 bit value that can indicate up to 64 different conversion actions that occurred in the advertised app. For more information, see the "Source App" section below.

After receiving the postback, the ad network must verify that it's from Apple by combining the values above into a UTF-8 string, with an invisible separator (‘\u2063’) between them. They must be in the exact order below:

version + '\u2063' + ad-network-id + '\u2063' + campaign-id + '\u2063' + app-id + '\u2063' + transaction-id + '\u2063' + redownload + '\u2063' + source-app-id
Note: Conversion value is not included and 'source-app-id' is only included if it is present in the postback.

This value is then used in conjunction with Apple's public key to verify the conversion is valid. The specific steps are defined in Apple's documentation. If the verification passes then the message is valid, and if it fails the message should not be used to track a conversion.

Source App

The source app has considerably less responsibility than the ad network but still plays a pivotal role.

1. Add the ad network's ID to the app's Info.plist

Infio.plist is essentially a configuration file present in all apps that provides metadata information to the system or user for various purposes.

In order for an ad network to track conversions using SKAdNetwork, the ad network's ID (that they received during registration with Apple) must be present in the Info.plist file of the app displaying ads.

This means that the app must include the ad network ID of every ad network displaying ads in the source app. Not only does this mean a source app must include their partner ad networks, but possibly also that ad network's partners (like a DSP) if they will ultimately be the ones tracking the conversion.

2. Display the ads that the ad network signs

While this is listed under "Source App" this responsibility will ultimately fall on the ad network SDK if it is going to be handling displaying ads in the app. In any case, the source app must use a set of keys when they call the loadProduct() method to describe a specific impression from the ad network's ad in order to associate an app install with an ad campaign.

The loadProduct() method will load necessary details of the advertised app before loading these details in a system product screen in iOS from where a user would install an app. The required keys are below, these will look familiar as they are the same values used to generate the ad network signature. You will notice that one of the required keys is the ad network signature itself:

  • iTunes Item Identifier
  • Ad Network Identifier
  • Ad Network Campaign Identifier
  • Timestamp
  • Ad Network Nonce
  • Ad Network Signature
  • Ad Network Source App Store Identifier
  • Ad Network Version

Calling loadProduct() with these keys and the ad network signature will provide the OS with all the details required for tracking app installs by the ad network.

Advertised App

The advertised app is the app that is, well, being advertised! This is the app that is aiming to be installed by the user via a campaign from the ad network. This app still has responsibilities that it must execute in order for an ad network to attribute an install or optionally track a conversion using SKAdNetwork.

The advertised app must either call the registerAppForAdNetworkAttribution() OR the updateConversionValue() method for the device to generate an install notification and call the ad network's postback URL.

1a. registerAppForAdNetworkAttribution()

This method should be called when a user launches the advertised app. Calling this method will generate an install notification using attribution data loaded by the ad network and source app that will be sent to the postback URL provided by the ad network.

As soon as this method is called a 24-hour timer begins and the postback will be sent 0-24 hours after that initial 24-hour timer expires, so 24-48 hrs after the user installs and launches the advertised app. The 0-24 hour time frame is imposed by Apple to eliminate any possibility of tying a conversion to a particular user by precise time tracking.

1b. updateConversionValue(_:)

This method is called by the advertising app to update the "conversion value" sent in the postback. The meaning of this value is determined by the ad network or the advertised app. It is a 6-bit value, so there are 64 possible conversion values. Each one of these 64 values could possibly be interpreted as one or several meanings.

For example, a conversion value can be assigned to a user signing up for an account, another value could be used to indicate they bought an item in the app or another value can indicate a combination of several actions.

Apple only allows for a single conversion value in the postback, so if ad networks want to track multiple conversion actions by a single user they will presumably need to interpret a single value as multiple conversion actions.

Unlike the registerAppForAdNetworkAttribution() method, Apple allows the updateConversionValue() method to be called within a rolling 24-hour period, as long as the new conversion value is greater than the previous value. Calling the method with a greater conversion value will restart the 24-hour timer. The install notification, along with the conversion value, will be sent to the ad network 0-24 hours after the timer expires.

Where do we go from here?

Apple has provided us with the tools to track app installs and conversions in a privacy-compliant way. Implementing SKAdNetwork will become table stakes for any ad network wanting to work with app owners desiring to advertise their apps to gain more installs.

There are still some obstacles and questions we as an industry need to answer in order to gracefully implement SKAdNetwork into the ad tech ecosystem. Many of these questions relate to effectively integrating SKAdNetwork into programmatic advertising. Questions like:

  • Who is the "ad network"? Will this always be the DSP?
  • How will source apps handle updating Info.plist in an efficient way?
  • Will the ORTB spec be updated to include fields for the key values (ad network signature, App Store ID etc.) required when loadProduct() is called by the source app?
  • Will DSPs need to update their bidding logic to ensure they return bids that don't contain an IDFA?

These are just a few questions that need to be asked and answered in order for the industry to move forward in the post-IDFA world.