A Prebid Mobile plugin adapter that hands Chartboost-flagged winning bids to the Chartboost Monetization SDK for rendering, instead of letting Prebid render them. Same Monetization SDK surface that Chartboost Mediation drives, plugged into Prebid.
| Component | Version |
|---|---|
| Prebid Mobile SDK | 3.4.0+ (see the CHANGELOG for the certified version) |
| Chartboost Monetization SDK | 9.14.0+ |
| Android API | 21+ |
| kotlinx-coroutines-android | present at runtime (ships transitively with the Chartboost Monetization SDK) |
Prebid Mobile routes a winning bid to a registered plugin only when all of these hold:
- The bid carries
ext.prebid.targetingwithhb_pb+hb_bidder(so the SDK treats it as the winner). ext.prebid.meta.rendererNamematches the plugin'sgetName()(Chartboost-Android-SDK).ext.prebid.meta.rendererVersionmatches the plugin'sgetVersion(), byte for byte.
On a match, the plugin builds a Chartboost Banner / Interstitial / Rewarded, hands it the bid's
adm via cache(), and renders. A mismatch on any key falls back to Prebid's own rendering.
The Chartboost Monetization SDK and this adapter are hosted on Chartboost's Maven repository, not Maven
Central, so declare it alongside mavenCentral() (which serves Prebid Mobile and coroutines). In your
settings.gradle:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url "https://cboost.jfrog.io/artifactory/chartboost-ads" }
}
}Then in your app's build.gradle, add the adapter plus the SDKs it renders through. The adapter is published
compileOnly against both SDKs, so your app must depend on them directly:
implementation "com.chartboost:chartboost-prebid-adapter:309.14.0"
implementation "com.chartboost:chartboost-sdk:9.14.0"
implementation "org.prebid:prebid-mobile-sdk:3.4.0"The adapter uses Kotlin coroutines at runtime and expects kotlinx-coroutines-android on the app
classpath, which the Chartboost Monetization SDK already provides transitively; no extra dependency is
needed unless your build excludes it.
Then register the adapter once before initializing Prebid:
ChartboostPrebidAdapter.register()
PrebidMobile.initializeSdk(context, "https://<your-pbs-host>/openrtb2/auction") { status ->
Log.d("prebid", "init: $status")
}Then load a rendering ad unit as usual (BannerView / InterstitialAdUnit / RewardedAdUnit); a
Chartboost-flagged bid routes to this plugin automatically. Call BannerView.destroy() when you no longer
need the banner, as Prebid's own docs advise, so the Chartboost banner is released.
register() takes an optional ChartboostPrebidConfig. Every field has a default that reproduces the
bare register() behavior, so you only need to set what you want to change:
ChartboostPrebidAdapter.register(
ChartboostPrebidConfig(
location = "Home_Interstitial",
logLevel = LogLevel.DEBUG,
eventListener = myEventListener,
),
)From Java, build the same config with ChartboostPrebidConfig.Builder (Kotlin default arguments aren't
visible to Java callers); each setter returns this.
| Field | Default | What it does |
|---|---|---|
location |
"Prebid" |
Chartboost ad location tag attached to every plugin-rendered ad. A blank value coerces back to the default. Override to break out placements in Chartboost reporting. |
logLevel |
LogLevel.WARN |
Plugin log verbosity; see below. |
eventListener |
null |
Optional callback for plugin-rendered ad lifecycle events (see below). |
LogLevel is ordered least to most verbose:
| Level | Gates |
|---|---|
NONE |
Nothing — no warnings, no integration-info line. |
WARN (default) |
Warnings, plus the one-line output of logIntegrationInfo(). |
DEBUG |
Adds verbose per-ad debug logging on top of WARN. |
ChartboostPrebidEventListener reports what the plugin itself did with an ad, separately from Prebid's own
per-ad-unit listeners — useful for analytics or for telling a real adapter failure apart from a silent
routing fallback. All callbacks run on the main thread and take a ChartboostAdFormat
(BANNER / INTERSTITIAL / REWARDED):
onAdLoaded(format)onAdDisplayed(format)— the ad became visible. Fires on the Chartboost show event forINTERSTITIAL/REWARDED, and on the first recorded impression forBANNER(banners have no separate show signal).onAdClicked(format)onAdFailed(format, error)—erroris Prebid'sAdException. Also fires when a loadedINTERSTITIAL/REWARDEDad expires beforeshow(), or fails ashow()that uses it up. Prebid's own ad unit listener also reports the failure, so the publisher can load a new ad.onAdDismissed(format)— fullscreen only; banners never invoke it.onUserEarnedReward(format)— fullscreen only; banners never invoke it.
ChartboostPrebidAdapter also exposes three integration helpers:
unregister()— the counterpart toregister(); a no-op when nothing is registered. Call it to tear down a registration whoseeventListenercaptures an Activity, so the listener does not outlive it.matchesServerAdapterVersion(prebidServerAdapterVersion)— returns whetheradapterVersionexactly, byte-for-byte, equals the value your Prebid Server adapter stamps asext.prebid.meta.rendererVersion. A mismatch makes Prebid Mobile silently fall back to its own rendering, so assert on this during integration to fail fast instead of debugging a silent fallback.logIntegrationInfo()— logs the registered adapter name and version atWARN-or-above verbosity, for the same purpose.
The Chartboost Monetization SDK renders a banner at one of its own Banner.BannerSize dimensions and
nothing else:
| Size | Dimensions | Available from |
|---|---|---|
STANDARD |
320x50 | all supported versions |
MEDIUM |
300x250 | all supported versions |
LEADERBOARD |
728x90 | all supported versions |
HALFPAGE |
300x600 | Monetization SDK 9.14.0+ |
Given a winning bid's negotiated width and height, this adapter selects the largest of those sizes that
fits entirely inside the requested dimensions. A full-width slot of, say, 412x50 renders STANDARD
320x50 within it, the same way a fixed size is fitted into an adaptive banner slot.
If nothing fits, the bid is declined through DisplayViewListener.onAdFailed. That is final, not a
retry: Prebid Mobile's DisplayView.createBannerAdView picks a plugin once, via
getPluginForPreferredRenderer, and once our plugin has that bid, a decline chains straight to
BannerViewListener.onAdFailed on the publisher's listener. There is no second rendering attempt and no
fallback to Prebid's own renderer. A 320x49 slot is a no-fill, because even the shortest Chartboost banner
needs 50dp of height. The adapter never renders a size larger than the slot it was given: doing so would
still count a billable impression while overflowing the publisher's layout.
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. Chartboost's server side has to support a new size too before a bid for it can win.
If you see unexpected banner no-fills, the usual cause is a slot too small for any Chartboost size.
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 the Monetization SDK's own documentation for how. Plugin-rendered ads render through that same SDK instance, so its consent state applies to them as well.
| Path | What it is |
|---|---|
ChartboostPrebidPlugin/ |
The adapter library (the shipped artifact). |
scripts/ |
Release-automation helpers (get_rc_version.sh, see Versioning). |
Requires JDK 17. ./gradlew ci runs the same verification gate CI runs; RELEASING.md
describes what it covers.
BuildConfig.ADAPTER_VERSION is computed in the root build.gradle.kts from the scheme
(prebid_sdk_major × 100 + monetization_major).(monetization_minor).(adapter_revision),
using chartboostSdkVersion / prebidMobileVersion / adapterRevision (currently 309.14.0). The
Monetization patch is not encoded, the same as the iOS adapter: the adapter supports every patch of its
certified Monetization minor, so a Monetization patch release needs no new adapter version. The Prebid
Server adapter echoes this value back from the request, so the client-registered version and the
server-stamped version match by construction — no shared constant or lock-step release. Override with
-PADAPTER_VERSION=X.Y.Z to pin it.
The release process mirrors the Chartboost Mediation adapters:
- Release candidate (private): push a
prerelease/**branch, or run theprereleaseworkflow.scripts/get_rc_version.shpicks the next<version>-rcNagainst the private repo and publishes it there. RCs are always private, so a dynamic+/-rc+consumer always resolves the newest RC rather than a stale base version outranking it. - Public release: push a
v<version>tag, or runcreate-release-versionto open arelease/<version>PR that theauto-releaseworkflow tags for you on merge. Thereleaseworkflow verifies the tag equals the computed version, publishes the bare<version>to the public repo, and cuts a GitHub Release with the AAR.
The -rcN tail and the bare version both ride through the server echo, so the client-registered and
server-stamped versions still match.
Maintainers: see RELEASING.md for the one-time setup and how each workflow fits together.
MIT. See LICENSE.md.