Bidding adapter development

This guide is intended for ad networks looking to build a bidding adapter in order to participate in real-time bidding (RTB) within Google mediation. If you are a publisher, see the publisher mediation instructions.

A bidding adapter is the client-side part of the integration. The adapter enables your ad network SDK to communicate with Google Mobile Ads SDK to load ads served by your bidder.

For bidding to work correctly your adapter will need to handle initialization, collecting signals, loading ads, and relaying ad lifecycle events. In this guide we will walk you through how your adapter should be implemented to handle these operations.

Workflow of a bidding adapter

Initialization

A detailed flow of the entire request-response-rendering lifecycle of an adapter is shown below:

The adapter is responsible for the following portions of the workflow:

  • Steps 4-7: Initialize your adapter and call back Google Mobile Ads SDK once initialization completes.

  • Steps 10-13: Collect signals from your ad network SDK to be sent to your bidder to participate in an RTB request, and forward them to the Google Mobile Ads SDK.

  • Steps 18-21: Should your bidder return the winning bid, load the ad according to the response from your bidder. Once loaded, notify Google Mobile Ads SDK that the ad was loaded.

  • Step 23 and later: While your ad is displaying, notify the Google Mobile Ads SDK of impression and click events, as well as the other ad events that occur during the presentation lifecycle of your ad.

Implementing the bidding adapter

To create a bidding adapter for Google Mobile Ads SDK, you must extend the RtbAdapter abstract class. The following sections explain each abstract method in RtbAdapter .

getSDKVersionInfo()

Here you should return your SDK's version. This version is passed to your bidder as part of the OpenRTB request.

This method requires you to return a VersionInfo . The example below shows how you might convert your SDK's string version into a VersionInfo.

  @Override 
 public 
  
 VersionInfo 
  
 getSDKVersionInfo 
 () 
  
 { 
  
 // 
  
 Get 
  
 your 
  
 SDK 
 ' 
 s 
  
 version 
  
 as 
  
 a 
  
 string 
 . 
  
 E 
 . 
 g 
 . 
  
 "1.2.3" 
  
 // 
  
 String 
  
 versionString 
  
 = 
  
 YourSdk 
 . 
 getVersion 
 (); 
  
 String 
  
 splits 
 [] 
  
 = 
  
 versionString 
 . 
 split 
 ( 
 "\\." 
 ); 
  
 if 
  
 ( 
 splits 
 . 
 length 
  
> = 
  
 3 
 ) 
  
 { 
  
 int 
  
 major 
  
 = 
  
 Integer 
 . 
 parseInt 
 ( 
 splits 
 [ 
 0 
 ] 
 ); 
  
 int 
  
 minor 
  
 = 
  
 Integer 
 . 
 parseInt 
 ( 
 splits 
 [ 
 1 
 ] 
 ); 
  
 int 
  
 micro 
  
 = 
  
 Integer 
 . 
 parseInt 
 ( 
 splits 
 [ 
 2 
 ] 
 ); 
  
 return 
  
 new 
  
 VersionInfo 
 ( 
 major 
 , 
  
 minor 
 , 
  
 micro 
 ); 
  
 } 
  
 String 
  
 logMessage 
  
 = 
  
 String 
 . 
 format 
 ( 
 "Unexpected SDK version format: %s." 
  
 + 
  
 "Returning 0.0.0 for SDK version." 
 , 
  
 sdkVersion 
 ); 
  
 Log 
 . 
 w 
 ( 
 TAG 
 , 
  
 logMessage 
 ); 
  
 return 
  
 new 
  
 VersionInfo 
 ( 
 0 
 , 
  
 0 
 , 
  
 0 
 ); 
 } 
 

getVersionInfo()

Here you should return your adapter's version. This version is passed to your bidder as part of the OpenRTB request.

Google's open source and versioned adapters use a 4-digit adapter version scheme, but the VersionInfo only allows for 3 digits. To work around this, it is recommended to combine the last two digits into the patch version, as shown below.

  @Override 
 public 
  
 VersionInfo 
  
 getVersionInfo 
 () 
  
 { 
  
 // 
  
 Get 
  
 your 
  
 adapters 
 ' 
 s 
  
 version 
  
 as 
  
 a 
  
 string 
 . 
  
 E 
 . 
 g 
 . 
  
 "1.2.3.0" 
  
 String 
  
 versionString 
  
 = 
  
 BuildConfig 
 . 
 VERSION_NAME 
 ; 
  
 String 
  
 splits 
 [] 
  
 = 
  
 versionString 
 . 
 split 
 ( 
 "\\." 
 ); 
  
 if 
  
 ( 
 splits 
 . 
 length 
  
> = 
  
 4 
 ) 
  
 { 
  
 int 
  
 major 
  
 = 
  
 Integer 
 . 
 parseInt 
 ( 
 splits 
 [ 
 0 
 ] 
 ); 
  
 int 
  
 minor 
  
 = 
  
 Integer 
 . 
 parseInt 
 ( 
 splits 
 [ 
 1 
 ] 
 ); 
  
 int 
  
 micro 
  
 = 
  
 Integer 
 . 
 parseInt 
 ( 
 splits 
 [ 
 2 
 ] 
 ) 
  
 * 
  
 100 
  
 + 
  
 Integer 
 . 
 parseInt 
 ( 
 splits 
 [ 
 3 
 ] 
 ); 
  
 return 
  
 new 
  
 VersionInfo 
 ( 
 major 
 , 
  
 minor 
 , 
  
 micro 
 ); 
  
 } 
  
 String 
  
 logMessage 
  
 = 
  
 String 
 . 
 format 
 ( 
 "Unexpected adapter version format: %s." 
  
 + 
  
 "Returning 0.0.0 for adapter version." 
 , 
  
 versionString 
 ); 
  
 Log 
 . 
 w 
 ( 
 TAG 
 , 
  
 logMessage 
 ); 
  
 return 
  
 new 
  
 VersionInfo 
 ( 
 0 
 , 
  
 0 
 , 
  
 0 
 ); 
 } 
 

initialize()

Timeout: 30 seconds

The initialize() method is the first method called in your adapter. It is called only once per session. This method provides you with a list of MediationConfiguration objects that represent the full list of placements in this app that are configured for your ad network; You can loop through this list to parse the credentials for each placement, and pass relevant data to your SDK for initialization.

Once your SDK is initialized and is ready to receive ad requests, invoke the onInitializationSucceeded() method of the InitializationCompleteCallback . This callback is forwarded to the app publishers so that they can know they can start loading ads.

  @Override 
 public 
  
 void 
  
 initialize 
 ( 
 Context 
  
 context 
 , 
  
 InitializationCompleteCallback 
  
 initializationCompleteCallback 
 , 
  
 List<MediationConfiguration> 
  
 mediationConfigurations 
 ) 
  
 { 
  
 // 
  
 Initialize 
  
 your 
  
 ad 
  
 network 
 ' 
 s 
  
 SDK 
 . 
  
 ... 
  
 // 
  
 Invoke 
  
 the 
  
 InitializationCompleteCallback 
  
 once 
  
 initialization 
  
 completes 
 . 
  
 initializationCompleteCallback 
 . 
 onInitializationSucceeded 
 (); 
 } 
 

collectSignals()

Timeout: 1 second

Each time the publisher requests an ad, a new instance of your RtbAdapter is created and the collectSignals() method is called. This instance of RtbAdapter will be used for the duration of the ad request, response, and rendering lifecycle for that ad. The collectSignals() method enables your adapter to provide signals from the device to be sent to your bidder in an OpenRTB request.

collectSignals() is called on a background thread. Google Mobile Ads SDK simultaneously asks for signals from all adapters participating in bidding. Please be respectful and limit calls to the UI thread during this time. Any heavy work that your adapter or SDK needs to do to collect signals should be done in the initialize() method and cached.

Once you have your signals ready, call the onSuccess() callback with your encoded signals.

Here's an example implementation:

  @ 
 Override 
 public 
  
 void 
  
 collectSignals 
 ( 
 RtbSignalData 
  
 rtbSignalData 
 , 
  
 SignalCallbacks 
  
 signalCallbacks 
 ) 
  
 { 
  
 String 
  
 signals 
  
 = 
  
 YourSdk 
 . 
 getSignals 
 (); 
  
 signalCallbacks 
 . 
 onSuccess 
 ( 
 signals 
 ); 
 } 
 

If your adapter fails to collect signals, call signalCallbacks.onFailure() with a string explaining the error that occurred.

Implement ad loading methods

Timeout: 10 seconds

If your bidder returns the winning bid, the Google Mobile Ads SDK calls your adapter to load the winning ad, passing you any data that your bidder returned that your SDK needs to load that ad.

The exact load method that is called depends on the ad format this request is for:

Ad Format Load method
Banner loadBannerAd()
Interstitial loadInterstitialAd()
Rewarded loadRewardedAd()

Implement these methods for the ad formats your adapter supports.

The load method is called on the UI thread, on the same instance of the adapter from which you provided signals. This method provides you the following parameters:

  • A MediationAdConfiguration , which contains parameters your SDK needs to load the ad for the winning bid, such as the bid response and any credentials the publisher configured in the AdMob UI.

  • A MediationAdLoadCallback object used to notify Google Mobile Ads SDK when the loading succeeds or fails.

Once your SDK loads the ad, call mediationAdLoadCallback.onSuccess() . In the event ad loading fails, call mediationAdLoadCallback.onFailure() with a string explaining the error that occurred.

The mediationAdLoadCallback.onSuccess() method requires that you pass in an object that confirms to one of the "Ad" interfaces defined by the Google Mobile Ads SDK. These ad interfaces ask you to provide some information about the ad.

MediationAdConfiguration also has a getWatermark() method to return a base64-encoded string representing a PNG image. This image should be tiled in a transparent overlay on your ads. Reach out to Google for additional guidance on how to render the watermark. It contains metadata about the ad being shown for use by publishers to determine the source of ads shown.

For banners, you'll be asked to provide the banner view. For interstitial and rewarded ads, you'll be asked to implement a show() method to show the ad at a later point in time. As a best practice, we recommend making your class that does the ad loading also be responsible for implementing these ad methods.

The following is a sample implementation of loadBannerAd() . Keep in mind that your adapter's implementation will look different, as your adapter integrates against a different SDK.

  public 
  
 final 
  
 class 
  
 SampleRtbAdapter 
  
 extends 
  
 RtbAdapter 
  
 { 
  
 ... 
  
 @ 
 Override 
  
 public 
  
 void 
  
 loadBannerAd 
 ( 
  
 MediationBannerAdConfiguration 
  
 adConfiguration 
 , 
  
 MediationAdLoadCallback<MediationBannerAd 
 , 
  
 MediationBannerAdCallback 
>  
 callback 
 ) 
  
 { 
  
 SampleBannerRenderer 
  
 bannerRenderer 
  
 = 
  
 new 
  
 SampleBannerRenderer 
 ( 
 adConfiguration 
 , 
  
 callback 
 ); 
  
 bannerRenderer 
 . 
 render 
 (); 
  
 } 
 } 
 // 
  
 Renders 
  
 a 
  
 banner 
  
 ad 
 , 
  
 and 
  
 forwards 
  
 callbacks 
  
 to 
  
 Google 
  
 Mobile 
  
 Ads 
  
 SDK 
 . 
 public 
  
 class 
  
 SampleBannerRenderer 
  
 implements 
  
 MediationBannerAd 
  
 { 
  
 private 
  
 MediationBannerAdConfiguration 
  
 adConfiguration 
 ; 
  
 private 
  
 final 
  
 MediationAdLoadCallback<MediationBannerAd 
 , 
  
 MediationBannerAdCallback 
>  
 adLoadCallback 
 ; 
  
 private 
  
 AdView 
  
 adView 
 ; 
  
 private 
  
 MediationBannerAdCallback 
  
 callback 
 ; 
  
 public 
  
 SampleRtbBannerRenderer 
 ( 
  
 MediationBannerAdConfiguration 
  
 adConfiguration 
 , 
  
 MediationAdLoadCallback<MediationBannerAd 
 , 
  
 MediationBannerAdCallback 
>  
 adLoadCallback 
 ) 
  
 { 
  
 this 
 . 
 adConfiguration 
  
 = 
  
 adConfiguration 
 ; 
  
 this 
 . 
 adLoadCallback 
  
 = 
  
 adLoadCallback 
 ; 
  
 } 
  
 public 
  
 void 
  
 render 
 () 
  
 { 
  
 adView 
  
 = 
  
 new 
  
 AdView 
 ( 
 adConfiguration 
 . 
 getContext 
 ()); 
  
 adView 
 . 
 setAdSize 
 ( 
 adConfiguration 
 . 
 getAdSize 
 ()); 
  
 // 
  
 serverParameters 
  
 are 
  
 the 
  
 parameters 
  
 entered 
  
 in 
  
 the 
  
 AdMob 
  
 UI 
  
 for 
  
 your 
  
 network 
 . 
  
 adView 
 . 
 setAdUnitId 
 ( 
 adConfiguration 
 . 
 getServerParameters 
 () 
 . 
 getString 
 ( 
 "adUnitId" 
 )); 
  
 // 
  
 Map 
  
 the 
  
 callbacks 
  
 from 
  
 your 
  
 SDK 
  
 to 
  
 Google 
 's SDK. 
  
 adView 
 . 
 setAdListener 
 ( 
 new 
  
 AdListener 
 () 
  
 { 
  
 // 
  
 See 
  
 the 
  
 next 
  
 step 
  
 for 
  
 more 
  
 information 
  
 on 
  
 callback 
  
 mapping 
 . 
  
 // 
  
 ... 
  
 }); 
  
 // 
  
 Get 
  
 the 
  
 bid 
  
 response 
  
 and 
  
 watermark 
  
 from 
  
 the 
  
 ad 
  
 configuration 
  
 and 
  
 // 
  
 pass 
  
 the 
  
 relevant 
  
 information 
  
 to 
  
 your 
  
 SDK 
 . 
  
 String 
  
 ad 
  
 = 
  
 adConfiguration 
 . 
 getBidResponse 
 (); 
  
 String 
  
 watermark 
  
 = 
  
 adConfiguration 
 . 
 getWatermark 
 (); 
  
 Bundle 
  
 extras 
  
 = 
  
 new 
  
 Bundle 
 (); 
  
 extras 
 . 
 putString 
 ( 
 "bid" 
 , 
  
 ad 
 ); 
  
 extras 
 . 
 putString 
 ( 
 "watermark" 
 , 
  
 watermark 
 ); 
  
 AdRequest 
  
 request 
  
 = 
  
 new 
  
 AdRequest 
 . 
 Builder 
 () 
  
 . 
 addNetworkExtrasBundle 
 ( 
 AdMobAdapter 
 . 
 class 
 , 
  
 extras 
 ) 
  
 . 
 build 
 (); 
  
 adView 
 . 
 loadAd 
 ( 
 request 
 ); 
  
 } 
  
 // 
  
 MediationBannerAd 
  
 implementation 
  
 @ 
 NonNull 
  
 @ 
 Override 
  
 public 
  
 View 
  
 getView 
 () 
  
 { 
  
 return 
  
 adView 
 ; 
  
 } 
 } 
 

Relay ad presentation lifecycle events

The final responsibility of the adapter is to notify Google Mobile Ads SDK of any presentation lifecycle events, so that they can be forwarded to the publisher. The publisher expects these callbacks at specific times no matter which ad network serves the ad, so it's important that as many of these callbacks are invoked as possible, and at the right time, so that Google Mobile Ads SDK can forward them to the publisher.

Adapters should invoke the following events when applicable:

Common to all formats
Method
When to call
reportAdClicked()
The ad was clicked.
reportAdImpression()
The ad rendered an impression.
onAdOpened()
The ad presented a full screen view.
onAdClosed()
The ad's full screen view has been closed.
onAdLeftApplication()
The ad caused the user to leave the application.
Rewarded ads
onRewarded()
The user is granted a reward.
Video callbacks (rewarded and native ads)
onVideoStarted()
The ad's video started.
onVideoCompleted()
The ad's video completed.

The adapter gets a MediationAdLoadCallback<MediationAdT, MediationAdCallbackT> object back upon calling mediationAdLoadCallback.onSuccess() . Adapters are expected to hold onto this object and use it to invoke presentation events that occur on your ad.

Typically, most of these events are driven by your ad network's SDK. The adapter's role is simply to map the callbacks from your ad network SDK to the Google Mobile Ads SDK.

The following example demonstrates how you would forward callbacks from your SDK's ad listener to Google Mobile Ads SDK:

  adView 
 . 
 setAdListener 
 ( 
 new 
  
 AdListener 
 () 
  
 { 
  
 public 
  
 void 
  
 onAdLoaded() 
  
 { 
  
 callback 
  
 = 
  
 adLoadCallback.onSuccess(SampleBannerRenderer.this) 
 ; 
  
 } 
  
 public 
  
 void 
  
 onAdImpression 
 () 
  
 { 
  
 if 
  
 (callback 
  
 != 
  
 null) 
  
 { 
  
 callback.reportAdImpression() 
 ; 
  
 } 
  
 } 
  
 public 
  
 void 
  
 onAdFailedToLoad 
 ( 
 LoadAdError 
  
 adError 
 ) 
  
 { 
  
 adLoadCallback.onFailure(" 
 Error 
 : 
  
 " 
  
 + 
  
 adError 
 . 
 toString 
 ()); 
  
 } 
  
 public 
  
 void 
  
 onAdClosed 
 () 
  
 { 
  
 if 
  
 (callback 
  
 != 
  
 null) 
  
 { 
  
 callback.onAdClosed() 
 ; 
  
 } 
  
 } 
  
 public 
  
 void 
  
 onAdOpened 
 () 
  
 { 
  
 if 
  
 (callback 
  
 != 
  
 null) 
  
 { 
  
 callback.onAdOpened() 
 ; 
  
 callback.reportAdClicked() 
 ; 
  
 } 
  
 } 
  
 public 
  
 void 
  
 onAdLeftApplication 
 () 
  
 { 
  
 if 
  
 (callback 
  
 != 
  
 null) 
  
 { 
  
 callback.onAdLeftApplication() 
 ; 
  
 } 
  
 } 
 } 
 ); 
 

Required assets for native ad impression tracking

Google Mobile Ads SDK records an impression for a native ad when 1 px of the ad is visible. If your ad network SDK requires specific assets to be displayed in order to render a valid impression, your bidder can indicate these required native assets in the bid response. Google Mobile Ads SDK then validates that your required native assets are displayed prior to recording an impression.

See the native required assets documentation for more information on how to specify additional required assets in the bid response.

Show ad errors

For full screen formats, such as interstitial and rewarded ads, in the success load callback you will provide an implementation of MediationInterstitialAd or MediationRewardedAd so that Google Mobile Ads SDK can ask your adapter to show the ad.

Google Mobile Ads SDK expects that if an adapter successfully loaded an ad, the ad is ready to show when the publisher asks to show it. This means that every show call should result in an impression.

However, there may be corner cases where you're unable to show an ad. If you can't show the ad, call the onAdFailedToShow() callback to cancel the impression.

The table below shows how presentation callbacks affect impression recording for full screen ad formats:

Callback Result
onAdOpened() Impression recorded
onAdFailedToShow() Impression failure 1
None of the above for several seconds Impression recorded

1 For failed impressions, your ad network is not charged for the impression, but it impacts your billable event rate adjustment. See bid request signals for more information.

The following mock example demonstrates a load/show lifecycle where an ad show call may result in a failure.

  final 
  
 class 
  
 SampleRtbAdapter 
  
 extends 
  
 RtbAdapter 
  
 implements 
  
 MediationRewardedAd 
  
 { 
  
 private 
  
 MediationRewardedAdCallback 
  
 callback 
 ; 
  
 private 
  
 RewardedAd 
  
 rewardedAd 
 ; 
  
 ... 
  
 @ 
 Override 
  
 public 
  
 void 
  
 loadRewardedAd 
 ( 
  
 MediationRewardedAdConfiguration 
  
 adConfiguration 
 , 
  
 final 
  
 MediationAdLoadCallback<MediationRewardedAd 
 , 
  
 MediationRewardedAdCallback 
>  
 loadCallback 
 ) 
  
 { 
  
 // 
  
 Load 
  
 an 
  
 ad 
 . 
  
 This 
  
 mock 
  
 example 
  
 uses 
  
 Google 
 's SDK, but in practice 
  
 // 
  
 your 
  
 adapter 
  
 will 
  
 load 
  
 the 
  
 ad 
  
 using 
  
 your 
  
 ad 
  
 network 
 's SDK. 
  
 RewardedAd 
 . 
 load 
 ( 
 adConfiguration 
 . 
 getContext 
 (), 
  
 "ca-app-pub-3940256099942544/5224354917" 
 , 
  
 new 
  
 AdRequest 
 . 
 Builder 
 () 
 . 
 build 
 (), 
  
  new 
  
 RewardedAdLoadCallback 
 () 
  
 { 
  
 @ 
 Override 
  
 public 
  
 void 
  
 onAdLoaded 
 ( 
 @ 
 NonNull 
  
 RewardedAd 
  
 rewardedAd 
 ) 
  
 { 
  
 // 
  
 When 
  
 the 
  
 ad 
  
 loads 
 , 
  
 invoke 
  
 the 
  
 load 
  
 success 
  
 callback 
 . 
  
 callback 
  
 = 
  
 loadCallback 
 . 
 onSuccess 
 ( 
 SampleRtbAdapter 
 . 
 this 
 ); 
  
 } 
  
 }); 
  
 } 
  
 @ 
 Override 
  
 public 
  
 void 
  
 showAd 
 ( 
 Context 
  
 context 
 ) 
  
 { 
  
 // 
  
 In 
  
 this 
  
 mock 
  
 example 
 , 
  
 your 
  
 ad 
  
 network 
  
 requires 
  
 an 
  
 activity 
  
 context 
 , 
  
 but 
  
 // 
  
 didn 
 't receive one, making you unable to show the ad. 
  
 if 
  
 ( 
 ! 
 ( 
 context 
  
 instanceof 
  
 Activity 
 )) 
  
 { 
  
 AdError 
  
 error 
  
 = 
  
 new 
  
 AdError 
 ( 
 1 
 , 
  
 "Context must be an activity" 
 , 
  
 "com.google.ads.mediation.sample" 
 ); 
  
 callback 
 . 
 onAdFailedToShow 
 ( 
 error 
 ); 
  
 } 
  
  // 
  
 This 
  
 example 
  
 shows 
  
 Google 
  
 SDK 
 's callbacks, but it' 
 s 
  
 likely 
  
 your 
  
 SDK 
  
 // 
  
 has 
  
 similar 
  
 presentation 
  
 callbacks 
 . 
  
 rewardedAd 
 . 
 setFullScreenContentCallback 
 ( 
 new 
  
 FullScreenContentCallback 
 () 
  
 { 
  
 @ 
 Override 
  
 public 
  
 void 
  
 onAdShowedFullScreenContent 
 () 
  
 { 
  
 // 
  
 Your 
  
 ad 
  
 network 
  
 SDK 
  
 successfully 
  
 showed 
  
 the 
  
 ad 
 . 
  
 Call 
  
 onAdOpened 
 () 
 . 
  
 callback 
 . 
 onAdOpened 
 (); 
  
 } 
  
 @ 
 Override 
  
 public 
  
 void 
  
 onAdFailedToShowFullScreenContent 
 ( 
 AdError 
  
 adError 
 ) 
  
 { 
  
 // 
  
 Your 
  
 ad 
  
 network 
  
 SDK 
  
 failed 
  
 to 
  
 show 
  
 the 
  
 ad 
 , 
  
 invoke 
  
 onAdFailedToShow 
 . 
  
 // 
  
 In 
  
 practice 
 , 
  
 you 
  
 will 
  
 map 
  
 your 
  
 SDK 
 's error to an AdError. 
  
 AdError 
  
 error 
  
 = 
  
 new 
  
 AdError 
 ( 
 adError 
 . 
 getCode 
 (), 
  
 adError 
 . 
 getMessage 
 (), 
  
 adError 
 . 
 getDomain 
 ()); 
  
 callback 
 . 
 onAdFailedToShow 
 ( 
 adError 
 ); 
  
 } 
  
 }); 
  
 rewardedAd 
 . 
 show 
 (( 
 Activity 
 ) 
  
 context 
 , 
  
 ... 
 ); 
  
 } 
 } 
 
Create a Mobile Website
View Site in Mobile | Classic
Share by: