Skip to main content

How to Enable "Secure Signals" for InMobi Bidding in AdMob

 You have successfully set up InMobi as a bidding source in your AdMob mediation groups. You have integrated the InMobi SDK and the corresponding AdMob adapter. Your dashboard shows "Active," yet your fill rates are abysmal, or the eCPM is suspiciously static.

In 90% of cases, this is not an issue with your traffic quality or the InMobi demand. It is a configuration silent failure.

Modern programmatic bidding relies on passing encrypted data objects—"signals"—from the client device to the mediation server. For InMobi, Google AdMob requires an explicit opt-in for these signals to be ingested. Without enabling "Secure Signals," the InMobi bidder receives a bid request without the necessary context to value the impression, resulting in a no-bid or a floor-price bid.

This guide details the technical root cause of this failure, the mandatory UI configuration to fix it, and the code required to ensure the signal pipeline remains open.

The Root Cause: The Opaque Signal Pipeline

To understand why this setting is mandatory, we must look at how Real-Time Bidding (RTB) functions within the Google Mobile Ads (GMA) SDK.

In a traditional Waterfall setup, the ad server simply calls the network SDKs sequentially. Bidding is different. When your app initializes, the InMobi SDK gathers device signals (identifiers, location data if permitted, device model, connection type) and compresses them into an opaque string—the Bid Token.

When the GMA SDK prepares an ad request:

  1. It queries the installed InMobi Adapter.
  2. The Adapter asks the InMobi SDK for the Bid Token.
  3. The GMA SDK bundles this token into the request sent to Google's servers.

Here is the failure point: Google enforces strict data privacy boundaries. Even if the SDK sends the token, Google's backend will strip this signal before passing it to the InMobi exchange unless you have explicitly authorized "Secure Signals" for that specific partner.

If the switch is off, InMobi receives a bid request from Google, but the payload is empty of the user-specific data required to determine the bid price. Consequently, InMobi declines to bid.

Solution: Enabling Secure Signals in AdMob UI

Before touching the codebase, you must authorize signal sharing in the AdMob console. This setting is often buried away from the standard "Mediation" tab.

1. Access Linked Services

Navigate to your AdMob dashboard. In the sidebar, select Settings. From the sub-menu, select Linked Services.

2. Locate Secure Signals

You will see a tab or section labeled Secure Signals. This section controls which third-party bidders are allowed to receive obfuscated user and device signals via the Google SDK.

3. Activate InMobi

Search for "InMobi" in the list of partners.

  • Toggle the status to ON.
  • If InMobi is not in the list, verify that you have successfully added InMobi as a "Bidder" in at least one Mediation Group.

Note: Changes here can take up to 4 hours to propagate through Google's global ad serving infrastructure.

Client-Side Implementation: Modern Best Practices

Enabling the UI toggle is useless if the app code does not correctly initialize the adapters. Below are the rigorous implementation standards for Android (Kotlin) and iOS (Swift) to ensure signals are generated correctly.

Android Implementation (Kotlin)

Ensure you are using the AndroidX libraries and the latest stable versions of the GMA SDK and InMobi Adapter.

build.gradle.kts (App Level):

dependencies {
    // Always keep the main SDK and the adapter in sync
    implementation("com.google.android.gms:play-services-ads:23.0.0")
    
    // The InMobi adapter automatically pulls in the InMobi SDK
    // Check Google's developer site for the latest matching version
    implementation("com.google.ads.mediation:inmobi:10.6.0.0") 
}

AdManager.kt (Initialization Logic):

Do not lazily load the adapter. Initialize the Mobile Ads SDK immediately upon app launch to allow the InMobi SDK time to generate the pre-fetch bid token.

import android.content.Context
import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.RequestConfiguration
import com.inmobi.sdk.InMobiSdk
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class AdManager(private val context: Context) {

    fun initializeAds() {
        // Run on background IO thread to prevent main thread blocking during init
        CoroutineScope(Dispatchers.IO).launch {
            
            // OPTIONAL: Set GDPR/CCPA Consent configurations here
            // This is critical for EU/California traffic revenue
            val requestConfiguration = RequestConfiguration.Builder()
                .setTagForChildDirectedTreatment(RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_FALSE)
                .build()
            MobileAds.setRequestConfiguration(requestConfiguration)

            // Initialize GMA SDK
            MobileAds.initialize(context) { initializationStatus ->
                val statusMap = initializationStatus.adapterStatusMap
                val inMobiStatus = statusMap["com.google.ads.mediation.inmobi.InMobiAdapter"]

                if (inMobiStatus?.initializationState == com.google.android.gms.ads.initialization.AdapterStatus.State.READY) {
                    // InMobi is ready to generate bid tokens
                    println("InMobi Adapter initialized successfully.")
                } else {
                    // Log error for debugging - essential for monitoring failures
                    println("InMobi Init Failed: ${inMobiStatus?.description}")
                }
            }
        }
    }
}

iOS Implementation (Swift)

For iOS, you must ensure the adapter is included via CocoaPods or Swift Package Manager and that SKAdNetwork IDs are present in your Info.plist.

Podfile:

platform :ios, '14.0'
use_frameworks!

target 'YourAppTarget' do
  pod 'Google-Mobile-Ads-SDK'
  pod 'GoogleMobileAdsMediationInMobi'
end

AppDelegate.swift:

import UIKit
import GoogleMobileAds
// Note: You do not need to import InMobiSDK directly if using the Mediation adapter
// unless you need specific InMobi configurations (like logging).

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        
        // Initialize the Google Mobile Ads SDK
        GADMobileAds.sharedInstance().start { status in
            
            // Deep inspection of adapter status
            let adapterStatus = status.adapterStatusesByClassName
            if let inMobiStatus = adapterStatus["GADMAdapterInMobi"] {
                if inMobiStatus.state == .ready {
                    print("InMobi Adapter is ready for bidding.")
                } else {
                    print("InMobi failed to initialize: \(inMobiStatus.description)")
                }
            }
        }
        
        return true
    }
}

Deep Dive: Verifying the Signal Exchange

How do you confirm that the "Secure Signals" toggle is actually working before you release to production? You cannot rely solely on the AdMob dashboard, as data is delayed. You must inspect the network traffic.

Using Charles Proxy or Fiddler

  1. Connect your test device to a proxy tool (Charles Proxy is recommended).
  2. Enable SSL Proxying for googleads.g.doubleclick.net.
  3. Trigger an ad request in your app.
  4. Inspect the POST request to Google.

What to look for: You are looking for the encrypted blob representing the signals. While you cannot decrypt it, you should verify its presence. Search the payload for a structure similar to bidding_data or specific keys associated with InMobi (often containing inmobi or im_signals).

If "Secure Signals" is disabled, the adapter might initialize locally, but the outbound request to Google will lack the specific extension object that carries the InMobi token.

Common Pitfalls and Edge Cases

Even with the toggle on and code present, revenue may remain low due to these overlooked factors.

1. Missing SKAdNetwork Items (iOS)

With iOS 14.5+, bidding partners require SKAdNetworkItems in your Info.plist to attribute installs. Without this, InMobi cannot verify app install performance, leading to extremely low bids.

Ensure this is in your Info.plist:

<key>SKAdNetworkItems</key>
<array>
  <!-- InMobi SKAdNetwork ID -->
  <dict>
    <key>SKAdNetworkIdentifier</key>
    <string>wzmmz9fp6w.skadnetwork</string>
  </dict>
  <!-- Add Google's and other buyers' IDs here -->
</array>

2. ProGuard/R8 Obfuscation (Android)

If you run a release build and ads fail, your minification rules might be stripping the InMobi adapter classes. Add the following to proguard-rules.pro:

-keep class com.inmobi.** { *; }
-keep interface com.inmobi.** { *; }
-dontwarn com.inmobi.**
-keep public class com.google.ads.mediation.inmobi.InMobiAdapter { *; }

3. GDPR and CMP Conflicts

InMobi is highly sensitive to consent strings. If you use a Consent Management Platform (CMP), ensure it writes the TCF v2.0 string to SharedPreferences (Android) or UserDefaults (iOS). The InMobi SDK automatically reads this. If the user declines consent, InMobi may stop bidding entirely rather than bidding on non-personalized inventory.

Conclusion

The transition from Waterfall to Bidding reduces latency and increases ARPDAU, but it increases configuration complexity. The "Secure Signals" toggle in AdMob is the gatekeeper for InMobi's bidding logic. By enabling this setting and verifying your SDK integration with the code provided above, you ensure that every ad request carries the necessary data payload to maximize competition and revenue.