Cross Promotion Tracking


Question - What is the best source of traffic you can get for your new app/s?

Answer - your own users from your other apps! After all, your users already know and (hopefully) love your brand and apps. 

Using cross-promotion campaigns with these users should get you high conversion and retention rates compared with most other sources of traffic. Let's also not forget that this traffic is 100% free of media source charges.

However, to avoid misuse or overuse of this precious resource of existing active users, it is highly recommended to track these campaigns carefully.

AppsFlyer allows you to track and attribute installs originating from cross promotion campaigns of your existing apps. Afterwards, you can optimize on your cross-promotion traffic to get even better results.

Note - Cross Promotion Tracking is available on AppsFlyer's SDK versions 4.8.0 and above.

How Does it Work?

1. User is exposed to the cross-promo ad on your app (Optional - track the impression. Please see below)

2. User clicks on the ad.

3. The SDK's trackAndOpenStore method tracks the click and "redirects" the user to the app store's page for the promoted app.

4. After the promoted app is installed and launched, the AppsFlyer dashboard shows the newly acquired user under the media source af_cross_promotion. The app driving the install appears as a site_id of this media source.  


Tracking Cross Promotions

Tracking both impressions and clicks of cross promotion campaigns is very useful. It enables you to calculate the impressions to clicks conversion rate, or even impressions to installs conversion rates, and optimize accordingly.

Tip - In cross promotion campaigns the impressions to installs conversion rate is actually an affinity score between your apps. The higher is the rate the closer are the apps in terms of attractiveness to your users.

Tracking cross-promotion clicks and impressions is performed by using two separate API calls as described below. Each API call can also be passed a Map of key values, which can be anything that fits your cross promotion tracking use case. In addition, any AppsFlyer tracking parameter can be passed as part of this Map.

With the first launch of the promoted app all the original parameters can be accessed via the SDK's conversion data API, for Android or iOS.

Tracking Impressions

To track an impression use the following API call. Make sure to use the promoted App ID as it appears within the AppsFlyer dashboard.


//void trackCrossPromoteImpression(Context context,
//                                         String promoted_app_id,
//                                         String campaign,
//                                         Map<String,String> user_params);
CrossPromotionHelper.trackCrossPromoteImpression(this, "", null);


static NSString *const kCrossPromotedAppId = @"123456789";
static NSString *const kCrossPromotedCampaign = @"test campaign";
- (void)viewDidLoad {
   [super viewDidLoad];    
       // generate impression for cross-promotion
       [AppsFlyerCrossPromotionHelper trackCrossPromoteImpression:kCrossPromotedAppId

Tracking Cross Promotion Click and Launching the Store

Use the following code to track the click and launch the app store's app page.


//void trackAndOpenStore(Context context, String promoted_app_id, String campaign, Map<String,String> user_params);
String campaign = “Cross Promo Campaign”;
Map<String, String> parameters = new HashMap();
parameters.put(“af_sub1”, “val”);
parameters.put(“custom_param”, “val2”);
CrossPromotionHelper.trackAndOpenStore(this, "", campaign, parameters); 


iOS allows you to utilize the StoreKit component to open the App Store while remaining in the context of your app. The following code snippet demonstrates how to open the StoreKit class and check that it has been properly initialized. You can read more about the StoreKit documentation here.

static NSString *const kCrossPromotedAppId = @"123456789";
static NSString *const kCrossPromotedCampaign = @"test campaign";
- (void) crossPromotion {    
NSDictionary *parameters = @{@"af_sub1": @"val", @"custom_param": @"val2" };
   [AppsFlyerCrossPromotionHelper trackAndOpenStore:kCrossPromotedAppId
                              openStore:^(NSURLSession *urlSession, NSURL *clickURL)
    NSURLSessionDataTask *dataTask;
    dataTask = [urlSession dataTaskWithURL:clickURL
                         completionHandler:^(NSData * _Nullable data,
                                             NSURLResponse * _Nullable response,
                                             NSError * _Nullable error)
            if (error) {
                NSLog(@"AppsFlyer crossPromotionViewed Connection failed! Error - %@",[error localizedDescription]);
                  if (NSClassFromString(@"SKStoreProductViewController") == nil) {
                      NSString *iTunesLink = [linkGenerator generateLink];                               
                          [[UIApplication sharedApplication] openURL:[NSURL URLWithString:iTunesLink] options:@{} completionHandler:^(BOOL success) {
                                  NSLog(@"AppsFlyer openAppStoreForAppID completionHandler result %d",success);
        [dataTask resume];       
          if (NSClassFromString(@"SKStoreProductViewController") != nil) {
              [self openStoreKit:kCrossPromotedAppId viewController:self];

- (void) openStoreKit:(NSString*) appID
      viewController: (UIViewController*) viewController
       SKStoreProductViewController *storeController = [[ SKStoreProductViewController alloc ] init ];    
   NSDictionary *productParameters = @{ SKStoreProductParameterITunesItemIdentifier : appID };
   [ storeController loadProductWithParameters: productParameters completionBlock:^( BOOL result, NSError *error )
        if ( result )
            [viewController presentViewController:storeController animated:YES completion:nil];

Custom Dashboard Views

Below are the available views of the Custom Dashboard:




Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request
Powered by Zendesk