Rendering contracts

Ad formats

Every format uses the same core auction and tracking pipeline. Format modules translate approved OpenRTB markup into a bounded Android lifecycle and expose callbacks that keep the publisher in control.

Use a banner for persistent, non-blocking inventory. The same module supports a standard 320x50 placement and a 300x250 MRECT. MRAID markup is rendered in a guarded WebView and impressions are viewability-gated.

Kotlin
val banner = BannerAd.Builder("article-footer")
    .adSize(AdSize.BANNER_320x50)
    .listener(object : BannerAdListener {
        override fun onAdLoaded() = banner.show(bannerView)
        override fun onAdFailed(error: AdError) = handle(error)
    })
    .build()

banner.load()

Interstitial

Load before a natural break, retain the object while the screen is alive, and show only after readiness is reported. The SDK does not decide when an interruption is appropriate.

Kotlin
val interstitial = InterstitialAd.Builder("level-complete")
    .listener(object : InterstitialAdListener {
        override fun onInterstitialLoaded() = enableContinueAction()
        override fun onInterstitialFailed(error: AdError) = continueWithoutAd()
    })
    .build()

interstitial.load()
if (interstitial.isReady()) interstitial.show(activity)

IAB Native 1.2

Native ads return structured title, body, image, icon, advertiser, CTA and tracking assets. The publisher owns the final Android layout while the SDK owns parsing, clicks and viewable impression registration.

Kotlin
val nativeAd = NativeAd.Builder("recommendation-card")
    .listener(object : NativeAdListener {
        override fun onNativeAdLoaded(ad: NativeAd) {
            ad.bindTo(nativeAdView)
        }
        override fun onNativeAdFailed(error: AdError) = hideSlot()
    })
    .build()

nativeAd.load()
Viewable impression rule

Native impression trackers fire after at least 50% of the registered view remains visible for one continuous second.

VAST rewarded video

The video module parses VAST Inline and Wrapper documents and reports start, quartile, completion and skip events. Grant the publisher reward only from onRewardEarned().

Kotlin
val video = VideoAd.Builder("rewarded-session")
    .listener(object : VideoAdListener {
        override fun onVideoAdLoaded() { watchButton.isEnabled = true }
        override fun onRewardEarned() { grantPublisherReward() }
        override fun onVideoAdFailed(error: AdError) { handle(error) }
    })
    .build()

video.load()

App Open

App Open listens for background-to-foreground transitions, preloads eligible inventory and applies local frequency and expiry constraints. Configure conservative caps so monetization does not obstruct returning users.

Application.kt
AppOpenAd.initialize(this, "app-open", listener)
AppOpenAd.setFrequencyCapHours(1)
AppOpenAd.setAdExpiryMinutes(30)

Conversational sponsored suggestions

This module adapts an ordinary Native 1.2 creative for a chat or AI assistant surface. It renders a disclosed card between messages. It does not insert an advertiser claim into the assistant's answer and does not read raw conversation text.

Kotlin
val suggestionAd = ConversationalAd.Builder("assistant-inline-1")
    .listener(listener)
    .build()

suggestionAd.load()

val suggestion = suggestionAd.suggestion
if (suggestion.hasAction) {
    suggestionAd.performAction(context)
} else {
    suggestionAd.handleClick(context)
}
BoundaryEnforcement
DisclosureThe suggestion contract always includes a sponsored disclosure.
Content separationAd UI renders between messages, never inside answer text.
Context minimizationOnly registered taxonomy values may enter the request.
Renderable or silentMissing required Native assets produce no-fill, not a broken card.

Wallet and intent actions

Wallet is an optional executable capability, not a separate inventory type. Install the module before SDK initialization is used for eligible requests. The request advertises only actions that both publisher policy and the actual application build allow.

Application.kt
ApexAds.init(this, config)
WalletAdExtension.install()
Fallback remains first-class

If the slot, application build or returned creative cannot execute a Wallet action, Apex keeps the standard Native, MRECT or interstitial click experience available.

In-app bidding

Fetch a bid token before loading the mediation network. If Apex has no eligible bid, continue the host waterfall rather than blocking the placement.

Kotlin
ApexInAppBidder.fetchBidToken(
    "placement-001",
    AdFormat.INTERSTITIAL,
    object : InAppBidListener {
        override fun onBidReady(token: BidToken) {
            mediationAd.setLocalExtraParameter("apex_bid_token", token.token)
            mediationAd.setLocalExtraParameter("apex_bid_cpm", token.cpmUsd.toString())
            mediationAd.loadAd()
        }

        override fun onBidFailed(error: AdError) = mediationAd.loadAd()
    }
)