People-Based Attribution & Smart Banners | AppsFlyer

Chapter 7

Advanced Topics

Web to App Strategy: Banners & Links

Considering the driver of web to app is an important and often neglected part of an engineer’s thoughts around attribution.

Typically organizations get spun up around analyzing and thoughtfully considering the following problem:

If we drive users from Mobile Web to the app will that negatively impact overall revenue? How do I compare my Web users to my app users?

Typically when teams that have widespread Mobile Web adoption and are worried about its impact on revenue, it’s important to note that App users convert to purchase universally at a much higher rate, with 3x higher conversion rates. This is largely because apps can deliver a UX that is much higher quality and easier to navigate through the purchase funnel. In addition to the overall ease of conversion on apps compared to mWeb. Other factors play into why it’s important to drive users to the app:

  • Login: When users are logged in on the app it makes it much easier for them to simply add something to their cart and checkout. Apps can retain login credentials for longer sessions, and the UX design of a native experience is easier and higher quality to web. This is why users spend more time and convert more in apps compared to Mobile Web.
  • Engagement: In addition to having an easier and better experience in the app compared to Mobile Web, apps can leverage push notifications, message center, feeds and other native only elements to prompt users to purchase or pickup an abandoned cart. Email is the only option available for Mobile Web users to be prompted. This higher rate of activation can lead to better results.

Outside of the business benefits of driving users to the app from Mobile Web, there is justification from an attribution and technology perspective that it is highly advantageous to have a cohesive web to app strategy.

AppsFlyer's Smart Banners

This is because People-Based Attribution, which was earlier discussed, in par

t relies on your company’s use of the same attribution system throughout your marketing stack – on web, in the app, on ads, and in emails – so that people are more appropriately and 

intelligently attributed across touchpoints. As discussed, the more you measure with a single Attribution system, the better you’re going to be able to identify the sources of traffic and the richer quality understanding you’ll develop of your users across platforms.

AppsFlyer's holistic attribution

If you record users across all your marketing touchpoints using the same attribution tooling, you’ll get better attribution results and richer/more accurate data related to your users sources. This is the fundamental premise of People Based Attribution, and an argument for why you should stick with one single Attribution provider for all your needs.

What does Great Look Like?

What does great web to app strategy even look like? You’re convinced at this point that you need a banner, but how should you design it and what’s the easiest way to power it?

There are a few options:

  1. Custom Design and Custom Measurement.
  2. Out of Box Design and Measurement.
  3. Hybrid of the above.

Option #1 is to design a banner and implement your own custom measurement not using an Attribution tool at all. There are lots of reasons why this would be disadvantageous, but the crux being that it is an immense amount of work when there are easier options available. You maintain control at the expense of speed and flexibility. Here are some examples of fully custom banners that companies have made on their own:

Option #2 is the optimal and easiest approach: use an out of the box Web SDK with it’s design and measurement solutions that are available as JS methods. AppsFlyer provides some static code that is used to generate the banner and some optional methods and parameters that can be used to customize the design and measurement.

The code sample below shows you how out-of-box is literally copy and paste. The Web SDK has a method to create a banner that floats on the top of the website and provides options in the settings variable that customize the title, icon, call to action (CTA), as well as a long list of measurement parameter options that can be customized and set at a static and dynamic level using Javascript.

The benefit of this method is that the developer doesn’t need to worry about both designing the banner, ensuring it fits all browsers and device models AND doesn’t have to worry about properly constructing and maintaining the attribution URL that floats under the button of the CTA. In this case, AppsFlyer is creating the URL with the attribution settings and generating the link. This is helpful as certain pages may have settings that vary dynamically, and so this out of both settings variable allows the developer to customize the experience and measure as the website changes.



<script type=“text/javascript” src=“appsflyer-banner.min.js”></script>

<link rel=“stylesheet” href=“appsflyer-banner.min.css”>

<script type=“text/javascript”>

var banner = new AFBanner();

var settings = {

   // banner settings

   title: “AppsFlyer”,

   subtitle: “Measure campaigns on the go”,

   app_icon: “img/app_icon.png”,

   call_to_action: “Install”,

   show_only_mobile: true,


   // attribution settings

   media_source: “banner_pid”,

   campaign: “banner_c”,

   adset: “banner_adset”,

   adset_id: “banner_adset_id”,

   ad: “banner_ad”,

   ad_id: “banner_ad_id”,

   site_id: “banner_site_id”,

   sub1: “banner_sub1”,


   // routing settings

   onelink_id: “pGHC”,

   subdomain: “appsflyer”,

   mobile_deep link: “appsflyer://”





   <div id=“my-banner”></div>




Regardless of your choice, one thing is very certain – do not use the “out of box” meta tags provided by Apple and Android. Not only do these provide limited to no measurement, which means no contribution to your overall Attribution model, but they provide no customization. If you’re going to go to the trouble of installing some JS on your site, you might as well opt for a few extra minutes and install a banner that accomplishes more than sending users to the App Store.

Native smart banner

Deep Linked Email


Ever since the advent of Apple Universal Links, countless marketers, product managers and engineers have lamented over emails that no longer deep link to the app.
This is partially due to the complexity of linking mechanisms that has been outlined in previous sections. Adding to the complexity is that there are so many different email clients that handle these mechanisms differently.

However, there is hope! Deep Linking with Email is not as complex as people make it out to be. There is one case that is hard to handle – iOS, when users have the app – but otherwise, nothing really changes for the vendor, client or user. You can handle deep linking from email yourself, much like you handle routing from any other 3rd Party Attribution Service. It just requires an understanding of Apple Universal Links/Android App Links, a willingness to use AppsFlyer or other vendor links in your URLs, and a willingness to modify your client code to handle email links very specifically.

Specifically, you have two options to handle Email Links:

  1. Turn off click recording from your Email Service Provider (ESP). This can actually be pretty painful to marketing teams, however, if you’re a programmatic or have a code based implementation of an ESP this might be easiest. In this case, when you turn off click recording, you can use your web links or 3rd Party Attribution Links right inside your emails and they will route the user as you expect.
  2. Handle Apple Universal Links and Android App Links – on your ESP click recording domain. This will require a small client side change to handle the ESP domain. Then you can retrieve the underlying URL from the email and route the user as you’d expect.

Sendgrid provides out of the box functionality to handle or resolve URLs in this way for method #2. This code is very generic and could work with any ESP. It’s merely an HTTP call to the URL with the right headers. So far, we’ve found this to work with all the major ESPs including Responsys, Sailthru, Braze, Sendgrid, and Salesforce.

Why ESP deep links Break

Let’s quickly recap why emails often don’t deep link users properly on newer operating systems:


  • ESPs wrap links in click recording.
  • This breaks Apple Universal Links, and complicates Android.
  • ESPs don’t provide reliable routing to app or web based on a variety of circumstances like a tool such as OneLink provides.

The only real case where deep linking behaves poorly is when the user has the app on iOS. In this case, the ESP link that measures clicks “breaks” the universal link functionality. You have to develop a system to handle this. This explains what the  problem is when people say “email deep links” or “universal links” are broken for email.

As a final note, people often ask, “well, what about desktop links?!” Desktop links behave normally in all cases. The ESP link just wraps whatever redirects you want. Redirects on desktop never go to any type of app and most Desktop experiences go to web still, so there is no modification needed.

Where ESP deep links break

So, there you have it – don’t believe the hype from vendors who try to sell you that deep linked Email requires an expensive product. Using attribution links or deep links from AppsFlyer or other standard 3rd Party Attribution Services should work easily and without an additional cost in almost all cases based on the following assumptions:

  1. You must set up deferred and regular deep linking. For AppsFlyer, this includes “OneLink”.
  2. You must set up Apple Universal Links and Android Apps Links with these individual vendors.

If you meet both of these requirements, then using regular deep links in your emails works for iOS & Android when the user doesn’t have the app. In these cases, the user can either go to mobile web or the app store depending on your preference.

If the user has the app on Android, these links will either open the app immediately via a Chrome Intent or the ESP link will route to the attribution link which will open the app via a URI scheme. You could also replicate the exact same functionality on Android as on iOS using Android App Links.

How It Works

  1. You will keep click recording turned on.
  2. You will setup Apple Universal Links and Android App Links on your ESP domain. Most ESPs now support this in their documentation. For example, Sendgrid has very detailed instructions on how to enable this on their site:
  3. Once Universal Links are enabled, then the app will open from the ESP click recording domain. You now need a way to retrieve the underlying URL that was put into the email HTML by the marketing team. You can use Sendgrid’s out of box URL Resolution code snippet:


– (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
   if (userActivity.activityType == NSUserActivityTypeBrowsingWeb) {
       NSURL *encodedURL = userActivity.webpageURL;
       if (encodedURL == nil) {
           NSLog(@”Unable to handle user activity: No URL provided”);
           return false;
       NSURLSession *session = [NSURLSession sharedSession];
       NSURLSessionDataTask *task = [session dataTaskWithURL:encodedURL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
           if (response == nil || [response URL] == nil) {
               NSLog(@”Unable to handle URL: %@”, encodedURL.absoluteString);
           // Now you have the resolved URL that you can
           // use to navigate somewhere in the app.
           NSURL *resolvedURL = [response URL];
           NSLog(@”Original URL: %@”, resolvedURL.absoluteString);
       [task resume];
   return YES;


If you have written your app for Android, you can use HttpURLConnection to resolve the URL by setting setInstanceFollowRedirects to false.

protected void onCreate(Bundle savedInstanceState) {

protected void onNewIntent(Intent intent) {
   String action = intent.getAction();
   final String encodedURL = intent.getDataString();
   if (Intent.ACTION_VIEW.equals(action) && encodedURL != null) {
       Log.d(“App Link”, encodedURL);
       new Thread(new Runnable() {
           public void run() {
               try {
                   URL originalURL = new URL(encodedURL);
                   HttpURLConnection ucon = (HttpURLConnection) originalURL.openConnection();
                   URL resolvedURL = new URL(ucon.getHeaderField(“Location”));
                   Log.d(“App Link”, resolvedURL.toString());
               catch (MalformedURLException ex) {
                   Log.e(“App Link”,Log.getStackTraceString(ex));
               catch (IOException ex) {
                   Log.e(“App Link”,Log.getStackTraceString(ex));

Developers have lots of options at this point. Because you will get back the underlying URL, you could choose to deep link off of your own web URLs AND your attribution URLs.

ESP Link clicked by user in email…

              → Opens App via Apple Universal Links or Android App Link

              → Resolve  URL

              → URL could be of a few varieties:



              → Handle URL like you might handle these links already!

As you can see, you are not constrained to buying a deep linked email product, or relying on a vendor in any way you want. We recommend you at least handle the case of your own links and your preferred Attribution and Deep Linking partner, but don’t waste time and money on product and services that pretend to simplify this well known technical system.

How It Works (Flow Diagram)

Email Creation

  • Marketer inputs a URL into their email campaign. This could be a regular company domain URL or an AppsFlyer link.
  • Your email service provider such as Sendgrid wraps up this link when the email goes out.
  • The email the end user sees shows this ESP URL:
    • Examples:

ESP deep linking flow with AppsFlyer

When a user taps this link on iOS Chrome or Android (or iOS, Safari, but doesn’t have the app) then things work just fine. There’s literally no difference. It’s just regular old link redirection.

Email Redirect Cases

When a user on iOS 9.3+ who has the app taps the link, if they’ve setup Universal Links or Android App Links on their click recording domain, then the app will open immediately.

In the diagram below you can see three separate cases:

Case #1: This is the flow of what has already been described as Deferred deep linking. Without any type of 3rd party redirection on your email links, you can use AppsFlyer links out of box to direct users to web or the app store. After install they may be deep linked to the right place in the app without any additional client side handling.

Case #2: In this case, it’s assumed that 3rd party click recording is enabled with your email service provider. If you’re using AppsFlyer or your own domain URLs, a simple piece of client side code can help you unwrap the underlying URL and route the user to the appropriate place in the app. By default, when the user has the app, they will open to the app immediately via Universal Links or Android App Links, whereby you’ll need to unwrap the ESP URL and resolve. If they do not have the app, AppsFlyer or your own domain URL can take them to the appropriate spot in the App Store or on Mobile Web.

Case #3: If you’re in need of a simple solution, you can use AppsFlyer only to intelligently direct the user to the App when the user has it. AppsFlyer will fire a URI scheme from the browser if they know the user has the app.

AppsFlyer ESP redirection cases

Managing ESP Universal Links: Resolving URL, Handling Clicks & Routings

  • The app should employ the code snippet referenced above to retrieve the underlying URL.
    • If the underlying URL is an AppsFlyer link or one of your own links where the query params are listed out, then no further async calls are required. Just handle the link by parsing query params sending them to the app’s route handler.
    • NOTE: If the underlying URL is an AppsFlyer OneLink Short URL, then you would need to subsequently make an async request to AppsFlyer to retrieve the link metadata before being able to process is. For this reason, we usually recommend using long form URLs where the key values are visible in the URL to make routing easy and not require another roundtrip call.
    • If it’s any other type of URL you can handle it similarly.

Current Issues with Apple Universal Links

Apple Universal Links is a useful technology that is proven to offer a better UX for users who have the app. However, these links have a few important limitations to be aware of, otherwise  you and your product teams will be spending endless hours debugging issues that cannot be fixed. There are actually four core issues as of the writing of this document. They almost all only applicable to Apple Universal Links (iOS 12), not Android App Links.

Issue #1: No Recording or Attribution. Because Apple Universal Links are not a redirect, but rather a system applied to links to open the app, it is very difficult to establish true click recording. Why? Because the app opens immediately from Apple Universal Links. There’s no redirect through a webpage to count a click to a server. Instead, when the app opens, the URL that opens the app gets reported in via a well known Apple code snippet called `continueUserActivity`. To count a click on the URL, a marketing team would have to setup a server and manually count the click from the app.

A much simpler and easier solution is to use an attribution & deep linking tool, such as AppsFlyer. These systems will have Universal Links on their actual domain, such as and automatically execute this type of recording for you. In short, whenever you need to record users who click on links, you should use a 3rd party tool, like OneLink.

Issue #2: No Link Wrapping Allowed. This problem goes by many names. Link wrapping, click recording, link redirect. They all refer to the same thing. When a marketer runs an ad or sends an email, often the service they are using will take the link they are using and “wrap it” or send it through a redirect so that the system they are using can count a click. It does this by redirecting to their website before sending the user to the final destination URL that the marketer input into the system.

Deep linking wrapping

Both Apple Universal Links and Android App Links cannot be wrapped in other URLs. If you do this, then the link will redirect users to the web fallback instead of to the app. This mostly impacts marketers running paid ads with services like Double Click (where URLs get wrapped) and email marketers who have click recording enabled with their Email Service Provider (ESP).

In both cases, other 3rd party tools may wrap URLs you are using that would otherwise behave as Universal Links. This breaks the functionality and defeats the purpose of using Universal Links. There are a variety of solutions to this, from turning off click recording, to employing a specialty consultant to help navigate the complexity.

Issue #3: Phantom Banner Syndrome. For some reason, Apple could randomly inject a banner ad onto your site in Safari when Universal Links is implemented. There is no way to control this, customize it, or record it. It’s a strange feature that Apple introduced with Universal Links and has confused the market quite a bit. Most customers just choose to ignore this, as it is only displayed in a few cases, while a click on Apple Universal Links would normally take the user to your app and not your website.

Phantom banner

Issue #4: General Performance Instability. Starting with iOS 11, many apps have noticed that Universal Links do not always perform the same way.  iOS leverages the domain information from the Apple App Site Association (AASA) file you’ve established in order to open apps with Apple Universal Links. When a new user on iOS installs the app, the AASA file is downloaded into local storage on the user’s device, and is then parsed to configure the routing for Universal Links at the device level, allowing for a user to tap a link and route properly with a configured domain. Unfortunately, on iOS 11.2, developers report that the AASA file no longer reliably downloads onto the device and into local storage after install, and therefore, since the file is not present, Universal Links don’t work. Generally, they are also known to be difficult to debug with many implementation steps to install.

There is a well known Apple bug regarding this issue that is being monitored which you can follow here:

Assuming you’ve setup Universal Links on your regular URLs or on the URLs you use for your attribution provider, you can test this and possibly get Universal Links to work again by doing the following:

  • Logout of app.
  • Delete app.
  • Install the app from the app store or test/QA site.
  • Restart the device (turn off and then on again) – on iOS 11 this can often fix strange entitlement issues where the behavior of the link is not correct when clicked
  • Create or find a link you are trying to test.
  • Paste the link in Notes, iMessage or in an email using the Apple Mail Client.
    • Do not use Slack, Facebook or any other app to click the link.
    • Do not paste the link into Safari – this will not work correctly.
  • Click the link.
  • The app should open immediately, without a redirect through the browser, and route the user to the proper place in the app.

About the Authors