Rewarded Video Ads

Overview

Rewarded video ads are a great way to keep users engaged in your app while earning ad revenue. The reward generally comes in the form of in-game currency (gold, coins, power-ups, etc.) and is distributed to the user after a successful video completion.

MoPub’s mediation solution officially supports rewarded videos from popular ad networks without any extra integration with network SDKs. We recommend placing rewarded video ads where your users are already engaging with in-app purchases or in locations where users may be seeking an in-app rewards, such as at the end of a game level or at currency redemption points. Once your user has completed the rewarded experience, you can designate the reward they will receive.

Prerequisites

Before integrating rewarded video ads in your app, you must:

Basic Integration

Important: Please do not use publisher-provided overlays (such as close buttons) that are located with the ad placement and that subsequently cover the ad creative. Doing so is against MoPub Policy. If you have questions, please reach out to your account team or support@mopub.com for additional assistance.

Step 1. Initialize the MoPub SDK

Initialize the MoPub SDK on app launch. Typically this is done in your Activity’s onCreate() method. Note: If you have been using the MoPubRewardedVideos.initializeRewardedVideo() API, it is deprecated starting with MoPub SDK v5.0.0, so be sure to use the new initialization API.

It’s not necessary to explicitly initialize any mediated rewarded video network SDKs via their APIs; the MoPub SDK handles that logic on your behalf.

Step 2. Request and Cache the Rewarded Video

Cache a rewarded video for a given ad unit ID (often a placement within the app; for example, a game-over screen or in-app store):

MoPubRewardedVideos.loadRewardedVideo("YOUR_AD_UNIT_ID");

Step 3. Show the Rewarded Video

Check if the rewarded video has been fully cached by calling MoPubRewardedVideos.hasRewardedVideo(String adUnitId) before offering to play it to the user.

Show the rewarded video when the user clicks to watch it:

MoPubRewardedVideos.showRewardedVideo("YOUR_AD_UNIT_ID");

Step 4. Configure the Callback Server

Your callback server must return a 200 HTTP response status code when it successfully receives the reward callback. If your server returns a 500 HTTP response status code, MoPub will continually call the server at increasing intervals until your server returns a 200 HTTP code or the maximum retry limit of 14 is reached. The maximum retry limit is subjected to a two-hour time limit. MoPub stops the retries when your server returns a 200 HTTP response status code.

HTTP Response Code Description When Used
200 Successful Request Return this response code for a successful callback
500 Internal Server Error Return this response code when a callback server error occurs

If any other HTTP response status code is returned, MoPub logs the response and does not retry.

If the MoPub server detects a failure to connect, it may retry, to ensure that your server receives callbacks. Because of this, there is a slight possibility that your callback server may receive duplicate callbacks (from the same callback URL, for the same rewarded video). We recommend that you store the hash ID (the value from the %%VERIFIER%% macro) and only give a user one reward for each unique ID.

To secure the callback sent from MoPub to your callback server, the %%VERIFIER%% macro must be present in the callback URL. The %%VERIFIER%% is a SHA256 hash generated from the callback’s parameter values and uses a Secret Key. You can find the Callback Secret Key in the MoPub UI Account Settings page.

Your server should use the Callback Secret Key to regenerate the SHA256 hash from the callback’s parameter values. If the hash generated on your server matches the one in the callback sent by MoPub, this signals that the callback is valid and the user should be rewarded.

To generate the hash on the reward server:

Step Example
1. Parse the callback URL and retrieve the query parameters. Callback URL: https://api.example.com/callback.php?customer_id=3453523454&id=70bae1905f7844a3a012a5f4173021db&hash=28f3b28b09b2578db06ee371990b5a02882523eba954d5a1b57afe2c7e7d3f10&value=20&type=Coins
2. Drop the verifier key and value from the array of parameters. Verifier Hash: hash=28f3b28b09b2578db06ee371990b5a02882523eba954d5a1b57afe2c7e7d3f10
3. Sort the query parameters alphabetically. Alphabetical array of query parameters (excluding the verifier)
* customer_id=3453523454
* id=70bae1905f7844a3a012a5f4173021db
* type=Coins
* value=20
4. Concatenate the values in that alphabetical order. Concatenated String: 345352345470bae1905f7844a3a012a5f4173021dbCoins20
5. Hash the concatenated string using a HMAC SHA256 hash algorithm and the Callback Secret Key. HMAC SHA256 the concatenated string and the Secret Key: 7dbcfd2a42134f47bfb72daa02f85ec9
* The result: 28f3b28b09b2578db06ee371990b5a02882523eba954d5a1b57afe2c7e7d3f10
* The result matches the hash passed in the request

After generating the hash, compare the received hash with your generated hash. They should be identical. Once the hash is verified, your server must return a 200 response code to MoPub and can reward the user.

Refer to our list of available server-side callback macros.

Step 5. Optionally Implement Lifecycle Callbacks

Network SDKs need to be notified of changes in the activity lifecycle so they can keep track of the current activity and load and show rewarded videos. For example, you can add lifecycle callbacks to all of your activities (including your Launcher Activity) that will load or show rewarded videos.

For Mediation SDKs that track Activity lifecycle events, you must notify MoPub when those events happen, so that MoPub can pass them onto mediated network SDKs, as shown:

    @Override
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       MoPub.onCreate(this);
       // ...
    }

    @Override
    public void onPause() {
        super.onPause();
        MoPub.onPause(this);
    }

    @Override
    public void onStop() {
        super.onStop();
        MoPub.onStop(this);
    }

    @Override
    public void onResume() {
        super.onResume();
        MoPub.onResume(this);
    }

    // Additional lifecycle events

    // The following methods are required for Chartboost rewarded video mediation
    @Override
    public void onStart() {
        super.onStart();
        MoPub.onStart(this);
    }

    @Override
    public void onRestart() {
        super.onRestart();
        MoPub.onRestart(this);
    }

    @Override
    public void onStop() {
        super.onStop();
        MoPub.onStop(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        MoPub.onDestroy(this);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        MoPub.onBackPressed(this);
    }

Step 6. Optionally Set a Rewarded Video Listener

You can set a rewarded video listener to receive relevant callbacks:

public class MainActivity extends Activity {
    private MoPubRewardedVideoListener rewardedVideoListener;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        MoPub.onCreate(this);

        rewardedVideoListener = new MoPubRewardedVideoListener() {
            @Override
            public void onRewardedVideoLoadSuccess(String adUnitId) {
                // Called when the video for the given adUnitId has loaded. At this point you should be able to call MoPubRewardedVideos.showRewardedVideo(String) to show the video.
            }
            @Override
            public void onRewardedVideoLoadFailure(String adUnitId, MoPubErrorCode errorCode) {
                // Called when a video fails to load for the given adUnitId. The provided error code will provide more insight into the reason for the failure to load.
            }

            @Override
            public void onRewardedVideoStarted(String adUnitId) {
                // Called when a rewarded video starts playing.
            }

            @Override
            public void onRewardedVideoPlaybackError(String adUnitId, MoPubErrorCode errorCode) {
                //  Called when there is an error during video playback.
            }

            @Override
            public void onRewardedVideoClicked(@NonNull String adUnitId) {
                //  Called when a rewarded video is clicked.
            }

            @Override
            public void onRewardedVideoClosed(String adUnitId) {
                // Called when a rewarded video is closed. At this point your application should resume.
            }

            @Override
            public void onRewardedVideoCompleted(Set<String> adUnitIds, MoPubReward reward) {
                // Called when a rewarded video is completed and the user should be rewarded.
                // You can query the reward object with boolean isSuccessful(), String getLabel(), and int getAmount().
            }
        };

        MoPubRewardedVideos.setRewardedVideoListener(rewardedVideoListener);
    }
}

Advanced Use Cases

Advanced use cases include:

Mediation Settings

Mediation settings enable you to pass in third-party network specific settings and can be provided as additional parameters during the rewarded video initialization call. For Vungle, during Unity and Chartboost mediation, this is the only mechanism by which a user ID or customer ID can be specified in networks’ server-side callbacks.

Each subclass of CustomEventRewardedVideo specifies its own implementation of mediation settings with its own constructor. For instructions on how to pass in your mediation settings, follow these directions when you initialize the MoPub SDK.

Mediated Network Pre-Initialization

Passing in a list of rewarded video network classes that extend from CustomEventRewardedVideo triggers an attempt to pre-initialize those rewarded networks, in the order that they are passed, with the initialization parameters last cached for each network. If no cached initialization parameters are found for a network, pre-initialization for that network is skipped.

Pre-initializing the network SDKs provides the network with the necessary lead time between SDK initialization and ad request to ensure a successful ad request. Every successful call to MoPubRewardedVideo.loadRewardedVideo() updates the initialization parameters in the cache for that network.

To use the rewarded video pre-initialization API, follow the instructions when you initialize the MoPub SDK. To opt out of the pre-initialization API, simply pass in an empty list.

Note: You can combine the existing on-demand network SDK initialization with this partial pre-initialization call.

Passing Custom Data

There may be cases where your reward server needs additional information to determine an appropriate reward for the user. When the rewarded video is presented, the app can call MoPubRewardedVideos.showRewardedVideo(String adUnitId, String customData), where the second parameter is an optional string containing custom data. The optional custom data is sent as part of the URL in the server-to-server callback.

Considerations:

  • We recommended that the custom data String not exceed 8kb in size because this will significantly degrade performance. Try to keep the custom data payload as small as possible.

  • Custom data is only passed if the ad unit has been set up for server-side callbacks.

  • In addition to specifying the custom data at presentation time, the server-side callback URL in the MoPub UI must also include a query parameter that uses the %%CUSTOM_DATA%% macro. For example:

       https://www.your.com/reward?custom_data=%%CUSTOM_DATA%%
    

Known Limitations

  • Reward type must be in English only. We do not currently support localized characters.

  • At this time, we do not support concurrent ad requests using the same ad unit ID.

Last updated November 18, 2020

TWITTER, MOPUB, and the Bird logo are trademarks of Twitter, Inc. or its affiliates. All third party logos and trademarks included are the property of their respective owners.

© 2020 MoPub (a division of Twitter, Inc.)