Kiip Server-to-Server Integration

Overview

The Kiip Server-to-Server integration allows thirty parties to integrate with the Kiip platform by making server-to-server calls instead of using a Kiip Mobile or Web SDK.

The following flow is used when initiating server-to-server integration:

  1. Initiate a user session when a device comes online by calling the Session endpoint.
  2. For every action your application deems rewardable, make a server call using the Moment endpoint. The Kiip Platform will return a reward if we are able to reward the moment. When testing, passing the test flag as true will ensure a reward is always returned.

Session Endpoint

Start a session when a user opens the app. This is required so Kiip can receive moment/reward requests while the app is in use. The below describes the format of the call needed to start a session.

POST /2.0/server/moment/
Accept: application/json
Content-Type: application/json
Host: api.kiip.me

{
	"app”:{
		"app_key":<"app key found in Kiip dashboard">,
		"version":<"client version number of the app">
	},
	"connection":{
		"ip":<"ip address of the device">,
		"carrier":<"e.g. 'ATT'">,
		"type":<"Connection type e.g. 'Wifi'">
	},
	"device":{
		"id":<"The Advertising Identifier provided by the device">,
		"density":<"screen density e.g. '3.5'">,
		"lang":<"e.g. 'en'">,
		"locale":<"e.g. en_US">,
		"manufacturer":<"device manufacturor name e.g. 'Apple'">,
		"model":<"e.g. 'nexus_5'">,
		"os":<"e.g. Android 5.0">,
		"resolution":<"e.g. 1080x1776">
		"user_agent":<"e.g. Mozilla/5.0 (iPhone; CPU iPhone OS 11_2_6 like Mac OS X) AppleWebKit/604.5.6 (KHTML, like Gecko) Mobile/15D100">
	},
	"location":{
		"lat":<"float e.g. '39.04371920'">,
		"lng":<"float e.g. '77.48748990'">,
	},
	"close_button":<"Can be used to hide the close reward button when set to 0 or false">,
	"email_address":<"Used to prefill the email address for earned rewards">,
	"test":<"set to either true or false">,
	"sdk_version":<"Kiip SDK version">,
	"user":{
		"age":<"years old">,
		"gender":<"either 'm' or 'f' if available">,
		"userid":<"string">

	},
	"events:[
		{
		"id":<"session_start">,
		"start":<"ISO 8601 date format">
		}
	]
}

JSON Payload Components

Below is a list of all required payload components. If you have any questions about the use of these components, please contact support@kiip.me.

device

  • id: The ADID or Identifier
  • density: The screen density (if available)
  • locale: The user’s setting for locale
  • os: This should always include a version number
  • lang: Set at the device level
  • model: Set at the device level
  • resolution: Set at the device level
  • manufacturer: The device’s manufacturer
  • user_agent: User agent of the device’s browser

app

  • app_key: Kiip application key found in the dashboard
  • version: The current client version number

connection

  • ip: a valid ip address provided by device
  • carrier: Provided by device e.g. ‘ATT’
  • type: Provided by device e.g. ‘WIFI’

test

In order to test your Kiip implementation, this should be set to true. In a live environment, this must be set to false.

sdk_version

The current Server-to-Server SDK is version 1.0.

user

  • age: User age (if available)
  • gender: Users gender, either ‘m’ or ‘f’ (if available)
  • userid: A string containing a user’s id for use in virtual currency rewards

location

  • lat: This is always a number between -90 and 90
  • lng: This is always a number between -180 and 180

close_button

By default, a close button is shown when rewards are earned. Can be used to hide the close reward button when set to 0 or false.

email_address

When supplied with an email address, this component will be used to prefill a user’s email address when a reward is earned.

events

  • id: Should be either ‘session_start’ or ‘session_end’ depending whether the user opens or closes the app
  • start: ISO 8601 date format

Example Request

https://api.kiip.me/2.0/server/moment

Payload
{
	"app”:{
		"app_key":"a05a2fd245170d452de01a6abc786922",
		"version":"4281020"
	},
	"connection":{
		"ip":"54.174.101.1",
		"type":"WIFI"
	},
	"device":{
		"id":"45e3-1d799e20-963a-4ddd-8593-0683b30e7d5b",
		"lang":"en",
		"locale":"en_US",
		"manufacturer":"google",
		"model":"nexus_5",
		"os":"Android 5.0",
		"resolution":"1080x1776"
	},
	"location":{
		"lat":39.04371920,
		"lng":77.48748990,
	},
	"sdk_version":"1.0",
	"test":true,
	"user":{
		"gender":"m"
	},
	"events":[
		{
			"id":"session_start",
			"start":"2015-01-28T01:32:22.852Z"
		}
	]
}

Response

The server will respond to valid requests with a JSON document containing a single key date holding the session start time in ISO8601 format.

{
     "date": "2015-01-28T01:32:24.697136"
}

Moment Endpoint

When a user completes a rewardable event, the server should make a call to the moment endpoint requesting a reward. The call is described below. If Kiip deems the moment rewardable, a JSON document will be returned containing the reward information. Otherwise, no reward will be returned.

POST /2.0/server/moment/
Accept: application/json
Content-Type: application/json
Host: api.kiip.me

{
	"app”:{
		"app_key":<"app key found in Kiip dashboard">,
		"version":<"client version number of the app">
	},
	"connection":{
		"ip":<"ip address of the device">,
		"carrier":<"e.g. 'ATT'">,
		"type":<"Connection type e.g. 'Wifi'">
	},
	"device":{
		"id":<"The Advertising Identifier provided by the device">,
		"density":<"screen density e.g. '3.5'">,
		"lang":<"e.g. 'en'">,
		"locale":<"e.g. en_US">,
		"manufacturer":<"device manufacturor name e.g. 'Apple'">,
		"model":<"e.g. 'nexus_5'">,
		"os":<"e.g. Android 5.0">,
		"resolution":<"e.g. 1080x1776">
	},
	"location":{
		"lat":<"float e.g. '39.04371920'">,
		"lng":<"float e.g. '77.48748990'">,
	},
	"moment":{
		"id":<"UUID found in the Kiip dashboard associated with a given moment">
	},
	"close_button":<"Can be used to hide the close reward button when set to '0' or 'false'">,
	"email_address":<"Used to prefill the email address for earned rewards">,
	"sdk_version":<"Kiip SDK version">,
	"test":<"either true or false">,
	"user":{
		"age":<"years old">,
		"gender":<"either 'm' or 'f' if available">,
		"userid":<"string">
	},
}

JSON Payload Components

Below is a list of all required payload components for a Moment Endpoint. If you have any questions about the use of these components, please contact support@kiip.me

device

  • id: The ADID or Identifier
  • density: The screen density (if available)
  • locale: The user’s setting for locale
  • os: This should always include a version number
  • lang: Set at the device level
  • model: Set at the device level
  • resolution: Set at the device level
  • manufacturer: The device’s manufacturer

app

  • app_key: Kiip application key found in the dashboard
  • version: The current client version number

moment

  • id: The uuid associated with the a given moment from the Kiip dashboard

close_button

Unless explicitly set to 0 or false the reward close button will be present.

email_address

When supplied with an email address, this component will be used to prefill a user’s email address when a reward is earned.

connection

  • ip: A valid ip address, provided by device
  • carrier: Provided by device e.g. ‘ATT’
  • type: Provided by device e.g. ‘WIFI’

test

In order to test your Kiip implementation, this should be set to true. In a live environment, this must be set to false.

sdk_version

Currently the Server-to-Server sdk is in version 1.0.

user

  • age: User age (if available)
  • gender: Users gender, either ‘m’ or ‘f’ (if available)
  • userid: A string containing a user’s id for use in virtual currency rewards

location

  • lat: This is always a number between -180 and 180
  • lng: This is always a number between -180 and 180

Example Request

https://api.kiip.me/2.0/server/moment

Payload
{
	"app”:{
		"app_key":"a05a2fd245170d452de01a6abc786922",
		"version":"4281020"
	},
	"connection":{
		"ip":"54.174.101.1",
		"type":"WIFI"
	},
	"device":{
		"id":"45e3-1d799e20-963a-4ddd-8593-0683b30e7d5b",
		"lang":"en",
		"locale":"en_US",
		"manufacturer":"google",
		"model":"nexus_5",
		"os":"Android 5.0",
		"resolution":"1080x1776"
	},
	"location":{
		"lat":39.04371920,
		"lng":77.48748990,
	},
	"moment":{
		"id":"CgkIraKVsdIBEAIQEA"
	},
	"close_button":"",
	"email_address":"hello@kiip.me",
	"sdk_version":"2.3.0",
	"test":false,
	"user":{
		"gender":"f"
	},
	"event":[
		{
			"id":"session_start",
			"start":"2015-01-28T01:32:22.852Z"
		}
	]
}

Example Response

Note: The ‘notification’ blob in the response contains the reward name and the reward creative URL which can be used in the reward notifications in the app. Reward notifications are optional but this blob will be required if using reward notifications.

{
	"date": "2016-07-07T18:47:06.353111", 
	"notification": {
		"reward_name": "Test Reward - Virtual Click", 
		"reward_image_url": "https://d3aq14vri881or.cloudfront.net/5473ca60-2891-a32d-d30d-cd6f3d4dcc67_KiipRewardTemplate.png"
	}, 
	"view": {
		"email_bounced": false,
		"id": "test_5473ca54-59a5-cf65-d319-c91697297fcc", 
		"modal": {
			"message": "Test Reward - Virtual Click", 
			"timeout": 10, 
			"body_url": "https://api.kiip.me/reward/577ea3aa-b723-ae81-660c-79fae3443e12/5473ca54-59a5-cf65-d319-c91697297fcc?application_id=565a559f-a0ef-3384-66bc-669e61d12c93&locale=en_US&moment_id=575130b8-2637-d8f4-e587-cce64f693f4a&sdk_version=1.0&r=153891&mode=standalone&preview=true&sdk=none",
 			"title": "Loading your Kiip Reward:"
		}, 
	"used_date": null
	}
}

Verify a Reward Redemption

If you choose to validate a reward redemption, you may via a server callback. First you will have to set up a callback URL. This requires creating an endpoint on an accessible server.

Currently, the reward redemption callback URL may only be used with virtual currency reward redemptions.

Issue Virtual Currency

When a user redeems a reward containing virtual currency, the Kiip servers will immediately POST a request to the callback URL specified in your setup. This postback does require a user_id be set on the Kiip object.

This requires creating an endpoint on an accessible server.

The POST request will contain the following data:

{
	   "transaction_id": <reward id>,
	   "content": <virtual_uuid>,
	   "name": <currency name>,
	   "quantity": <virtual currency value>,
	   "user_id": <user id passed to Kiip at moment>,
	   "signature": <signature>
}

Async Virtual Currency Issuance Endpoint

The issuance endpoint will receive commands from Kiip to issue virtual currency in response to later events, such as an application install, survey completion, or purchase. This does require a user_id be set on the Kiip object.

As the message format is different from virtual currency reward redemption messages, it is possible to reuse the endpoint for this purpose.

The JSON POST request will contain the following data:

  • content (string): The unique identifier of the virtual currency (e.g. coins)
  • quantity (int): The quantity of the virtual currency (e.g. 20)
  • user_id (string): A unique field in which to verify the user. This could be any unique identifier, be it a login handle, email address or Advertising ID. This is required if using the virtual currency reward redemption callback.
  • transaction_id (string): The linked reward ID.
  • nonce (string): A string, when combined with the transaction ID, can be used to uniquely reference a message.
  • origin (string): The event that triggered this issuance event (i.e., survey, other).
  • signature (string): The HMAC of the payload. Used to verify valid POSTs. See below for more information.

Verify a virtual currency issuance command using this string containing the following:

sha1(content + quantity + user_id + transaction_id + nonce + origin + app_secret)

Here’s a quick example of how you would verify the request in python:

def is_valid_message(content, quantity, user_id, nonce, origin, transaction_id, signature):
    sign = '%s%s%s%s%s%s%s' % (content, quantity, user_id, transaction_id, nonce, origin, YOUR_APPLICATION_SECRET)
    return hashlib.sha1(sign).hexdigest() == signature

3. Verify the Callback

Verify a virtual currency callback using this string containing the following:

sha1(content + name + quantity + userid + transaction_id + app_secret)

Here’s a quick example of how you would verify the request in python:

def is_valid_request(content, quantity, userid, transaction_id, signature):
    sign = '%s%s%s%s%s' % (content, name, quantity, userid, transaction_id, YOUR_APPLICATION_SECRET)
    return hashlib.sha1(sign).hexdigest() == signature

Display Reward

If a moment is rewardable, the above Moment call will return a JSON document describing the reward. The document contains a key view.modal.body_url that is the URL to the HTML page displaying the reward.

It is recommended to display this URL in an iframe or webview. However, you may display the reward in any way you see fit.

GET <view.modal.body_url> HTTPS/1.1

Example Request

https://api.kiip.me/reward/preview/<reward id>?locale=<locale>&sdk_version=<sdk version>&r=394542&application_id=<application id>&moment_id=<moment id>

e.g.

https://api.kiip.me/reward/preview/509821a1-48cf-59b6-38cd-d7cb63e20cbb?locale=&sdk_version=2.0.9&r=394542&application_id=545ab108-1cc7-86ca-0031-2b8b91b9141f&moment_id=5463e141-93ad-6f92-42e3-25a55294b9ac

Closing the Webview

Typically, Server-to-Server implementations will handle dismissing a reward unit automatically. However, there will be a webview left behind that requires dismissing.

Server-to-Server implementations for iOS and Android require the following code in order to know when to close the webview that contained a dismissed reward unit.

iOS

// UIWebViewDelegate
- (BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
{
    NSURL *url = request.URL;
    if ([url.scheme isEqualToString:@"kiip"]) {
       if ([url.host isEqualToString:@"did_dismiss"]) {
          //handle 'close' logic here.
       }
       return NO;
    }
    return YES;
}

Android

public final class RewardUnitView extends WebView {

    private static final String KIIP_URL_SCHEME = "kiip";
    private static final String KIIP_HOST_DID_DISMISS = "did_dismiss";

    @Override
    public boolean shouldOverrideUrlLoading(final WebView view, String url) {
        Uri uri = Uri.parse(url);
        if (KIIP_URL_SCHEME.equals(uri.getScheme())) {
            if (KIIP_HOST_DID_DISMISS.equals(uri.getHost())) {
                //handle 'close' logic here.
            }
            return true;
        }
        return false;
    }
}

Notes about Device IDs

All calls to the Kiip platform must include a valid device ID. In most cases, the device ID should be the device specific Advertiser Identifier that is returned by the mobile operating system.

45e6-4ce34c50-bf87-4b00-6eb1-0ab0d6147788