Introduction

The XAPP Creatives API provides a set of RESTful endpoints for creating and retrieving information related to a XAPP. Access to the service is limited through a Publisher Token that can be obtained from XAPPmedia. Every request made to an endpoint should include the token as a header parameter under the name X-SDK-Auth-Token. Without this information, the service will reject any request with a HTTP Status Code of 403.

Currently, the service provides the following endpoints:

# Retrieve all accounts for a publisher
GET         /api/v1/accounts

# Retrieve all the phrases for a publisher
GET         /api/v1/phrases

# Retrive all the XAPPs for a publisher
GET         /api/v1/xapps

# Retrieve specific XAPP
GET         /api/v1/xapps/:xappId

# Retrieve actions for a XAPP
GET         /api/v1/xapps/:xappId/actions

# Get the enabled status for a XAPP
GET         /api/v1/xapps/:xappId/enable

# Delete a XAPP
DELETE      /api/v1/xapps/:xappId

# Enable a XAPP
PUT         /api/v1/xapps/:xappId/enable

# Disable a XAPP
DELETE      /api/v1/xapps/:xappId/enable

# Create a new XAPP. This endpoint accepts a JSON payload or a
# x-www-form-urlencoded payload
POST       /api/v1/xapps

# Create a new XAPP. This endpoint accepts a multi-part/form upload
POST       /api/v1/func/xapps

# Create a new Account. This endpoint accepts a JSON payload or a
# x-www-form-urlencoded payload
POST       /api/v1/accounts

# Update an account. This endpoint accepts a JSON payload or a
# x-www-form-urlencoded payload
PUT       /api/v1/accounts/:accountId

# Delete an Account. Does not need any payload.
DELETE   /api/v1/accounts/:accountId

For all the operations, the Publisher information is encoded in the token that is sent with every request. The response from the service is of type application/json;utf-8 and hence the endpoints can be accessed programatically using any language of your choice as long as the JSON payload can be parsed appropriately or through tools such as Postman, Soap UI, etc…

Accessing the Endpoints

In this section, we will provide example code snippets for accessing the XAPP Rest API using Java programming language. The examples use UniRest HTTP library. You can use any other HTTP library for Java. Please consult the appropriate documentations for those libraries.

In all the following discussions, baseUrl is assumed to be of the form:

http://host:port/api/v1/{endpoint}

where {endpoint} will be replaced with the actual resource endpoint as you will see shortly in the examples.

When accessing any of the aforementioned service endpoints, the service will either return the requested data assuming everything went well with the request or it will return an appropriate ErrorResponse data. Hence, when parsing the response, we have to handle both cases. In the code examples that follow, we will define methods that return object of type Pair. A pair, as the document indicates, consists of two elements: the left element, if present will contain the data you requested through the endpoint and the right element, if present indicates the ErrorResponse sent by the API service. Only one element will be non-null.

Utility Method For JSON to Object Conversion

The following utility methods can be used to parse the JSON response received from the API service. As indicated in the previous section, the response from the API service can be either the requested data or an error response data. So, given the response string received from the service, these methods will convert the received payload into a appropriate data model or ErrorResponse object.


import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.ImmutablePair;
import com.xappmedia.creative.model.error.ErrorResponse;

private ObjectMapper mapper = new ObjectMapper()
                .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                .enable(SerializationFeature.EAGER_SERIALIZER_FETCH);

/**
 * Create ErrorResponse from the given aValue
 *
 * @param aValue A JSON response
 *
 * @returns ErrorResponse
 *
 */
private ErrorResponse getError(String aValue) {

        ErrorResponse error = null;

        if (aValue == null) return error;

        try {
            error = mapper.readValue(aValue, ErrorResponse.class);
        } catch (IOException e) {
            error = null;
        }

        if (error != null && error.getStatusCode() == null) {
            error = null;
        }

        return error;
    }

    /**
     * Create the model from JSON String
     *
     * @param aValue Response databind
     * @param type Model type
     *
     * @returns Pair<T, ErrorResponse>
     *           If everything went well, the left object will have the actual
     *           model data. In case of error, the right object will have the
     *           ErrorResponse object
     *
     */
    private <T> Pair<T, ErrorResponse> createModel(String aValue, Class<T> type) {

        T rv;

        ErrorResponse error = null;

        try {
            rv = mapper.readValue(aValue, type);
            error = mapper.readValue(aValue, ErrorResponse.class);
        } catch (IOException e) {
            rv = null;
            try {
                error = mapper.readValue(aValue, ErrorResponse.class);
            } catch (IOException e1) {
                error = null;
            }

        }

        if (error != null && error.getStatusCode() == null) {
            error = null;
        }

        return ImmutablePair.of(rv, error);
    }

Generic Method for API Service Resource Retrievals

The following method defines a generic method for retrieving data from the API service. The method requires two parameters: an resourceName string representing the resource to retrieve and a dataType representing the retuned data model type.


import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.tuple.Pair;
import com.xappmedia.creative.model.error.ErrorResponse;

   /**
    * This method retrieves data for a specific resource as
    * indicated by the endpoint parameter and returns the
    * result as appropriate data model object as indicated
    * by the dataType parameters
    *
    * @param resourceName Resource name
    * @param dataType Data type
    *
    * @returns Pair<T, ErrorResponse>
    *           If everything went well, the left object will have the actual
    *           model data. In case of error, the right object will have the
    *           ErrorResponse object
    */

   public <T> Pair<T, ErrorResponse> getData(String resourceName, Class<T> dataType) {

        Pair<T, ErrorResponse> rv = null;

        try {

            HttpResponse<String> response = Unirest.get(this.baseUrl)
                    .routeParam("endpoint", resourceName)
                    // Must include this with every request
                    .header("X-SDK-Auth-Token", this.publisherToken)
                    .asString();

            // Invoke the utility method for parsing the response
            rv = this.createModel(response.getBody(), dataType);

        } catch (UnirestException e) {
            // Handle the error
        }

        return rv;

    }

For all the data retrieval discussions to follow, we will use this generic method. For each operation, we just need to pass in the appropriate resource name and the data model class type, that is it.

Retrieve a collection of all the Accounts

This method returns a collection of all the accounts for a specific publisher token.


import org.apache.commons.lang3.tuple.Pair;
import com.xappmedia.creative.model.Accounts;
import com.xappmedia.creative.model.error.ErrorResponse;

   public Pair<Accounts, ErrorResponse> getAccounts() {

        return getData("accounts", Accounts.class);

    }

Retrieve a collection of all the Phrases

This method returns a collection of all the action phrases for a specific publisher token.


import org.apache.commons.lang3.tuple.Pair;
import com.xappmedia.creative.model.PhraseList;
import com.xappmedia.creative.model.error.ErrorResponse;

   public Pair<Accounts, ErrorResponse> getPhrases() {

        return getData("phrases", PhraseList.class);

    }

Retrieve a collection of all the XAPPs

This method returns a collection of all the XAPPs for a specific publisher token.


import org.apache.commons.lang3.tuple.Pair;
import com.xappmedia.creative.model.AdsList;
import com.xappmedia.creative.model.error.ErrorResponse;

   public Pair<Accounts, ErrorResponse> getXAPPs() {

        return getData("xapps", AdsList.class);

    }

Creating a new Account

This endpoint accepts either a JSON or x-www-form-urlencoded payload. Each request for an account creation must include an account name and account type. Following example shows a JSON payload for a new account of type HOUSE:

  {
    "accountName": "TestSureshAccount",
    "accountType": "HOUSE"
  }

Allowed values for accountType are [HOUSE, COMMERCIAL, SPONSORED].

With the above JSON payload, we can send a request to the service as follows:


/**
 * Create a new Account using  JSON payload
 *
 * @param endpoint
 *          Endpoint for creating a Account
 *          (with respect to a base URL)
 * @param jsonPayload
 *          Data in JSON format
 *
 * @return Pair<Account, ErrorResponse>
 *           If everything went well, the left object will have the newly
 *           created Account. In case of error, the right object will have the
 *           ErrorResponse object
 *
 */
public Pair<Account, ErrorResponseList> createAccount(String endpoint, String jsonPayload) {

    Pair<Account, ErrorResponseList> rv = null;

    try {
        HttpResponse<String> response = Unirest.post(this.baseUrl)
                .routeParam("endpoint", endpoint)
                .header("X-SDK-Auth-Token", this.publisherToken)
                .header("Content-Type", "application/json")
                .body(jsonPayload)
                .asString();

        // Process the response string and create the Account
        // model object or the ErrorResponseList object
        rv = this.createModel(response.getBody(), Account.class);

    } catch (UnirestException e) {

        // Handle the error
        e.printStackTrace();
    }

    return rv;
}


where the endpoint is accounts.

Creating a XAPP

Following discussion assumes that we are sending a simple JSON payload to the service to create a XAPP. In otherwords, there is no multi-part/form upload of data. For creating a new XAPP, we need to provide at a minimum, the following informations:

Parameter Name In Payload
Account Name account.accountName
Ad Name adName
Target URL targetURL
Image URL imageURL
Prompt Audio URL promptAudioURL


Additionally, you require at least one action to be included in the request. Without an action, the ad will be just a regular Branding Ad. XAPP API supports many different action types such as Call, GoTo, Download, Email and Custom.

In the following example, we assume a Call action. At a minimum, this action requires the following parameters:

callAction.phoneNumber - A phone number for the call to action

callAction.phrase.phrase - An action phrase to which the user responds

And here is a JSON payload to create a new XAPP with Call action:

  {
    "account.accountName":"FooAccount",
    "adName":"Foo Ad",
    "targetURL":"https://www.xappmedia.com",
    "imageURL":"https://s3.amazonaws.com/xapp-image/1-800-Flowers-Flowers_And_Gifts-Ad_Image640x1136-106d6f61-aa62-4695-a986-dd511508296d.jpg",
    "promptAudioURL": "https://s3.amazonaws.com/xapp-audio/1800FLOWERS-FLOWERS_AND_GIFTS-BA-1247-08-22-2014-26522151-5f1d-4c8c-8538-07414a7a92f6.m4a",
    "callAction.phoneNumber":"123-456-7890",
    "callAction.phrase.phrase":"Call Now"
  }


With the above JSON document, we can send a request to the service as follows:

    /**
     * Create a new XAPP using  JSON payload
     *
     * @param endpoint
     *          Endpoint for creating a XAPP
     *          (with respect to a base URL)
     * @param jsonPayload
     *          Data in JSON format
     *
     * @return Pair<Ad, ErrorResponse>
     *           If everything went well, the left object will have the newly
     *           created XAPP. In case of error, the right object will have the
     *           ErrorResponse object
     *
     */
    public Pair<Ad, ErrorResponseList> createXapp(String endpoint, String jsonPayload) {

        Pair<Ad, ErrorResponseList> rv = null;

        try {
            HttpResponse<String> response = Unirest.post(this.baseUrl)
                    .routeParam("endpoint", endpoint)
                    .header("X-SDK-Auth-Token", this.publisherToken)
                    .header("Content-Type", "application/json")
                    .body(jsonPayload)
                    .asString();

            rv = this.createAdModel(response.getBody());

        } catch (UnirestException e) {

            // Handle the error
            e.printStackTrace();
        }

        return rv;
    }


where the endpoint is xapps.

Minimum Required Action parameters

Each action requires a minimum number of parameters. The following sub-sections elucidate these parameters for each action that we support:

Call Action:

callAction.phrase.phrase

callAction.phoneNumber

GoTo Action:

gotoAction.phrase.phrase

gotoAction.targetURL

Email Action:

emailAction.phrase.phrase

emailAction.fromAddress

emailAction.subject

and one of (but not both)

emailAction.body

emailAction.htmlBody

Download Action:

downloadAction.phrase.phrase

downloadAction.iosStoreURL

downloadAction.androidStoreURL

MoreAction Action:

moreAction.phrase.phrase

moreAction.moreInfoAudioURL

CustomAction Action:

Users can create an array of custom actions with each request. Hence, the format used for sending custom actions uses the index notation of HTML. So, for each custom action, all the associated parameters will have the form customAction[0].xxx, customActions[1].yyy, etc.

Required parameters are:

customActions[i].phrase.phrase

customActions[i].customParameters

where i is the index in the range 0 <= i < number of custom actions.

As an example, here is what the custom actions payload with three such actions look like in a x-www-form-urlencoded payload:

  {
     "customActions[0].phrase.phrase": "mayo clinic",
     "customActions[0].customParameters": "Number One in Health care",
     "customActions[1].phrase.phrase": "E-S-P-N",
     "customActions[1].customParameters": "All the Sports you need",
     "customActions[2].phrase.phrase": "CNN",
     "customActions[2].customParameters": "First In Breaking News",

  }

Alternatively, the above payload can also be expressed as follows in JSON using JSON array:


  {
    "customActions": [{
  	    "phrase.phrase":"mayo clinic",
  	    "customParameters": "Number One in Health care"
	   },
	    {
  	    "phrase.phrase":"E-S-P-N",
  	    "customParameters": "All the Sports you need"
	   },
	    {
  	    "phrase.phrase":"CNN",
  	    "customParameters": "First In Breaking News"
	  }]
  }