OpenWrap-InApp Developer Guide: Android InApp Header Bidding for MoPub (1.2.1)

Document created by catherine.racette on Aug 8, 2017Last modified by catherine.racette on Oct 25, 2017
Version 12Show Document
  • View in full screen mode

(Version 1.2.1)

Introduction

In-App Header Bidding allows publishers to allocate ad inventory using a technology and methodology that bypasses inefficiencies that have kept apps from finding the best prices.


Header bidding is the process of sending out an initial ad call to one or more buyers to solicit an exact price for inclusion in the ad server’s inventory allocation process.

 

High-Level Process Overview

  1. The prefetch/header bidding ad call needs to be initiated before requesting ad from Primary SDK.
  2. Buyers get first look at the inventory and submit a pre-bid price.
  3. This pre-bid price then becomes the bid floor for the ad server call, which checks if any other buyers in the same priority tier can beat it. As a result, inventory gets allocated to the highest yielding buyer while respecting other publisher controls that may have been set up in the ad server.

 

Header bidding primarily benefits publishers who use third party SDKs (e.g., MoPub/DFP) to manage their ads. However, MoPub doesn’t allow publishers to effectively pull in programmatic buyers that compete against marketplace and direct deals, so publishers are limited to which buyers they can utilize.


When a screen in the publisher's app is loaded, the code reaches out to PubMatic for bids before the ad server’s direct sales are called.

 

The diagram below shows how PubMatic OpenWrap - InApp header bidder integrates with publisher’s app.

 

The header bidding arrangement accomplishes several objectives:

  • All the demand sources are bidding at the same time, which replaces waterfall’s preferential ordering of buyers.
  • Advertisers have a chance at obtaining the best ad inventory.
  • Stats have shown publisher gains as high as 50 percent in CPMs when moving to header bidding setup. 

Supported Ad Format

  • Simple Banner

Prerequisites 

Before continuing with the in-app code integration, use the guidelines in the following MoPub SDK documentation to get started with MoPub and banner integration for Android.

 

 

In-App Code Integration

Use the instructions below to complete the in-app code integration.

  1. Integrating the PubMatic Sample Code in the Publisher’s Application
  2. Adding Permissions to the Manifest File
  3. Creating a Header Bidding Request
  4. Prefetching Bids Using PMPrefetchManager
  5. Handling Prefetched Bids from PMPrefetchManager
  6. Receiving Winning Bids Using MoPub’s Custom Event (Adapter) Class
  7. Get Rendered Ad from Prefetched Creative
  8. Using HeaderBiddingBannerHelper (Optional)
  9. Setting Refresh Interval (Optional)
  10. App debugging

 

Integrating the PubMatic Sample Code in the Publisher’s Application

Copy the contents of the “core” package to the Publisher’s Android application. Refer to the code, provided by PubMatic, for faster and easier integration.

Import the following classes to integrate the Header Bidding request:

import com.pubmatic.headerbidding.core.PMAdSize; 
import com.pubmatic.headerbidding.core.PMBannerImpression;
import com.pubmatic.headerbidding.core.PMBannerPrefetchRequest;
import com.pubmatic.headerbidding.core.PMBid;
import com.pubmatic.headerbidding.core.PMPrefetchManager;
import com.pubmatic.headerbidding.core.PubMaticBannerAdRequest;
import com.pubmatic.headerbidding.core.PubMaticConstants;

Adding Permissions to the Manifest File

Declare the following security permissions in your manifest file (AndroidManifest.xml).

 

Table 1. Basic Permissions for the Manifest File

PermissionDescription and Manifest File Entry
InternetAccess the Internet. Required for ad-content download.
<uses-permission android:name="android.permission.INTERNET" />
Network StateAccess the Network state. Required for retrieving network details from ConnectivityManager
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Creating a Header Bidding Request

  1. Create Impression objects that contain information about specific ad slots such as impressionId (Unique identifier), slot name, sizes and slot index. Separate object of PMBannerImpression class must be created for each ad slot. 
PMBannerImpression bannerImpression = new PMBannerImpression(<ImpressionId>, <SlotName>, <AdSizes>,
<SlotIndex>);
  • ImpressionId: Used to identify unique ad slot/banner of the MoPub screen. This should match with imp_id configured in step 2 in the Ad Server Setup section below.
  • SlotName: A string identifier. It should be the same slot name mapped to PubMatic ad tag. Refer to the inventory mapping completed by PubMatic.
  • SlotIndex: Required when the same slot name is used multiple times on the screen. For example, if there are two slot name on the screen, testAd (Above the fold) and testAd (Below the fold), then slotindex can be used to differentiate between slots with the same name.
  • AdSizes: Can be provided to request an ad with different sizes.

  1. Create a prefetch request object by specifying the publisher id and impressions, from step 1, to prefetch bids. It is required to make an ad request to PubMatic against impression objects.

    PMBannerPrefetchRequest adRequest = PMBannerPrefetchRequest.initHBRequestForImpression
    (<Context>, <pubId>, List<PMBannerImpression>);

     

  2. Specify targeting information on the prefetch request object such as store URL, app domain, gender, ethnicity, etc.
    Sample code for creating ad request & setting basic parameters:
PMBannerPrefetchRequest adRequest = PMBannerPrefetchRequest.initHBRequestForImpression(mContext, <Publisher ID>, bannerImpressions); 
adRequest.setAWT(PubMaticBannerAdRequest.AWT_OPTION.WRAPPED_IN_JS);
adRequest.addKeyword("entertainment");
adRequest.addKeyword("sports");
adRequest.setEthnicity(PubMaticBannerAdRequest.ETHNICITY.ASIAN_AMERICAN);
adRequest.setDoNotTrack(false);
adRequest.setApplicationPaid(false);
// Designated market area (DMA) code of the user.
// This field is applicable for US users only. For example, dma=734
adRequest.setDMA("734");
adRequest.setCoppa(true);
adRequest.setOrmmaComplianceLevel(1);
adRequest.setAppCategory("Game");
adRequest.setIABCategory("IAB1-1,IAB1-7");

For additional parameter details, please refer Table 3 in the ‘PubMatic Prefetch API Parameter Details’ section below.         

Prefetching Bids Using PMPrefetchManager

  1. Create an object of PMPrefetchListener:
PMPrefetchManager.PMPrefetchListener listener = new
PMPrefetchManager.PMPrefetchListener () {
@Override
public void onBidsFetched(Map<String, PMBid> hBResponse) {
Log.d(TAG, "onBidsFetched");
// Header bidding completed.
// Now send the custom data to MoPub.
requestMoPubAd(hBResponse);
}
@Override
public void onBidsFailed(String errorMessage) {
Log.d(TAG, "Header Bidding failed. " + errorMessage);
// Get on with requesting MoPub for ads without HB data.
requestMoPubAd(null);
}
};
  1. Create Prefetch Manager object by specifying the context and set PMPrefetchListener instance. PMPrefetchListener has callback methods for success & failure case of prefetch bid request.
PMPrefetchManager pmPrefetchManager =
PMPrefetchManager.getInstance(<Context>);

pmPrefetchManager.setPrefetchListener(listener);
  1. Set a network timeout using setNetworkTimeout (<timeout in seconds>) method on PMPrefetchManager instance. Default network timeout is 3 seconds, defined as NETWORK_TIMEOUT_SECONDS in PubMaticConstants.java. It can be customized as required. It defines the maximum timeout required to get the response from PubMatic ad server. The Ad server (DFP/MoPub) call will be sent; Either PubMatic responds before this timeout or when the set timeout lapses.

    pmPrefetchManager.setNetworkTimeout(<TIMEOUT>); 
  2. Call prefetchCreatives() on instance of PMPrefetchManager created in step 2.

pmPrefetchManager.prefetchCreatives(<PMBannerPrefetchRequest>);

Handling Prefetched Bids from PMPrefetchManager

  1. Upon success, the Prefetch Manager will respond with a callback onBidsFetched(Map<String, PMBid>) (in PMPrefetchListener class) with a map of PMBid objects.

    The keys for this map will be the impression ids. The PMBid object will contain impression ids and bid information.
  2. Get an instance of MoPubView class (in MoPub SDK) providing it with all the targeting information using setKeywords().
//Include string variables in class 
private final String BID = "bid";
private final String BID_ID = "bidid";
private final String WDEAL_ID = "wdeal";
private final String BID_STATUS = "bidstatus";
private final int BID_DECIMAL_ROUNDOFF= 1;

//Fetch the winning bid details for the impressionId & send to MoPub
PMBid pubResponse = hBResponse.get(<impressionId>);
StringBuilder requestBuilder;

if (pubResponse != null) {

requestBuilder = new StringBuilder();

if(!TextUtils.isEmpty(pubResponse.getDealId())) {
requestBuilder.append(WDEAL_ID+":"+ pubResponse.getDealId());
requestBuilder.append(",");
}

if(!TextUtils.isEmpty(pubResponse.getImpressionId())) {
requestBuilder.append(BID_ID+":"+pubResponse.getImpressionId());
requestBuilder.append(",");
}

String price = String.valueOf(pubResponse.getPrice());

if(!TextUtils.isEmpty(price)) {
double bidPrice = Double.valueOf(price);

if(bidPrice > 0.0d) {
requestBuilder.append(BID+":"+price+",");
requestBuilder.append(BID_STATUS+":1");
} else
requestBuilder.append(BID_STATUS+":0");
}
mopubView.setKeywords(requestBuilder.toString());
}
mopubView.setAdUnitId(<Mopub Ad Unit>);

 

Below is the utility method to round off the bid price up to ‘x’ decimal places. In the current sample code, it has been rounded up to 1 decimal place and can be customized as required. Make sure the similar line item has been configured in MoPub portal. Please refer to the Ad Server Setup section below.

private String getRoundoffPrice(double value, int places) { 
    if (places < 0)
        throw new IllegalArgumentException();

    String formatter = "%."+places+"f";
    return String.format(formatter, value);
  1. Disable the AutoRefresh feature for the MoPubView.
    mopubView.setAutorefreshEnabled(false); 
  2. Call loadAd() from MoPubView class object.
    mopubView.loadAd(); 

 

Receiving Winning Bids Using MoPub's Custom Event (Adapter) Class

Publisher needs to implement a custom event adapter inheriting MoPub’s CustomEventBanner. For every winning bid, this adapter will receive callback where serverExtras contains the impressionId for which the header bid has won. Assuming it has been configured in MoPub portal along with the full path of this adapter class.

 

@Override 
protected void loadBanner(Context context, final CustomEventBannerListener
customEventBannerListener, Map<String, Object> localExtras, Map<String, String>
serverExtras) {

String winningImpressionId = serverExtras.get("adunit");
}


Get Rendered Ad from Prefetched Creative

Call getPubMaticAdView() on PMPrefetchManager instance passing the impressionId and size received in the previous step. In case of success, this method will return a rendered creative in a webView & fire impression trackers.

Define these variables in class:

private CustomEventBannerListener mListener; 
private WebView mPubmaticAdView;

 

Sample code to render Ad from prefetched creative:

@Override 
    protected void loadBanner(Context context, final CustomEventBannerListener
customEventBannerListener, Map<String, Object> localExtras, Map<String, String> serverExtras) {
        mListener = customEventBannerListener;
        String winningImpressionId = serverExtras.get("adunit");

        if(!TextUtils.isEmpty(winningImpressionId)) {

            PMPrefetchManager headerBiddingManager = PMPrefetchManager.getInstance(context);
            mPubmaticAdView = headerBiddingManager.getPubMaticAdView(winningImpressionId);

            //Return Pubmatic AdView to MoPub
            if (mPubmaticAdView != null)
                mListener.onBannerLoaded(mPubmaticAdView);
            else
                mListener.onBannerFailed(MoPubErrorCode.ADAPTER_CONFIGURATION_ERROR);
        } else
            mListener.onBannerFailed(MoPubErrorCode.ADAPTER_CONFIGURATION_ERROR);
    }

As mentioned above, Call onBannerLoaded() on the custom event listener instance if a valid ad is returned (i.e. webview is not null) else call onBannerFailed() with error code.

As a part of cleanup of resources, it is recommended to free the Ad objects. Below is a sample code:

@Override 
protected void onInvalidate() {

mListener = null;

if(mPubmaticAdView!=null) {
ViewGroup parent = (ViewGroup)mPubmaticAdView.getParent();
if(parent!=null)
parent.removeView(mPubmaticAdView);
mPubmaticAdView.destroy();
mPubmaticAdView = null;
}
}

 

Using HeaderBiddingBannerHelper (Optional)

The HeaderBiddingBannerHelper is a template that manages the PubMatic pre-fetch calls and makes ad server requests by providing PubMatic bids. This step is optional and can be skipped, particularly if a publisher would like more control over the Ad server calls (MoPub ad request). Alternatively, a publisher may choose to complete this step, as HeaderBiddingBannerHelper class can make the integration easier. 


Customize this class to integrate any other header bidding partner in addition to PubMatic.

 

  1. Create an AdSlotInfo object for each ad slot by providing slot name, list of ad sizes and PublisherAdView.

    MoPubHeaderBiddingBannerHelper.AdSlotInfo adSlotInfo = new MoPubHeaderBiddingBannerHelper
    .AdSlotInfo(<SlotName>, <List[AdSizes]>, <MoPubView>);
  2. Create a list of AdSlotInfo objects.
  3. Create an object of MoPubHeaderBiddingBannerHelper giving it the context and the ad slot list created in step 2. Now call execute.
    MoPubHeaderBiddingBannerHelper hbBannerHelper = new MoPubHeaderBiddingBannerHelper (<Context>, <AdSlotInfoList>); 
    hbBannerHelper.execute();

 

Setting Refresh Interval (Optional)

This solution provides an optional feature to auto-refresh the banner ad after a specified interval.

The default value for refresh interval is 0 seconds, i.e., by default auto-refresh feature is disabled. The publisher can set an appropriate refresh interval by calling setRefreshInterval(<value in sec>) of PMPrefetchManager. Expected value should be in range of 12 to 120.

 

Table 2. Ad Refresh Behavior on Setting Refresh Interval Value

Value (X) in secondsBehavior
X<=0Ad will not refresh 
X > 0 & X <= 12 Ad will get refreshed after every 12 seconds. 
X > 12 & X <=120 Ad will get refreshed after every X seconds
X > 120Ad will get refreshed after every 120 seconds

 

Note: To use this feature, please disable the ad server’s refresh functionality. Please refer to the MoPub portal documentationfor additional information.

                  

App debugging

Header bidding code logs the request & response from the PubMatic server in debug mode. This debug log can help to see if PubMatic is providing proper bids or not. Below is a sample log from the Header bidding sample application.

 

PubMatic Prefetch API Parameter Details

Please refer the following setter functions for sending the targeting parameter values.

 

Table 3. PMBannerPrefetchRequest APIs/Setters

S. noMethodDescription
1setStoreURL(String storeUrl)URL of the app store from where a user can download this application. This URL must match the storeurl that is whitelisted in the UI.
2setAppDomain(String appDomain)Indicates the domain of the mobile application
3setApplicationPaid(boolean paid)

Indicates whether the mobile application is a paid version or not. Possible values are:

false - Free version
true - Paid version

4setAWT(AWT_OPTION awtOption)

Indicates whether the tracking URL has been wrapped or not in the creative tag.

Possible options are:

 

DEFAULT - Indicates that the tracking URL is sent separately in the response JSON as tracking_url. In this case, the tracking_url field is absent in the JSON response.

 

WRAPPED_IN_IFRAME - Indicates that the tracking_url value is wrapped in an Iframe and appended to the creative_tag.

 

WRAPPED_IN_JS - Indicates that the tracking_url value is wrapped in a JS tag and appended to the creative_tag.

5setPMZoneId(String pmZoneId)This parameter is used to pass a zone ID for reporting.
6setEthnicity(ETHNICITY ethnicity)Numeric code of ethnicity
7setIncome(String income)User's income or income range in dollars (whole numbers). For example, inc=50000 or 50000-75000. 
8setYearOfBirth(String yearOfBirth)Visitor's birth year as a four-digit integer. For example, 1975.
9setGender(String gender)Gender of the visitor. Possible values are:
M - Male
F - Female
O - Others
10setCity(String city)City of the user. For example, city=New York
11setZip(String zip)Home zip code if the visitor is present in the U.S.; otherwise it indicates the postal code. 
12setCoppa(boolean coppa)

Indicates whether the visitor is COPPA-specific or not. For COPPA (Children's Online Privacy Protection Act) compliance, if the visitor's age is below 13, then such visitors should not be served targeted ads.

 

Possible options are:
false - Indicates that the visitor is not COPPA-specific and can be served targeted ads.
true - Indicates that the visitor is COPPA-specific and should be served only COPPA-compliant ads.

 

The United States Federal Trade Commission has written a comprehensive FAQ on complying with COPPA at http://business.ftc.gov/documents/Complying-with-COPPA-Frequently-Asked-Questions.

13setOrmmaComplianceLevel(int ormmaaComplianceLevel)Minimum compliance level. Possible values are 0, 1 and 2.
14setIABCategory(String iabCategory)

List of IAB content categories for the overall site/application. Refer the "Table 6.1 Content Categories" in the Open RTB 2.1 / 2.2 specifications document.

If the site/application falls under multiple IAB categories, you can send categories separated by comma

15addKeyword(String keyword)list of keywords indicating the consumer's interests or intent. 
16setLocation(Location location)Location object
17setDoNotTrack(boolean state)If set, it restricts user and device targeting. Default value is false.
This can also be set by end user, on enabling the “Opt out of Ads Personaization” option in an android phone.
Settings > Google > Ads > Opt out of Ads Personalization
18setAndroidAidEnabled(boolean isAndroidAidEnabled)

If set, it uses advertisement id otherwise it uses android id for targeting.

 

This has effect only if DoNotTrack is set to false.

19setAppCategory(String appCategory)Application primary category as displayed on storeurl page for the respective platform.
20setUdidHash(HASHING_TECHNIQUE hash)

Based on the given hashing type, UDID value hashed & sent to the ad server.

 

Note: If setAndroidAidEnabled(true) is invoked & hashing type is also set then hashed as well as raw advertising id would be sent to ad server.

Note: For more details about these parameters, please refer to HTTP Parameters Details (SSP Ad Server) 

PubMatic Mapping 

Inventory mapping for PubMatic slots and ad tags must be completed in the PubMatic Admin console. Please contact your Customer Success Manager to complete this process.

 

Ad Server Setup on MoPub

The following steps are required so impressions can be allocated to PubMatic by the ad server, based on actual bid price and the recommendation from PubMatic. These are passed to the ad server using key-value pairs added to the MoPub ad request using PubMatic OpenWrap - InApp header bidding code.

 

The publisher needs to provide trafficker level access to create these line items to the email id provided by the PubMatic operations team.

 

Step 1: Create a new order in MoPub for In-App Header Bidding API with PubMatic as the advertiser and add the relevant details.

 

Step 2: Set the price and priority of the line items.

  • Select Network for Type and a Priority of 12. (To enable PubMatic’s response to compete with MoPub Marketplace and Ad Networks).
  • Select Custom Native Network for the Network and add Class name and Data. <Class> is an adapter (subclass of CustomEventBanner class) class name. Data should be a map of <imp_id>:<adunit_id>. Add <imp_id> same as impression id passed in PMBannerImpression.   

Step 3: Ad unit targeting. Assign line items to appropriate ad units.

 

 

Step 4: Set targeting on the “bidstatus” value as 1 from the In-App Header Bidding API tag’s response. In addition to “bidstatus”, you can also set targeting on “m_bid”. For more information, please refer to the Best Practices to Create Tags in the Ad Server section. 

 

Pre-Launch Verification

Before setting traffic live, PubMatic’s Solutions Engineering team will assist the publisher’s technical and ad operations teams conduct pre-launch verification. Once verifications are complete the set up is ready to go live on a small number of sites. Post-launch, the PubMatic Operations team will ensure that the publisher is achieving the desired results and will provide consultation to ramp up the implementation.

 

Best Practices for Creating Line Items in the Ad Server

To control monetization through In-App Header Bidding at a granular level, you may:

  • Create multiple In-App Header Bidding line items in the ad server for each ad unit/ad size/CPM range/geo.
  • Use “m_bid” as the targeting attribute.
  • Place the line items at different priorities based on their pricing and relevance.

 

Important Notes:

  • Currently PubMatic supports (one decimal point) 10 cent granularity in key value targeting.
  • The maximum length of the keywords that MoPub supports is 10K characters. As a result, you can approximately add 300+ bid values in each line item, assuming each targeting line has 30 characters.

    Example:
    This line item will match any ad request containing keyword "bidstatus:1,m_bid:0.#" (# between 0 to n) 
    m_bid:0.1 AND bidstatus:1
    m_bid:0.2 AND bidstatus:1
    m_bid:0.3 AND bidstatus:1
    ...
    m_bid:0.n AND bidstatus:1

 

Examples:

If 80% of the bids are between $0 to $3, create line items at a $0.1 granularity. For other ranges you can create line items at a higher granularity.

 

Sample Variations:
30 line items between $0-$3 with rate increment of $0.1

  • LineItem 1 (covers $0-$0.09) Targeting: bid=0.01,bid=0.02....,bid=0.09, rate=$0.05
  • LineItem 2 (covers $0.10-$0.19) Targeting: bid=0.1, rate=$0.15
    and so on for next 28 line items

15 Line items between $3-$8 with rate increment of $0.30

  • LineItem 31 (covers $3.0-$3.29) Targeting: bid=3.01,bid=3.1,bid=3.2, rate=$3.15
  • LineItem 32 (covers $3.30-$3.59) Targeting: bid=3.3,bid=3.4,bid=3.5, rate=$3.45
    and so on for next 13 line items

12 Line items between $9-$20 with rate increment of $1.0

  • LineItem 46 (covers $9.0-$9.99) Targeting: bid=9, rate=$9.5
  • LineItem 47 (covers $10.0-$10.99) Targeting: bid=10, rate=$3.45
    and so on for next 10 line items

 

A final high- priority line item for very high bids

  • Line Item 58 (Covers $20 and above) Targeting : bid=20,bid=21,bid=22...... bid=50) rate= $21

 

Reporting

Reporting is provided through PubMatic’s comprehensive analytics platform. Header Bidder Performance report provides insights into how PubMatic in-app header bidder is performing.

 

  • MoPub reporting functionality should be used if reporting at the line item level is required.
  • Header Bidder Performance Report is available in the PubMatic UI. Select Analytics | Reports | Advanced Reports from the main navigation.

 

Sample Report

Attachments

    Outcomes