At a glance: Record and attribute installs originating from cross-promotion campaigns of your apps.
Question: What is the best source of traffic you can get for your new apps?
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.
To avoid misuse or overuse of the precious resource of existing active users, its best practice to attribute these campaigns carefully.
AppsFlyer allows you to attribute and record installs originating from cross-promotion campaigns of your existing apps. Afterward, you can optimize your cross-promotion traffic to get even better results.
Cross-promotion Attribution is supported starting AppsFlyer SDK 4.8+
Note! Cross-promotion by IDFV requires SDK 6.0.2+. IDFV is collected automatically and no further action is required by the developer.
How does it work?
- The user is exposed to the cross-promo ad on your app. The ad creative can be a banner, video, or any clickable object.
- [optional] SDK sends a cross-promo impression to the user.
- The user clicks on the ad.
- logAndOpenStore method records the click and redirects the user to the app store's page for the promoted app. The click that the SDK creates already includes the device advertising ID for best attribution results. In addition, you can add additional parameters to the attribution link such as lookback window, ad set names, subscriber parameters and more.
- 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 asite_id
of this media source.
Note
Regular mobile ads activate a URL when clicked. Cross-promotion mobile ads don't have a link, but instead they activate the AppsFlyer SDK logAndOpenStore method.
Attributing cross-promotions
Attributing 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.
Attributing 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 use case.
For example, using the map of parameters you can set the click lookback window and other parameters such as ad IDs, ad sets. You can also mark the campaign as incentivized campaigns. See AppsFlyer attribution parameter for more information.
For a list of standard parameters that you can pass to the API method, see AppsFlyer attribution parameter.
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.
Attributing cross-promotion clicks
Use the following code to attribute the click and launch the app store's app page. The code creates an attribution link and adds the device advertising ID to it.
String campaign = "Cross Promo Campaign";
Map<String, String> parameters = new HashMap();
parameters.put("af_sub1", "val");
parameters.put("custom_param", "val2");
CrossPromotionHelper.logAndOpenStore(this, "com.mygosoftware.android.loginbox", campaign, parameters);
static NSString *const kCrossPromotedAppId = @"123456789";
static NSString *const kCrossPromotedCampaign = @"test campaign";
- (void) crossPromotion {
NSDictionary *parameters = @{@"af_sub1": @"val", @"custom_param": @"val2" };
[AppsFlyerCrossPromotionHelper logAndOpenStore:kCrossPromotedAppId
campaign:kCrossPromotedCampaign
parameters:parameters
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]);
}
else
{
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];
}
}];
Dictionary<string,string> parameters = new Dictionary<string,string>();
parameters.Add("af_sub1","val");
parameters.Add("custom_param","val2");
AppsFlyer.attributeAndOpenStore("com.mygosoftware.android.loginbox","test campaign",parameters);
In Android, the call for this method should result in opening the Play Store and redirecting to the relevant app.
Dictionary<string,string> parameters = new Dictionary<string,string>();
parameters.Add("af_sub1","val");
parameters.Add("custom_param","val2")
AppsFlyer.attributeAndOpenStore("123456789","test campaign",parameters);
In iOS a Attribution Link is generated and returned to the onOpenStoreLinkGenerated
method in the AppsFlyerTrackerCallbacks
object. By default, the method opens the link in a web browser and redirects to the App-Store. You can change this behavior by editing the onOpenStoreLinkGenerated
method in the AppsFlyerTrackerCallbacks
to any other logic.
Note
You can add any of these attribution link parameters to the generated link.
Attributing cross-promotion impressions
To attribute an impression use the following API call. Make sure to use the promoted App ID as it appears within the AppsFlyer dashboard.
String appID = "com.app";
String campaign = "Cross Promo Campaign";
Map<String, String> parameters = new HashMap();
parameters.put("af_sub1", "val");
parameters.put("custom_param", "val2");
CrossPromotionHelper.logCrossPromoteImpression(this, appID, campaign, parameters);
val appID = "com.app"
val campaign = "Cross Promo Campaign"
val parameters = HashMap<String, String>()
parameters.put("af_sub1", "val")
parameters.put("custom_param", "val2")
CrossPromotionHelper.logCrossPromoteImpression(
this,
appID,
campaign,
parameters
)
static NSString *const kCrossPromotedAppId = @"123456789";
static NSString *const kCrossPromotedCampaign = @"test campaign";
/*...*/
- (void)viewDidLoad {
[super viewDidLoad];
NSDictionary *kCrossPromotedParameters = @{@"af_sub1": @"val", @"custom_param": @"val2" };
/* generate impression for cross-promotion */
[AppsFlyerCrossPromotionHelper logCrossPromoteImpression:kCrossPromotedAppId
campaign:kCrossPromotedCampaign parameters:kCrossPromotedParameters];
}
var appID = "com.app"
var campaign = "Cross Promo Campaign"
var parameters = [String : String]()
parameters["af_sub1"] = "val"
parameters["custom_param"] = "val2"
AppsFlyerCrossPromotionHelper.logCrossPromoteImpression(appID, campaign: campaign, parameters: parameters)
AppsFlyer.recordCrossPromoteImpression(string promotedAppID, string campaign);
Attributing cross-promotion with non-native platforms
Currently, the cross-promotion attribution APIs are available only for native Android and iOS SDKs and for Unity. However, non-native platforms can perform cross-promotions attribution just as effectively. These include platforms such as Adobe air, Cordova, Xamarin, React native, Marmalade etc.
To do this you need to build an attribution Link, which is invoked when the user clicks on the cross-promotion ad. The link MUST contain the media source name af_cross_promotion and the site ID of the promoting app.
Clicks cross-promotion URL format:
http://app.appsflyer.com/{PROMOTED APP ID}?pid=af_cross_promotion&
af_siteid={PROMOTING APP NAME}
Impressions cross-promotion URL format:
http://impression.appsflyer.com/{PROMOTED APP ID}?pid=af_cross_promotion&
af_siteid={PROMOTING APP NAME}
Tip
If you need frequent changes in the attribution link parameters, consider building a short URL via the Link Management dashboard page, instead of using the Cross-promotion API. Doing this would enable you to add or change any parameters on the cross-promotion attribution link without changing the app's code.
Viewing the results
Promoted app view
As with any other media source, you can see on your promoted app's dashboard the traffic coming from cross-promotion campaigns:
1. Select the af_cross_promotion
media source
2. Group by site ID to compare the traffic from the promoting apps
3. The apps (site IDs) with the best conversion rates have the best affinity with the promoted app, and their users are most likely to install it.
Promoting apps view
While the dashboard of the receiving app enables seeing which apps send the best traffic to it, you may want to see things from the perspective of the contributing apps. This is not possible to see on the promoting apps dashboard, as it shows incoming traffic and the said traffic is outgoing for them. However, Custom dashboards enable watching information from several of your apps in one place, including the cross-promotion traffic.
This is very useful for viewing installs, clicks, impressions and ultimately conversion data rates from several apps promoting any single app. This enables comparing the affinity between each of the promoting apps and the promoted app, and to optimize your cross-promotion campaigns accordingly.
Below is an example Custom Dashboard widget that performs this: