logo

Help Center/Details/

Reporting API 2.0(Beta)

Date Feature
2020/12/01
  • Supports T+0 “date*placement_id*country” level estimated revenue data. (Note that estimated revenue data might take a few days to stabilize) 
  • Supports UTC+0 estimated revenue data (Available from 2020/12/01. Note that billing is still based on UTC+8 data)
  • Returns app package name
  • Updated signing method
2020/12/20
  • Updated request demo
2021/01/12
  • “Region“ has become an optional request parameter
2021/03/16
  • Added response fields:media_name,code_name,os.
  • Updated request sample and code sample.


Request

Request Params Type Mandatory Allowed Value Default Value Note
user_id int Yes - - user_id is your Pangle account id
role_id int Yes - - Role_id can be found adjacent to your security key. The api will only return data of the apps the role has access to. To retrieve complete data, please make sure you have permission for all the apps.
reporting api.png
timestamp int Yes - - In unix time format. Eg:1095379200;Timestamp is the current timestamp. When the offset between timestamp and the current time is greater than 10 minutes, a parameter error will be returned to prevent request replay
version string Yes 2.0 - Version of this reporting api, please fill in 2.0
date string Yes - - YYYY-MM-DD, e.g. '2020-10-10'
time_zone int No 0 or 8 8 8 for utc8; 0 for utc0; Please note that Pangle's billing data is still based on UTC8
currency string No usd or cny cny
region string No Two digit country/region code under ISO3166-1, eg:cn
sign string Yes - - 1)A string in hexadecimal that should be generated with the method provided below.
2)Sign Sample:7ff19ec1961d8c2b7c7b3845d974d22e
sign_type string Yes MD5 -


Request Sample



https://www.pangle.cn/union_pangle/open/api/rt/income?currency=cny&date=2021-01-12&role_id=459&sign_type=MD5&time_zone=8&user_id=459&version=2.0&timestamp=1615778032&sign=598b733d2eb8d5ef7fb326fc2061dfa1

How is the param "sign" generated?

To get the right sign value, you should:

  1. Sort your request keys by alphabetical order
  2. Sign your request keys and values with your security key (Security key can be found in the Pangle platform - SDK Integration - Data API)
  3. sign=md5(k1=v1&k2=v2...security-key)

Sign - Python Code Sample

# coding=utf-8
import hashlib


class PangleMediaUtil:
    user_id = 459
    role_id = 459
    secure_key = "xxxxsecure_key"

    version = "2.0"
    sign_type_md5 = "MD5"
    KEY_USER_ID = "user_id"
    KEY_ROLE_ID = "role_id"
    KEY_VERSION = "version"
    KEY_SIGN    = "sign"
    KEY_SIGN_TYPE = "sign_type"
    PANGLE_HOST = "https://www.pangle.cn"

    @classmethod
    def sign_gen(self, params):
        """Fetches sign .
        Args:
        params: a dict need to sign
        secure_key: string

        Returns:
        A dict. For example:

        {'url': 'a=1&sign_type=MD5&t=2&z=a&sign=7ff19ec1961d8c2b7c7b3845d974d22e',
        'sign': '7ff19ec1961d8c2b7c7b3845d974d22e'}
        """
        result = {
            "sign": "",
            "url": "",
        }
        try:
            if not isinstance(params, dict):
                print("invalid params: ", params)
                return result

            if self.user_id != "":
                params[self.KEY_USER_ID] = self.user_id

            if self.role_id != "":
                params[self.KEY_ROLE_ID] = self.role_id

            params[self.KEY_VERSION] = self.version
            params[self.KEY_SIGN_TYPE] = self.sign_type_md5

            param_orders = sorted(params.items(), key=lambda x: x[0], reverse=False)
            raw_str = ""
            for k, v in param_orders:
                raw_str += (str(k) + "=" + str(v) + "&")
                print("raw sign_str: ", raw_str)
                if len(raw_str) == 0:
                    return ""
                sign_str = raw_str[0:-1] + self.secure_key
                print("raw sign_str: ", sign_str)

            sign = hashlib.md5(sign_str.encode()).hexdigest()
            result[self.KEY_SIGN] = sign
            result["url"] = raw_str + "sign=" + sign
            return result
        except Exception as err:
            print("invalid Exception", err)
            return result

    @classmethod
    def get_signed_url(self, params):
        return self.sign_gen(params).get("url", "")

    @classmethod
    def get_media_rt_income(self, params):
        result = self.get_signed_url(params)
        if result == "":
            return ""
        return self.PANGLE_HOST + "/union_pangle/open/api/rt/income?" + result


# Code Sample
params = {
    "currency": "usd",
    "time_zone": 0,
    "date": "2020-12-18",
    "region": "jp",
    "timestamp":"1615778032",
}
PangleMediaUtil.user_id = 459  # Replace with pangle account id
PangleMediaUtil.role_id = 459  # Replace with pangle role_id
PangleMediaUtil.secure_key = "xxxxsecure_key"
print(PangleMediaUtil.get_media_rt_income(params))


Sign - PHP Code Sample


<?php

final class pangle_media_util{
    
    private static $user_id = 459;                # Replace with your user_id
    private static $role_id  = 459;               # Replace with your role_id
    private static $secure_key = "xxxxsecure_key";    # Replace with your Secutiry Key
    private static $version = "2.0";
    const PANGLE_HOST = "https://www.pangle.cn";
    const KEY_SIGN_TYPE="sign_type";
    const KEY_SIGN = "sign";
    const KEY_ROLE_ID = "role_id";
    const KEY_USER_ID = "user_id";
    const KEY_VERSION = "version";
    
    // Supported sign method
    private static $sign_array = array(
        'MD5' => 'sign_md5',
    );

    // md5 sign method
    private static function sign_md5($str, $key){
        
        $sign_str = $str . $key;
        $sign = md5($sign_str);
        printf("md5 [sign string without key:%s] => [%s]", $sign_str,$sign);
        return $sign;
    }
    
    // Examine sign method
    private static function valid_sign_method($method){
        
        if (empty(self::$sign_array[$method])) {
            printf("unexpected sign method %s", $method);
            return false;
        }
        return true;
    }
    
    // Sign the string
    private static function sign($method, $str, $key){
        if (!self::valid_sign_method($method)) {
            return false;
        }
        
        return call_user_func(array('self', self::$sign_array[$method]), $str, $key);
    }
    
    // Sign the array
    private static function make_sign($method, $arr_input, $sign_key){
        // Config array to be signed
        $sign_str = '';
        foreach ($arr_input as $key => $val) {
            $sign_str .= '&' . strval($key) . '=' . strval($val);
        }
        $sign_str = substr($sign_str, 1);
        
        // Sign
        $ret = self::sign($method, $sign_str, $sign_key);
        return $ret;
    }
    
    // Create signed query string
    private static function make_signed_querystring($method, $arr_input, $key, $key_sign = self::KEY_SIGN, $key_sign_method = self::KEY_SIGN_TYPE){
        // Sign
        $sign = self::make_signed_array_utf8($method, $arr_input, $key, $key_sign, $key_sign_method);
        if (!$sign) {
            return false;
        }
        
        // Create querystring
        $query_string = http_build_query($arr_input);
        
        return sprintf("%s&%s=%s", $query_string, $key_sign, $sign);
    }
    
    /**
    * to retuen data in json,convert the sign result  into utf-8
    *@param sign_method, array to sign, secure_key, array key of sign and sign_method
    *@return result of sign when success while false if not.
    */
    private static function make_signed_array_utf8($method, &$arr_input, $key, $key_sign = self::KEY_SIGN, $key_sign_method = self::KEY_SIGN_TYPE){
        // add the sign method into the array to be signed
        $arr_input[$key_sign_method] = $method;
        $arr_input[self::KEY_VERSION] = self::$version;
        if (self::$role_id != "") {
            $arr_input[self::KEY_ROLE_ID] = self::$role_id;
        }
        
        if (self::$user_id != "") {
            $arr_input[self::KEY_USER_ID] = self::$user_id;
        }
    
        // Sort Array
        if(!ksort($arr_input)){
            printf("make_signed_array_utf8::sort arr_input failed, arr: %s", printf($arr_input, true));
            return false;
        }

        // create string to be signed
        $signStr = '';
        foreach ($arr_input as $inputKey => $inputVal) {
            $signStr .= '&'.$inputKey.'='.$inputVal;
        }
        $signStr = substr($signStr, 1);
        
        // convert the string to utf-8
        $signStr = mb_convert_encoding($signStr, 'UTF-8', 'GBK');
        
        // Sign
        $ret = self::sign($method, $signStr, $key);
        if(!$ret){
            printf("make sign_utf8 failed, method:%s, str:%s", $method, print_r($arr_input, true));
            return false;
        }
        return $ret;
    }

    static function get_media_rt_income_url($method, $arr_input, $key_sign = self::KEY_SIGN, $key_sign_method = self::KEY_SIGN_TYPE) {
        try {
            return self::PANGLE_HOST . "/union_pangle/open/api/rt/income?" . self::make_signed_querystring($method, $arr_input, self::$secure_key, $key_sign, $key_sign_method);
        } catch (Exception $e) {
            printf($e->getMessage());
            return "";
        }
    }
    
    static function set_secure_key($secure_key) {
        self::$secure_key = $secure_key;
    }
    
    static function set_user_id($user_id) {
        self::$user_id = $user_id;
    }
    
    static function set_role_id($role_id) {
        self::$role_id = $role_id;
    }

}

# Sample
# pangle_media_util::set_secure_key("xxxxsecure_key");
pangle_media_util::set_user_id(459);
pangle_media_util::set_role_id(459);
$params = array(
    "currency"  => "usd",
    "date"      => "2020-11-19",
    "region"    => "jp",
    "time_zone" => 0,
    "timestamp" => "1615778032",
);
$url = pangle_media_util::get_media_rt_income_url('MD5', $params);
echo "\n\n" . $url . "\n";

?>


Response

Primary Params Type Note
Code string Status code
Message string Gives explanation in case an error occurs
Data dict {
  "date" : income_info
}





income_info is a list comprised of dictionaries that contains the following information

Param Name Type Description
time_zone string timezone
currency string currency
region string Two digit country/region code under ISO3166-1
app_id int App id
app_name string App Name
ad_slot_id int Placement id
ad_slot_type int 1(In-feed ad)、2(Banner(Horizontal))、3(Splash ad)、4(Interstitial ad)、5(Rewarded Video Ads)、6(Full Page Video Ads)、7(Draw in-feed ad)、8(In-Stream Ads)、9(New interstitial ad)
package_name string Package name in the form of aaa.bbb.ccc
request int Ad request.  Available upon invitation, returns 0 otherwise.
return int Ad response.  Available upon invitation, returns 0 otherwise.
fill_rate float Fill Rate.  Available upon invitation, returns 0 otherwise.
show int Impressions
click int Clicks
click_rate float Click Through Rate
revenue float Estimated Revenue
ecpm float Estimated Ecpm
media_name string Account name
code_name string Slot name
os string Operating system




Request Sample
https://partner.oceanengine.com/union_pangle/open/api/rt/income?user_id=561&sign=7ff19ec1961d8c2b7c7b3845d974d22e&timestamp=1606034728&date=2020-11-19&currency=usd&region=jp&role_id=561&version=2.0&sign_type=MD5

Response Sample
{
    "Code":"PG0000",
    "Message": "success"
    "Data":{
        "2020-11-19":[
            {
                "ad_slot_id":811583091,
                "app_code_type":0,
                "app_id":5011583,
                "app_name":xxx,
                "ad_slot_type":1,
                "package_name":xxx,
                "media_name":xxx,
                "code_name":xxx,
                "os":xxx,
                "click":0,
                "click_rate":0,
                "currency":"usd",
                "date":"2020-11-19",
                "ecpm":7.71,
                "fill_rate":100,
                "region":"JP",
                "request":8,
                "return":8,
                "revenue":0.06,
                "show":8,
                "time_zone":8
            },
            {
               "ad_slot_id":811583092,
                "app_code_type":0,
                "app_id":5011583,
                "app_name":xxx,
                "ad_slot_type":1,
                "package_name":xxx,
                "media_name":xxx,
                "code_name":xxx,
                "os":xxx,
                "click":0,
                "click_rate":0,
                "currency":"usd",
                "date":"2020-11-19",
                "ecpm":7.71,
                "fill_rate":100,
                "region":"JP",
                "request":8,
                "return":8,
                "revenue":0.06,
                "show":8,
                "time_zone":8
            }
        ]
    }
}


Message

Code Message
100 Success. Any other status code means the request has been unsuccessful
101 Sign verification failed
102 Invalid user_id
103 Invalid date format
106 Exceed QPS limits. Pangle allows up to 5 qps
114 Invalid param




Did the content solve your problem?