How to Integrate an MMP SDK (Step-by-Step Guide)

Complete guide to integrating mobile measurement partner SDKs. Avoid common mistakes and get attribution working correctly the first time.

Justin Sampson
How to Integrate an MMP SDK (Step-by-Step Guide)

How to Integrate an MMP SDK (Step-by-Step Guide)

MMP SDK integration is straightforward if you follow the right sequence. Most issues come from configuration mistakes, not technical complexity.

This guide covers the complete integration process across major MMPs, common pitfalls, and how to validate everything works before going live.

The actual code implementation takes a few hours. The setup, configuration, and testing determine whether your attribution works correctly from day one.

Pre-Integration Checklist

Before writing any code, prepare:

1. Account Setup

Create your MMP account and complete basic configuration:

  • Company profile
  • Billing information
  • Team member access

2. App Details

Have ready:

  • iOS: Bundle ID, App Store ID
  • Android: Package name, SHA-1 fingerprint for Google Play
  • App name and category
  • Primary timezone (must match your analytics tools)

3. Partner Credentials

Gather API credentials for ad networks you'll integrate:

  • Facebook/Meta app ID
  • Google Ads conversion ID
  • TikTok advertiser ID
  • Other network-specific identifiers

4. Development Resources

  • Access to your app's codebase
  • Development environment set up for iOS and/or Android
  • Test devices for both platforms
  • Staging/development MMP account (if available)

Step 1: Dashboard Setup

Create Your App Profile

All MMPs follow a similar pattern:

  1. Log into your MMP dashboard
  2. Navigate to "Add App" or "Apps" section
  3. Enter app details:
    • App name
    • Platform (iOS, Android, or both)
    • Bundle ID (iOS) / Package name (Android)
    • Store URLs
    • Primary category

Configure Basic Settings

Timezone:

  • Must match your other analytics tools
  • Cannot be changed after data starts flowing
  • Affects cohort reporting boundaries

Attribution Windows:

  • Click-through attribution: 7 days (industry standard)
  • View-through attribution: 1 day (industry standard)
  • Reattribution window: 30-90 days

Privacy Settings:

  • Enable/disable IP collection
  • Configure data retention periods
  • Set GDPR/CCPA compliance flags

Generate SDK Credentials

Most MMPs provide:

  • App token or SDK key (unique identifier for your app)
  • Secret key (for server-to-server communication)
  • Environment flags (production vs sandbox)

Important: Keep these credentials secure. Don't commit them directly to version control—use environment variables or secure credential management.

Step 2: SDK Installation

iOS Integration (Swift)

Using CocoaPods:

Add to your Podfile:

pod 'Adjust', '~> 4.38'
# or
pod 'AppsFlyerFramework', '~> 6.14'
# or
pod 'BranchSDK', '~> 3.3'

Run:

pod install

Using Swift Package Manager:

  1. In Xcode, go to File → Add Packages
  2. Enter the MMP's SDK repository URL
  3. Select version and add to target

Manual installation:

  • Download the framework
  • Drag to your Xcode project
  • Add to "Frameworks, Libraries, and Embedded Content"

Android Integration (Kotlin)

Add to your app-level build.gradle:

dependencies {
    implementation 'com.adjust.sdk:adjust-android:4.38.0'
    // or
    implementation 'com.appsflyer:af-android-sdk:6.14.0'
    // or
    implementation 'io.branch.sdk.android:library:5.9.0'

    // Required for most MMPs
    implementation 'com.android.installreferrer:installreferrer:2.2'
}

Add required permissions to AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Optional but recommended for attribution accuracy -->
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>

React Native

Most MMPs provide React Native wrappers:

npm install react-native-appsflyer
# or
npm install react-native-adjust
# or
npm install react-native-branch

Then link:

cd ios && pod install && cd ..

Flutter

dependencies:
  appsflyer_sdk: ^6.14.0
  # or
  adjust_sdk: ^4.38.0
  # or
  flutter_branch_sdk: ^7.0.0

Step 3: SDK Initialization

iOS (Swift)

Initialize in AppDelegate.swift:

import Adjust

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    // Create Adjust config
    let adjustConfig = ADJConfig(
        appToken: "YOUR_APP_TOKEN",
        environment: ADJEnvironmentProduction  // Use ADJEnvironmentSandbox for testing
    )

    // Optional: Set log level for debugging
    adjustConfig?.logLevel = ADJLogLevelVerbose

    // Optional: Enable event buffering
    adjustConfig?.eventBufferingEnabled = true

    // Initialize SDK
    Adjust.appDidLaunch(adjustConfig)

    return true
}

For AppsFlyer:

import AppsFlyerLib

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    AppsFlyerLib.shared().appsFlyerDevKey = "YOUR_DEV_KEY"
    AppsFlyerLib.shared().appleAppID = "YOUR_APP_ID"

    // For debugging
    AppsFlyerLib.shared().isDebug = true

    // Start SDK
    AppsFlyerLib.shared().start()

    return true
}

For Branch:

import Branch

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    // Initialize Branch
    Branch.getInstance().initSession(launchOptions: launchOptions) { (params, error) in
        // Handle deep link data
        if let params = params {
            // Process attribution data
            print("Branch params: \(params)")
        }
    }

    return true
}

Android (Kotlin)

Initialize in your Application class:

import com.adjust.sdk.Adjust
import com.adjust.sdk.AdjustConfig

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // Create Adjust config
        val config = AdjustConfig(
            this,
            "YOUR_APP_TOKEN",
            AdjustConfig.ENVIRONMENT_PRODUCTION  // Use ENVIRONMENT_SANDBOX for testing
        )

        // Optional: Set log level
        config.setLogLevel(LogLevel.VERBOSE)

        // Initialize SDK
        Adjust.onCreate(config)
    }
}

For AppsFlyer:

import com.appsflyer.AppsFlyerLib

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        AppsFlyerLib.getInstance().init("YOUR_DEV_KEY", null, this)
        AppsFlyerLib.getInstance().start(this)

        // For debugging
        AppsFlyerLib.getInstance().setDebugLog(true)
    }
}

Don't forget to register your Application class in AndroidManifest.xml:

<application
    android:name=".MyApplication"
    ...>
</application>

Critical Timing Considerations

Initialize before any other SDKs when possible. This ensures:

  • Attribution data is captured first
  • Deep link parameters are available to other SDKs
  • All subsequent events are properly attributed

iOS-specific: For SKAdNetwork support, initialization must happen before the first app open completes.

Android-specific: Install referrer can only be fetched once per install. Early initialization is critical.

Step 4: Deep Linking Configuration

iOS Universal Links

  1. Enable Associated Domains in Xcode capabilities

  2. Add your domain:

    applinks:yourdomain.com
    
  3. Create apple-app-site-association file on your server at:

    https://yourdomain.com/.well-known/apple-app-site-association
    
  4. Handle universal links in AppDelegate:

func application(_ application: UIApplication,
                 continue userActivity: NSUserActivity,
                 restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {

    // For Adjust
    Adjust.appWillOpen(userActivity.webpageURL)

    // For AppsFlyer
    AppsFlyerLib.shared().continue(userActivity, restorationHandler: nil)

    // For Branch
    Branch.getInstance().continue(userActivity)

    return true
}

Android App Links

  1. Add intent filter to your AndroidManifest.xml:
<activity android:name=".MainActivity">
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:scheme="https"
            android:host="yourdomain.com" />
    </intent-filter>
</activity>
  1. Create assetlinks.json file at:

    https://yourdomain.com/.well-known/assetlinks.json
    
  2. Handle deep links in your Activity:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // Handle deep link
    val data: Uri? = intent?.data

    // For Adjust
    Adjust.appWillOpenUrl(data, applicationContext)

    // For AppsFlyer
    AppsFlyerLib.getInstance().performOnAppAttribution(this, data)
}

Step 5: Event Tracking Implementation

Define Your Event Schema

Before implementing, document:

  • Event names (use consistent naming convention)
  • Event parameters/properties
  • When each event fires
  • Expected volume per event

Example schema:

Event: purchase_completed
Parameters:
  - revenue (number, required)
  - currency (string, required)
  - product_id (string, required)
  - category (string, optional)
Fires: After successful purchase confirmation

iOS Event Tracking

import Adjust

// Simple event
let event = ADJEvent(eventToken: "abc123")
Adjust.trackEvent(event)

// Event with revenue
let purchaseEvent = ADJEvent(eventToken: "abc123")
purchaseEvent?.setRevenue(9.99, currency: "USD")
purchaseEvent?.setTransactionId("unique_transaction_id")  // Prevents duplicate tracking
Adjust.trackEvent(purchaseEvent)

// Event with custom parameters
let registrationEvent = ADJEvent(eventToken: "def456")
registrationEvent?.addCallbackParameter("user_id", value: "12345")
registrationEvent?.addCallbackParameter("signup_method", value: "email")
Adjust.trackEvent(registrationEvent)

Android Event Tracking

import com.adjust.sdk.Adjust
import com.adjust.sdk.AdjustEvent

// Simple event
val event = AdjustEvent("abc123")
Adjust.trackEvent(event)

// Event with revenue
val purchaseEvent = AdjustEvent("abc123")
purchaseEvent.setRevenue(9.99, "USD")
purchaseEvent.setOrderId("unique_transaction_id")  // Prevents duplicate tracking
Adjust.trackEvent(purchaseEvent)

// Event with custom parameters
val registrationEvent = AdjustEvent("def456")
registrationEvent.addCallbackParameter("user_id", "12345")
registrationEvent.addCallbackParameter("signup_method", "email")
Adjust.trackEvent(registrationEvent)

Best Practices for Event Tracking

Prevent duplicate events:

  • Always use transaction IDs for revenue events
  • Implement debouncing for user-triggered events
  • Don't track events in loops or frequently-called functions

Parameter naming:

  • Use snake_case consistently
  • Keep names descriptive but concise
  • Document all parameters

Data types:

  • Revenue: Always use decimal/float, never integers
  • Currency: ISO 4217 codes (USD, EUR, GBP)
  • IDs: Strings, not numbers (preserves leading zeros)

Step 6: Partner Integration

Configure Ad Network Integrations

In your MMP dashboard:

  1. Navigate to "Integrations" or "Partners"
  2. Find your ad network (Facebook, Google, TikTok, etc.)
  3. Click "Enable" or "Add"
  4. Enter required credentials
  5. Configure postback URLs

Facebook/Meta Integration

Requirements:

  • Facebook App ID
  • Business Manager ID
  • System User token (for Advanced Mobile Measurement)

Steps:

  1. In MMP dashboard, go to Facebook integration
  2. Enter Facebook App ID
  3. Enable "Advanced Mobile Measurement" (if available)
  4. Configure event mapping (map MMP events to Facebook events)

Google Ads Integration

Requirements:

  • Google Ads customer ID
  • Conversion tracking ID
  • Google Play API access (for Android)

Steps:

  1. In MMP dashboard, go to Google Ads integration
  2. Enter customer ID
  3. Link Google Play Console (for Android conversion tracking)
  4. Configure event mapping

TikTok Integration

Requirements:

  • TikTok advertiser ID
  • App ID from TikTok dashboard

Steps:

  1. In MMP dashboard, go to TikTok integration
  2. Enter advertiser ID and app ID
  3. Configure event mapping
  4. Enable postbacks

Step 7: Testing and Validation

Test Device Setup

Most MMPs provide test modes that don't affect production data.

Adjust test mode:

// iOS
adjustConfig?.logLevel = ADJLogLevelVerbose

// Add test device
adjustConfig?.addTestDevice("YOUR_DEVICE_ADVERTISING_ID")

AppsFlyer test mode:

// iOS
AppsFlyerLib.shared().isDebug = true

Validation Checklist

1. Attribution Testing:

  • Install app from different sources (organic, Facebook ad, Google ad)
  • Verify install is attributed correctly in dashboard
  • Check attribution data appears within 5 minutes

2. Event Tracking:

  • Trigger each implemented event
  • Verify events appear in dashboard
  • Check event parameters are captured correctly
  • Confirm revenue values display accurately

3. Deep Linking:

  • Click universal link/app link
  • Verify app opens to correct screen
  • Check deep link data is accessible in app
  • Test deferred deep linking (click before install)

4. Platform-Specific:

iOS:

  • SKAdNetwork postbacks are configured
  • ATTrackingManager permission is implemented
  • Install validates on first app open

Android:

  • Install referrer is captured
  • Play Store attribution works
  • Deferred deep linking functions correctly

Using Debug Tools

Adjust:

  • Use "Testing Console" in dashboard
  • View real-time event logs
  • Check attribution data for test devices

AppsFlyer:

  • Use "Test Mode" in dashboard
  • View SDK integration status
  • Real-time event debugger

Branch:

  • Use "Link Validation" tool
  • Test deep links in Link Debugger
  • View session data in real-time

Common Issues and Fixes

Attribution not working:

  • Check SDK is initialized before any other code
  • Verify app token/key is correct
  • Confirm network connectivity permissions
  • Check timezone matches across MMP and analytics tools

Events not appearing:

  • Verify event tokens match dashboard configuration
  • Check event naming follows MMP requirements
  • Ensure SDK is initialized before tracking events
  • Review log output for error messages

Deep links not opening:

Revenue not tracking:

  • Ensure revenue events include currency code
  • Use unique transaction IDs
  • Don't track negative revenue
  • Verify numeric format (decimal, not integer)

Step 8: Production Deployment

Pre-Launch Checklist

  • Remove or disable verbose logging
  • Switch from sandbox to production environment
  • Remove test device identifiers
  • Verify all partner integrations are enabled
  • Document event schema for your team
  • Set up attribution dashboards
  • Configure alerts for attribution drops

Gradual Rollout Strategy

Phase 1: Internal Testing (Days 1-3)

  • Release to internal testers
  • Monitor attribution for 100% of test installs
  • Verify all events track correctly

Phase 2: Beta Release (Days 4-7)

  • Release to 5-10% of users
  • Monitor for attribution issues
  • Check event volume matches expectations

Phase 3: Full Release (Day 8+)

  • Roll out to 100% of users
  • Continue monitoring for 30 days
  • Document any issues and resolutions

Monitoring Post-Launch

Daily (first week):

  • Check install attribution rate (should be 90%+)
  • Verify event volume matches user activity
  • Monitor for attribution delays (should be under 5 minutes)

Weekly (first month):

  • Review cohort retention data
  • Compare MMP data to ad network dashboards
  • Check for attribution discrepancies
  • Audit fraud prevention filters

FAQs

How long does MMP SDK integration take?

Basic SDK integration takes 2-6 hours for experienced developers. Full implementation including custom events, deep linking, and partner integrations typically takes 1-3 days. Add another 1-2 days for thorough testing and validation.

Do I need separate SDKs for iOS and Android?

Yes, you'll implement platform-specific SDKs for iOS and Android. For cross-platform frameworks like React Native or Flutter, most MMPs provide wrapper SDKs that handle both platforms with unified code.

When should I initialize the MMP SDK?

Initialize the SDK as early as possible in your app's lifecycle—ideally in application:didFinishLaunchingWithOptions on iOS or Application.onCreate on Android. This ensures you capture all attribution data and don't miss early events.

Can I track events before SDK initialization completes?

No, events tracked before SDK initialization will be lost. Always initialize the SDK first, then track events. For events that might fire early (like app open), use SDK callbacks to ensure initialization is complete.

How do I test without affecting production data?

Use your MMP's sandbox/test environment, enable debug logging, and add your test device IDs to the SDK configuration. Most MMPs filter test devices from production reporting automatically.


MMP integration is straightforward when you follow the sequence: account setup, SDK installation, initialization, event implementation, partner configuration, and thorough testing. Most issues come from configuration mistakes—not technical complexity. Take time to validate everything before going live, and you'll avoid attribution gaps that are difficult to fix retroactively.

MMPSDK integrationmobile attributionimplementationdeveloper guide

Related Resources