广告收入跟踪 API 参考
通过服务器到服务器集成,使用 Singular 的 REST API 跟踪印象级广告货币化收入,以进行归因分析和广告系列优化,作为 SDK 实施的替代方案。
概述
服务器到服务器使用案例
广告收入应用程序接口(Ad Revenue API)可实现印象级广告货币化跟踪,应用程序将收入数据从中介平台转发到您的后台,再由后台传输到 Singular 的服务器,以进行广告收入分析和报告。
支持的功能:
- 广告货币化收入:跟踪来自中介平台的印象级收入
- 平台归因:将广告收入与用户获取活动联系起来
- 中介整合:支持所有主要广告中介平台
- 货币转换:根据组织设置自动进行货币转换
数据流架构
服务器到服务器广告收入跟踪采用四步数据传输流程。
- 客户端收集:应用程序从中介平台 SDK 收集印象级收入数据
- 服务器传输:应用程序将广告收入数据转发至您的后端服务器
- 设备图谱查询:服务器从 Singular 设备图中检索或更新设备详情
- 事件 API 调用:服务器将 __ADMON_USER_LEVEL_REVENUE__ 事件发送到 Singular REST API 端点
关键要求
先决条件
- 事件发生前的会话:会话必须在任何广告收入跟踪之前建立
- 顺序:无效的会话顺序会导致数据不一致和归因错误
- 调解平台数据:直接从调解 SDK 收集所需属性--有关实施细节,请参阅SDK 指南
集成限制:
- 实时处理:请求单独处理,不支持批处理
- 按时间顺序事件:事件必须按发生顺序发送
- 无重复数据删除:Singular 不重复数据--实施服务器端重复数据删除以防止重复
- 数据永久性:设备级数据摄取后不可删除--发送前进行验证
API 端点选择
Singular 提供两个 EVENT 端点版本,针对不同的集成架构进行了优化。
端点选择:根据集成架构和设备标识符策略选择端点。用例决定正确的端点。
事件端点 V1
V1 使用案例
使用事件端点 V1 集成特定于平台的设备标识符(IDFA、IDFV、AIFA、ASID 等)。
推荐用于
- 纯服务器端:无 Singular SDK 实施的服务器端集成
- 混合(非 SDID):Singular SDK 不使用 Singular Device ID (SDID) 的混合集成
端点 URL:
GET https://s2s.singular.net/api/v1/evt
事件端点 V2
V2 使用案例
使用 Event Endpoint V2 进行混合集成,其中 Singular SDK 使用 SDID 跟踪会话,服务器使用相同的 SDID 发送事件。
推荐用于
- 混合(基于 SDID):Singular SDK 使用 SDID 跟踪会话,服务器端事件使用相同的 SDID
- 简化标识符:避免使用特定平台设备标识符(IDFA、AIFA 等)的实施方案
端点 URL:
GET https://s2s.singular.net/api/v2/evt
账户启用:V2 端点需要单账户配置才能使用 SDID。请联系您的解决方案工程师或 CSM 进行启用。
所需设备标识符
设备标识符要求因端点版本和平台而异。 请查看以下平台特定要求。
V1 端点标识符
平台特定标识符
事件终端 V1 需要基于设备操作系统和应用程序分发方法的特定平台广告标识符。
| 参数 | 平台 | 说明 |
|---|---|---|
idfa
|
iOS |
广告商标识符 (IDFA)支持广告跟踪和营销活动归因。 ATT 要求:iOS 14.5 以上版本要求用户通过应用程序跟踪透明度选择加入
示例: |
idfv
|
iOS |
供应商标识符 (IDFV)在同一供应商的所有应用程序中保持一致。 始终必填:无论 ATT 状态或 IDFA 是否可用,都必须包含
示例: |
aifa
|
安卓 (谷歌播放) |
Google Advertising ID (GAID)支持用户重置广告跟踪。
示例: |
asid
|
安卓 (谷歌播放) |
Android 应用程序集 ID为同一开发者提供具有隐私意识的跨应用程序跟踪。 始终需要:必须包含在 Google Play 设备上,无论 GAID 是否可用
示例: |
amid
|
安卓 (亚马逊) |
亚马逊广告 ID,用于没有 Google Play 服务的亚马逊 Fire 设备。
示例: |
oaid
|
安卓 (中国 OEM) |
开放广告标识符 (OAID),用于不支持 Google Play 服务的中国制造设备。
示例: |
andi
|
安卓 (非 Google Play) |
Android ID 是设备生成的 64 位标识符。 限制使用:禁止在 Google Play 设备上使用,只有在没有其他可用标识符且应用程序未通过 Google Play 发布的情况下才能使用。
示例: |
V2 端点标识符
仅 SDID 要求
事件端点 V2 对所有平台都只要求单一设备 ID (SDID),从而简化了设备识别。
| 参数 | 描述 |
|---|---|
sdid
|
平台:iOS、安卓 从 Singular SDK 获取或在客户端生成的奇异设备 ID。
示例: |
必填参数
除设备标识符外,所有 EVENT 请求都必须包含这些必要参数。
参数格式:所有参数必须使用 GET 方法作为 URL 查询参数传递。请勿在 JSON 请求正文中发送参数。
API 身份验证
| 参数 | 类型 | 说明 |
|---|---|---|
a
|
string
|
用于 API 身份验证的单个 SDK 密钥。 从以下地址获取:Singular UI → 主菜单 →开发工具 重要:请勿使用报告 API 密钥,否则请求将被拒绝。
举例说明: |
设备参数
| 参数 | 说明 |
|---|---|
p
|
应用程序的平台(区分大小写)。 允许值:安卓、iOS
示例:Android |
ip
|
设备的公共 IPv4 IP 地址。支持 IPv6,但建议使用 IPv4,以实现属性兼容性。
示例:公共 IPv4 地址 |
ve
|
事件发生时设备的操作系统版本。
示例:事件发生时设备的操作系统版本: |
应用程序参数
| 参数 | 说明 |
|---|---|
i
|
应用程序标识符(区分大小写)。
举例说明: |
att_authorization_statusiOS |
应用程序跟踪透明度 (ATT) 状态代码(iOS 14.5+)。 状态值:
始终需要:即使未执行 ATT,也要通过
示例 |
事件参数
| 参数 | 说明 |
|---|---|
n
|
被跟踪事件的名称。 广告收入必填事件名称:
|
e
|
JSON URL 编码字符串,指定来自调解平台的自定义事件属性。 必填属性:
可选属性:
JSON 结构:
URL 编码示例:
注意:省略无值的属性。 |
is_admon_revenue
|
指定事件是否为广告收入指标的广告货币化收入事件。
示例 |
is_revenue_event
|
指定事件是否为收入指标的收入事件。
示例:指定事件是否为收入指标的收入事件: |
amt
|
印象收入的货币金额。
示例:货币金额 |
cur
|
ISO 4217三字母大写货币代码。
示例:ISO 4217 三字母大写货币代码: |
可选参数
可选参数通过额外的上下文和功能增强了广告收入跟踪功能。
网络参数
| 参数 | 说明 |
|---|---|
use_ip
|
指示 Singular 从 HTTP 请求中提取 IP 地址,而不是 限制:
示例 |
country
|
ISO 3166-1 alpha-2双字母国家代码。
当以下情况时必须提供IP 地址不可用或
示例:ISO 3166-1 alpha-2 双字母国家代码 |
数据隐私
| 参数 | 说明 |
|---|---|
data_sharing_options
|
JSON URL 编码的最终用户同意数据共享。必须在所有后续 EVENT 请求中持续传递。 用户同意(选择加入):
用户拒绝(退出):
URL 编码示例: |
跨设备支持
| 参数 | 说明 |
|---|---|
custom_user_id
|
您用于跨设备跟踪的内部用户 ID。
示例 |
请求示例
示例代码展示了广告收入 EVENT 终端在多种编程语言中的集成。
示例免责声明:代码示例可能不包括所有必要参数。开发/测试时请使用唯一的i (应用程序标识符)。
Python 示例
import requests
params = {
'a': 'sdk_key_here',
'p': 'Android',
'i': 'com.singular.app',
'ip': '10.1.2.3',
've': '9.2',
'aifa': '8ecd7512-2864-440c-93f3-a3cabe62525b',
'asid': 'edee92a2-7b2f-45f4-a509-840f170fc6d9',
'n': '__ADMON_USER_LEVEL_REVENUE__',
'e': '{"ad_platform":"AdMob","ad_mediation_platform":"admob.AdMobAdapter","ad_unit_id":"ca-app-pub-6325336052/44923540"}',
'is_admon_revenue': 'true',
'is_revenue_event': 'true',
'amt': 0.00782,
'cur': 'USD'
}
response = requests.get('https://s2s.singular.net/api/v1/evt', params=params)
print(response.json())
cURL 示例
curl -G "https://s2s.singular.net/api/v1/evt" \
--data-urlencode "a=sdk_key_here" \
--data-urlencode "p=Android" \
--data-urlencode "i=com.singular.app" \
--data-urlencode "ip=10.1.2.3" \
--data-urlencode "ve=9.2" \
--data-urlencode "aifa=8ecd7512-2864-440c-93f3-a3cabe62525b" \
--data-urlencode "asid=edee92a2-7b2f-45f4-a509-840f170fc6d9" \
--data-urlencode "n=__ADMON_USER_LEVEL_REVENUE__" \
--data-urlencode 'e={"ad_platform":"AdMob","ad_mediation_platform":"admob.AdMobAdapter","ad_unit_id":"ca-app-pub-6325336052/44923540"}' \
--data-urlencode "is_admon_revenue=true" \
--data-urlencode "is_revenue_event=true" \
--data-urlencode "amt=0.00782" \
--data-urlencode "cur=USD"
HTTP 示例
GET /api/v1/evt
?a=sdk_key_here
&p=Android
&i=com.singular.app
&ip=10.1.2.3
&ve=9.2
&aifa=8ecd7512-2864-440c-93f3-a3cabe62525b
&asid=edee92a2-7b2f-45f4-a509-840f170fc6d9
&n=__ADMON_USER_LEVEL_REVENUE__
&e=%7B%22ad_platform%22%3A%22AdMob%22%2C%22ad_mediation_platform%22%3A%22admob.AdMobAdapter%22%2C%22ad_unit_id%22%3A%22ca-app-pub-6325336052%2F44923540%22%7D
&is_admon_revenue=true
&is_revenue_event=true
&amt=0.00782
&cur=USD HTTP/1.1
Host: s2s.singular.net
Accept: application/json
Java 示例
// Base URL
String baseUrl = "https://s2s.singular.net/api/v1/evt";
// Parameters
Map<String, String> params = new HashMap<>();
params.put("a", "sdk_key_here");
params.put("p", "Android");
params.put("i", "com.singular.app");
params.put("ip", "10.1.2.3");
params.put("ve", "9.2");
params.put("aifa", "8ecd7512-2864-440c-93f3-a3cabe62525b");
params.put("asid", "edee92a2-7b2f-45f4-a509-840f170fc6d9");
params.put("n", "__ADMON_USER_LEVEL_REVENUE__");
params.put("e", "{\"ad_platform\":\"AdMob\",\"ad_mediation_platform\":\"admob.AdMobAdapter\",\"ad_unit_id\":\"ca-app-pub-6325336052/44923540\"}");
params.put("is_admon_revenue", "true");
params.put("is_revenue_event", "true");
params.put("amt", "0.00782");
params.put("cur", "USD");
// Build URL with encoded parameters
StringBuilder urlBuilder = new StringBuilder(baseUrl);
urlBuilder.append('?');
for (Map.Entry<String, String> entry : params.entrySet()) {
if (urlBuilder.length() baseUrl.length() + 1) {
urlBuilder.append('&');
}
urlBuilder.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8))
.append('=')
.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
}
// Create connection
URL url = new URL(urlBuilder.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
// Get response
int responseCode = conn.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream())
);
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// Check status
System.out.println("HTTP Status Code: " + responseCode);
System.out.println("Response: " + response.toString());
// Disconnect
conn.disconnect();
响应代码和错误
EVENT 端点返回 HTTP 状态代码和 JSON 响应,表明请求成功或失败。
完整错误文档:S2S 响应代码和错误处理
测试与验证
使用 Singular SDK 控制台进行实时数据验证,在生产部署前验证 S2S 广告收入集成。
测试程序
端到端验证
- 注册测试设备:获取设备广告 ID 并添加到Singular SDK 控制台
- 启用控制台日志:在 SDK 控制台中添加设备标识符,以捕获测试数据
-
使用开发应用程序 ID:用开发版本(如
com.singular.app.dev)覆盖应用程序标识符,将测试数据与生产数据分开 - 构建和启动:从终止状态构建或打开应用程序
- 验证客户端数据:确认应用程序向服务器发送所有必要的 Singular 数据点
-
验证会话:确认服务器将 SESSION 请求发送至
https://s2s.singular.net/api/v1/launch并包含所有必要参数 - 检查 SDK 控制台(会话):几秒钟内,SDK 控制台中应出现 SESSION 事件
广告收入事件测试
- 触发广告印象:在应用程序中生成广告印象以触发调解平台回调
- 验证调解数据:确认发送到服务器的印象数据包含所有必要的调解平台属性
-
验证服务器请求:确认服务器向
https://s2s.singular.net/api/v1/evt发送了包含所有必要参数的 EVENT 请求 - 检查 SDK 控制台(事件):几秒钟内,SDK 控制台中应出现 __ADMON_USER_LEVEL_REVENUE__ 事件
- 重复测试:以预期值和正确的收入金额验证发送的所有广告印象
关键验证:
- 在收到 EVENT 之前,确认 SESSION 事件发生在应用程序打开/前景时
- 确认 EVENT 所需的数据点与 SESSION 数据点匹配
- 确认事件参数中传递的调解平台详细信息正确无误
- 确认正确的收入金额和货币
成功指标:如果广告收入事件出现在 SDK 控制台中,则表明您已成功完成端到端广告收入集成测试!
其他资源
测试文档
综合测试指南:S2S 集成测试指南