API Reference
XXinstall 归因系统完整 API 接口文档,包括 SDK API 和管理后台 API。
认证
SDK API
SDK API 使用 appKey + HMAC-SHA256 签名认证:
- 通过参数
appKey或请求头X-App-Key传递 - 签名算法:
HMAC-SHA256(appKey + timestamp + fpMd5, appSecret) fpMd5=md5(phpJsonEncode(ksort(fingerprint)))
Admin API
管理后台 API 使用 JWT Bearer Token:
Authorization: Bearer <jwt-token>
SDK API
归因存储
POST /api/v1/attribution/store
上报推广落地页采集的设备指纹和归因参数。
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
appKey | string | 是 | 应用 Key |
fingerprint | object | 是 | 设备指纹对象 |
sign | string | 是 | HMAC-SHA256 签名 |
fpMd5 | string | 否 | 指纹 JSON 的 MD5(消除跨平台序列化差异) |
timestamp | number | 是 | 秒级时间戳 |
inviteCode | string | 否 | 邀请码 |
channel | string | 否 | 渠道标识 |
sdkVersion | string | 否 | SDK 版本号 |
extraParams | object | 否 | 自定义扩展参数 |
响应示例:
{
"code": 0,
"msg": "ok",
"data": {
"recordId": 42,
"clipCode": "aB3xK9mZ"
}
}
归因匹配
POST /api/v1/attribution/resolve
客户端 SDK 调用,匹配设备的归因来源。
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
appKey | string | 是 | 应用 Key |
fingerprint | object | 是 | 设备指纹对象 |
sign | string | 是 | HMAC-SHA256 签名 |
fpMd5 | string | 否 | 指纹 JSON 的 MD5(消除跨平台序列化差异) |
timestamp | number | 是 | 秒级时间戳 |
clipboardData | string | 否 | 剪贴板内容(含零宽字符) |
响应示例:
{
"code": 0,
"msg": "ok",
"data": {
"matched": true,
"inviteCode": "ABC123",
"channel": "wechat",
"confidence": 0.92,
"matchType": "fingerprint"
}
}
设备画像上报
POST /api/v1/device/profile
App SDK 在归因匹配成功后异步上报设备画像数据,用于设备去重和防刷。
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
appKey | string | 是 | 应用 Key |
sign | string | 是 | HMAC-SHA256 签名 |
timestamp | number | 是 | 秒级时间戳 |
fingerprint | object | 是 | 归因时使用的设备指纹 |
fpMd5 | string | 否 | 指纹 JSON 的 MD5 |
deviceProfile | object | 是 | 设备画像数据 |
attributionResult | object | 否 | 本次归因结果 |
deviceId | string | 否 | 设备标识 |
sdkVersion | string | 否 | SDK 版本号 |
deviceProfile 字段:
| 字段 | 类型 | 说明 |
|---|---|---|
buildFingerprint | string | Android: Build.FINGERPRINT; iOS: 机型+系统版本 |
installedAppsHash | string | 已安装常见 App 的 MD5 hash |
sensorListHash | string | 设备传感器列表的 MD5 hash |
brand | string | 品牌 |
model | string | 型号 |
device | string | 设备名(Android) |
product | string | 产品名(Android) |
hardware | string | 硬件名(Android) |
abis | string | CPU 架构(Android) |
响应示例:
{
"code": 0,
"msg": "ok",
"data": {
"deviceId": "dp_xxxx",
"isNewDevice": true
}
}
事件上报
POST /api/v1/event/track
上报单个用户行为事件。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
appKey | string | 是 | 应用 Key |
deviceId | string | 是 | 设备标识 |
eventName | string | 是 | 事件名称 |
eventType | int | 否 | 事件类型:1=下载, 2=安装, 3=打开, 4=注册, 5=留存, 6=付费 |
eventTime | string | 否 | ISO 8601 时间,默认当前时间 |
properties | object | 否 | 事件属性 |
批量事件上报
POST /api/v1/event/batch
批量上报事件,单次最多 50 条。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
appKey | string | 是 | 应用 Key |
events | array | 是 | 事件数组(结构同单条上报) |
mobileconfig 生成
GET /api/v1/mobileconfig/generate
生成 iOS WebClip 配置文件。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
appKey | string | 是 | 应用 Key |
inviteCode | string | 否 | 邀请码 |
channel | string | 否 | 渠道标识 |
返回 Content-Type: application/x-apple-aspen-config。
Admin API
登录
POST /admin/auth/login
| 参数 | 类型 | 必填 |
|---|---|---|
username | string | 是 |
password | string | 是 |
响应:
{
"code": 0,
"data": {
"token": "eyJ...",
"user": { "id": 1, "username": "admin", "role": "super_admin" }
}
}
个人信息
GET /admin/auth/profile
返回当前登录用户信息。
租户管理
| 方法 | 路径 | 说明 | 权限 |
|---|---|---|---|
| GET | /admin/tenants | 租户列表 | super_admin |
| POST | /admin/tenants | 创建租户 | super_admin |
| PUT | /admin/tenants/:id | 更新租户 | super_admin |
应用管理
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /admin/apps | 应用列表 |
| POST | /admin/apps | 创建应用 |
| PUT | /admin/apps/:id | 更新应用 |
| POST | /admin/apps/:id/reset-secret | 重置 Secret |
渠道管理
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /admin/channels | 渠道列表 |
| POST | /admin/channels | 创建渠道 |
| PUT | /admin/channels/:id | 更新渠道 |
数据统计
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /admin/stats/overview | 概览(今日/总量) |
| GET | /admin/stats/attribution | 归因统计(按天/渠道/场景) |
| GET | /admin/stats/events | 事件统计 |
| GET | /admin/stats/funnel | 转化漏斗 |
统计通用参数:
| 参数 | 类型 | 说明 |
|---|---|---|
appId | int | 按应用筛选 |
days | int | 时间范围(默认 7,最大 90) |
groupBy | string | 分组方式:day / channel / scene |
channel | string | 渠道筛选(仅漏斗) |
匹配日志
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /admin/match-logs | 日志列表(分页) |
| GET | /admin/match-logs/:id | 日志详情 |
列表参数:
| 参数 | 类型 | 说明 |
|---|---|---|
appId | int | 按应用筛选 |
scene | string | 按场景筛选 |
matched | int | 0=未匹配, 1=已匹配 |
competitive | int | 1=仅竞争匹配 |
page | int | 页码 |
size | int | 每页条数(最大 100) |
频率限制
所有 SDK API 接口受双层频率限制保护:
| 限制维度 | 默认限额 | 说明 |
|---|---|---|
| appKey | 1000 次/分钟 | 按应用限流 |
| IP | 120 次/分钟 | 按客户端 IP 限流 |
超出限制返回 HTTP 429,响应头包含 Retry-After。
租户可在管理后台自定义 appKey 层级的限额。
错误码
| code | 说明 |
|---|---|
| 0 | 成功 |
| 401 | 认证失败(appKey 无效 / Token 过期) |
| 403 | 权限不足 |
| 404 | 资源不存在 |
| 409 | 资源冲突(如用户名已存在) |
| 422 | 参数校验失败 |
| 429 | 请求频率超限 |
| 500 | 服务器内部错误 |