SESSION 端点 API 参考
通过 Singular 的 REST API 使用服务器到服务器(S2S)集成作为 SDK 实现的替代方案,跟踪用户会话并为应用安装、再互动和留存指标提供归因能力。
概述
服务器到服务器用例
当用户打开你的应用时,SESSION 端点会通知 Singular,从而支持安装和再互动归因以及留存指标。刚接触服务器到服务器?请参阅 S2S 基础指南 了解核心概念和通用设置。
支持的功能:
- 安装归因: 针对营销广告系列的首次触点归因
- 再互动归因: 针对回访用户的多触点归因
- 留存指标: 基于会话的互动跟踪
会话管理
SESSION 端点向 Singular 通知应用打开事件,以便初始化用户会话用于归因和跟踪。
何时发送会话
会话触发条件
在以下应用生命周期事件中发送 SESSION 请求:
- 全新安装: 安装后首次启动应用
- 终止状态启动: 从完全关闭状态打开应用
- 从后台切换到前台: 应用在超时时间过后返回前台(推荐:60 秒)
会话超时逻辑
实现会话超时机制,以防止应用短暂进入后台期间产生过多的 SESSION 请求。
推荐实现:
- 超时时长: 60 秒(1 分钟)
- 前台 < 超时: 如果应用在超时时间内返回前台,则不发送 SESSION
- 前台 > 超时: 如果应用在后台停留超过超时时间,则发送 SESSION
- 应用生命周期跟踪: 使用应用生命周期事件和计时器来管理会话状态
深度链接支持:
对于通过深度链接、Universal Links 或 App Links 打开应用且已填充
openuri
参数的情况,无论超时状态如何,都应始终发送 SESSION。
归因处理
基于会话的归因
Singular 会处理 SESSION 请求,以确定归因类型并触发相应的工作流程。
| 会话类型 | Singular 处理 | 归因结果 |
|---|---|---|
| 首次会话(新安装) | 触发安装归因流程 | 将安装归因到营销广告系列 |
| 符合再互动条件 | 触发再互动归因流程 | 将用户回访归因到广告系列或深度链接 |
| 标准会话 | 记录会话用于留存跟踪 | 计入用户活动和互动指标 |
了解更多: 再互动归因常见问题
事件顺序要求
会话和事件的时序会直接影响归因准确性和数据质量。
关键排序规则:
- 会话先于事件: 必须在该会话的任何事件之前收到单个 SESSION
- 实时事件传输: 应用内事件必须在其相应会话之后实时发送
- 顺序处理: 无效的会话顺序会导致数据不一致和归因错误
API 端点规范
SESSION 端点接受 POST 请求,参数以
application/x-www-form-urlencoded
形式发送。
端点
基础 URL 和方法
POST https://s2s.singular.net/api/v1/launch
必需的请求头:
Content-Type: application/x-www-form-urlencoded
请求格式:
POST /api/v1/launch HTTP/1.1
Host: s2s.singular.net
Content-Type: application/x-www-form-urlencoded
param1=value1¶m2=value2
必需参数
所有 SESSION 请求都必须包含这些必需参数,并使用正确的值和格式。
API 身份验证
SDK Key
| 参数 | 详情 |
|---|---|
a
|
类型:
字符串
重要: 请勿使用 Reporting API Key。请求将被拒绝。
示例:
|
设备标识符
特定平台标识符
| 参数 | 详情 |
|---|---|
idfa
|
平台:
iOS
|
idfv
|
平台:
iOS
|
aifa
|
平台:
Android
|
asid
|
平台:
Android
|
amid
|
平台:
Android
|
oaid
|
平台:
Android
|
andi
|
平台:
Android
受限使用: 在 Google Play 设备上禁止使用——请改用 AIFA 和 ASID。仅当没有其他可用标识符且应用不通过 Google Play 分发时才发送。
示例:
|
sdid
|
平台:
iOS、Android、PC、Xbox、PlayStation、Nintendo、MetaQuest、CTV
|
设备参数
设备信息
| 参数 | 详情 |
|---|---|
p
|
类型:
字符串
|
ip
|
类型:
字符串
|
ve
|
类型:
字符串
|
ma
|
平台:
iOS、Android
|
mo
|
平台:
iOS、Android
|
lc
|
平台:
iOS、Android
|
bd
|
平台:
iOS、Android
|
应用参数
应用信息
| 参数 | 详情 |
|---|---|
i
|
类型:
字符串
|
app_v
|
类型:
字符串
|
att_authorization_status
|
平台:
iOS
始终必需:
即使未实现 ATT,也要传递
示例:
|
| 参数 | 详情 |
|---|---|
install
|
类型:
布尔值
|
install_time
|
平台:
iOS、Android
这是设备安装时间,而非 Singular 的归因安装时间。归因使用首次会话(
请参阅 设备数据检索指南 了解如何在 iOS 和 Android 上获取此值。 |
update_time
|
平台:
iOS、Android
请参阅 设备数据检索指南 了解如何在 iOS 和 Android 上获取此值。 |
反欺诈参数
安装来源验证
| 参数 | 详情 |
|---|---|
install_source
|
平台:
Android、PC
|
install_receipt
|
平台:
iOS
|
深度链接参数
深度链接支持
| 参数 | 详情 |
|---|---|
openuri
|
平台:
iOS、Android
|
ddl_enabled
|
平台:
iOS、Android
|
singular_link_resolve_required
|
平台:
iOS、Android
|
高级归因参数
平台归因增强
| 参数 | 详情 |
|---|---|
install_ref
Native PC (Google Play Games)
|
平台:
Android (Google Play)
|
meta_ref
|
平台:
Android (Google Play)
自 2025 年 6 月 18 日起: Meta Advanced Mobile Measurement (AMM) 无需再实现 Meta Install Referrer。如果已启用 AMM,则不推荐使用。
经过 JSON URL 编码的 Meta Install Referrer,用于细粒度的用户级归因数据。
|
attribution_token
|
平台:
iOS
|
可选参数
可选参数可增强跟踪能力并支持高级功能。
时间戳参数
| 参数 | 详情 |
|---|---|
utime
|
类型:
整数
|
umilisec
|
类型:
整数
|
网络和位置参数
| 参数 | 详情 |
|---|---|
use_ip
|
类型:
布尔值
限制:
示例:
|
country
|
类型:
字符串
|
ua
|
类型:
字符串
|
c
|
平台:
iOS、Android
|
cn
|
平台:
iOS、Android
|
自定义属性
| 参数 | 详情 |
|---|---|
global_properties
|
类型:
JSON
|
卸载跟踪支持
| 参数 | 详情 |
|---|---|
apns_token
|
平台:
iOS
|
fcm
|
平台:
Android
|
数据隐私参数
| 参数 | 详情 |
|---|---|
data_sharing_options
|
类型:
JSON
|
dnt
|
平台:
iOS、Android
|
dntoff
|
平台:
iOS、Android
|
跨设备支持
| 参数 | 详情 |
|---|---|
custom_user_id
|
类型:
字符串
禁止 PII: 请勿传递个人身份信息。请使用经过哈希处理或以其他方式匿名化的内部标识符,而不是原始的电子邮件地址、电话号码或姓名。
示例:
|
SKAdNetwork 支持
| 参数 | 详情 |
|---|---|
skan_conversion_value
|
平台:
iOS
|
skan_first_call_timestamp
|
平台:
iOS
|
skan_last_call_timestamp
|
平台:
iOS
|
Google Ads ICM 支持(Beta)
| 参数 | 详情 |
|---|---|
odm_info
|
平台:
iOS
|
odm_error
|
平台:
iOS
|
请求示例
示例代码演示了如何在多种编程语言中集成 SESSION 端点。
示例免责声明:
代码示例可能未包含所有必需参数。在生产环境实现之前,请先验证完整的参数列表。开发/测试时请使用唯一的
i
(应用标识符)。
Python 示例
import requests
url = 'https://s2s.singular.net/api/v1/launch'
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
data = {
'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',
'aifa': '8ecd7512-2864-440c-93f3-a3cabe62525b',
'asid': 'edee92a2-7b2f-45f4-a509-840f170fc6d9',
'install': 'true',
'n': 'MyCoolAppName',
'bd': 'Build/13D15',
'app_v': '1.2.3',
'openuri': 'myapp://home/page?queryparam1=value1',
'ddl_enabled': 'true',
'install_source': 'com.android.vending',
'install_time': 1510040127,
'update_time': 1510090877
}
response = requests.post(url, data=data, headers=headers)
print(response.json())
cURL 示例
curl -X POST "https://s2s.singular.net/api/v1/launch" \
-H "Content-Type: application/x-www-form-urlencoded" \
--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 "aifa=8ecd7512-2864-440c-93f3-a3cabe62525b" \
--data-urlencode "asid=edee92a2-7b2f-45f4-a509-840f170fc6d9" \
--data-urlencode "install=true" \
--data-urlencode "n=MyCoolAppName" \
--data-urlencode "bd=Build/13D15" \
--data-urlencode "app_v=1.2.3" \
--data-urlencode "openuri=myapp://home/page?queryparam1=value1" \
--data-urlencode "ddl_enabled=true" \
--data-urlencode "install_source=com.android.vending" \
--data-urlencode "install_time=1510040127" \
--data-urlencode "update_time=1510090877"
HTTP 示例
POST /api/v1/launch HTTP/1.1
Host: s2s.singular.net
Content-Type: application/x-www-form-urlencoded
Accept: application/json
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&aifa=8ecd7512-2864-440c-93f3-a3cabe62525b&asid=edee92a2-7b2f-45f4-a509-840f170fc6d9&install=true&n=MyCoolAppName&bd=Build%2F13D15&app_v=1.2.3&openuri=myapp%3A%2F%2Fhome%2Fpage%3Fqueryparam1%3Dvalue1&ddl_enabled=true&install_source=com.android.vending&install_time=1510040127&update_time=1510090877
Java 示例
// Endpoint
String endpoint = "https://s2s.singular.net/api/v1/launch";
// 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("aifa", "8ecd7512-2864-440c-93f3-a3cabe62525b");
params.put("asid", "edee92a2-7b2f-45f4-a509-840f170fc6d9");
params.put("install", "true");
params.put("n", "MyCoolAppName");
params.put("bd", "Build/13D15");
params.put("app_v", "1.2.3");
params.put("openuri", "myapp://home/page?queryparam1=value1");
params.put("ddl_enabled", "true");
params.put("install_source", "com.android.vending");
params.put("install_time", "1510040127");
params.put("update_time", "1510090877");
// Build form-urlencoded body
StringBuilder form = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (form.length() > 0) form.append('&');
form.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8))
.append('=')
.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
}
byte[] body = form.toString().getBytes(StandardCharsets.UTF_8);
// Create connection
URL url = new URL(endpoint);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Accept", "application/json");
// Write body
try (OutputStream os = conn.getOutputStream()) {
os.write(body);
}
// 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();
System.out.println("HTTP Status Code: " + responseCode);
System.out.println("Response: " + response.toString());
conn.disconnect();
响应码和错误
SESSION 端点返回 HTTP 状态码和 JSON 响应,指示请求成功或失败。
完整的错误文档: S2S 响应码和错误处理
测试和验证
在生产环境部署之前,使用 Singular SDK Console 进行实时数据验证,以验证 S2S 集成。
测试流程
端到端验证
- 注册测试设备: 获取设备广告 ID 并添加到 Singular SDK Console
- 启用 Console 日志记录: 在 SDK Console 中添加设备标识符以捕获测试数据
-
使用开发环境 App ID:
使用开发版本覆盖应用标识符(例如
com.singular.app.dev),以将测试数据与生产数据分开 - 启动应用: 从终止状态打开应用以触发会话
- 验证客户端数据: 确认应用向你的服务器发送了所有必需的 Singular 数据点
-
验证服务器请求:
确认你的服务器向
https://s2s.singular.net/api/v1/launch发送了包含所有必需参数的 SESSION 请求 - 检查 SDK Console: 几秒钟内,SESSION 事件应出现在 SDK Console 中
- 重复测试: 验证每次应用进入和切换到前台时都会触发 SESSION
关键验证: 确认在任何 EVENT 请求之前,SESSION 事件都会在应用打开/切换到前台时发生。无效的顺序会导致归因错误。
成功指标: 如果 SESSION 出现在 SDK Console 中,说明你已成功完成端到端集成测试!
其他资源
测试文档
完整的测试指南: S2S 集成测试指南