> ## Documentation Index
> Fetch the complete documentation index at: https://docs.permutive.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Xandr (AppNexus) Integration

> Add Permutive targeting to Xandr ad requests

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

<CardGroup cols={4}>
  <Card title="Installation" href="#installation" icon="download" />

  <Card title="Basic Usage" href="#basic-usage" icon="code" />

  <Card title="Impressions" href="#impression-tracking" icon="eye" />

  <Card title="Issues" href="#troubleshooting" icon="wrench" />
</CardGroup>

## 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`:

```kotlin theme={"dark"}
dependencies {
    implementation("com.permutive.android:core:1.12.0")
    implementation("com.permutive.android:appnexus:1.7.0")  // Add this
    
    // Also add Xandr SDK (not included)
    implementation("com.appnexus.opensdk:appnexus-sdk:8.+")
}
```

<Note>
  The AppNexus add-on does not include the Xandr SDK. You must add it separately.
</Note>

See [Installation Guide](/sdks/mobile/android/getting-started/installation) for details.

***

## Basic Usage

### Adding Permutive Targeting

The add-on provides extension methods for adding Permutive targeting to Xandr ad views:

<CodeGroup>
  ```kotlin Kotlin theme={"dark"}
  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()
      }
  }
  ```

  ```java Java theme={"dark"}
  import com.appnexus.opensdk.AdView;
  import com.permutive.android.appnexus.AdViewUtils;

  public class MainActivity extends AppCompatActivity {

      private AdView adView;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);

          Permutive permutive = ((MyApplication) getApplication()).getPermutive();

          adView = findViewById(R.id.banner_ad);

          // Add Permutive targeting
          AdViewUtils.addPermutiveTargeting(adView, permutive);

          // Enable impression tracking
          AdViewUtils.setPermutiveAdListener(adView, permutive);

          // Load ad
          adView.loadAd();
      }
  }
  ```
</CodeGroup>

***

## Impression Tracking

### Basic Impression Tracking

Track ad impressions automatically:

<CodeGroup>
  ```kotlin Kotlin theme={"dark"}
  // 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
          }
      }
  )
  ```

  ```java Java theme={"dark"}
  // Without existing AdListener
  AdViewUtils.setPermutiveAdListener(adView, permutive);

  // With existing AdListener (to avoid conflicts)
  AdViewUtils.setPermutiveAdListener(adView, permutive, new AdListener() {
      @Override
      public void onAdLoaded(AdView ad) {
          // Your code here
      }

      @Override
      public void onAdRequestFailed(AdView ad, ResultCode error) {
          // Your code here
      }
  });
  ```
</CodeGroup>

<Warning>
  If you're already using an `AdListener`, pass it to `setPermutiveAdListener()` as the second parameter to avoid conflicts with Permutive impression tracking.
</Warning>

***

## Native Ads

### Adding Targeting to Native Ads

<CodeGroup>
  ```kotlin Kotlin theme={"dark"}
  import com.appnexus.opensdk.NativeAdRequest

  val nativeAdRequest = NativeAdRequest(this, "placement_id")

  // Add Permutive targeting
  nativeAdRequest.addPermutiveTargeting(permutive)

  // Load native ad
  nativeAdRequest.loadAd()
  ```

  ```java Java theme={"dark"}
  import com.appnexus.opensdk.NativeAdRequest;
  import com.permutive.android.appnexus.AdViewUtils;

  NativeAdRequest nativeAdRequest = new NativeAdRequest(this, "placement_id");

  // Add Permutive targeting
  AdViewUtils.addPermutiveTargeting(nativeAdRequest, permutive);

  // Load native ad
  nativeAdRequest.loadAd();
  ```
</CodeGroup>

***

## 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](/sdks/mobile/android/core-concepts/contextual-data) for details.

***

## Complete Integration Example

<CodeGroup>
  ```kotlin Kotlin theme={"dark"}
  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()
      }
  }
  ```

  ```java Java theme={"dark"}
  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.AdViewUtils;

  public class ArticleActivity extends AppCompatActivity {

      private AdView adView;

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

          Permutive permutive = ((MyApplication) getApplication()).getPermutive();

          // Track page (enables contextual cohorts)
          EventProperties props = new EventProperties.Builder()
              .with("article_id", 12345)
              .with("category", "technology")
              .build();

          PageTracker pageTracker = permutive.trackPage(
              props,
              "Article Title",
              Uri.parse("https://example.com/article"),
              null
          );

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

          // Add Permutive targeting
          AdViewUtils.addPermutiveTargeting(adView, permutive);

          // Set up impression tracking with custom listener
          AdViewUtils.setPermutiveAdListener(adView, permutive, new AdListener() {
              @Override
              public void onAdLoaded(AdView ad) {
                  Log.d("Ads", "Ad loaded successfully");
              }

              @Override
              public void onAdRequestFailed(AdView ad, ResultCode error) {
                  Log.e("Ads", "Ad failed to load: " + error);
              }

              @Override
              public void onAdClicked(AdView ad) {
                  Log.d("Ads", "Ad clicked");
              }
          });

          // Load ad
          adView.loadAd();
      }
  }
  ```
</CodeGroup>

***

## 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

```kotlin theme={"dark"}
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](/sdks/mobile/android/core-concepts/contextual-data) for details.

***

## Use Cases

### News/Content App

```kotlin theme={"dark"}
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

```kotlin theme={"dark"}
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()`:

```kotlin theme={"dark"}
// ✅ 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:

```kotlin theme={"dark"}
// Add targeting to all ads
listOf(bannerAd, interstitialAd).forEach { ad ->
    ad.addPermutiveTargeting(permutive)
    ad.setPermutiveAdListener(permutive)
    ad.loadAd()
}
```

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="No Targeting Parameters in Ad Request">
    **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)`
  </Accordion>

  <Accordion title="Impressions Not Tracked">
    **Problem:** Ad impressions not being tracked.

    **Cause:** Not calling `setPermutiveAdListener()`.

    **Solution:** Always set the Permutive ad listener:

    ```kotlin theme={"dark"}
    adView.setPermutiveAdListener(permutive)
    ```
  </Accordion>

  <Accordion title="AdListener Conflicts">
    **Problem:** Your existing AdListener stops working.

    **Cause:** Permutive listener overriding yours.

    **Solution:** Pass your listener to `setPermutiveAdListener()`:

    ```kotlin theme={"dark"}
    adView.setPermutiveAdListener(
        permutive,
        yourExistingListener  // Pass your listener here
    )
    ```
  </Accordion>

  <Accordion title="Contextual Cohorts Not Included">
    **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](/sdks/mobile/android/core-concepts/contextual-data#troubleshooting).
  </Accordion>

  <Accordion title="Ads Not Serving">
    **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](/sdks/mobile/android/troubleshooting/common-errors) for more troubleshooting.
  </Accordion>
</AccordionGroup>

***

## Best Practices

<Tabs>
  <Tab title="Do">
    * 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
  </Tab>

  <Tab title="Don't">
    * Load ads before Permutive is initialized
    * Skip impression tracking
    * Omit URLs from `trackPage()` if you want contextual cohorts
    * Override AdListener without passing it to `setPermutiveAdListener()`
  </Tab>
</Tabs>

***

## 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

```kotlin theme={"dark"}
// 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
```

***

## Related Documentation

<CardGroup cols={2}>
  <Card title="Contextual Data" icon="bullseye" href="/sdks/mobile/android/core-concepts/contextual-data">
    Content-based targeting
  </Card>

  <Card title="Page Tracking" icon="file" href="/sdks/mobile/android/features/page-tracking">
    Track pages for contextual cohorts
  </Card>

  <Card title="Cohorts and Activations" icon="users" href="/sdks/mobile/android/core-concepts/cohorts-and-activations">
    Understanding segments
  </Card>

  <Card title="Installation" icon="download" href="/sdks/mobile/android/getting-started/installation">
    Add-on installation
  </Card>

  <Card title="Google Ad Manager" icon="google" href="/sdks/mobile/android/integrations/google-ad-manager">
    Alternative ad platform
  </Card>

  <Card title="Issues" icon="wrench" href="/sdks/mobile/android/troubleshooting/common-errors">
    Solve common issues
  </Card>
</CardGroup>

***

## API Reference

For complete API documentation, see the [Javadocs](https://sdk-docs.permutive.com/index.html).

### 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](/sdks/mobile/android/troubleshooting/common-errors)
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](https://docs.xandr.com/bundle/mobile-sdk/page/mobile-sdk.html).
