SDK Bidding

The MobileFuse SDK supports an SDK bidding implementation that can be used by mediation platforms. Our SDK Bidding solution uses a token generation and rendering mechanism.

The following formats are supported by bidding:

  • Banner
  • Medium Rectangle
  • Interstitial
  • Rewarded
  • Native

Bidding Token Generation

An SDK-generated token must be passed to the MobileFuse bidding endpoint for every bidding request. Our tokens are encoded strings and may be up to 4000 bytes in size (but are generally much smaller).

To generate a token using our SDK, create a token request object and pass it to the token provider class. Example implementations for each platform follow:

// Optionally pass in privacy preferences
MobileFusePrivacyPreferences.Builder privacyBuilder = new MobileFusePrivacyPreferences.Builder();
privacyBuilder.setUsPrivacyConsentString(mediationPlatform.usPrivacyString);
privacyBuilder.setIabConsentString(mediationPlatform.iabConsentString);
privacyBuilder.setSubjectToCoppa(mediationPlatform.isAgeRestrictedUser);

// Determine test mode
boolean isTestModeEnabled = mediationPlatform.isTestModeEnabled;

// Create our token request
MobileFuseBiddingTokenRequest tokenRequest = MobileFuseBiddingTokenRequest(
    privacyBuilder.build(),
    isTesting
);

// Generate a token - asynchronous:
MobileFuseBiddingTokenProvider.getToken(
    tokenRequest,
    activity,
    new TokenGeneratorListener() {
        @Override
        public void onTokenGenerated(String token) {
            callback.onTokenCollected(token);
        }

        @Override
        public void onTokenGenerationFailed(String error) {
            callback.onTokenCollectionFailed(error);
        }
    }
);
// Optionally pass in privacy preferences
MobileFusePrivacyPreferences *privacyPrefs = [[MobileFusePrivacyPreferences alloc] init];
[privacyPrefs setUsPrivacyConsentString: mediationPlatform.usPrivacyString];
[privacyPrefs setIabConsentString: mediationPlatform.iabConsentString];
[privacyPrefs setSubjectToCoppa: mediationPlatform.isAgeRestrictedUser];

// Determine test mode
BOOL isTesting = mediationPlatform.isTestModeEnabled;

// Create our token request
MFBiddingTokenRequest* request = [[MFBiddingTokenRequest alloc] init];
request.privacyPreferences = privacyPrefs;
request.isTestMode = isTesting;

// Generate a token:
NSString* token = [MFBiddingTokenProvider getTokenWithRequest:request withCallback:^(NSString * _Nonnull token) {
    [delegate didCollectToken: token];
});

📘

Privacy Preferences

Only populate the privacy preferences fields if your mediation SDK has values set for that specific purpose. Every field in the privacy preferences object is optional, and should be set to its default value to indicate that a preference is unknown or no preference has been set.

The returned token is a base-64 encoded string, for example:

H4sIAAAAAAAAAGWOTQrCMBBG7zLrsVhDVXoHTyBdpE0qgfyRxFAJubuTulJXA+/NfN8UUMbDeC8gVPSavwy3/CEDjGDWDfAHRxnyLvuOdcdDWAZambm1DRbgXlEWwwHPeJkqQlZCun+D4INLbnE6Ej0RZY3jdaqV5DN+4uSW2nBGCW+p9OZmpeVKmlp3mr9eqdSYZKSjvr4BZcS0rdkAAAA=

Our tokens do not contain any user PII, even in an encoded form. If we update our token to include PII in the future, we will ensure:

  1. We conform to any privacy preferences passed in - PII will not be passed for opted-out or do-no-track users.
  2. Any PII will end-to-end encrypted between our SDK and the MobileFuse ad exchange.

The mediation platform does not need to do any validation on the token, just pass the value on to MobileFuse in the appropriate OpenRTB field.

Bidding

Our bidding endpoint is <https://mfx.mobilefuse.com/openrtb?ssp=%%SSP_PARTNER_ID%%>

Required fields

  • The endpoint should be populated with your SSP partner ID - we will send you this before integration begins
  • The user.data[0].segment[0].signal OpenRTB field must contain the token that was generated by the SDK
  • The imp[0].tagid must be set to the MobileFuse placement ID that users can supply in your mediation console UI for this particular placement

Example request/responses

On a successful bid, the seatbid[0].bid[0].ext.signaldata field will be populated with a signal token that should be passed back to our SDK for rendering when our bid wins (see Rendering an ad from a response token).

If our bid does not win, the Loss URL (seatbid[0].bid[0].lurl) should be triggered with the relevant macros expanded.

An example bidding request/response is provided below. For more details of our bidding endpoint and other sample requests, please see OpenRTB Bid Requests

{
  "id": "ff71e4a7-2622-493d-bfb8-de446a4152ac",
  "user": {
    "data": [
      {
        "segment": [
          {
            "signal": "H4sIAAAAAAAAAGWOTQrCMBBG7zLrsVhDVXoHTyBdpE0qgfyRxFAJubuTulJXA+/NfN8UUMbDeC8gVPSavwy3/CEDjGDWDfAHRxnyLvuOdcdDWAZambm1DRbgXlEWwwHPeJkqQlZCun+D4INLbnE6Ej0RZY3jdaqV5DN+4uSW2nBGCW+p9OZmpeVKmlp3mr9eqdSYZKSjvr4BZcS0rdkAAAA="
          }
        ]
      }
    ]
  },
  "imp": [
    {
      "id": "1",
      "tagid": "418545",
      "instl": 0,
      "banner": {
        "format": [
          {
            "w": 320,
            "h": 50
          }
        ]
      }
    }
  ],
  "device": {
    "geo": {
      "lat": 42.360,
      "lon": -71.057
    },
    "ua": "Mozilla/5.0 (Linux; Android 9; Pixel 3 XL Build/PD1A.180720.030; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.64 Mobile Safari/537.36",
    "ip": "140.241.0.100",
    "ifa": "01234567-1234-1234-1234-012345678901"
  },
  "app": {
    "bundle": "com.test"
  }
}
{
  "id": "ff71e4a7-2622-493d-bfb8-de446a4152ac",
  "bidid": "2daa3b63ca75c5d111318b2530d00b60",
  "seatbid": [
    {
      "bid": [
        {
          "id": "eea5560fddc6687b22b3b523c20a5106_banner",
          "adomain": [
            "mobilefuse.com"
          ],
          "impid": "1",
          "crid": "test_js_banner",
          "h": 50,
          "price": 2.681,
          "w": 320,
          "lurl": "https://mfx-us-east-1.mobilefuse.com/lurl?reqid=eea5560fddc6687b22b3b523c20a5106&loss=${AUCTION_LOSS}&price=${AUCTION_PRICE}",
          "exp": 300,
          "ext": {
            "signaldata": "H4sIAAAAAAAAA42QXWvCMBiF/8oIwytj89GkXVHHkF0IY4653RVKPt5ipV9rWnSI/32pwtjuvEo4OSfned8TUrZCCZo70xVtf+c6s0jRru9bl6RBGlT5EQ8Og3I9prOq0UUJ+eBgZpoqDfYOHzrVttA9dvBV2AWAEkKS3FojZRxpxjTXgnHDiBKUyBQt52lw7VqiqS9vKlXUHuD/1/7Je6zXe3B9tneZVnUNndfh2KKEEzJFO5QIf5RDV3rjrcyj/UbaSdk4t7g/PX2uPtab1+xls92eJ21XGPijvr2vV89nT1aBLVTWf7fgcX55L3aUsJmM6RT54mGc6DJbnkcUQhVhJhnD4QO3WOc6xhbCUKqQCqYMGjOubWoH1xCzSnEtuVGRMMJSSjmNNROcWEK0JD7gQPXjSnN/P/hlMXL+AYsE7eDoAQAA"
          }
        }
      ],
      "seat": "mf"
    }
  ]
}

Rendering an ad using a BidResponse signaldata

The signaldata bid response field can be used to complete the entire lifecycle of ad creation and display.

This string should be passed directly to the loadAdFromBiddingToken (Android) / loadAdWithBiddingResponseToken (iOS) methods. The ad instance will then behave as documented in the standard SDK documentation: MobileFuse SDK

Your mediation console should allow the publisher to enter in a placement ID for each ad unit - this is passed to the server during the bid, and should also be passed to the constructor/init method of each ad instance:

Interstitial Ad

// placementId should be configured in the mediation platform UI and passed back to this method:
interstitialAd = new MobileFuseInterstitialAd(activity, placementId);
interstitialAd.setListener(new MobileFuseInterstitialAd.Listener(){ ... }); // Register an ad listener
interstitialAd.loadAdFromBiddingToken(bidResponse.seatbid[0].bid[0].ext.signaldata);// Load the ad from signaldata
// placementId should be configured in the mediation platform UI and passed back to this method:
interstitialAd = [[MFInterstitialAd alloc] initWithPlacementId: placementId];
[interstitialAd registerAdCallbackReceiver: myMediationCallbackDelegate]; // Register an ad listener
[interstitialAd loadAdWithBiddingResponseToken: bidResponse.seatbid[0].bid[0].ext.signaldata]; // Load the ad from signaldata

Banner Ad/MREC

bannerAd = new MobileFuseBannerAd(activity, placementId, MobileFuseBannerAd.AdSize.BANNER_320x50);
bannerAd.setListener(new MobileFuseBannerAd.Listener(){ ... }); // Register an ad listener
bannerAd.loadAdFromBiddingToken(bidResponse.seatbid[0].bid[0].ext.signaldata);// Load the ad from signaldata
bannerAd = [[MFBannerAd alloc] initWithPlacementId: placementId withSize: MOBILEFUSE_BANNER_SIZE_320x50];
[bannerAd registerAdCallbackReceiver: myMediationCallbackDelegate]; // Register an ad listener
[bannerAd loadAdWithBiddingResponseToken: bidResponse.seatbid[0].bid[0].ext.signaldata]; // Load the ad from signaldata

Rewarded Ad

rewardedAd = new MobileFuseRewardedAd(activity, placementId);
rewardedAd.setListener(new MobileFuseRewardedAd.Listener(){ ... }); // Register an ad listener
rewardedAd.loadAdFromBiddingToken(bidResponse.seatbid[0].bid[0].ext.signaldata);// Load the ad from signaldata
rewardedAd = [[MFInterstitialAd alloc] initWithPlacementId: placementId];
[rewardedAd registerAdCallbackReceiver: myMediationCallbackDelegate]; // Register an ad listener
[rewardedAd loadAdWithBiddingResponseToken: bidResponse.seatbid[0].bid[0].ext.signaldata]; // Load the ad from signaldata