Prebid Integration on Android

This guide adds the Chartboost Prebid adapter to an Android app that already runs Prebid Mobile. If you are new to the adapter, read the Prebid Integration Overview first.

Minimum Requirements 🔗

Component Version
Prebid Mobile SDK 3.4.0+
Chartboost Monetization SDK 9.14.0+
Android API 21+
kotlinx-coroutines-android present at runtime, ships transitively with the Monetization SDK

The adapter is compiled against the Monetization SDK rather than bundling it. Adapter 309.14.0 is certified against Monetization SDK 9.14.0, which is the pairing the samples below install.

Declare kotlinx-coroutines-android yourself only if your build excludes the transitive copy.

1. Add the repositories and dependencies 🔗

The adapter compiles against the Chartboost Monetization SDK and Prebid Mobile but does not bundle them, so your app declares all three dependencies explicitly.

Declare the repositories in your settings file (settings.gradle.kts or settings.gradle), not in the module build file. Current Android project templates set RepositoriesMode.FAIL_ON_PROJECT_REPOS, which turns a module-level repositories block into a build failure. If your project already has a dependencyResolutionManagement block, add only the Chartboost maven line to it rather than pasting a second block, which would drop your repositoriesMode setting. Each sample below shows two files, marked by comments.

  • // settings.gradle.kts
    dependencyResolutionManagement {
        repositories {
            google()
            mavenCentral()
            maven("https://cboost.jfrog.io/artifactory/chartboost-ads/")
        }
    }
    
    // app/build.gradle.kts
    dependencies {
        implementation("org.prebid:prebid-mobile-sdk:3.4.0")
        implementation("com.chartboost:chartboost-sdk:9.14.0")
        implementation("com.chartboost:chartboost-prebid-adapter:309.14.0")
    }
    
  • // settings.gradle
    dependencyResolutionManagement {
        repositories {
            google()
            mavenCentral()
            maven { url 'https://cboost.jfrog.io/artifactory/chartboost-ads/' }
        }
    }
    
    // app/build.gradle
    dependencies {
        implementation 'org.prebid:prebid-mobile-sdk:3.4.0'
        implementation 'com.chartboost:chartboost-sdk:9.14.0'
        implementation 'com.chartboost:chartboost-prebid-adapter:309.14.0'
    }
    

The adapter version (309.14.0) encodes the Prebid Mobile major plus the Monetization SDK version it is certified against, so 309.14.0 pairs with Monetization SDK 9.14.0 and any later patch of that minor.

2. Register the adapter and initialize 🔗

Register the Chartboost plugin adapter before the first ad load. Registering before or right after PrebidMobile.initializeSdk both work. The Chartboost Monetization SDK is started separately, the same way as a standalone Chartboost integration (see Monetization SDK Get Started).

  • import com.chartboost.prebid.ChartboostPrebidAdapter
    import org.prebid.mobile.PrebidMobile
    
    // Attaches the Chartboost adapter name and version to every auction request.
    ChartboostPrebidAdapter.register()
    
    PrebidMobile.initializeSdk(context, "https://<your-pbs-host>/openrtb2/auction") { status ->
        Log.d("prebid", "init: $status")
    }
    
  • import com.chartboost.prebid.ChartboostPrebidAdapter;
    import com.chartboost.prebid.ChartboostPrebidConfig;
    import org.prebid.mobile.PrebidMobile;
    
    // register() takes a config. From Java, build one with the Builder (Kotlin default
    // arguments are not visible to Java callers).
    ChartboostPrebidAdapter.INSTANCE.register(new ChartboostPrebidConfig.Builder().build());
    
    PrebidMobile.initializeSdk(context, "https://<your-pbs-host>/openrtb2/auction", status ->
        Log.d("prebid", "init: " + status));
    

3. Load ads as usual 🔗

Load a Prebid Mobile rendering ad unit (BannerView, InterstitialAdUnit, or RewardedAdUnit) exactly as you would without the adapter. A Chartboost-flagged winning bid routes to the Chartboost adapter automatically; everything else uses Prebid’s default renderer. No per-ad-unit Chartboost code is required.

4. Configure the adapter (optional) 🔗

Pass a ChartboostPrebidConfig to register() to change logging, the Chartboost reporting location, or to attach lifecycle callbacks. Every field has a default that preserves the no-argument behavior.

Field Default What it does
location "Prebid" Chartboost ad location applied to every plugin-rendered ad. A blank value coerces back to the default. Set it to separate placements in Chartboost reporting.
logLevel WARN Plugin log verbosity: NONE, WARN, or DEBUG.
eventListener null Lifecycle callbacks for ads the adapter renders (see below).
  • import com.chartboost.prebid.ChartboostPrebidAdapter
    import com.chartboost.prebid.ChartboostPrebidConfig
    import com.chartboost.prebid.LogLevel
    
    val config = ChartboostPrebidConfig(
        location = "prebid_rewarded",
        logLevel = LogLevel.DEBUG,
    )
    ChartboostPrebidAdapter.register(config)
    
  • import com.chartboost.prebid.ChartboostPrebidAdapter;
    import com.chartboost.prebid.ChartboostPrebidConfig;
    import com.chartboost.prebid.LogLevel;
    
    ChartboostPrebidConfig config = new ChartboostPrebidConfig.Builder()
        .setLocation("prebid_rewarded")
        .setLogLevel(LogLevel.DEBUG)
        .build();
    ChartboostPrebidAdapter.INSTANCE.register(config);
    

Lifecycle callbacks 🔗

Attach a ChartboostPrebidEventListener to observe what the Chartboost adapter specifically did, independently of Prebid’s own per-ad-unit listeners. All callbacks run on the main thread. onAdDismissed and onUserEarnedReward are fullscreen-only and never fire for banners.

Every callback takes a ChartboostAdFormat, one of BANNER, INTERSTITIAL, or REWARDED. In Kotlin each callback has a default empty body, so override only the ones you need. Kotlin default bodies are invisible to Java, so a Java listener has to override all six.

  • import com.chartboost.prebid.ChartboostAdFormat
    import com.chartboost.prebid.ChartboostPrebidConfig
    import com.chartboost.prebid.ChartboostPrebidEventListener
    import org.prebid.mobile.api.exceptions.AdException
    
    val config = ChartboostPrebidConfig(
        eventListener = object : ChartboostPrebidEventListener {
            override fun onAdLoaded(format: ChartboostAdFormat) {}
            override fun onAdDisplayed(format: ChartboostAdFormat) {}
            override fun onAdClicked(format: ChartboostAdFormat) {}
            override fun onAdFailed(format: ChartboostAdFormat, error: AdException) {}
            override fun onAdDismissed(format: ChartboostAdFormat) {}
            override fun onUserEarnedReward(format: ChartboostAdFormat) {}
        },
    )
    
  • import com.chartboost.prebid.ChartboostAdFormat;
    import com.chartboost.prebid.ChartboostPrebidConfig;
    import com.chartboost.prebid.ChartboostPrebidEventListener;
    import org.prebid.mobile.api.exceptions.AdException;
    
    ChartboostPrebidConfig config = new ChartboostPrebidConfig.Builder()
        .setEventListener(new ChartboostPrebidEventListener() {
            @Override public void onAdLoaded(ChartboostAdFormat format) {}
            @Override public void onAdDisplayed(ChartboostAdFormat format) {}
            @Override public void onAdClicked(ChartboostAdFormat format) {}
            @Override public void onAdFailed(ChartboostAdFormat format, AdException error) {}
            @Override public void onAdDismissed(ChartboostAdFormat format) {}
            @Override public void onUserEarnedReward(ChartboostAdFormat format) {}
        })
        .build();
    

Unregistering the adapter 🔗

Call unregister() to remove the Chartboost adapter from Prebid Mobile’s registry. This matters when your eventListener captures an Activity (or any context that shouldn’t outlive it): tear the registration down so the listener is released with it. Prebid evicts by plugin name, so unregister() drops whatever is registered under the Chartboost name and is a no-op when nothing is registered.

You don’t need unregister() if you call register(config) once in Application.onCreate with a listener that holds no Activity. If the listener must hold an Activity, call register(config) in that Activity’s onCreate, before its first ad load, and pass the same config each time, because register() with no arguments resets your settings. Keep a reference to the Activity that registered last, for example in your Application, and in onDestroy call unregister() only while that reference still points at this Activity. Android can run the old Activity’s onDestroy after the new one’s onCreate, and an unconditional unregister() there removes the new registration, so every later ad falls back to Prebid’s default renderer.

  • ChartboostPrebidAdapter.unregister()
    
  • ChartboostPrebidAdapter.INSTANCE.unregister();
    

5. Verify the integration 🔗

The most common integration issue is an adapter version that doesn’t match your Prebid Server’s stamp, which makes Prebid silently fall back to its default renderer. Confirm the match during integration:

  • import android.util.Log
    import com.chartboost.prebid.ChartboostPrebidAdapter
    
    // The value your Prebid Server stamps as ext.prebid.meta.rendererVersion. Read it from your server
    // config or a test bid response. Do not pass the client's own version, or the check can never fail.
    val serverRendererVersion = "<the rendererVersion your Prebid Server stamps>"
    
    // Logs the registered adapter name and version at WARN-or-above verbosity.
    ChartboostPrebidAdapter.logIntegrationInfo()
    
    // Or read the registered values directly.
    Log.d("prebid", "${ChartboostPrebidAdapter.adapterName} ${ChartboostPrebidAdapter.adapterVersion}")
    
    check(ChartboostPrebidAdapter.matchesServerAdapterVersion(serverRendererVersion)) {
        "Adapter version mismatch: Chartboost bids will fall back to Prebid's default renderer"
    }
    
  • import android.util.Log;
    import com.chartboost.prebid.ChartboostPrebidAdapter;
    
    // The value your Prebid Server stamps as ext.prebid.meta.rendererVersion. Read it from your server
    // config or a test bid response. Do not pass the client's own version, or the check can never fail.
    String serverRendererVersion = "<the rendererVersion your Prebid Server stamps>";
    
    // Logs the registered adapter name and version at WARN-or-above verbosity.
    ChartboostPrebidAdapter.INSTANCE.logIntegrationInfo();
    
    // Or read the registered values directly.
    Log.d("prebid", ChartboostPrebidAdapter.INSTANCE.getAdapterName() + " "
        + ChartboostPrebidAdapter.INSTANCE.getAdapterVersion());
    
    boolean matches = ChartboostPrebidAdapter.INSTANCE
        .matchesServerAdapterVersion(serverRendererVersion);
    

logIntegrationInfo() writes through the plugin’s own log, so LogLevel.NONE silences it. Leave logLevel at its WARN default, or raise it, while you verify. The line lands in logcat under the tag ChartboostPrebid.

The Chartboost Monetization SDK renders a banner at one of its own Banner.BannerSize dimensions and nothing else:

Size Dimensions
STANDARD 320x50
MEDIUM 300x250
LEADERBOARD 728x90
HALFPAGE 300x600

Given a winning bid’s negotiated width and height, the adapter selects the size with the largest area that fits entirely inside them. A full-width bid of, say, 412x50 renders STANDARD 320x50 within it, the same way a fixed size is fitted into an adaptive banner slot. Largest by area, not by width: a 728x250 bid renders MEDIUM 300x250 rather than LEADERBOARD 728x90. The adapter never renders a size larger than the space it was given, because that would count a billable impression while overflowing your layout.

If nothing fits, the adapter declines the bid through the load callback, so the load fails instead of rendering at the wrong size. A 320x49 bid is a no-fill, because even the shortest Chartboost banner needs 50dp of height.

The size set is read from the host SDK at runtime, so a size added in a later Monetization SDK release becomes selectable without an adapter release. Your Prebid Server has to offer that size in the auction as well.

This adapter does not collect, store, or forward any consent signals. GDPR, US Privacy (CCPA), COPPA, and GPP are owned by the Chartboost Monetization SDK. The Chartboost Monetization SDK will collect these signals, if available from consent management platforms. Configure your regulatory signals via your consent management platform before loading ads, exactly as you would for any other Chartboost integration; see SDK Privacy Methods for how. Plugin-rendered ads render through that same SDK instance, so its consent state applies to them as well.

Troubleshooting 🔗

A Chartboost-flagged bid renders through Prebid’s default renderer. Check that the adapter name (Chartboost-Android-SDK) and version both match what your Prebid Server returns in ext.prebid.meta. A mismatch is silent by design.

Banners no-fill with a size message. The bid’s negotiated size is too small for any Chartboost banner size. See Banner sizes. Most size mismatches are filtered server-side before they reach the device, so a client-side no-fill points at a bid whose size the auction should not have offered.