Server API integration manual (eng)

Request format

The request should be sent to:

https://api.devtodev.com/stat/v1/?api=ak-cDNRQl0Lypq4AOUrx8aGGMnmJT1FSebd
where:

  • api  - individual devtodev API app key, which can be found on the page of app integration;

  • v1 - the current version of API aggregator.

All the transferred data must be in UTF8 encoding. The value of parameters must be transferred URL encoded.

Contents must be sent as POST in gzip. 
The archive must contain json with one or more events for one or several users. 

The size of a package can't exсeed 1 MB before compression. Packages that exсeed this size can't be processed. 

If there are several events they must be formed inside an user object by type (name).

{

    "abcd1234abcd" : {              // Main identifier (device or user ID)
        "prev" : "asdf2345234asdf", // Previous main identifier (device or user ID)
                                    // in case it has been changed 
        "userId":"",                // Additional identifier (it is used if there is an identifier
                                    // that is different from the main identifier.
                                    // For example, a cross-platform user identifier)
        "prevUserId":"";            // Previous additional identifier in case it has been changed
        "sc" :[                     // Event name
            {},                     // Parameters of the first event
            {},                     // Parameters of the second event
            …
        ],
        "gs" :[                     // Event name 
            {}                      // Event parameters
        ],
        …
    },
    "1234abc1234" : {               // Unique user ID
        "userID":"",                // Additional identifier (it is used if there is an identifier
                                    // that is different from the main identifier.
        "sc" :[                     // Event name
            {},                     // Parameters of the first event
            {},                     // Parameters of the second event
            …
        ],
        "gs" :[                     // Event name 
            {}                      // Event parameters
        ],
    },
}

 

Response format

HTTP Код

State

413

Wrong size of the data package (exceeds the maximum) 

400

API key is absent

401

Wrong API key

403

Administrative restrictions on data reception from a client 

400

Error of data unpacking

{
	"error_message":"Wrong GZIP format"
}

 

400

Error of JSON format

{
	"error_message":"Wrong JSON format"
}

 

200

Package is received

200

Package is received, but there are errors found during the validation of events syntax.

The errors found are specified in an answer in the following format:

1.

{
    "errors": {
        "rg": {
            "expected": "[timestamp]",
            "received": [
                "[timestamps]",
                "[timestaTTmp]"
            ]
        }
    }
}

The message indicates that there have been received fields listed under the tag "received", but there are no fields that are listed under the tag "expected" among them. Such event will not be processed. 

2.

{
    "errors": {
        "rg": {
            "expected": "[timestamp]",
            "useless": [
                "[timestamps]",
                "[timestaTTmp]"
            ]
        }
    }
}

The message indicates that there have been received extra fields listed under the tag "useless", however fields listed under the tag "expected" are enough. Such event will be processed. 

   


The list of events

New user

Optional event.

It is used in the following cases:

  1. it is necessary to change the registration dates of existing users;

  2. to duplicate existing user base.

The event can't be submitted as a batch. The repeated sending is highly undesirable!

"rg" : [
	{
		"timestamp" : 1386259227    // the date of registration
	}
]

Information about a sourse of user appearance 

(traffic source, referral)

It is used when it is necessary to track data about a sourse of user apearance. The event is sent when an app is first launched by a user if a user came from a tracked source. Maximum of the fields from the following accessible data must be transferred. 

"rf" : [
    {
        "timestamp" : 1386259227,   // Required field! The date of registration
        "publisher" : "",           // Required field! The source from which a user came - the name of 
                                    // An advertising platform (advertising network)
        "subpublisher" : "",        // In case a platform is an aggregator - the name of a platform 
                                    // From which a user was resold 
        "subad" : "",               // Specific banner from which a user came (for Facebook)
        "subadgroup" : "",          // The group of ads(for Facebook)
        "subcampaign" : "",         // The name of a campaign from which a user came 
        "subplacement" : "",        // Banner placement - its position on a page 
        "subsite" : "",             // Who placed a banner (an app/ a website where a banner is placed)
        "country" : "US",           // Required field! The country of a user (format ISO 3166-1 alpha-2)
        "currencyCode" : "USD",     // The currency of referral's cost (format ISO 4217)
        "cost" : 9.99,              // The cost of a referral in a specified currency 
    }
]

Information about a user 

It is not sent in case there is some data missing.
The event can't be submitted as a package.

"ui" : [
	{
		"country" : "GB",              // The country of a user (format ISO 3166-1 alpha-2)
		"language" : "en",             // The language of a user (format ISO 639-1 (1998)
		"crossUid": "customuserid",    // Custom user ID
		"ip" : "127.0.0.1",            // IP
		"carrier" : "Beeline",         // The name of a network operator
		"isRooted" : 0,                // Rooted (jailbroken) device (1 - rooted)
		"userAgent" : "a lot of info"  // Browser user-agent
	}
]

 

"pl" : [
    {
        "data": {
           "age" : 21,                            //Reserved. User's age in years
           "cheater" : true,                      //Reserved. True, if a user is a cheater 
                                                  //In case you have your own methods to detect
                                                  //cheaters, you can mark such users.
                                                  //Event records made by cheaters will be 
                                                  //ignored when counting statistical metrics. 

           "tester" : true,                       //Reserved. True, if a user is a tester 
                                                  //Attention! This marker cannot be removed
                                                  //through the SDK (It can not be set to false
												  //after true).
                                                  //Event records made by testers will be 
                                                  //ignored when counting statistical metrics. 

           "gender" : 1,                          //Reserved. User's sex 0-unknown, 1-male, 2-female 
           "name" : "John Doe",                   //Reserved. User's name
           "email" : "john@email.com",            //Reserved. User's e-mail 
           "phone" : "+15555555555",              //Reserved. User's phone number 
           "photo" : "http://google.com/pic.png", //Reserved. User's photo

           //Custom characteristics of a user in a key-value format 
           "key1" : "stringValue",                //String value
           "key2" : 1.54,                         //Number value
           "key3" : [1,2,"something"]             //Array
        },
       "timestamp" : 12313                        //The date of data changes
    }
]   

"pl" : [
    {
        "data": {
            "key1" : null,                        //Remove user's characteristic key1
            "key2" : null                         //Remove user's characteristic key2
        },
       "timestamp" : 12313
    }
]

"pl" : [
    {
        "data" : null,                            //Clear all custom characteristics of a user 
        "timestamp" : 123412
    }
]

 

Information about an app

The recommended interval of sending is not more than once per 24h.

"ai" : [
    {
        "sdkVersion" : "1.1",        // Required. In case of communication via API, 
                                     // the version of implementation of a communication mechanism
        "appVersion" : "1.2",        // App version
        "codeVersion" : 14.0,        // Version of app's code 
        "bundleId" : "com.myown.app" // App's bundle 
    }
]

Information about a device

The recommended interval of sending is not more than once per 24h.

Information is the most relevant for mobile devices.

"di" :[
    {
        "manufacturer" : "Apple",                   // The manufacturer of a device
        "model" : "iPhone 4,1",                     // uname (iOS), MODEL (Android)
        "screenResolution" : "1024x768",            // The display's resolution of a device
        "screenDpi" : 144,                          // The density of display's points
        "odin" : "klflaiuewfuasydfiasydpf98ay4",    // DeviceUniqueId SHA-1 (Windows Phone),
                                                    // AndroidId SHA-1 (Android)
        "openUdid" : "f;isyofa7w8yp4fapw49",        // OpenUDID ((Android, iOS, Windows phone)
        "idfa" : "AYTSD-ADSYS-LAUSDY-IUAYSD",       // Ad identifier IDFA (iOS)
        "idfv" : "87ASD-9A7SD-AD2G-Q26EO-AS7D",     // Device identifier within the vendor IDFV (iOS)
        "d2dUdid" : "dsufyoa-sfa3wr-ra3rawQ2-AWR3A",// Base64 от DeviceUniqueId (Windows Phone) , 
                                                    // random by http:// www.ietf.org/rfc/rfc4122.txt (Android)
        "imei" : "w87ea6owe7aow78eaow",             // IMEI (Android)
        "androidId" : "o8a7d6oa8s7b6doa87sb6d8bs",  // AndroidID (Android)
        "advertisingId" : "38400000-8cf0-11bd-b23e-10b96e40000d", // Advertising ID (Android, Windows phone 8.1)
        "serialId" : "asd76asd9",                   // Hardware serial number  (Android,Windows phone)
        "deviceVersion": "8.1",                     // OS version
        "deviceModel": "Windows"                    // The name of OS family
    }
]

Game session 

In case it is possible to fix the length of a session, it is sent during the end of a session or during the next session. If there is no such possibility, send the date of the start of a session, the length of a session must be placed in the middle in case it is known. The absence of a parameter of a session's length makes it impossible to count some metrics.  

"gs" : [
    {
        "timestamp" : 1386259227,   // The date of session's start 
        "length" : 34,              // The length of a session in seconds
        "level" : 3,                // Player's level 
        "inProgress" : ["village"]
    },
    …
]

Tutorial steps

The event allows to learn how a user goes through a tutorial. The event is created after every completed step.

Attention! If a tutorial that hasn't been completed is programmed to reset to the beginning, the repeated reference of identical steps will be counted and influence the statistical metrics. 

"tr" : [
    {
        "step" : 1,                // the number of a tutorial step that has been completed 
        "timestamp" : 1386259227,  // date
        "level" : 3,               // player's level
        "inProgress" : ["village"],// location (game level) in which an action has been performed
        …
    }
]

Use the following constants for basic actions:

"step" : -1  // The beginning of a tutorial(before completing the first step)
"step" : 0   // The tutorial is skipped 
"step" : -2  // The tutorial is completed (instead of the last step's number)

In all other cases use the number of steps above 0. 

New level

Allows you to analyse players' distribution by game levels. The event is created when a player moves to the next level. In order to track the average state of game currency accounts, the amount of spendings and earnings of a currency, the amount of a game currency bought while completing a level, you can also send this data in this event.  

"lu" : [
    {
        "level" : 10,              // Required. The level that a player got 
        "timestamp" : 1386259227,  // Required. The date of moving to the next level 
        "inProgress" : ["village"],// Location (game level)in which an action has been performed
        "balance" : {              // Optional. The balances of a game currency at the end of a level 
            "money1" : 123,        // The name of a game currency as a key and its amount 
            "money2" : 11,
            …
        },
        "spent" : {                // Optional. The amount of a currency spent on a level
            "money1" : 12,         // The name of a game currency as a key and its amount 
            "money2" : 2,
            "wood" : 12,
            …
        },
        "earned" : {               // Optional. The in-game currency that was earned on a level
            "money1" : 8,    
            "money2" : 2,
            "stone" : 1,
            …
        },
        "bought" : {                // Optional. The in-game currency that was bought on a level 
            "money1" : 10,
            "money2" : 2,
            …
        }
    },
    …
]

Connection to social networks

Allows you to track existing connections to social networks.

"sc" : [
    {
        "socialNetwork" : "FB",   // The name of a social network. The value from the list
                                  // of constants for popular networks or your own string name
        "timestamp" : 1386259227, // The date of connection
        "level" : 3,              // Player's level
        "inProgress" : ["village"]// Location (game level) in which an action has been performed
    },
    ...
]

Constants that are supported by the system:

EN

Evernote

RT

Reddit

FB

Facebook

RR

Renren

GM

Google Mail

TB

Tumblr

GP

Google+

TW

Twitter

IN

LinkedIn

VK

VK

OK

Odnoklassniki

VB

Viber

PI

Pinterest

WP

WhatsApp

QQ

Qzone

   

Publication in social networks

Allows you to track publications in social networks. It also allows you to analyze viral channels to optimize marketing efficiency. 

It is sent after a publication has been approved by a social network.

"sp" : [
    {
        "socialNetwork" : "FB",   // The name of a social network. The value from the list of 
                                  // constants for popular networks or your own string name
        "postReason" : "levelup", // The reason of publication (max. 32 symbols). We recommend you
                                  // to group reasons instead of sending such names as "Level 99 reached".
        "timestamp" : 1386259227, // The date of publication 
        "level" : 3,              // Player's level 
        "inProgress" : ["village"]// Location (game level)in which an action has been performed
    },
    ...
]

We recommend to specify actions that encourage to make a publication as a reason:

For example:

  • Start playing

  • New level reached

  • New building

  • New ability

  • Quest completed

  • New item

  • Collection completed

  • Invitation

 
  • Asking for help

  • New Record

  • Achievement

  • URL sharing

  • Recommendation

  • Review

and so on...

Real payment

In case you transfer data related to several transactions, group them by item name.

"rp": [
    {
        "name": "inapp_name_1",         // The name of a purchase 
        "entries": [
            {
                "orderId": "124567.7654321",// Transaction identifier (max. 64 symbols)
                "price": 1.99,              // The price of a purchase in a transaction currency
                "currencyCode": "USD",      // Transaction currency(ISO 4217 format)
                "timestamp": 1386259227,    // The date of a transaction
                "level": 3,                 // Player's level
                "inProgress": ["village"]   // Location (game level) in which an action has been performed
            },{     //If there is one more identical purchase for a report period
                "orderId": "1224567.7634327",
                "price": 1.99,
                "currencyCode": "USD",
                "timestamp": 1386259227,
                "level": 3,
                "inProgress": ["village"]
            }
        ]
    },{     //If there are other purchases for a report period 
        "name": "inapp_name_2",
        "entries": [
            {
                "orderId": "1234567.7654321",
                "price": 9.99,
                "currencyCode": "USD",
                "timestamp": 1386259227,
                "level": 3,
                "inProgress": ["town"]
            }
        ]
    }
]


In-game purchase

It is used to track the ways in which an in-game currency is spent and the popularity of in-game items.

"ip" :  [
    {
        "purchaseType" : "Weapon",  // The group of an item (max. 96 symbols)
        "purchaseId" : "Dagger",    // The unique name or ID of an item (max. 32 symbols)
        "purchaseAmount" : 1,       // The amount of items bought
        "purchasePrice" : 1.0,      // The price of an item (the overall price of a purchase if there 
                                    // are several identical items are bought) in an in-game currency 
        "purchasePriceCurrency" : "Coins",  // The name of an in-game currency that was used to buy
                                            // an item (max. 24 symbols)
        "timestamp" : 1231872631,   // The date of a purchase
        "level" : 3,                // Player's level
        "inProgress" : ["village"]  // Location (game level) in which an action has been performed
    },
    …
]

In case one item is sold in several currencies, a purchase is divided into several events, the amount of which corresponds to the number of currencies. Wherein the number of items is specified only in one event. 

"ip" :  [
    {
        "purchaseType" : "Weapon",  // The group of an item (max. 96 symbols)
        "purchaseId" : "Dagger",    // The unique name or ID of an item (max. 32 symbols)
        "purchaseAmount" : 1,       // The amount of items bought
        "purchasePrice" : 1.0,      // The price of an item (the overall price of a purchase if there 
                                    // are several identical items are bought) in an in-game currency 
        "purchasePriceCurrency" : "Coins",  // The name of an in-game currency that was used to buy
                                            // an item (max. 24 symbols)
        "timestamp" : 1231872631,   // The date of a purchase
        "level" : 3,                // Player's level
        "inProgress" : ["village"]  // Location (game level) in which an action has been performed
    },
    {
        "purchaseType" : "Weapon", 
        "purchaseId" : "Dagger",   
        "purchaseAmount" : 0,      
        "purchasePrice" : 2.0,     
        "purchasePriceCurrency" : "Gold", 
        "timestamp" : 1231872631,
        "level" : 3,               
        "inProgress" : ["village"]
    },
    …
]

Custom event

If it is necessary to count events that are absent from the main types of events, use user events. An event must have the unique name and can include up to 10 parameters. You can use up to 300 unique names.

"ce" : [
    {
        "name" : "house_purchase",          // The name of an event (max. 72 symbols)
        "entries" : [
            {
                "t1" : 1231872631,          // The date of an event
                "level" : 3,                // Player's level
                "inProgress" : ["village"], // Location (game level) in which an action has been performed
                "p" : {
                    "t1" : {
                        // up to 10 parameters grouped by data types
                        "double" : {        // Parameters with values - in numbers
                            "key1" : 1,     // The name of a parameter as a key(max. 32 symbols) and
                                            // the value of a parameter
                            "key2" : 2.123,
                            …
                        },
                        "string" : {        // Parameters with values - in strings
                            "key3" : "a",   //  The name of a parameter as a key(max. 32 symbols) and
                                            // the value of a parameter (max. 255 symbols)
                            "key4" : "abc",
                            …
                        }
                    }                       
                }
            },
            {                               // If there are several events with the same name 
            "t1" : 1231872638,
            "level" : 3,                    
            "inProgress" : ["village"],
            "p" : {
                "t1" : {
                    "double" : {
                        "key1" : 1,
                        "key2" : 2.123,
                        …
                    },
                    "string" : {
                        "key3" : "a", 
                        "key4" : "abc",
                        …
                    }
                }                       
            }
        }
    },
    {                                       // If one user had several events with different names for
                                            // a reporting period, continue 
        …
    }
]

Progression event

First of all, the event is used for games with short locations (game levels) that are completed during one game session. The event allows to gather data about success in location completion and receive statistics by parameters that are changeable during location completion. 

"pe" : [
    {
        "id" : "location2",         // The name of a location
        "level" : 3,                // Player's level at the moment of location completion 
        "params" : {                // Event parameters
            "source" : "location1", // The name of the previous location of a player 
            "difficulty" : 1,       // Optional. The level of difficulty of location completion 
            "success" : true,       // Success in location completion 
            "duration" : 180        // Optional. Time in seconds of location completion
        },
        "spent" : {                 // Optional. Resources spent during location completion
            "money1" : 12,          // The record of a resource in the format of 
                                    // resource's name - the amount of a resource
            "money2" : 2, 
            "wood" : 12
        }, 
         "earned" : {               // Optional. Resources that are received during location completion 
             "money1" : 8, 
             "money2" : 2, 
             "stone" : 1
        },
        "timestamp" : 1234567890    // The time of exit from a location
    }
]

Tracking state (GDPR)

Limiting the processing of user data. The right to erasure.

This event is implemented in accordance with the GDPR requirements.

A developer must use this event in case a user doesn’t want their data to be sent and processed in the devtodev system.

When calling "ts" event with the parameter "isTrackingAllowed": false, it is a command to the server to delete all user’s personal data that has been collected by devtodev from this app and a command to block the collection of any data of this user in future.

The user will remain listed as an impersonal unit in previously aggregated metrics.

When sending a true value, the permission to block data collection is removed.

{
	"JohnDoe": {
		"prev": "LittleJohn",
		"ts" : [{ 
        	"isTrackingAllowed": false,
        	"timestamp" : 1386259227
		}]
	}
}

An example of a package

'POST' https://api.devtodev.com/stat/v1/?api=ak-npADyEmjxc0usQR52k6it38zUPSloGT7 with gziped body: {
 

{
	"JohnDoe": {
		"prev": "LittleJohn",
		"tr": [{
			"step": 1,
			"timestamp": 1386259227,
			"level": 1,
			"inProgress": ["village"]
		}, {
			"step": 2,
			"timestamp": 1386259236,
			"level": 1,
			"inProgress": ["village"]
		}, {
			"step": 3,
			"timestamp": 1386259288,
			"level": 1,
			"inProgress": ["town"]
		}],
		"gs": [{
			"timestamp": 1386259227,
			"length": 1250,
			"level": 3
		}],
		"gr": [{
			"gender": 1
		}],
		"lu": [{
			"level": 4,
			"inProgress": ["village"],
			"timestamp": 1442392006,
			"balance": {
				"Coins": 1234,
				"Gold": 11
			}
		}],
		"ce": [{
			"name": "Round_finished",
			"entries": [{
				"t1": 1442392451,
				"level": 4,
				"inProgress": ["village"],
				"p": {
					"t1": {
						"double": {
							"Round_time": 83,
							"Score": 2.123
						},
						"string": {
							"Result": "Victory",
							"Type": "Flawless"
						},
						"date": {
							"Finished": 1442392451
						}
					}
				}
			}, {
				"t1": 1442393455,
				"level": 4,
				"inProgress": ["town"],
				"p": {
					"t1": {
						"double": {
							"Round time": 102,
							"Score": 1.5
						},
						"string": {
							"Result": "Defeat",
							"Type": "Shameful"
						},
						"date": {
							"Finished": 1442393455
						}
					}
				}
			}]
		}],
		"pe": [{
			"id": "town",
			"level": 3,
			"params": {
				"source": "vilage",
				"difficulty": 2,
				"success": true,
				"duration": 180
			},
			"spent": {
				"Turns": 54,
				"Boost Bomb": 1,
				"Extra 5 Turns": 1
			},
			"earned": {
				"Stars": 3,
				"Score": 1200,
				"Coins": 5
			},
			"timestamp": 1234567890
		}],
		"ip": [{
			"purchaseType": "Weapon",
			"purchaseId": "Dagger",
			"purchaseAmount": 1,
			"purchasePrice": 30.0,
			"purchasePriceCurrency": "Coins",
			"timestamp": 1442393479,
			"level": 4,
			"inProgress": ["village"]
		}],
		"rp": [{
			"name": "Currency pack 1",
			"entries": [{
				"orderId": "1234567.7654321",
				"inProgress": ["village"],
				"level": 4,
				"price": 1.99,
				"currencyCode": "USD",
				"timestamp": 1442393460
			}]
		}],
		"sp": [{
			"socialNetwork": "FB",
			"postReason": "New level reached",
			"level": 4,
			"inProgress": ["village"],
			"timestamp": 1442392006

		}]
	}
}

Utility for testing 

An utility for sending packets

https://www.devtodev.com/upload/files/devtodevapitester.jar

An example of sending to PHP

An example of the implementation of a request to PHP with the use of Curl. The sending of a real payment. 

$url = 'https://api.devtodev.com/stat/v1/?api='.$api;
$params = [
        $uid=>[
            'rp' =>[
                [
                    'name' => $name,
                    'entries' =>[
                        [
                            'orderId' => $transactionId,
                            'price' => 100,
                            'currencyCode' => 'USD',
                            'timestamp' => time(),
                            'level'=> 5,
                            'inProgress'=> ['village']
                        ]
                    ]
                ]
            ]
        ]
];

$curlHandle = curl_init($url);
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array('Content-Type: text/plain;charset=UTF-8'));
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curlHandle, CURLOPT_POST, TRUE);
curl_setopt($curlHandle, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, gzencode(json_encode($params)));
curl_setopt($curlHandle, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curlHandle, CURLOPT_ENCODING, 'gzip');
$response = curl_exec($curlHandle);
Google Play
RAW export