EVENT 端点 API 参考
通过服务器到服务器集成,使用 Singular 的 REST API 跟踪应用内事件和收入,以进行归因分析和营销活动优化,作为 SDK 实施的替代方案。
概述
服务器到服务器用例
EVENT API 支持应用程序内事件跟踪,应用程序将用户交互数据转发至后台,后台将数据传输至 Singular 服务器,用于事件归因和收入分析报告。
支持的功能:
- 事件归因:将用户行为与营销活动联系起来
- 收入跟踪:测量和归因应用内购买和交易
- 自定义事件:跟踪从注册到等级完成的任何用户互动
- 事件属性:为事件附加上下文数据,以便进行更深入的分析
数据流架构
服务器到服务器事件跟踪遵循四步数据传输流程。
- 客户端收集:应用程序收集事件数据和设备标识符
- 服务器传输:应用程序将事件数据转发到后端服务器
- 设备图查询:服务器从 Singular 设备图中检索或更新设备详细信息
- 事件 API 调用:服务器将事件发送至 Singular REST API 端点
关键要求
先决条件
- 事件发生前的会话:在跟踪任何事件之前,必须先建立会话
- 顺序:无效的会话顺序会导致数据不一致和归因错误
集成限制:
- 实时处理:请求单独处理,不支持批处理
- 按时间顺序事件:事件必须按发生顺序发送
- 无重复数据删除:Singular 不重复数据--实施服务器端重复数据删除以防止重复
- 数据永久性:设备级数据摄取后不可删除--发送前进行验证
事件跟踪指南
按照 Singular 命名规则和数据结构的最佳实践实施事件跟踪。
事件定义
定义事件
在实施 S2S 集成之前,请定义贵组织希望跟踪的完整事件列表,以便进行营销活动绩效分析。
事件规划指南:定义应用程序内事件
事件命名影响:传递给 Singular 的事件名称直接决定了事件在报告、导出和回传中的显示方式。
标准事件命名
最佳实践:
- 标准事件:使用Singular 的标准事件命名规范,简化合作伙伴集成映射
- 英语:以英文传递事件名称,以便与第三方合作伙伴和分析解决方案兼容
- 标准属性:为事件属性使用标准事件属性名称
字符限制
长度限制:
- 事件名称:最多 32 个 ASCII 字符(非 ASCII 转换为 UTF-8 时为 32 字节
- 事件属性:每个属性键和值最多不超过 500 个 ASCII 字符
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 发布的情况下才能使用。
示例: |
sdid
|
网络、PC、控制台、CTV |
单个设备 ID,用于没有原生广告标识符的平台。
示例: |
sing
|
仅限企业 |
客户端定义的标识符,用于无法使用标准标识符的特殊用例。 受限:仅限企业客户--必须由 Singular 解决方案工程师根据每个应用程序启用。
示例: |
V2 端点标识符
仅 SDID 要求
Event Endpoint V2 对所有平台只要求使用 Singular 设备 ID (SDID),从而简化了设备识别。
| 参数 | 说明 |
|---|---|
sdid
|
平台:iOS、Android、Web、PC、Xbox、PlayStation、任天堂、MetaQuest、CTV 从 Singular SDK 获取的奇异设备 ID 或为 PC/控制台/CTV 生成的客户端 ID。
示例: |
必填参数
除设备标识符外,所有 EVENT 请求都必须包含这些必要参数。
参数格式:所有参数必须使用 GET 方法作为 URL 查询参数传递。请勿在 JSON 请求正文中发送参数。
API 身份验证
| 参数 | 类型 | 说明 |
|---|---|---|
a
|
string
|
用于 API 身份验证的单个 SDK 密钥。 从以下地址获取:Singular UI → 主菜单 →开发工具 重要:请勿使用报告 API 密钥,否则请求将被拒绝。
举例说明: |
设备参数
| 参数 | 说明 |
|---|---|
p
|
应用程序的平台(区分大小写)。 允许值:Android、iOS、Web、PC、Xbox、Playstation、任天堂、MetaQuest、CTV
示例 |
ip
|
设备的公共 IPv4 IP 地址。支持 IPv6,但建议使用 IPv4,以保证属性兼容性。
示例 |
ve
|
事件发生时设备的操作系统版本。
示例:事件发生时设备的操作系统版本: |
应用程序参数
| 参数 | 说明 |
|---|---|
i
|
应用程序标识符(区分大小写)。
例如 |
att_authorization_statusiOS |
应用程序跟踪透明度 (ATT) 状态代码(iOS 14.5+)。 状态值:
始终需要:即使未执行 ATT,也要通过
示例 |
事件参数
| 参数 | 说明 |
|---|---|
n
|
被跟踪事件的名称。
例如 |
可选参数
可选参数通过额外的上下文和功能来增强事件跟踪功能。
时间戳参数
| 参数 | 类型 | 说明 |
|---|---|---|
utime
|
int
|
事件的 10 位 Unix 时间戳。
例如 |
umilisec
|
int
|
含毫秒的 13 位 Unix 时间戳。
举例 |
maiOS、安卓 |
string
|
设备品牌(制造商名称)。必须与
示例: |
moiOS、安卓 |
string
|
设备型号。必须与
示例: |
lciOS、安卓 |
string
|
IETF 本地标记--两个字母的语言和国家代码,用下划线分隔。
示例 |
bdiOS、安卓 |
string
|
设备构建标识符,URL 编码。
示例: |
事件属性
| 参数 | 说明 |
|---|---|
e
|
指定自定义事件属性的 JSON URL 编码字符串。 JSON 结构:
URL 编码示例:
|
global_properties
|
JSON URL 编码对象,包含全局应用于事件的自定义键值对。 限制:
JSON:
URL 编码: |
网络参数
| 参数 | 说明 |
|---|---|
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。
示例 |
SKAdNetwork 支持
| 参数 | 说明 |
|---|---|
skan_conversion_valueiOS |
事件发生时的最新 SKAdNetwork 转换值。 了解更多信息:SKAdNetwork 实现
示例: |
skan_first_call_timestampiOS |
首次调用 SKAdNetwork API 的 Unix 时间戳。
示例:iOS |
skan_last_call_timestampiOS |
事件发生时最近一次调用 SKAdNetwork API 的 Unix 时间戳。
示例:iOS |
收入跟踪
通过适当的验证和货币处理,跟踪应用内购买和收入事件。
所需收入参数
基本收入跟踪
在执行自己的收入验证时,跟踪收入事件所需的最低参数。
最佳实践:在向 Singular 发送事件请求之前,先在服务器端与应用程序商店验证收入事件。 如果自行验证,则只需要这些参数。
| 参数 | 类型 | 说明 |
|---|---|---|
is_revenue_event
|
string
|
指定事件是否为收入事件。
示例 |
amt
|
double
|
交易的货币金额。
示例:交易金额 |
cur
|
string
|
ISO 4217三字母大写货币代码。
示例:ISO 4217 三字母大写货币代码: |
收入验证参数
Singular 验证收入
可选参数,用于 Singular 对应用程序商店执行服务器端收入验证。
验证要求:
- 如果依赖 Singular 对应用程序商店的收入进行验证,则必须使用该参数
- 确认购买收据和签名值的语法正确
-
不正确的格式会导致 Singular 阻止收入并生成
__iapinvalid__事件。
| 参数 | 说明 |
|---|---|
purchase_receiptiOS、安卓 |
从购买交易中收到的收据。
示例(iOS):
示例(Android,URL 编码):
|
receipt_signature安卓 |
用于签署购买收据的签名(仅限 Android)。 示例:
|
purchase_product_id
|
产品 SKU 标识符。
示例:产品 SKU 标识符: |
purchase_transaction_id
|
交易标识符。
示例(iOS):
示例(安卓): |
请求示例
示例代码展示了 EVENT 端点与多种编程语言的集成。
示例免责声明:代码示例可能未包含所有所需参数。在生产实施前,请验证完整的参数列表。使用唯一的i (应用程序标识符)进行开发/测试。
Python 示例
import requests
params = {
'a': 'sdk_key_here',
'p': 'Android',
'i': 'com.singular.app',
'ip': '10.1.2.3',
've': '9.2',
'ma': 'samsung',
'mo': 'SM-G935F',
'lc': 'en_US',
'bd': 'Build/13D15',
'aifa': '8ecd7512-2864-440c-93f3-a3cabe62525b',
'asid': 'edee92a2-7b2f-45f4-a509-840f170fc6d9',
'n': 'sng_add_to_cart'
}
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 "ma=samsung" \
--data-urlencode "mo=SM-G935F" \
--data-urlencode "lc=en_US" \
--data-urlencode "bd=Build/13D15" \
--data-urlencode "aifa=8ecd7512-2864-440c-93f3-a3cabe62525b" \
--data-urlencode "asid=edee92a2-7b2f-45f4-a509-840f170fc6d9" \
--data-urlencode "n=sng_add_to_cart"
HTTP 示例
GET /api/v1/evt
?a=sdk_key_here
&p=Android
&i=com.singular.app
&ip=10.1.2.3
&ve=9.2
&ma=samsung
&mo=SM-G935F
&lc=en_US
&bd=Build%2F13D15
&aifa=8ecd7512-2864-440c-93f3-a3cabe62525b
&asid=edee92a2-7b2f-45f4-a509-840f170fc6d9
&n=sng_add_to_cart 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("ma", "samsung"); params.put("mo", "SM-G935F"); params.put("lc", "en_US"); params.put("bd", "Build/13D15");
params.put("aifa", "8ecd7512-2864-440c-93f3-a3cabe62525b");
params.put("asid", "edee92a2-7b2f-45f4-a509-840f170fc6d9");
params.put("n", "sng_add_too_cart"); // 使用编码参数构建 URL 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('&'); } urlBuilder.append('&'); { urlBuilder.append('&')append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8)) .append('=') .append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8); } urlBuilder.UTF_8)); } // 创建连接 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()); //获取响应receiveResponseCode(); 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()); // 断开连接 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发送了包含所有所需参数的事件请求 - 检查 SDK 控制台(事件):几秒钟内,SDK 控制台中应出现 EVENT
- 重复测试:根据预期值验证发送的所有事件
关键验证:
- 在收到 EVENT 之前,确认 SESSION 事件发生在应用程序打开/前景时
- 确认 EVENT 所需的数据点与 SESSION 数据点匹配
成功指标:如果事件出现在 SDK 控制台中,则表明您已成功完成端到端事件集成测试!
其他资源
测试文档
综合测试指南:S2S 集成测试指南