Native API Integrations

Supersonic provides the ability to utilize our Offerwall product via ‘Native’ implementations within your application. The document will cover the following:

  1. Product Overview
  2. Overview of the API Cycle
  3. Calling the API
  4. Parsing the Response
  5. Custom Offer Wall implementation Example 

Product Overview

This API offers access to the raw building blocks of the Offerwall to make custom constructions in your application, instead of using our finished product in its pre-defined ad format. This creates a unique ad experience that complements the overall experience of your app.

We recommend using the Native API in the following circumstances:

  1. Custom Offerwall UI
    Ability to control a variety of colors, fonts and background of the Offer Wall.
  2. Special ad appearance and design
    For example, an “App of the day” which is presented in the app’s native look and feel, that will achieve better user targeting and higher user engagement.
  3. Mobile Web integrations
    Your application is not Native and thus cannot use the Supersonic SDK.

Overview of the API Cycle

  1. Access the API to retrieve the available campaigns when you want them for your users.
  2. Parse the returned data object to retrieve the data you will need to construct your Ad experience.
  3. Create the Ad experience for your users utilizing the data points retrieved.
  4. After your users complete the engagements with the presented offers, you will process the completion to grant them their reward. To learn about reward notifications, read our Server-to-Server Callbacks article.

Supersonic Native API Monetization Cycle

Calling the API

To access Supersonic’s Mobile offers, you will call the mobilePanel.php API. Below is the API end-point you will call with its standard format:

http://www.supersonicads.com/delivery/mobilePanel.php?nativeAd=1&format=json&applicationUserId=[USER_ID]&applicationKey=[APP_KEY]&deviceOs=[DEVICE_OS]&deviceIds[TYPE]=[DEVICE_ID]&isLimitAdTrackingEnabled=[true/false]&deviceOSVersion=[osVersion]

Mandatory Parameters

The table below lists the mandatory parameters which must be passed as part of the API request.

Name Description Examples / Notes
applicationKey Your applications unique key from your Supersonic Admin applicationKey=31kj3hkj
applicationUserId Your end-users unique identifier [USER_ID] must be URL-encoded (for example, “123%40abc.com” rather than “123@abc.com”).
format The data format of the API’s response Our default returned format is HTML. You can add “&format=xml” or “&format=json” in order to achieve the result in XML or JSON format. To allow this usage, you should contact your Account Manager. Without the format parameter (or with&format=html value) the response will result with Supersonics default HTML and CSS.
nativeAd=1 Marker to specify Native Ad Implementations This identified returns or newer formatted response with better data values to use in your implementation. Make sure with your Account Manager that usage of xml/json is allowed, as noted in the ‘format‘ parameter above.
deviceOs=[DEVICE_OS] The OS of the users Device [DEVICE_OS] should be either “ios” or “android”
deviceIds[TYPE]=[DEVICE_ID] The Type of deviceID being passed from the users phone

[TYPE] should be either IFA for iOS or AID for Android.

Example – iOS: &deviceIds[IFA]=AAA-BBB-111-222-CCC

Example – Android: &deviceIds[AID]=DDD-EEE-111-222-CCC

[DEVICE_ID] The actual ID of the deviceID [DEVICE_ID] – The device ID value. Apple support IFA while Android support AID. The IFA should be taken from ASIdentifierManager class, the AID should be taken from the AdvertisingIdClient.Info class.
isLimitAdTrackingEnabled=[true/false] The user’s ad tracking limitation state isLimitAdTrackingEnabled=[true/false] – the limit ad tracking state should be taken from Google API AdvertisingIdClient.Info class for Android devices or ASIdentifierManager class for iOS devices.
deviceOSVersion=[osVersion] The operating system version of the device

The OS Version should be the API version for Android, and the string version for iOS.

Example – Android: deviceOSVersion=22

Example – iOS: deviceOSVersion = 9.2

Optional Parameters:

The table below lists the optional parameters which can be passed as part of the API request.

Name Description Examples \ Notes
pageSize Number of offers to serve on a single page Example: pageSize=1 – Recommended to be used with ‘Deal of the Day’ integration.
page Used to create pagination – which requires a special UI – “Next Page” page=3
applicationUserCreationDate The date in which the user has created his/her account. Important for Supersonic Fraud Control

applicationUserCreationDate=2011-12-01

Must be in the yyyy-mm-dd format.

Should be used in addition toapplicationUserCreationDateSignature

applicationUserCreationDateSignature The md5 hashing of the following strings: [applicationUserId][applicationUserCreationDate][applicationPrivateKey]

Must be used with the ‘applicationUserCreationDate’

applicationUserCreationDateSignature=e9fa940eb5f3b889f3ec98913b2acd0e

Used with applicationUserCreationDate

scope Used to present a customer support page “Missing currency” instead of Offer Wall scope=999
currencyName Specifies an alternative currency name (possibly other than what has been predefined) currencyName=Gems
language Force specific language for the static texts

language=es

Pass the standard 2 characters ISO code for languages. Please note that the offers themselves may still be presented in the language which is relevant for the target country

ip

Control the country (user will see offers bases on the the ip address).(valid only for server API integ.)

*Contact your Account Manager if you plan to use this parameter*

ip= 61.198.213.83

Requires to use accessKey and secretKey parameters (their values can be found in the Setup | API form).

mobileCarrier The service carrier of the users device mobileCarrier=Vodafone
deviceModel The model of the users device deviceModel=GT-S5360
deviceOEM The manufacturer of the users device deviceOEM=samsung
location The location of the users device the user’s location according to the device’s GPS, using the format latitude,longitude.location=8.620794,52.3724269
suppressStatistics Suppress any statistic counting for this impression suppressStatistics=1This option can be used if you wish to test your production app/site without having any influence on the aggregated statistics
applicationUserGender Used to improve Targeting

applicationUserGender=male

Possible values: male; female

Default: unknown

applicationUserBirthday Used to improve Targeting

applicationUserBirthday=1982-03-27Used to improve Targeting

Values:
0: Unknown
1: 13-17
2: 18-20
3: 21-24
4: 25-34
5: 35-44
6: 45-54
7: 55-64
8: 65+

Custom Parameters Used for internal segmentation Custom_[ParameterName]=[ParameterValue]
Example: Custom_Gender=Female

Parsing the Response

Once you call the API, the server will respond with all available campaigns according to the request format. For example a JSON / XML response will be as follows:

JSON

Supersonic Native API Monetization Parse response with JSON

XML

Supersonic Native API Monetization Parse response with XML

At this stage you will want to parse out the necessary data from the response to use in your Ad Unit.

We recommend utilizing the following data points to construct the Ad Unit:

  • Offer Name
  • Credit Amount
  • ClickURL
  • Offer Icon

 

The entire response includes:

Key name Description
offerId The ID of the delivered campaign
bundleId * For App-Install offers* The unique identifier of the app in the store
rewards The reward that the user will receive upon completing the offer
rewardsText The text that will state the name of the reward (Gems, etc.)
userFlow The type of the offer: Install, Sign-in etc.
callToAction The action required from the user to get rewarded
title The name of the application
creatives > creativeId Identification of the campaigns’ specific entity in SSA server (bannerID, it differs from offerID)
creatives > url The dynamic URL that redirects the user to the app
creatives > image An icon of the promoted app (114×114 or 125×125)

Custom Offerwall Implementation Example

Here is an example of a publisher who created their own Offerwall utilizing the Native API and designed their own implementation native to the look and feel of their application:

Supersonic Native API Monetization Example

‘Deal of the Day’ Integration Example

The most highly recommended implementation of the Native API is the ‘Deal of the Day’ Ad Unit. This unit is highly effective in converting users and driving significant daily revenue. This entails promoting a single offer each day to the user in unique placements within the application. The user is highly incentivized to complete the daily special offer to take advantage of a time-sensitive opportunity. Creating this type of implementation is easy with the Native API.

To begin:

  1. Call the Native API adding in the optional ‘pageSize=1‘ parameter to the request. This will ensure you get only the top offers available returned in the response.
  2. See the below code example for how to implement this into a Native iOS/Android application.

 

Best practices for using the ‘Deal of the Day’ Ad Unit include utilizing the following returned keys:

Key Name Description
rewards The reward that the user will receive upon completing the offer
creative/ title The name of the offer
creative/ url The dynamic URL that redirects the user to the offers landing page
creative/ image / url An icon of the promoted offer (114×114 or 125×125)

Code Example

public class Supersonic {
    public static class Image {
        int width;
        int height;
        String url;
    }
    public static class Creative {
        String creativeId;
        String title;
        String description;
        String url;
        Image image;
    }
    public static class Offer {
        int offerId;
        String bundleId;
        int rewards;
        String rewardsText;
        String disclaimer;
        Creative[] creatives;
    }
    public static class Response {
        InnerResponse response;
    }
    public static class InnerResponse {
        int errorCode;
        String errorMessage;
        int items;
        int total;
        Offer[] offers;
    }
    private String buildRequestWithParamters(Context context, String applicationKey,
                                          String applicationUserId, Location location, Map<String, String> extraParameters) {
        DeviceProperties deviceProperties = DeviceProperties.getInstance(context);
        // builds the query:
        StringBuilder requestParameters = new StringBuilder();
        if (applicationUserId != null && applicationUserId.length() > 0) {
            requestParameters.append("applicationUserId=").append(applicationUserId);
        }
        if (applicationKey != null && applicationKey.length() > 0) {
            requestParameters.append("&applicationKey=").append(applicationKey);
        }
        requestParameters.append("&deviceOEM=").append(deviceProperties.getDeviceOem());
        requestParameters.append("&deviceModel=").append(deviceProperties.getDeviceModel());
        for (String deviceIdType : deviceProperties.getDeviceIds().keySet()) {
            requestParameters.append("&deviceIds[").append(deviceIdType).append("]=")
                    .append(deviceProperties.getDeviceIds().get(deviceIdType));
        }
        requestParameters.append("&deviceOs=").append(deviceProperties.getDeviceOsType());
        requestParameters.append("&deviceOSVersion=").append(Integer.toString(deviceProperties.getDeviceOsVersion()));
        // optional:
        if (deviceProperties.getDeviceCarrier() != null && deviceProperties.getDeviceCarrier().length() > 0) {
            requestParameters.append("&mobileCarrier=").append(deviceProperties.getDeviceCarrier());
        }
        if (location != null) {
            requestParameters.append("&location=").append(location.getLongitude())
                    .append(",").append(location.getLatitude());
        }
        if (extraParameters != null && extraParameters.size() > 0) {
            for (Map.Entry<String, String> entry : extraParameters.entrySet()) {
                requestParameters.append("&").append(entry.getKey()).append("=").append(entry.getValue());
            }
        }
        return requestParameters.toString().replace(" ", "%20");
    }
    public String buildUrl(Context context, String userId, String referrer) {
        Location l = LocationUpdater.getInstance().getCurrentLocation();
        HashMap<String, String> params = new HashMap<>();
        params.put("format", "json");
        params.put("currencyName", context.getString(R.string.earn_vip_hours));
        params.put("language", Locale.getDefault().getLanguage());
        if (referrer != null) {
            params.put("custom_referrer", referrer);
        }
        return "http://www.supersonicads.com/delivery/mobilePanel.php?" + buildRequestWithParamters(context, "3906547d", userId, l, params);
    }
    public interface AotdLoadedListener {
        public void onAotdLoaded(Offer offer);
    }
    public void loadAppOfTheDay(final Context context, final AotdLoadedListener listener, final String referrer) {
        Me.get(new Me.MeLoadedListener() {
            @Override
            public void onMeLoaded(User me) {
                String url = buildUrl(context, me.getId() + "", referrer);
                JQuery.i("AOTD: Load from " + url);
                JQuery aq = new JQuery(context);
                aq.ajax(url, String.class, new Network.GsonCallback(Response.class) {
                    @Override
                    public void onSuccess(Response result) {
                        if (result.response.errorCode == 0 && result.response.offers.length > 0) {
                            listener.onAotdLoaded(result.response.offers[0]);
                        }
                    }
                    @Override
                    protected void onCheckFailed(String url, String response, AjaxStatus status) {
                        super.onCheckFailed(url, response, status);
                        JQuery.i("AOTD: Failed to load " + status.getError());
                    }
                    @Override
                    protected void onRequestFinished() {
                        super.onRequestFinished();
                    }
                });
            }
        });
    }
    public interface AotdViewLoadedListener {
        public void onAotdViewLoaded(View view);
    }
    public void loadAotdInto(final JaumoActivity activity, final ViewGroup parent, final AotdViewLoadedListener listener, String referrer) {
        loadAppOfTheDay(activity, new AotdLoadedListener() {
            @Override
            public void onAotdLoaded(Offer offer) {
                if (offer.creatives.length > 0) {
                    final Creative c = offer.creatives[0];
                    View v = activity.getLayoutInflater().inflate(R.layout.ad_aotd, parent, false);
                    JQuery q = new JQuery(v);
                    q.id(R.id.cadHeadline).text(Html.fromHtml(c.title));
                    q.id(R.id.cadBody).text(Html.fromHtml(c.description));
                    q.id(R.id.cadLogo).image(c.image.url);
                    q.id(R.id.cadButton).text(R.string.aotd_cta, offer.rewards);
                    q.id(R.id.cad).text(R.string.aotd_cta, offer.rewards)
                            .clicked(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    activity.openUrl(c.url);
                                }
                            });
                    listener.onAotdViewLoaded(v);
                }
            }
        }, referrer);
    }
}