In-app environment - Technical Requirements

Welcome to the integration documentation for In-App Bidding mode with Pubstack. This integration relies on Prebid Mobile SDK (v3+), in GAM Bidding-only mode.


✅ Prerequisites

  • Native iOS (Swift) or Android (Kotlin) application (WebView not supported by Prebid Mobile SDK - available with a standard web integration)

  • SDKs to integrate:

    • Prebid Mobile SDK v3+

    • Google Mobile Ads SDK (GMA)

    • Google IMA SDK (for Instream video ads)

    • Consent Management Platform (CMP) compatible with TCF v2

    • iOS only: ATT (App Tracking Transparency)


1. 🧱 Prebid SDK Initialization

The initialization of the Prebid SDK establishes the connection with Prebid Server – in our case, the server managed or instrumented by Pubstack. This includes configuring the endpoint URL and client identifiers.

Pubstack Identifiers: Pubstack provides an Account ID (publisher ID on Prebid Server) per application (and per OS) and uses config IDs (ad unit configuration IDs) for inventory.

  • The Account ID is used during SDK initialization.

  • Each ad placement will have its own config ID (see AdUnits section).

Android (Kotlin)

iOS (Swift)

In these examples, Prebid is initialized with:

  • Account ID provided by Pubstack (available in Media & stacks > Select your app > Connect to Pubstack).

  • Prebid Server URL: Pubstack endpoint.

Then Prebid Mobile will:

  1. Check Prebid Server health (internal /status call) to ensure it’s reachable.

  2. Prepare its internal components (local cache, etc.).

  3. Use these parameters for all subsequent bid requests.

⚠️ Important: Prebid.initializeSDK must be called only once (typically at app launch, after the CMP). The SDK must be initialized before creating AdUnit objects or calling fetchDemand().


2. 🛡️ CMP and ATT

CMP

circle-info

Include Pubstack vendor (ID 1408) in the list of allowed vendors, similar to other partners.

The CMP usually provides standardized keys in the app’s local storage, which Prebid SDK can automatically read:

  • IABTCF_gdprApplies → whether the user is subject to GDPR (1 or 0).

  • IABTCF_TCString → encoded TCF v2 consent string summarizing user choices.

  • IABTCF_PurposeConsents → binary string indicating consent or not for each purpose (e.g. the first bit = Purpose 1: access device info).

Prebid SDK reads these values at initialization and on each bid request, without modifying or validating them.

👉 If the CMP stores them in the IAB format, no need to pass them explicitly into Prebid – the SDK will use them automatically.

SDK behavior depending on GDPR consent:

  • Non-GDPR (gdprApplies=false): SDK sends advertising ID (IDFA/AAID) by default.

  • GDPR, no consent for Purpose 1: SDK does not send IDFA/AAID; bid requests are anonymous.

  • GDPR, consent given for Purpose 1: SDK sends IDFA/AAID normally.

  • Invalid or undefined consent: SDK defaults to not sending any ID unless gdprApplies is explicitly false.

✅ To comply with GDPR:

  1. Initialize the CMP at app launch, before requesting ads.

  2. Ensure the TC String is stored locally (NSUserDefaults / SharedPreferences) before initializing Prebid or calling fetchDemand().

circle-info

Once consent is obtained (or updated during session), Prebid automatically uses the latest value for the next bid request. If consent changes, trigger an update (e.g. re-run fetchDemand or recreate the AdUnit) to reflect new privacy parameters.


ATT (iOS only)

On iOS 14+, AppTrackingTransparency (ATT) requires explicit user permission to access IDFA. This directly impacts Prebid: if the user denies tracking, IDFA won’t be available or sent to partners.

Scenarios:

  • Authorized: App has ATT permission → Prebid SDK retrieves IDFA via AdSupport and includes it in bid requests (unless blocked by GDPR).

  • Denied/Not requested: No IDFA collection possible → Prebid still sends bid request, but without IDFA. Bidders must rely on other signals (IP, context, alternative IDs).

Integration required: Developer must trigger the ATT authorization request via ATTrackingManager.requestTrackingAuthorization at the right moment (often at app launch or before personalized ads). Apple recommends explaining ATT usage to the user before showing the popup.

⚠️ Don’t forget to add NSUserTrackingUsageDescription in Info.plist, otherwise the ATT popup won’t show.


3. 📦 Declaring AdUnits

A Pubstack ad unit represents an ad placement in the app, linked to a bidding configuration on Prebid Server.

Currently, Pubstack supports Banner, Interstitial, and Instream Video formats.


Each Banner AdUnit is defined by:

  • A configId (identifier of the placement configured in Pubstack/Prebid Server).

  • A size (largest standard size the placement can accept).

💡 This size will be the only one injected in the bid request.

Naming rules – pbAdSlot (pubstack_adunit_name):

It is important to clearly name and identify placements. Prebid provides the pbAdSlot field (placement name) to pass the ad unit name to the server. Pubstack uses it to track the adunit_name.

  • Sent in imp.ext.data.pbadslot of the bid request.

  • Stored by Pubstack.

  • Prebid 3.0 also supports GPID (Global Publisher ID) for standardized placement IDs (often GAM code) → adUnit.setGpid("...") on Android / adUnit.gpid = "..." on iOS.

iOS Example

Android Example


Interstitial

Each Interstitial AdUnit is defined by:

  • configId: ad unit name in Pubstack.

  • minWidthPerc & minHeightPerc: % of screen width/height the ad must occupy to qualify as an interstitial.

Example:

  • minWidthPerc=80 → must cover ≥80% of screen width.

  • minHeightPerc=60 → must cover ≥60% of screen height.

As with banners, use clear naming rules:

  • pbAdSlot (pubstack_adunit_name) → sent in imp.ext.data.pbadslot and stored by Pubstack.

  • GPID (optional but recommended) → standardized GAM ad unit ID, sent in imp.gpid.

iOS Example

Android Example


Instream Video (pre-/mid-/post-roll)

Instream video ads are served within video content (pre-roll, mid-roll, or post-roll) using the IMA SDK. Each Instream AdUnit is defined by:

  • A configId (identifier of the placement configured in Pubstack/Prebid Server).

  • A size (video player dimensions, typically 640x480).

  • Video parameters following OpenRTB 2.6 specification.

💡 Instream ads require the Google IMA SDK (Interactive Media Ads) in addition to the standard Prebid and GMA SDKs.

Required video parameters:

Parameter
Value
Description

plcmt

Signals.Plcmt.InStream

Placement type (plcmt=1)

placement

Signals.Placement.InStream

OpenRTB placement

Customizable video parameters:

Parameter
Type
Description

mimes

Array

Supported MIME types (e.g., "video/mp4")

protocols

Array

VAST versions supported

playbackMethod

Array

Auto-play behavior

minDuration

Integer

Minimum ad duration (seconds)

maxDuration

Integer

Maximum ad duration (seconds)

minBitrate

Integer

Minimum bitrate (kbps)

maxBitrate

Integer

Maximum bitrate (kbps)

api

Array

Supported APIs (e.g., OMSDK)

isSkippable

Boolean

Whether the ad can be skipped

startDelay

Enum

Pre-roll, mid-roll, or post-roll position

iOS Example

Android Example

circle-info

All video parameter fields follow the OpenRTB 2.6 specificationarrow-up-right.


4. 🎯 Prebid Fetch & GAM Ad Load

Once the Prebid AdUnit is configured, the flow to display an ad via GAM is:

  1. Prebid auction call → Trigger fetchDemand() on the Prebid AdUnit, passing the GAM ad request object.

  2. GAM Ad Request → GAM SDK sends the request with the ad unit ID + Prebid-enriched targeting.

  3. Creative rendering → If a Prebid line item matches, GAM serves a universal creative (Prebid Universal Creative or cache-based) which retrieves and renders the actual winning ad.

triangle-exclamation

Android Example (Kotlin, GMA SDK 23.6.0+)

Interstitial

iOS Example (Swift, GMA SDK 11.9.0+)

Interstitial

🔎 How it works

  • fetchDemand(): Sends an OpenRTB request to Prebid Server (with size, configId, pbAdSlot/gpid).

  • Prebid Server: Runs the auction across connected SSPs/DSPs and returns the winning bid.

  • Prebid SDK: Adds targeting key-values into the GAM request (bid_bidder, bid_cpm, hb_cache_id, etc.).

  • GAM: Uses these targeting keys to match against Prebid line items. If a Prebid line item wins, GAM serves the universal creative which then fetches and renders the actual winning ad.

triangle-exclamation

Instream Video (via IMA SDK)

The Bidding-Only Instream flow works as follows:

  1. fetchDemand from Prebid to retrieve the winning keywords.

  2. Generate the IMA ad tag URL for GAM using those keywords (Prebid utility).

  3. Load and play the ad via IMA SDK in your video player (pre-/mid-/post-roll).

🍏 iOS Example (Swift, IMA SDK 3.18+)

🤖 Android Example (Kotlin, IMA SDK 3.31+)

triangle-exclamation

🔎 How Instream works

  • fetchDemand(): Sends an OpenRTB request to Prebid Server with video parameters.

  • Prebid Server: Runs the auction across connected SSPs/DSPs and returns the winning VAST URL.

  • IMAUtils: Generates a GAM ad tag URL containing Prebid targeting keys.

  • IMA SDK: Loads the ad tag, GAM matches against Prebid line items, and serves the winning VAST creative.

  • Video Player: Renders the VAST ad at the appropriate position (pre-/mid-/post-roll).

circle-exclamation

5. 🧪 Test & Debug

  • Check Prebid logs for bid responses.

  • Ensure GAM request contains targeting keys (bid_bidder, bid_cpm, etc.).

  • Use Google Ad Inspector for local testing.

Last updated