Server-to-Server Retrieving Device Data Guide

Retrieving Device Data Guide

Singular requires specific device identifiers to be included in all API requests for accurate attribution. These identifiers include:

  • Google Advertising ID (GAID) and Google App Set ID (ASID) for Google Play Devices
  • Amazon Advertising ID for Non-Google Play Amazon Devices
  • Open Advertising ID (OAID) for Chinese-manufactured Android devices
  • And if none of the above are available, the Android ID (ANDI) for Non-Google Play Devices
  • Identifier for Advertisers (IDFA) and Identifier for Vendors (IDFV) for iOS Devices

Singular also requires some Mobile device Parameters:

  • Locale (e.g., en_US)
  • Device Make (e.g., Samsung)
  • Device Model (e.g., iPhone 12, Samsung Galaxy S21)
  • Build (e.g., Build/13D15)

Singular provides code snippet examples to help you obtain these identifiers, which can be found below.

Sample Device Info Class

Identifiers

Required iOS Identifiers

  • The IDFV is required on all S2S requests
  • The IDFA should be provided if App Tracking Transparency Consent was provided by the user.
  • The ATT Authorization Status is also required.
How to retrieve iOS Device Data

Retrieving the Identifier for Advertisers (IDFA)

The Identifier for Advertisers (IDFA) helps advertisers track and attribute user actions (e.g., ad clicks, app installs) to specific campaigns, enabling precise ad targeting and campaign optimization.

Starting with iOS 14.5, users must opt-in via the App Tracking Transparency (ATT) framework before apps can access their IDFA. If users do not opt-in, the IDFA is unavailable, limiting tracking capabilities.

Retrieving the Identifier for Vendors (IDFV)

The Identifier for Vendors (IDFV) is a unique identifier assigned by Apple to a device, which is specific to a particular vendor or developer. It remains consistent across all apps from the same vendor on a given device, allowing the vendor to track user behavior and interactions across their app ecosystem without identifying the user personally.

  • Ensure the ATT prompt is shown and handled before attempting to access the IDFA.
  • If you are using ATT, capture the IDFA and pass it back to your server for use on Singular API requests.
  • Capture the IDFV and pass it back to your server for use on Singular API requests.

Example: Requesting ATT Authorization Status to Retrieve IDFA and IDFV with Console Logs

Here is the Objective-C and Swift code snippets to retrieve both the IDFA (Identifier for Advertisers) and IDFV (Identifier for Vendor) with console logs. This code includes handling App Tracking Transparency (ATT) permissions, which are required to access the IDFA starting from iOS 14.5.

Objective-CSwift
#import <AdSupport/AdSupport.h>
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <UIKit/UIKit.h>

- (void)retrieveIdentifiers {
    // Request ATT authorization (iOS 14.5+)
    [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
        dispatch_async(dispatch_get_main_queue(), ^{
            switch (status) {
                case ATTrackingManagerAuthorizationStatusAuthorized: {
                    // ATT authorized, retrieve IDFA
                    NSUUID *idfa = [[ASIdentifierManager sharedManager] advertisingIdentifier];
                    NSLog(@"IDFA: %@", [idfa UUIDString]);
                    break;
                }
                case ATTrackingManagerAuthorizationStatusDenied:
                case ATTrackingManagerAuthorizationStatusRestricted:
                case ATTrackingManagerAuthorizationStatusNotDetermined:
                    // ATT not authorized or not determined
                    NSLog(@"Tracking not authorized or not determined.");
                    break;
                default:
                    NSLog(@"Unknown ATT status.");
                    break;
            }

            // Retrieve IDFV (always available)
            NSUUID *idfv = [[UIDevice currentDevice] identifierForVendor];
            if (idfv != nil) {
                NSLog(@"IDFV: %@", [idfv UUIDString]);
            } else {
                NSLog(@"Unable to retrieve IDFV.");
            }
        });
    }];
}

// Call the method to retrieve identifiers
[self retrieveIdentifiers];
  • IDFA: Requires ATT authorization from iOS 14.5+. Without user consent, the IDFA will return all zeros.
  • IDFV: Always available and should should always be provided on Singular API Requests.

Required Android Identifiers (Google Play Devices)

  • The ASID is required on all S2S requests
  • The AIFA (GAID) should be provided if available.
How to retrieve Android Device Data (Google Play)

Retrieving the Google Advertising Identifier (GAID)

The Google Advertising Identifier (GAID), also known as AIFA in Singular or Android Advertising ID (AAID), is a unique, user-resettable identifier assigned to Android devices. It helps advertisers and app developers track and attribute user actions (e.g., ad clicks, app installs) across apps to specific campaigns, enabling precise ad targeting and campaign optimization, while maintaining user privacy.

JavaKotlin
Dependencies

Make sure you have added the required dependency for Google Play Services in your build.gradle file:

dependencies {
    implementation 'com.google.android.gms:play-services-ads-identifier:17.0.0'
}

 

If your app build is targeting Android 12/API level 31 or higher, add permissions in the AndroidManifest.xml to access the Google Advertising ID:

<uses-permission android:name="com.google.android.gms.permission.AD_ID" />

 

Usage

To use this method, simply call it from your activity or application class:

AdIdUtils.getGoogleAdId(getApplicationContext());

 

Java Code to Retrieve Google Advertising ID (GAID)
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;

public class AdIdUtils {

    // Method to retrieve the Google Advertising ID (GAID)
    public static void getGoogleAdId(Context context) {
        // Running the task in a background thread
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    // Retrieve the Advertising ID info
                    Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
                    
                    // Get the GAID (Google Advertising ID)
                    String adId = adInfo.getId();
                    
                    // Check if "Limit Ad Tracking" is enabled by the user
                    boolean isLimitAdTrackingEnabled = adInfo.isLimitAdTrackingEnabled();
                    
                    // Log the results
                    Log.d("GoogleAdID", "Advertising ID: " + adId);
                    Log.d("GoogleAdID", "Limit Ad Tracking Enabled: " + isLimitAdTrackingEnabled);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

Retrieving the App Set ID (ASID)

The Android App Set ID provides a way for developers to track users across their own apps in a privacy-conscious manner. It is particularly useful for analytics and fraud prevention but cannot be used for advertising purposes such as personalized ads or measurement.

JavaKotlin
Dependencies

Make sure you have added the required dependency for Google Play Services in your build.gradle file:

dependencies {
    implementation 'com.google.android.gms:play-services-appset:16.1.0'
}

 

Usage

To use this function, simply call it from your activity or application class:

AppSetIdUtils.getAppSetId(getApplicationContext());

 

Java Code to Retrieve App Set ID
import android.content.Context;
import android.util.Log;
import com.google.android.gms.appset.AppSet;
import com.google.android.gms.appset.AppSetIdClient;
import com.google.android.gms.appset.AppSetIdInfo;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;

public class AppSetIdUtils {

    // Method to retrieve the App Set ID
    public static void getAppSetId(Context context) {
        // Get the AppSetIdClient instance
        AppSetIdClient client = AppSet.getClient(context);

        // Retrieve the App Set ID information asynchronously
        Task<AppSetIdInfo> task = client.getAppSetIdInfo();

        task.addOnSuccessListener(new OnSuccessListener<AppSetIdInfo>() {
            @Override
            public void onSuccess(AppSetIdInfo info) {
                // Get the App Set ID and its scope
                String appSetId = info.getId();
                int scope = info.getScope();

                // Log the results
                Log.d("AppSetID", "App Set ID: " + appSetId);
                Log.d("AppSetID", "Scope: " + (scope == AppSetIdInfo.SCOPE_DEVELOPER ? "Developer" : "App"));
            }
        }).addOnFailureListener(e -> {
            // Handle any errors that occur during retrieval
            Log.e("AppSetID", "Failed to retrieve App Set ID", e);
        });
    }
}

Required Android Identifiers (Non-Google Play Devices)

If no ASID or AIFA are available:

  • The AMID (Amazon Identifier) should be provided. Amazon Devices Only.
How to retrieve the Amazon Advertising ID (Non-Google Play)

Retrieving the Amazon ID (AMID)

To capture the Amazon Advertising Identifier in your Android app, you can use the Settings.Secure class to retrieve the identifier and check the user's ad tracking preferences. Here's a clean and simple code example based on the information provided by Amazon's documentation:

Make sure to handle scenarios where the Advertising ID might not be available (e.g., on non-Fire OS devices or older versions of Fire OS).

Always respect the user's Limit Ad Tracking preference when using this identifier for advertising or analytics purposes. This code should work on Amazon Fire devices running Fire OS 5.1 or later, as per Amazon's guidelines

JavaKotlin
Usage

You can call this method from your activity or service by passing in the ContentResolver:

// Example usage in an Activity
AdvertisingIdHelper.getAmazonAdvertisingId(getContentResolver());

 

Java Code to Retrieve the Amazon Advertising ID (AMID)
import android.content.ContentResolver;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.Log;

public class AdvertisingIdHelper {

    public static void getAmazonAdvertisingId(ContentResolver contentResolver) {
        String advertisingID = "";
        boolean limitAdTracking = false;

        try {
            // Get user's ad tracking preference
            limitAdTracking = (Settings.Secure.getInt(contentResolver, "limit_ad_tracking") == 0) ? false : true;

            // Get the Amazon Advertising ID
            advertisingID = Settings.Secure.getString(contentResolver, "advertising_id");

            // Log the values for demonstration purposes
            Log.d("AdvertisingID", "Amazon Advertising ID: " + advertisingID);
            Log.d("LimitAdTracking", "Limit Ad Tracking: " + limitAdTracking);

        } catch (SettingNotFoundException e) {
            // Handle case where settings are not available (e.g., non-Fire OS devices)
            Log.e("AdvertisingID", "Advertising ID not supported on this device", e);
        }
    }
}
  • The OAID (Open Advertising Identifier) should be provided. China domestic devices.
How to retrieve the Open Advertising ID (Non-Google Play)

Retrieving the Open Advertising ID (OAID)

The Open Advertising Identifier (OAID) is a unique, anonymous identifier used for advertising purposes on Android devices, particularly those manufactured in China. It was introduced by the Mobile Security Alliance (MSA) as an alternative to Google's Advertising ID (GAID) for devices where Google Play Services are unavailable or not supported, such as in the Chinese market.

The OAID is primarily used for advertising attribution and user tracking in environments where Google Play Services are restricted, allowing advertisers and developers to track user behavior while maintaining anonymity.

OAID is available on most Chinese-manufactured Android devices, including those from brands like Huawei, Xiaomi, and others. It can be accessed using the MSA SDK or Huawei Mobile Services (HMS).

JavaKotlin
Dependencies

Ensure your build.gradle file includes the necessary dependencies for the MSA SDK.

dependencies {
    implementation 'com.bun.msa.sdk:msa:1.0.26'  // Example version; check for the latest one
}

 

Java Code to Retrieve OAID
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import com.bun.msa.sdk.DeviceId;
import com.bun.msa.sdk.DeviceIdSupplier;
import com.bun.msa.sdk.IIdentifierListener;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "OAIDExample";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Initialize and request OAID
        getOAID();
    }

    private void getOAID() {
        try {
            // Create a DeviceId instance and request OAID asynchronously
            DeviceId deviceId = new DeviceId(this);
            deviceId.getDeviceIds(new IIdentifierListener() {
                @Override
                public void onSupport(boolean isSupport, DeviceIdSupplier supplier) {
                    if (isSupport && supplier != null) {
                        // Retrieve OAID from supplier
                        String oaid = supplier.getOAID();
                        Log.d(TAG, "OAID: " + oaid);
                    } else {
                        Log.e(TAG, "OAID not supported on this device");
                    }
                }
            });
        } catch (Exception e) {
            Log.e(TAG, "Error retrieving OAID", e);
        }
    }
}
  • If no other device identifier exists, then you may provide the ANDI (Android ID).
How to retrieve the Android ID (Non-Google Play)

Retrieving the Android ID (ANDI)

The Android ID is a unique 64-bit identifier generated by the Android operating system when a device is first set up. It is designed to be persistent across the lifetime of the device, but it can be reset under certain conditions such as a factory reset.

The Android ID is unique to each device and, starting from Android 8.0 (Oreo), it is scoped per app and per user. This means that different apps on the same device will receive different Android IDs unless they share the same signing key.

The Android ID remains constant unless the device undergoes a factory reset or if an app is uninstalled and reinstalled after an OTA (over-the-air) update.

JavaKotlin
Usage

To retrieve the Android ID in an Android app, you can use the following code snippet:

import android.provider.Settings;
import android.content.Context;

String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);

Required Web Identifiers

  • The SDID is required on all S2S requests
How to retrieve Singular Web SDK Device ID (SDID)

Retrieving the Singular Web SDK Device ID (SDID)

Description

Dependencies

You must have the Singular Web SDK implemented.

Usage

To use this method, simply call it from your web site code after the Singular SDK has Initialized:

window.singularSdk.getSingularDeviceId()

Required Mobile Device Params

  • The Locale, Device Make, Device Model, and Build are required on all S2S requests
How to retrieve Locale, Device Make, Model, and Build

Retrieving Locale, Device Make, Model, and Build

Objective-CSwiftJavaKotlin
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <sys/sysctl.h>

// Retrieve the Locale
NSString *retrieveLocale() {
    NSString *locale = [[NSLocale currentLocale] localeIdentifier];
    NSLog(@"Locale: %@", locale);
    return locale;
}

// Retrieve the Manufacturer
NSString *retrieveManufacturer() {
    // Set the Device Make to Apple    
    return @"Apple";
}

                            
// Retrieve the Device Model
NSString *deviceModel() {
    size_t bufferSize = 64;
    char model[bufferSize];
    int status = sysctlbyname("hw.machine", model, &bufferSize, NULL, 0);
    
    if (status == 0) {
        NSString *deviceModel = [NSString stringWithCString:model encoding:NSUTF8StringEncoding];
        NSLog(@"Device Model: %@", deviceModel);
        return deviceModel;
    } else {
        NSLog(@"Unable to retrieve device model.");
        return nil;
    }
}

// Retrieve the Build Version
NSString *buildVersion() {
    size_t bufferSize = 64;
    char build[bufferSize];
    int status = sysctlbyname("kern.osversion", build, &bufferSize, NULL, 0);
    
    if (status == 0) {
        NSString *buildVersion = [NSString stringWithCString:build encoding:NSUTF8StringEncoding];
        NSLog(@"Build Version: %@", buildVersion);
        return buildVersion;
    } else {
        NSLog(@"Unable to retrieve build version.");
        return nil;
    }
}

// Example usage
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // Retrieve Locale
        NSString *locale = retrieveLocale();

        // Retrieve Device Make
        NSString *make = retrieveManufacturer();
              
        // Retrieve Device Model
        NSString *model = deviceModel();
        
        // Retrieve Build Version
        NSString *build = buildVersion();
        
        // Log results
        if (locale) {
            NSLog(@"Locale: %@", locale);
        }
        
        if (make) {
            NSLog(@"Device Make: %@", make);
        }
              
        if (model) {
            NSLog(@"Device Model: %@", model);
        }
        
        if (build) {
            NSLog(@"Build Version: %@", build);
        }
    }
    return 0;
}