- Prerequisites
- Installation
- Insert the Teads parameters in the bid request
- Teads bid response
- Ad rendering & Ad listeners
- Ad Resizing
- Ad Formats
- AdPlacementSettings & AdRequestSettings
- Prebid Server setup
- Check list
This article shows you how to deliver Teads ads on your application using a standalone Prebid integration where you don't use the official Prebid SDK but you do have your own integration with a Prebid Server.
This integration requires you to integrate the Teads Adapter on server side and the Teads SDK on mobile side as well.
Teads SDK is still relevant in this sort of integration since the Teads Prebid Adapter will serve non-standard demand which requires a dedicated player.
Sample Teads App on GitHub
Teads inApp SDK Sample App
Prerequisites
Installation
Gradle
project/build.gradle
allprojects {
repositories {
...
maven { url "https://teads.jfrog.io/artifactory/SDKAndroid-maven-prod" }
}
}
app/build.gradle
dependencies {
...
// Teads inApp SDK
implementation("tv.teads.sdk.android:sdk:5.1.x@aar") { // or higher
transitive = true
}
}
Insert the Teads parameters in the bid request
Teads needs additional parameters in the bid request in order to process the bidding on its adapter.
Below you can see the part of the bid request JSON that concerns these additional parameters while other parts are omitted.
{
"imp":*,
"ext": {
"prebid": {
"sdk": {
"renderers": [
{
"name": "teads",
"version": "5.1.0",
"data": {
"extra1": true,
"extra2": "189"
}
}
]
}
}
}
}
Notice that such values are not static and you must retrieve it with the Teads SDK and embed the content in the node ext.prebid.sdk
by yourself.
So in order to retrieve such values use the PrebidAdPlacement
class as below. Do it at least once per app session.
import tv.teads.sdk.PrebidAdPlacement
import tv.teads.sdk.AdPlacementSettings
import tv.teads.sdk.AdRequestSettings
import tv.teads.sdk.TeadsSDK
val adRequestSettings = AdRequestSettings.Builder().build()
val adPlacementSettings = AdPlacementSettings.Builder()
.pageSlotUrl("http://your.url.com") // Ensure to inform your article url or domain url for brand safety matters
.addExtra(AdPlacementExtraKey.STANDALONE_PREBID_INTEGRATION, "1") // Add this extra to enable your standalone integration
.build()
val prebidAdPlacement = TeadsSDK.createPrebidPlacement(
context = this,
placementSettings = adPlacementSettings
)
prebidAdPlacement.getPrebidRequestData(
adRequestSettings = adRequestSettings,
onComplete = { result ->
// result is a JSONObject with the renderers list, see a sample below
// e.g. {"renderers":[{"name":"teads","version":"5.1.0","data":{"extra2":"189","extra1":true}}]}
}
)
Teads bid response
See below a simplified sample about what would be the bid response once Teads win the auction with the data that characterizes Teads as the winner of the auction:
{
"id": "f34bbf12-18c8-463d-80f1-1eba20e8f4bf",
"seatbid": [
{
"seat": "teads",
"bid": [
{
"id": "imp-video-300x250",
"impid": "f34bbf12-18c8-463d-80f1-1eba20e8f4bf",
"price": 3.91,
"nurl": "https://dummy.nurl.teads.tv",
"adm": "<html><body><p>Dummy creative content</p></body></html>",
"adid": "625187",
"adomain": ["teads.com"],
"cid": "1088501",
"crid": "625187",
"cat": ["IAB12"],
"ext": {
"prebid": {
"meta": {
"rendererName": "teads",
"rendererVersion": "5.1.4"
},
"targeting": {
"hb_pb": "3.91",
"hb_bidder": "teads"
}
}
},
"h": 250,
"w": 300
}
]
}
],
"cur": "USD"
}
Ad rendering & Ad listeners
Once Teads win the auction, delegate the ad rendering to Teads SDK by passing to it the winning bid response and subscribe to the ad lifecycle as below.
See that an instance of AdRequestSettings
is necessary with the key AdPlacementExtraKey.STANDALONE_PREBID_INTEGRATION
with value "1"
to enable this sort of integration.
import tv.teads.sdk.PrebidAdPlacement
import tv.teads.sdk.InReadAdModelListener
import tv.teads.sdk.AdPlacementSettings
import tv.teads.sdk.AdRequestSettings
import tv.teads.sdk.TeadsSDK
class PrebidCustomIntegrationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val adRequestSettings = AdPlacementSettings.Builder()
.pageSlotUrl("http://your.url.com") // Ensure to inform your article url or domain url for brand safety matters
.addExtra(AdPlacementExtraKey.STANDALONE_PREBID_INTEGRATION, "1") // Add this extra to enable your standalone integration
.build()
val adPlacementSettings = AdPlacementSettings.Builder().build()
val prebidAdPlacement = TeadsSDK.createPrebidPlacement(
context = this,
placementSettings = adPlacementSettings
)
// Implement the ad listener
val inReadAdModelListener = object : InReadAdModelListener {
override fun onAdReceived(ad: InReadAd, adRatio: AdRatio) {
// The ad model is received, bind it to your inReadAdView
binding.inReadAdView.bind(ad)
}
// Add the tracker view to the view group that encapsulates your inReadAdView
override fun adOpportunityTrackerView(trackerView: AdOpportunityTrackerView) {
binding.containerAdView.addView(trackerView)
}
// Resize the ad container view
override fun onAdRatioUpdate(adRatio: AdRatio) {
val layoutParams = binding.inReadAdView.layoutParams
layoutParams.height = adRatio.calculateHeight(binding.containerAdView.measuredWidth)
binding.containerAdView.layoutParams = layoutParams
}
// Implement the following callbacks as you want
override fun onAdImpression() {}
override fun onAdClicked() {}
override fun onAdError(code: Int, description: String) {}
override fun onAdClosed() {}
override fun onAdExpandedToFullscreen() {}
override fun onAdCollapsedFromFullscreen() {}
override fun onFailToReceiveAd(failReason: String) {}
}
// Finally load the ad
prebidAdPlacement.loadAd(
adResponse = stringfiedWinningBidJSON, // insert here your winning bid JSON received from your prebid server
adRequestSettings = adRequestSettings,
inReadBaseListener = inReadAdModelListener,
videoPlaybackListener = null // add a VideoPlaybackListener if you want to listen video events
)
}
}
Layout sample.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/containerAdView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<tv.teads.sdk.renderer.InReadAdView
android:id="@+id/inReadAdView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Ad Resizing
This part is a must and not implementing it will drastically affect the fill rate from Teads demand.
Having the ad creative correctly rendered is crucial to ensure great user experience and good performance measurement.
Allowed by VPAID standard; ads can adopt modular dimensions and ratio in place of pre-defined fixed sizes making necessary to be able to dynamically adapt the size and ratio of the ad view depending on the loaded creative.
Even though resize requests occur generally in the ad initialisation steps, it is necessary to be able to satisfy them all along the ad experience.
No action is required if the height constraint of the ad view (and its parent) is set to "wrap_content". The ad View will natively adapt to the requested ratio.
In the other case, it is mandatory to programmatically adapt the size of the Ad container.
The Teads inApp SDK will notify you each resize request coming from the creative.AdRatio contains all information to calculate the corresponding height for the requested width.
Use calculateHeight to ease the calculation.
As showed before, see the sample below where the containerAdView
is the view group that encapsulates your InReadAdView
import tv.teads.sdk.InReadAdModelListener
val inReadAdModelListener = object : InReadAdModelListener {
...
// Resize the ad container view
override fun onAdRatioUpdate(adRatio: AdRatio) {
val layoutParams = binding.inReadAdView.layoutParams
layoutParams.height = adRatio.calculateHeight(binding.containerAdView.measuredWidth)
binding.containerAdView.layoutParams = layoutParams
}
...
}
Ad Formats
Currently this integrations supports InRead
only.
ℹ️ Notice that InRead could serve image and video as well.
AdPlacementSettings & AdRequestSettings
Find the full settings list here
Prebid Server setup
Notice that in order to turn your Standalone integration fully functional and leverage from Teads demand you need to wire the Teads Adapter to your Prebid Server, please find more here.
The following configuration for each of your ad slots name is required:
{
"name": "imp-300x250-banner"
}
A placement id provided by your publisher manager is required as the sample below:
{
"ext": {
"teads": {
"placementId": 204344
}
}
}
Check list
- ✅ Insert the Teads parameters in the bid request
- ✅ Load your ad by informing the winning bid JSON
- ✅ Subscribe to the event listeners
- ✅ Implement ad view resizing
- ✅ Setup your Prebid Server with the Teads Adapter
- ✅ Ensure Brand Safety is enabled
- ✅ Ensure you comply with privacy legal requirements (GDPR/CCPA/GPP)
- ✅ Comply with app-ads.txt