# 同步归因

> 来源：https://help.gravity-engine.com/docs/attribution/synchronous-attribution
> 说明如何在调用 initialize 接口时开启同步归因，以便立即取得当前用户的买量归因结果，并介绍归因耗时分布与常见问题。



如果客户端需要在引力完成对该用户的归因后立即拿到买量归因结果，可以在调用引力 `initialize` 接口时开启**同步归因**（具体开启方式请参考对应技术栈客户端接入文档中 `initialize` 接口的说明）。

开启之后，引力会在 `initialize` 调用中同步执行归因逻辑并阻塞返回，归因完成后才会返回结果，返回的即为最终归因结果。

> **注意**
> **开启之后极端情况会有长达 `10s` 的接口阻塞，请谨慎开启！** 仅当客户端需要立即拿到归因结果时才建议开启；如果客户端不需要，请勿开启，可改用 [归因回调链接](/docs/attribution/attribution-callback) 在服务端接收归因结果，更符合常规的数据分析需求。

开启之后，`initialize` 接口的返回结果中会包含以下归因字段：

| 字段                         | 类型     | 说明                                                         |
| -------------------------- | ------ | ---------------------------------------------------------- |
| `token`                    | string | 用户 clientId                                                |
| `click_company`            | string | 归因平台，允许的枚举值请参考 [广告平台枚举值](/docs/appendix/ad-platform-enums) |
| `turbo_promoted_object_id` | string | 引力推广活动 ID                                                  |
| `ad_params`                | object | 在归因回调链接里拼接的参数，可参考下方「参数拼接」部分                                |

示例：

```json
{
  "token": "123456789",
  "click_company": "bytedance",
  "turbo_promoted_object_id": "af12sdafga6",
  "ad_params": {}
}
```

## 同步归因耗时 [#同步归因耗时]

同步归因会阻塞 `initialize` 接口的返回，归因耗时分布如下（线上数据统计）：

| 耗时区间         | 占比     |
| ------------ | ------ |
| ≤500ms       | 81.38% |
| >500ms \~ 1s | 7.01%  |
| >1s \~ 2s    | 6.95%  |
| >2s \~ 3s    | 2.28%  |
| >3s \~ 5s    | 1.90%  |
| >5s          | 0.49%  |

从统计结果看，绝大多数请求（81.38%）在 500ms 内返回，约 88% 的请求在 1s 内完成，只有 0.49% 的请求超过 5s（极端情况最长可达 `10s`）。

需要注意的是，同步归因会**阻塞 `initialize` 接口的返回**：归因耗时越长，客户端初始化等待越久。**仅当客户端需要立即使用归因结果时才建议开启**；如果客户端不需要，不建议开启，可改用 [归因回调链接](/docs/attribution/attribution-callback) 在服务端接收归因结果。

## 参数拼接 [#参数拼接]

您可以在推广活动页面配置拼接参数，具体支持的参数请参考：[归因回调链接](/docs/attribution/attribution-callback)。配置的归因回调参数会拼接到返回的 `ad_params` 中。

举例：

```text
?advertiser_id=__ADVERTISER_ID__&your_ad_id=__AD_ID__&a=b
```

则这个推广活动带来的用户，返回的 `ad_params` 为：

```json
{
  "advertiser_id": "123456",
  "your_ad_id": "123456",
  "a": "b"
}
```

## 兜底回调链接 [#兜底回调链接]

为了避免每个推广活动都需要配置一遍归因回调链接，我们提供了**兜底回调链接**，在回调触发时，会优先使用推广活动下的归因回调链接，若当前推广活动没有配置，则取兜底回调链接来完成归因信息的数据回调。

您可以在[引力后台-设置-应用管理-配置](https://web.gravity-engine.com/#/manage/appmanage)中添加兜底回调链接。

## 常见问题 [#常见问题]

1. **什么场景适合用同步归因？相比异步能缩短多少等待时间？**

   1. 客户端需要立即拿到归因结果时使用。相比异步回调，同步归因省去了服务端异步回调的排队耗时和归因流程内部重试的等待，`initialize` 接口返回时即可拿到最终归因结果，预期可缩短约 `4s`。

2. **同步归因和异步归因（归因回调链接）除了回调时机，还有其它区别吗？**

   1. 没有。两者只在归因完成后的回调方式、以及归因流程内部的重试上有区别，接入配置、参数与历史用户处理等均无差异。

3. **异步归因为什么会重试？重试对耗时有什么影响？**

   1. 异步归因在未能归因到媒体时会重试。典型场景：腾讯广告投放的微信小游戏，用户点击广告的瞬间小游戏就被拉起并触发归因，但腾讯侧的点击检测可能存在几秒延迟，此时还无法归因到腾讯，异步模式会重试，因此增加了归因耗时。同步归因在调用 `initialize` 接口时直接返回本次归因结果，省去了这部分重试等待。

4. **`initialize` 接口返回时归因已经完成了吗？拿到的是完整结果吗？**

   1. 已完成。同步归因会阻塞 `initialize` 接口，等待归因完成后才返回，返回的即为最终归因结果（即上方字段表中的全部字段）。

5. **开启同步归因会影响归因成功率吗？**

   1. App 场景基本无影响：App 从点击到激活的间隔较长，不存在媒体点击检测延迟下发的问题，因此不会重试，影响极低。小游戏场景下，如果媒体侧点击下发存在延迟，可能影响归因成功率。

6. **同时收到同步归因结果和异步回调，符合预期吗？两边结果会不一致吗？**

   1. 符合预期，两者结果一致，先后顺序不影响最终结果。

7. **同步结果和异步回调之间有唯一的归因事件 ID 吗？重复回调如何处理？**

   1. 没有唯一 ID。重复回调建议每次都按最新一次的结果覆盖更新全部归因字段：发生再归因时部分字段会更新，避免沿用过旧的数据。
