Skip to main content
The Xandr/AppNexus add-on library provides helper methods to automatically add Permutive targeting to Xandr ad requests and track impressions.

Overview

The AppNexus add-on provides:
  • Automatic targeting - Helper methods for Xandr ads
  • Impression tracking - Automatic ad impression tracking
  • Contextual cohorts - Content-based targeting (v1.7.0+)
  • Reaction segments - User cohort targeting
  • Simple integration - Minimal code changes required

Installation

Add the AppNexus add-on to your build.gradle.kts:
dependencies {
    implementation("com.permutive.android:core:1.10.0")
    implementation("com.permutive.android:appnexus:1.7.0")  // Add this
    
    // Also add Xandr SDK (not included)
    implementation("com.appnexus.opensdk:appnexus-sdk:8.+")
}
The AppNexus add-on does not include the Xandr SDK. You must add it separately.
See Installation Guide for details.

Basic Usage

Adding Permutive Targeting

The add-on provides extension methods for adding Permutive targeting to Xandr ad views:
import com.appnexus.opensdk.AdView
import com.permutive.android.appnexus.addPermutiveTargeting
import com.permutive.android.appnexus.setPermutiveAdListener

class MainActivity : AppCompatActivity() {

    private val permutive by lazy {
        (application as MyApplication).permutive
    }

    private lateinit var adView: AdView

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

        adView = findViewById(R.id.banner_ad)

        // Add Permutive targeting
        adView.addPermutiveTargeting(permutive)

        // Enable impression tracking
        adView.setPermutiveAdListener(permutive)

        // Load ad
        adView.loadAd()
    }
}

Impression Tracking

Basic Impression Tracking

Track ad impressions automatically:
// Without existing AdListener
adView.setPermutiveAdListener(permutive)

// With existing AdListener (to avoid conflicts)
adView.setPermutiveAdListener(
    permutive,
    object : AdListener {
        override fun onAdLoaded(ad: AdView) {
            // Your code here
        }

        override fun onAdRequestFailed(ad: AdView, error: ResultCode) {
            // Your code here
        }
    }
)
If you’re already using an AdListener, pass it to setPermutiveAdListener() as the second parameter to avoid conflicts with Permutive impression tracking.

Native Ads

Adding Targeting to Native Ads

import com.appnexus.opensdk.NativeAdRequest

val nativeAdRequest = NativeAdRequest(this, "placement_id")

// Add Permutive targeting
nativeAdRequest.addPermutiveTargeting(permutive)

// Load native ad
nativeAdRequest.loadAd()

What Gets Added to Ad Requests

When you call addPermutiveTargeting(), the following targeting parameters are added:

1. Reaction Segments (User Cohorts)

User behavioral segments:
Custom Keywords:
  permutive=segment_id_1,segment_id_2,segment_id_3

2. Contextual Cohorts (v1.7.0+)

Content-based segments from the current page:
Custom Keywords:
  permutive=segment_id_1,segment_id_2,contextual_segment_1,contextual_segment_2
These are automatically included when:
  • You’re using PageTracker with URLs
  • Contextual data feature is enabled
  • Content has been analyzed
See Contextual Data for details.

Complete Integration Example

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.net.Uri
import com.appnexus.opensdk.AdView
import com.appnexus.opensdk.AdListener
import com.appnexus.opensdk.ResultCode
import com.permutive.android.EventProperties
import com.permutive.android.appnexus.addPermutiveTargeting
import com.permutive.android.appnexus.setPermutiveAdListener

class ArticleActivity : AppCompatActivity() {

    private val permutive by lazy {
        (application as MyApplication).permutive
    }

    private lateinit var adView: AdView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_article)

        // Track page (enables contextual cohorts)
        val pageTracker = permutive.trackPage(
            title = "Article Title",
            url = Uri.parse("https://example.com/article"),
            eventProperties = EventProperties.from(
                "article_id" to 12345,
                "category" to "technology"
            )
        )

        // Set up ad view
        adView = findViewById(R.id.banner_ad)
        adView.placementID = "your_placement_id"

        // Add Permutive targeting
        adView.addPermutiveTargeting(permutive)

        // Set up impression tracking with custom listener
        adView.setPermutiveAdListener(
            permutive,
            object : AdListener {
                override fun onAdLoaded(ad: AdView) {
                    Log.d("Ads", "Ad loaded successfully")
                }

                override fun onAdRequestFailed(ad: AdView, error: ResultCode) {
                    Log.e("Ads", "Ad failed to load: $error")
                }

                override fun onAdClicked(ad: AdView) {
                    Log.d("Ads", "Ad clicked")
                }
            }
        )

        // Load ad
        adView.loadAd()
    }
}

Contextual Cohorts

Enabling Contextual Cohorts

Contextual cohorts are automatically included (v1.7.0+) when:
  1. Feature enabled - Contact your Customer Success Manager
  2. URLs provided - Use PageTracker with full URLs
  3. Content analyzed - Permutive has analyzed the content

Example with Contextual Cohorts

class ArticleActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // Track page with URL (enables contextual cohorts)
        val pageTracker = permutive.trackPage(
            title = article.title,
            url = Uri.parse(article.url),  // Full URL required
            eventProperties = EventProperties.from(
                "article_id" to article.id,
                "category" to article.category
            )
        )
        
        // Load ad - contextual cohorts automatically included
        adView.addPermutiveTargeting(permutive)
        adView.setPermutiveAdListener(permutive)
        adView.loadAd()
    }
}
See Contextual Data Guide for details.

Use Cases

News/Content App

class ArticleActivity : AppCompatActivity() {
    
    private fun displayArticleWithAds() {
        // Track article page
        val pageTracker = permutive.trackPage(
            title = article.title,
            url = Uri.parse(article.url),
            eventProperties = EventProperties.from(
                "category" to article.category,
                "author" to article.author
            )
        )
        
        // Load banner ad
        bannerAdView.addPermutiveTargeting(permutive)
        bannerAdView.setPermutiveAdListener(permutive)
        bannerAdView.loadAd()
        
        // Load interstitial ad
        interstitialAdView.addPermutiveTargeting(permutive)
        interstitialAdView.setPermutiveAdListener(permutive)
        interstitialAdView.loadAd()
    }
}

Video App

class VideoDetailsActivity : AppCompatActivity() {
    
    private fun displayVideoDetailsWithAd() {
        // Track video details page
        val pageTracker = permutive.trackPage(
            title = video.title,
            url = Uri.parse("app://video/${video.id}/details"),
            eventProperties = EventProperties.from(
                "video_id" to video.id,
                "genre" to video.genre
            )
        )
        
        // Load native ad in video list
        nativeAdRequest.addPermutiveTargeting(permutive)
        nativeAdRequest.loadAd()
    }
}

Ad Loading Best Practices

Load Ads After Page Tracking

For contextual cohorts, load ads after calling trackPage():
// ✅ CORRECT - Track page first
val pageTracker = permutive.trackPage(...)

// Small delay to allow contextual data retrieval
Handler(Looper.getMainLooper()).postDelayed({
    adView.addPermutiveTargeting(permutive)
    adView.loadAd()
}, 100)  // 100ms delay

Reuse Targeting for Multiple Ads

You can add targeting to multiple ad views:
// Add targeting to all ads
listOf(bannerAd, interstitialAd).forEach { ad ->
    ad.addPermutiveTargeting(permutive)
    ad.setPermutiveAdListener(permutive)
    ad.loadAd()
}

Troubleshooting

Problem: Permutive targeting not appearing in ad requests.Causes:
  1. Not calling addPermutiveTargeting()
  2. Permutive not initialized
  3. No cohorts available yet
Solutions:
  1. Verify you’re calling addPermutiveTargeting() before loadAd()
  2. Ensure Permutive is initialized before loading ads
  3. Check permutive.currentCohorts() returns data
  4. Enable debug logging: permutive.setDeveloperMode(true)
Problem: Ad impressions not being tracked.Cause: Not calling setPermutiveAdListener().Solution: Always set the Permutive ad listener:
adView.setPermutiveAdListener(permutive)
Problem: Your existing AdListener stops working.Cause: Permutive listener overriding yours.Solution: Pass your listener to setPermutiveAdListener():
adView.setPermutiveAdListener(
    permutive,
    yourExistingListener  // Pass your listener here
)
Problem: Only user cohorts included, not contextual.Causes:
  1. Contextual feature not enabled
  2. Not providing URLs in trackPage()
  3. Using older add-on version (<1.7.0)
  4. Content not yet analyzed
Solutions:
  1. Contact Customer Success Manager to enable feature
  2. Always provide full URLs to trackPage()
  3. Update to appnexus:1.7.0 or later
  4. Verify URLs are publicly accessible
See Contextual Data Troubleshooting.
Problem: Ads not displaying.This is not a Permutive SDK issue. Troubleshoot standard Xandr integration:
  1. Verify placement ID is correct
  2. Check ad inventory availability
  3. Verify Xandr SDK setup
  4. Review Xandr console
See Common Errors for more troubleshooting.

Best Practices

  • Call addPermutiveTargeting() on all ad views
  • Call setPermutiveAdListener() for impression tracking
  • Track pages with full URLs for contextual cohorts
  • Load ads after calling trackPage()
  • Pass existing AdListener to avoid conflicts

Version History

v1.7.0 (Latest)

  • ✅ Automatic contextual cohort support
  • ✅ Requires core 1.10.0+
  • ✅ Enhanced ad targeting

v1.6.x

  • Compatible with older core versions
  • Basic targeting and impression tracking
See the Permutive Dashboard for the latest release information.

Migration Notes

Upgrading to v1.7.0

No code changes required! Contextual cohorts are automatically included if:
  • Feature is enabled by Permutive
  • You’re using PageTracker with URLs
// Same code works with v1.6.x and v1.7.0
adView.addPermutiveTargeting(permutive)
adView.setPermutiveAdListener(permutive)
adView.loadAd()

// v1.7.0 automatically includes contextual cohorts


API Reference

For complete API documentation, see the Javadocs.

Kotlin Extensions

  • AdView.addPermutiveTargeting(permutive: Permutive) - Add targeting to AdView
  • NativeAdRequest.addPermutiveTargeting(permutive: Permutive) - Add targeting to native ad
  • AdView.setPermutiveAdListener(permutive: Permutive) - Enable impression tracking
  • AdView.setPermutiveAdListener(permutive: Permutive, listener: AdListener) - Enable tracking with custom listener

Java Utilities

  • AdViewUtils.addPermutiveTargeting(adView, permutive) - Add targeting
  • AdViewUtils.addPermutiveTargeting(nativeAdRequest, permutive) - Add targeting to native
  • AdViewUtils.setPermutiveAdListener(adView, permutive) - Enable impression tracking
  • AdViewUtils.setPermutiveAdListener(adView, permutive, listener) - Enable tracking with custom listener

Getting Help

If you encounter issues with Xandr integration:
  1. Check Troubleshooting Guide
  2. Verify AppNexus add-on is installed
  3. Ensure Xandr SDK is included separately
  4. Enable debug logging
  5. Contact your Customer Success Manager
For Xandr SDK issues unrelated to Permutive, consult Xandr’s documentation.