DAPI requirements

A DAPI ad is a single HTML file that must support the DAPI Protocol. DAPI protocol is a set of functions(resize,getDeviceData etc) and events (adResized,viewableChange etc.) that help integrate any ad in order to be used in the ironSource network.

DAPI related requirements

  • Ads must include within <head> the DAPI script from the implementation step from DAPI protocol
  • Avoid using window.onload since its override the behavior of the DAPI initialization script, instead use window.addEventListener
  • Clicks leading to the store page (Google Play Store, Apple App Store) must use dapi.openStoreUrl() (without parameters)

ironSource Ads DAPI integration

To implement DAPI in your creative, you need to add a specific header and then use DAPI functions and events in a particular order. Make sure that you’ve added your own code where necessary. 

Setup guide

Playable and interactive ads run inside the ironSource SDK via iFrame. Implement the dapi.js inside your HTML code to communicate with the ironSource SDK so that essential information like screen size, ad viewability, send click events, etc.

Implementation

Step 1: Add the following code in the <head> tag:

< script >
	function getScript(e, i) {
		var n = document.createElement("script");
		n.type = "text/javascript", n.async = !0, i && (n.onload = i), n.src = e, document.head.appendChild(n)
	}
function parseMessage(e) {
	var i = e.data,
		n = i.indexOf(DOLLAR_PREFIX + RECEIVE_MSG_PREFIX);
	if (-1 !== n) {
		var t = i.slice(n + 2);
		return getMessageParams(t)
	}
	return {}
}
function getMessageParams(e) {
	var i, n = [],
		t = e.split("/"),
		a = t.length;
	if (-1 === e.indexOf(RECEIVE_MSG_PREFIX)) {
		if (a >= 2 && a % 2 === 0)
			for (i = 0; a > i; i += 2) n[t[i]] = t.length < i + 1 ? null : decodeURIComponent(t[i + 1])
	} else {
		var o = e.split(RECEIVE_MSG_PREFIX);
		void 0 !== o[1] && (n = JSON && JSON.parse(o[1]))
	}
	return n
}
function getDapi(e) {
	var i = parseMessage(e);
	if (!i || i.name === GET_DAPI_URL_MSG_NAME) {
		var n = i.data;
		getScript(n, onDapiReceived)
	}
}
function invokeDapiListeners() {
	for (var e in dapiEventsPool) dapiEventsPool.hasOwnProperty(e) && dapi.addEventListener(e, dapiEventsPool[e])
}
function onDapiReceived() {
	dapi = window.dapi, window.removeEventListener("message", getDapi), invokeDapiListeners()
}
function init() {
	window.dapi.isDemoDapi && (window.parent.postMessage(DOLLAR_PREFIX + SEND_MSG_PREFIX + JSON.stringify({
		state: "getDapiUrl"
	}), "*"), window.addEventListener("message", getDapi, !1))
}
var DOLLAR_PREFIX = "$$",
	RECEIVE_MSG_PREFIX = "DAPI_SERVICE:",
	SEND_MSG_PREFIX = "DAPI_AD:",
	GET_DAPI_URL_MSG_NAME = "connection.getDapiUrl",
	dapiEventsPool = {},
	dapi = window.dapi || {
		isReady: function() {
			return !1
		},
		addEventListener: function(e, i) {
			dapiEventsPool[e] = i
		},
		removeEventListener: function(e) {
			delete dapiEventsPool[e]
		},
		isDemoDapi: !0
	};
init(); </script>

Step 2: Add the code below to know when the DAPI is ready to use

//LOAD the game, but do not start it until the ad is visible
window.addEventListener("load", function(){
  (dapi.isReady()) ? onReadyCallback() : dapi.addEventListener("ready", onReadyCallback); 
   //here you can put other code that not related to presenting any media information - do not play any audio/video/images at this moment
     //use this to prepare your creative to be shown(i.e. do necessary calculations or pre-loads)
});
function onReadyCallback(){
	//no need to listen to this event anymore
	dapi.removeEventListener("ready", onReadyCallback);
      let isAudioEnabled = !!dapi.getAudioVolume();
	if(dapi.isViewable()){
		adVisibleCallback({isViewable: true});
	}
	
      dapi.addEventListener("viewableChange", adVisibleCallback); //this event is used to know when the ad was visible/hidden
	dapi.addEventListener("adResized", adResizeCallback); //this event is used recalculate ad UI items(mostly upon rotation)
      dapi.addEventListener("audioVolumeChange",         audioVolumeChangeCallback); //this event is used to get info about any volume state change
}
function startGame() {
    //start your game here
    var screenSize = dapi.getScreenSize();
    //(add your own code here)
}
function pauseGame() {
    //pause your game here(add your own code here)
}
function adVisibleCallback(event){
	console.log("isViewable " + event.isViewable);
	if (event.isViewable){
		screenSize = dapi.getScreenSize();
		//START or RESUME the ad (add your own code here)
            event.startGame(); //example of function that can be called to start game
	} else {
		//PAUSE the ad and MUTE sounds or DO nothing if creative hasn’t been launched yet (add your own code here)
            event.pauseGame(); //example of function that can be called to pause game
	}
}
function adResizeCallback(event){
	screenSize = event;
	console.log("ad was resized width " + event.width + " height " + event.height);
}
//When user clicks on the download button - use openStoreUrl function
function userClickedDownloadButton(event){
	dapi.openStoreUrl();
}
function audioVolumeChangeCallback(volume){
	let isAudioEnabled = !!volume;
	if (isAudioEnabled){
		//START or turn on the sound(add your own code here)
	} else {
		//PAUSE the turn off the sound(add your own code here)
	}
}

Step 3: Implement the dapi.js API – Methods (if needed)

dapi.isReady

  • Description: Checks if the dapi is ready or not (if not, you shouldn’t use the dapi methods to play and run playable or interactive ads)
  • Pass params: None
  • Return value: Boolean (if ready – will return true, if not ready – false)

dapi.isViewable

  • Description: Returns true if the ad is currently viewable (for example, if the user presses the home button, the ad is not viewable)
  • Pass params: none
  • Return value: boolean (if viewable – will return true, if not – false)

dapi.getScreenSize

  • Description: Returns the exact screen size
  • Pass params: none
  • Return value: object (for example: {width: 200, height: 400})

dapi.openStoreUrl

  • Description: Call this method to direct a user to the app store when a user clicks on the “Install” or “Download” button. This method also tracks and registers a click with a tracking solution
  • Pass params: callback [function] optional, params [object] optional
  • Return value: none

dapi.getAudioVolume

  • Description: Returns the current status of the device audio
  • Pass params: none
  • Return value: int (example 0,100) – 0=mute, 100=sound on

dapi.js API – Events and Listeners

dapi.addEventListener

  • Description: Add event listeners (see list of listeners below)
  • Pass params: eventName [string] mandatory, callback [function] mandatory
  • Return value: none

dapi.removeEventListener

  • Description: Remove event listeners (see list of listeners below)
  • Pass params: eventName [string] mandatory, callback [function] mandatory
  • Return value: none

Events

Add listener to these events:

  • ready – listen to this event to determine when dapi.js is ready and available for use
  • viewableChange – listen to this event to know when the ad was visible/hidden
  • adResized – listen to this event to recalculate ad UI items
  • audioVolumeChange – listen to this event in order to be informed of any volume state change (from mute to sound on and vice versa)

dapi.js API – Notes

  • Listeners – you can add event listeners even before window.onload
  • viewableChange – use this event to know when the ad is actually shown in order to start/pause the game
    • You should load all the assets in the background before the ad is shown, but start the game only when the ad is visible 
    • When the ad isn’t visible (user clicked on the home button/closed the ad), you should pause the game and mute the sound
  • adResized – use this event to know when the screen was resized (e.g Landscape to Portrait)
  • dapi.getScreenSize() – this will return {width: 0, height: 0} while the ad is in the background or hidden. You should use it only when the ad is visible

HTML Example

Use this HTML as an example for a good DAPI implementation:
view-source:https://static.ssacdn.com/demand-creatives/assets/htmls/file-1683279877451.html