Universal Application Tracking

From MdotM API
Jump to: navigation, search

MdotM offers advertising clients device ID-based tracking for iOS apps and both device ID-based and non-device ID-based tracking for Android applications.

iOS tracking:

  1. Device ID-based Method: client or server-to-server code relays identifierForAdvertising device IDs to run on in-app traffic

Android tracking:

  1. Universal Android Referrer Method, which involves passing a "referrer" into a Google Play URL and receiving the referrer from the application upon download completion.
  2. Device ID-based method involves passing Google Advertising ID.

iOS: Server-to-Server Code

You may send ALL devices or just those attributed to MdotM by pinging the following URL server-to-server:

Sample postback URL: http://ads.mdotm.com/ads/trackback.php?appid={appid}&aid={idfa}&ate={ate}&eventID=install&advid={email}&clickid={clickid}

Required parameters: appid and {aid or clickid}

  • appid: 9 digit numeric Apple app ID
  • aid: user's advertisingIdentifier
  • ate: user's advertisingTrackingEnabled
  • eventID: use "install" for first launch events. For post-install events, this value must match the event ID inputted in the campaign funnel. Default in campaign funnel is "Purchase".
  • advid: use the email address of your account
  • clickid: ID provided by MdotM that's generated on the click

iOS Client-Side Code

When reporting all launch events to MdotM, call this method to relay device identifiers from your app to MdotM:

// replace [ADVID] and [APPID] below
- (void)reportAppOpenToMdotM {
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
 NSString *eventID = @"install";
 NSString *usertoken = @"yourusertoken"; // supply your own user token, using e.g. identifierForVendor or CFUUIDCreate
 NSString *aid = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
 NSString *ate = [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled] ? @"1" : @"0";
 NSString *appOpenEndpoint = [NSString stringWithFormat:@"http://ads.mdotm.com/ads/trackback.php?advid=%@&aid=%@&ate=%@&usertoken=%@&appid=%@&eventID=%@", @"[ADVID]", aid, ate, usertoken, @"[APPID]", eventID];
 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:appOpenEndpoint]];
 NSURLResponse *response;
 NSError *error = nil;
 NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
 [pool release];

iOS Post Install Tracking

If you have post-install events, simply populate the "eventID" parameter in your postback URL with custom values to track post-install events. Input a corresponding event ID in the campaign funnel for each different value used in the "eventID" parameter. Post-install events are sent server-to-server. When using deviceID-based tracking, call this url:


Required parameters: appid, eventID, and {aid or clickid}

Parameters defined above in #iOS_Conversion_Tracking.

Android Conversion Tracking

Sample postback URL: http://ads.mdotm.com/ads/receiver.php?referrer=&package=&gaid=&ate=&advid=&clickid=&eventID=&value=

Required parameters: package and {gaid or clickid}

  • referrer: referrer string collected from Google Play
  • package: app ID found in Google Play's URL
  • gaid: user's Google Advertising ID
  • ate: user's Advertising Tracking Enabled setting. If true set to 1. If false set to 0.
  • advid: use the email address that's registered in your account
  • clickid: ID provided by MdotM that's generated on the click
  • eventID: If using to track installs, this is not required. If using to track post-install (in-app) events, then eventID must match event ID inputted in campaign funnel. Default is "purchase".
  • value: additional numerical data for post install events, such as revenue

Android Client-Side Code

While developing application to retrieve the Google Advertising ID you need a Google play service SDK.

1. You set up your Android application to relay referrers to MdotM.
Step A: Add this to your manifest url:

<receiver android:name="com.atminn.urbanroundup.MdotmReceiver" android:exported="true" >
    <action android:name="com.android.vending.INSTALL_REFERRER" />

replacing "com.atminn.urbanroundup.MdotmReceiver" with your packagename, i.e. "com.mycompany.myapp.MdotmReceiver"

Next, add the below meta data inside the <application></application> tag of your application manifest file

        <meta-data  android:name="com.google.android.gms.version"  android:value="@integer/google_play_services_version" />

In addition, you must also add the following permissions, if you haven't already:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

Step B: Add this MdotmReceiver.java class to your project, replacing "com.atminn.urbanroundup" with your package name at the top:

package com.atminn.urbanroundup;

import java.net.URLEncoder;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.provider.Settings;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
import com.google.android.gms.common.GooglePlayServicesAvailabilityException;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import java.io.IOException;

public class MdotmReceiver extends BroadcastReceiver {
    public String postBackUrl = "";
    public String deviceId = "0";
    public String androidId = "0";
    public String gaid = "";
    public String ate = "";
    public void onReceive( Context context, Intent intent ) {
      String referrer = "";
      try {
        referrer = intent.getStringExtra( "referrer" );
        if ( referrer == null ) {
	  referrer = "null_referrer_found";
      } catch(Exception e) {
        referrer = "exception_found_retrieving_referrer";

      try {
        final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        deviceId = telephonyManager.getDeviceId();
        if ( deviceId == null ) deviceId = "0";
      } catch(Exception e) {
        deviceId = "0";

      try {
        androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
        if ( androidId == null ) androidId = "0";
      } catch(Exception e) {
        androidId = "0";

      Info adInfo = null;
      boolean isLAT = false;
      try {
	 adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context.getApplicationContext());
      } catch(GooglePlayServicesNotAvailableException e) {
	 // Google Play services is not available entirely.
      } catch(IOException e) {
        // Unrecoverable error connecting to Google Play services (e.g., the old version of the service doesn't support getting AdvertisingId).
      } catch(IllegalStateException e) {
	// This exception occurs when we run this code on main/UI  thread. So do run it on separate thread 
      } catch(GooglePlayServicesRepairableException e) {
	// Google play service needs update

      if ( adInfo != null ) {
         gaid = adInfo.getId();
	 isLAT = adInfo.isLimitAdTrackingEnabled();

      if ( isLAT ) { 
        ate = "1";
      } else {
        ate = "0";

      String packageName = "";
      Context applicationContext = context.getApplicationContext();
      if ( applicationContext == null ) {
        packageName = "null_package";
      } else {
        packageName = applicationContext.getPackageName();

      postBackUrl = "http://ads.mdotm.com/ads/receiver.php?referrer=" + URLEncoder.encode( referrer ) + "&package=" + URLEncoder.encode( packageName ) + "&gaid=" + URLEncoder.encode(gaid) + "&ate=" + ate;

    private Thread makePostBack = new Thread() {
      public void run() {
          HttpClient httpClient = new DefaultHttpClient();
          HttpGet httpGet = new HttpGet( postBackUrl ); 
        } catch(Exception e) {

Note: Android doesn't permit the use of multiple INSTALL_REFERRERs in the manifest. If you wish to have multiple receivers listen for the INSTALL_REFERRER, you will need to create your own custom receiver and call the onReceive functions for both from the custom receiver's onReceive function.

For example, it would be something like:

public class CustomReceiver extends BroadcastReceiver {
   public void onReceive( Context context, Intent intent ) {

2. Upload your application to the Android Market!

Note: The only way to test these trackbacks is by uploading the updated app to the Android Market and simulate a download. Upon simulation of the download, we can check on our end as to whether we saw the trackback.

3. When new app user clicks on your MdotM ad, the user is be taken to the Android Market URL with additional referrer parameter, such as:


We'll take care of all the referrer information -- you just need to let us know your package name.

4. When a user downloads your Android application, your application sends this referrer information back to MdotM. If MdotM finds a match between your referrer information and a click generated by MdotM, an install is recorded! This works in close to real-time, with 1-5 minute delays.

Parameters defined above in #Android_Conversion_Tracking.

Android Server-to-Server Code

Sample postback URL: http://ads.mdotm.com/ads/receiver.php?referrer=&package=&gaid=&ate=&advid=&clickid=

Required parameters: package and {gaid, clickid, or referrer}

Parameters defined above in #Android_Conversion_Tracking.

// $referrer sent to your servers
// $gaid sent to your servers
// $ate sent to your servers
// $deviceid sent to your servers:
//   your Android app sends: telephonyManager.getDeviceId()
// $androidid sent to your servers

// your application id which for
//  your Android app ("com.yourcompany.yourapp"), you can find in the Android manifest/Market URL  

$appid = "yourappid";  
$trackbackurl = "http://ads.mdotm.com/ads/receiver.php?referrer=".urlencode( $referrer )."&package=".urlencode( $appid )."&gaid=".urlencode($gaid)."&ate=".urlencode($ate)."&advid=".urlencode($advid)."&clickid=".urlencode($clickid);
$trackbackresult = file_get_contents($trackbackurl); // the result is a JSON object

Testing Referral Tracking

The definitive test is to submit the application to the market, construct a URL with a uniquely identifiable referrer and download from Google Play. This isn’t always practical during development so an alternative way to do this is to use adb to send the installation intent. Once connected via adb shell the following command will send the intent:

am broadcast -a com.android.vending.INSTALL_REFERRER -n your.pacakage.name.here/.ReferralReceiver --es "referrer" "utm_source=test_source&utm_medium=test_medium&utm_term=test_term&utm_content=test_content&utm_campaign=test_name"

Android Post Install Tracking

Populate the "eventID" parameter in your postback URL with custom values to track post-install events. Input a corresponding event ID in the campaign funnel for each different value used in the "eventID" parameter.

Post-install events are sent server-to-server by calling this url:


Required parameters: package, eventID, and {gaid or clickid}

Parameters defined above in #Android_Conversion_Tracking.

MdotM Unity Plug-In for Install Tracking

Advertisers that use Unity may download the Unity plugin for MdotM Install Tracking from the URLs below

iOS has two methods exposed (reportAppOpenWithAppleId and registerAppEvent) and Android pings are handled via the manifest file.

Conversion Tracking when using clickID ONLY

When a user clicks on an ad, MdotM would call your servers with a 32-character string unique to that click and passed to the parameter of your choice, e.g:


where [CLICKID] is a randomly generated unique 32-character string specific to each click.

You must store the string passed into your parameter yourparameter from the point the user lands on your page until the conversion event takes place.

You can then relay conversion event back to MdotM by firing one of the following pixels:



where the string that is passed in must be sent back in the clickid parameter in place of the macro {yourMacroForClickID}.