概要:本文重点讲解了如何使用URI来拉取CSV格式的AppsFlyer汇总报告。
相关参考——Pull API原始数据
Pull API汇总数据特点
- 返回的报告是CSV格式的。
- 数据更新频次与数据总览面板的导出数据页中对应报告的更新频次一致。请注意成本更新会有数小时延迟,具体取决于提供成本数据的渠道。
- 可用的筛选条件:媒体渠道和日期范围
- Pull API的其他功能包括:
- 可以按归因触点类型筛选结果
- 提供不同的时区选项
- Pull API适用于账户用户以及BI开发人员。
类别 | UA(用户获取) | 再营销* | Protect360 |
---|---|---|---|
分渠道报告 | ✓ | ✓ | ✓ |
分渠道每日报告 |
✓ | ✓ | ✓ |
每日报告 |
✓ | ✓ | ✓ |
分国家/地区报告 |
✓ | ✓ | ✓ |
按日期和地域汇总的报告 |
✓ | ✓ | ✓ |
*如要拉取再营销报告,请在URI中添加 |
扩展阅读:
概念定义
术语 | 描述 |
---|---|
Pull API |
通过URI下载CSV报告的解决方案。 |
调用/API调用 |
将URI复制粘贴到浏览器地址栏或通过脚本向AppsFlyer发送URI。 |
URI |
|
使用指南
URI模板简介
- 开发者资源中心(Dev Hub)中的URI模版已填充应用ID和报告类型。
- 模板中留出了API V1.0令牌以及日期范围的位置,这两个字段是需要您编辑的。
- URI中问号(?)右侧的部分是各种参数,每个参数都以&开始。您可以使用这些参数来设置筛选条件、添加特定的字段(如货币币种和时区),比如您可以通过media_source(媒体渠道)参数在汇总报告中筛选某一个媒体渠道的结果,如
&media_source=facebook
。 - 请完成以下入门教程,更熟练地掌握Pull API这个工具。
请完成以下Pull API报告入门流程:
前期准备:- 让AF账户管理员把V1.0 Token发给您。
请按以下步骤从开发者资源中心(Dev Hub)下载报告:
-
进入AppsFlyer开发者资源中心(Dev Hub)的API参考信息部分。
-
在左侧菜单栏中选择一个报告类型。
如原始数据报告(非自然量) > 激活。
各种可用报告类型请见下表。 - 填写所有必填字段。
- 界面右侧会显示URI模板。
- 点击复制图标,复制该URI。
- 在浏览器中打开一个新的标签页,然后将URI粘贴到地址栏中。
- 按下回车键,发送API调用。
开始下载报告。
报告 | 描述 | 更新频率 |
---|---|---|
原始数据报告(非自然) | ||
激活假量 | 用于记录非自然激活。每当有用户首次启动应用时就会生成一条记录。 |
实时 |
应用内事件 | 用于记录用户完成的事件。 |
实时 |
卸载 | 用于记录用户的应用卸载情况。 |
每日报告 |
重装激活 |
用于记录用户卸载应用后与拉新渠道互动并在再归因窗口期内重新安装并激活应用的情况。 | 实时 |
原始数据报告(自然量) |
||
自然激活 |
用于记录用户首次打开应用的情况。 |
持续滚动 |
自然应用内事件 |
用于记录用户所完成的事件的详细信息。 | 持续滚动 |
自然卸载 |
用于记录用户的应用卸载情况。 | 每日报告 |
自然重装激活 |
用于记录带量的再营销渠道在再互动窗口期内带来的广告收入。 |
每天更新一次 |
广告收入原始数据 |
||
非自然广告收入 |
用于记录非自然(由媒体渠道带来的)用户产生的广告收入。 | 每日报告 |
自然变现收入 | 用于记录自然(未归因到渠道的)用户产生的广告收入。 | 每日报告 |
Protect360 防作弊 | ||
激活假量 | 用于记录系统识别的激活假量,AF不会将这些激活归因到任何媒体渠道。 | 实时 |
归因后-重新被判断为假量 | 用于记录来自虚假激活的应用内事件,AF不会对这些事件进行归因。 | 实时 |
应用内事件 | 用于记录Protect360识别到的应用内事件假量。 | 每日报告 |
归因后假量-应用内事件 | 用于记录归因到某渠道后被识别为假量的激活所产生的应用内事件,或直接被识别为假量的应用内事件。 | 每日报告 |
点击 | 用于记录被Protect360拦截的用户所完成的点击。 | 每日报告 |
已拦截的激活回传 | 若某渠道带来的激活被拦截,该报告会记录发送到这些渠道的回传。 | 实时 |
数据回传 | ||
激活回传 | 用于记录用户首次打开应用所形成的激活。 | 每日报告 |
应用内事件回传 | 用于记录发送到渠道的应用内事件回传。 | 每日报告 |
再营销应用内事件回传 | 用于记录用户在再互动窗口期内完成的应用内事件。 | 实时 |
再营销转化回传 | 用于记录用户在再互动窗口期内完成的应用内事件。 | 实时 |
汇总数据Pull API的参数
汇总报告URI和参数
参数 | 描述 |
---|---|
api_token | 即V1.0 API令牌,在调用示例中显示为:<API TOKEN HERE>。 |
from |
|
to |
结束日期,与from 相对
|
参数 | 描述 |
---|---|
media_source |
用于按具体的媒体渠道筛选结果。
|
attribution_touch_type |
请根据示例来设置该参数,从而拉取浏览型归因(VTA)指标。 示例: |
currency |
收入和成本的货币币种。 汇总Pull API报告按应用层级的指定货币显示相关值。 |
reattr |
用于拉取再营销转化数据。
|
timezone |
【默认】数据以UTC时间显示。
选择时区时的注意事项
|
在报告中仅查看Google Ads的数据
https://hq.appsflyer.com/export/com.greatapp/partners_report/v5?api_token=xxxx
&from=2018-04-09&to=2018-05-09&media_source=googleadwords_int
在报告中仅查看Facebook的数据
https://hq.appsflyer.com/export/com.greatapp/partners_report/v5?api_token=xxxx
&from=2018-04-09&to=2018-05-09&media_source=facebook
参数 | 描述 |
---|---|
URI |
|
PID |
您可以使用 |
timezone |
选择您所使用的时区来显示数据。 如果不发送timezone参数,那么报告会以UTC时间来显示数据。 URI模板中包含了timezone参数。 示例: |
KPI关键绩效指标 |
Protect360参数在Pull API和Master API中是一样的。
|
浏览型归因(VTA)的KPI
- 请在Pull API汇总报告URI中添加参数attribution_touch_type=impression,来拉取VTA指标。具体请见下表示例。
- 该参数可用于任何汇总报告。只需从面板中复制URI,然后在其中加入该参数即可。
- 您可以通过添加&media_source参数来拉取某个渠道的报告,具体请见下表示例。
- 点击、展示、成本等部分VTA指标没有对应的值,因此在报告中显示为N/A。
示例 | URI示例 |
---|---|
仅VTA | https://hq.appsflyer.com/export/{app_id}/partners_report/v5?api_token={API token}&from=yyyy-mm-dd&to=yyyy-mm-dd&attribution_touch_type=impression |
VTA和媒体渠道 |
https://hq.appsflyer.com/export/{app_id}/partners_report/v5?api_token={API token}&from=yyyy-mm-dd&to=yyyy-mm-dd&attribution_touch_type=impression&media_source=example_ad_network |
开发人员的Pull API使用指南
部署原理
前期准备:
请先了解账户用户应如何使用Pull API。
其中需要注意以下几点:
- Dev Hub为每个可用的报告类型都提供了URI模板。请在左侧菜单栏中选择一个报告类型。
- 您可以通过修改模板来调整拉取到的数据,比如设定日期范围并根据参数筛选结果。
- 原始数据报告和汇总数据报告的参数有所不同,具体请见报告部分。
路径 |
|
路径参数 |
|
HTTP方法 |
|
参数 | 描述 |
---|---|
URI示例 |
|
api_token |
|
其他参数 |
各类报告的可用参数有所不同,具体请参见以下文档: |
示例
URI调用示例中包括可选参数:
https://hq.appsflyer.com/export/example.app.com/installs_report/v5?
api_token={Account owner API key should be used}&from=yyyy-mm-dd
&to=yyyy-mm-dd&additional_fields=keyword_id,store_reinstall,
deeplink_url,oaid,install_app_store,contributor1_match_type,
contributor2_match_type,contributor3_match_type,match_type
脚本示例
在脚本中添加Pull API来拉取数据
- 根据业务需求编辑脚本中的报告类型、日期范围和筛选条件部分。
- 下列示例中使用的是激活报告。
import okhttp3.*;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.concurrent.TimeUnit;
public class PullApi {
public static void main(String[] args){
String appID = "<APP_ID>";
String reportType = "<REPORT_TYPE>";
String apiToken = "<API_TOKEN>";
String from = "<FROM_DATE>";
String to = "<TO_DATE>";
String requestUrl = "https://hq.appsflyer.com/export/" + appID + "/" + reportType + "/v5?api_token=" + apiToken + "&from=" + from + "&to=" + to;
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
Request request = new Request.Builder()
.url(requestUrl)
.addHeader("Accept", "text/csv")
.build();
try {
Response response = client.newCall(request).execute();
if(response.code() != 200) {
if(response.code() == 404) {
System.out.println("There is a problem with the request URL. Please make sure it is correct");
}
else {
assert response.body() != null;
System.out.println("There was a problem retrieving the data: " + response.body().string());
}
} else {
assert response.body() != null;
String data = response.body().string();
BufferedWriter writer;
writer = new BufferedWriter(new FileWriter(appID + "-" + reportType + "-" + from + "-to-" + to + ".csv"));
writer.write("");
writer.write(data);
writer.close();
}
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
request = require('request');
const fs = require('fs');
const appID = '<APP_ID>';
const reportType = '<REPORT_TYPE>';
const apiToken = '<API_TOKEN>';
const from = '<FROM_DATA>';
const to = '<T0_DATE>';
const requestUrl = `https://hq.appsflyer.com/export/${appID}/${reportType}/v5?api_token=${apiToken}&from=${from}&to=${to}`;
request(requestUrl, (error, response, body) => {
if (error) {
console.log('There was a problem retrieving data:', error);
}
else if (response.statusCode != 200) {
if (response.statusCode === 404) {
console.log('There is a problem with the request URL. Make sure that it is correct');
} else {
console.log('There was a problem retrieving data:', response.body);
}
} else {
fs.writeFile(`${appID}-${reportType}-${from}-to-${to}.csv`, response.body, (err) => {
if (err) {
console.log('There was a problem writing to file: ', err);
} else {
console.log('File was saved');
}
});
}
});
import requests
app_id = '<APP_ID>'
report_type = '<REPORT_TYPE>'
params = {
'api_token': '<API_TOKEN>',
'from': 'FROM_DATE',
'to': 'TO_DATE'
}
request_url = 'https://hq.appsflyer.com/export/{}/{}/v5'.format(app_id, report_type)
res = requests.request('GET', request_url, params=params)
if res.status_code != 200:
if res.status_code == 404:
print('There is a problem with the request URL. Make sure that it is correct')
else:
print('There was a problem retrieving data: ', res.text)
else:
f = open('{}-{}-{}-to-{}.csv'.format(app_id, report_type, params['from'], params['to']), 'w', newline='', encoding="utf-8")
f.write(res.text)
f.close()
using System;
using RestSharp;
using System.Text;
using System.Net;
using System.IO;
namespace Pull_API
{
class PullAPi
{
static void Main(string[] args)
{
var appID = "<APP_ID>";
var reportType = "<REPORT_TYPE>";
var apiToken = "<API_TOKEN>";
var from = "<FROM_DATE>";
var to = "<TO_DATE>";
var requestUrl = "https://hq.appsflyer.com/export/" + appID + "/" + reportType + "/v5?api_token=" + apiToken + "&from=" + from + "&to=" + to;
var client = new RestClient(requestUrl);
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "text/csv; charset=UTF-8");
IRestResponse response = client.Execute(request);
HttpStatusCode statusCode = response.StatusCode;
int numericStatusCode = (int)statusCode;
if(numericStatusCode != 200){
if(numericStatusCode == 404){
Console.WriteLine("There is a problem with the request URL. Make sure that it is correct.");
} else {
Console.WriteLine("There was a problem retrieving data: " + response.Content);
}
} else {
System.IO.File.WriteAllText(@"" + appID + "-" + reportType + "-" + from + "-to-" + to + ".csv", response.Content);
Console.WriteLine("Data retrieved succesfully");
}
}
}
}
<?
$appID = '<APP_ID>';
$reportType = '<REPORT_TYPE>';
$apiToken = '<API_TOKEN>';
$from = '<FROM_DATE>';
$to = '<TO_DATE>';
$query = http_build_query([
'api_token' => $apiToken,
'from' => $from,
'to' => $to
]);
$requestUrl = 'https://hq.appsflyer.com/export/' . $appID . '/' . $reportType . '/v5?'.$query;
$report = $appID . '-' . $report . '-' . $from . '-to-' . $to;
$curl = curl_init($requestUrl);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_ENCODING, "");
curl_setopt($curl, CURLOPT_NOSIGNAL, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_MAXREDIRS, 10);
curl_setopt($curl, CURLOPT_FAILONERROR, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 100);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"cache-control: no-cache",
"Accept: text/csv; charset=UTF-8"
));
$response = curl_exec($curl);
$info = curl_getinfo($curl);
$err = curl_error($curl);
curl_close($curl);
var_dump($response);
if ($err) {
echo $info['http_code'];
echo "cURL Error #: " . $err . '. ';
if ($info['http_code'] == 404) {
echo 'There is a problem with the request URL. Make sure that it is correct';
}
if ($info['http_code'] == 401) {
echo 'There was a problem retrieving data: authentication failed.';
}
echo PHP_EOL;
} else {
$fp = fopen($report, 'w+');
fwrite($fp, $response);
fclose($fp);
echo $response;
}
?>
其他信息
特点与局限性
特征 | 说明 |
---|---|
规定的API令牌类型 |
![]() |
渠道权限 | N |
代理访问权限 | Y |
代理数据透明化 | Y |
应用层级指定货币 | Y |
应用层级指定时区 | Y |
成本 | 成本数据仅限UA广告;再营销广告或无转化广告(未带来任何激活的广告)是没有成本数据的。 |
数据时效性 | 持续滚动 |
历史数据 | Y |
非自然量数据 | Y |
自然量数据 | Y |
拉取频次限制 | |
大小限制 |
请注意:Pull API的原始数据报告最多可包含100万行数据,汇总数据报告最多可包含20万行数据。 |
广告系列名称变更 | Pull API报告不支持广告系列名称变更 |
API错误代码及疑难解答
状态 | 代码 | 问题表现/报错 | 解决方案 |
---|---|---|---|
OK | 200 | CSV文件为空 |
|
OK |
200 |
|
URI中没有API令牌 |
Bad request (请求无效) |
400 |
Raw Reports historical lookback is limited to 90 days |
将 |
Bad request (请求无效) |
400 |
Your API calls limit has been reached for the given report type |
- |
Unauthorized (无权限) |
401 |
Supplied API token is invalid |
向管理员申请现行令牌。 |
Unauthorized (无权限) |
401 |
Account may be suspended |
请登入面板并查看账户状态。 |
Not found (不存在) |
404 |
弹出AppsFlyer404报错页面 |
|