应用分发广告 API 接入文档
当前版本:v2.0.17(已部署)
待发布兼容扩展:下载图文广告的应用明示与广告标识,见 4.7 节。版本号、请求鉴权和现有回调参数保持不变;新增展示能力须按广告位验收后启用。
修订记录:
| 文档版本 | 修订内容 | 修订时间 |
|---|---|---|
| v2.0.3 | 更新文档 | 2024-05-10 |
| v2.0.4 | Bid Request.Imp 新增 pkgWhitelist 字段;Bid Request.Device 新增 did/didMd5/oaId/oaIdMd5 字段 |
2024-12-11 |
| v2.0.5 | 更新文档 | 2026-03-15 |
| v2.0.6 | 新增请求鉴权(query 参数 requestId、auth),见 2.3 节 |
2026-09-22 |
| v2.0.7 | BidAdContent 新增 iconUrl/downloadUrl 字段;补充请求示例、响应处理和事件上报规则 |
2026-10-12 |
| v2.0.8 | 新增通用 eventTracks 上报、事件编号和 deepLink/landingUrl 可选字段 |
2026-10-12 |
| v2.0.9 | 新增宏占位符向媒体透传:监测 URL 可携带 macroVersion=1 与 macro.<宏名> 占位符参数,媒体按 4.3/4.4/4.6 节替换端侧值后上报;宏定义表写入 4.6 节(不在响应体下发);平台转发前替换宏并拒绝非法回调,v2.0.8 及更早签发的监测 URL 兼容不变 |
2026-10-14 |
| v2.0.10 | device.w/device.h 与 app.version 由可选改为必填(缺失会导致无法填充);缺失时返回 HTTP 400 |
2026-10-15 |
| v2.0.11 | 补齐字段。请求侧新增:Imp titleMaxLen/descMaxLen/adType/impId/video/customizedInfo,Device androidId/androidIdMd5/orientation/paid/paid14/bootMark/updateMark/birthTime/syscoreVersion/appstoreVersion,Geo gpstype,App category/fit/queryWord/queryPkgname;did 原值与 carrier 改为按原值使用。响应侧新增:BidBase 创意字段(title/desc/imgs/video 等)、BidAdContent 应用详情字段(md5/size/universalLink/miniProgram 等)。新增竞败通知 track[].notice 与 GET /rtb/track/notice。按安装计费的广告 id 以 free- 开头。补充计费事件说明 |
2026-10-15 |
| v2.0.12 | 新增 2.4 节测试广告位 test-ad 使用说明 |
2026-10-15 |
| v2.0.13 | 测试广告位 test-ad 没有竞价结果时返回平台默认测试广告,不再返回 HTTP 204 |
2026-10-15 |
| v2.0.13 扩展(待发布) | 新增四个可选展示 URL;仅向完成展示验收的指定广告位返回。平台承担竞胜及通知补投,媒体沿用现有请求与回调 | 2026-10-16 |
| v2.0.14(已部署) | 每个接入方独立 token;平台按广告位识别接入方,不新增请求参数;token 为 64 位十六进制,一次请求不能混用不同接入方的广告位 | 2026-10-20 |
| v2.0.14 宏要求级别(已部署) | 监测 URL 上的客户端宏按 360 对接文档的要求级别处理:媒体有真实值就替换,没有就保留占位符原文,平台不再因宏返回 400;平台转发上游时,有值替换,缺值时触点坐标填 -999,其余保留上游原占位符;__win_price__ 仍由平台加密替换。取代 v2.0.9 的宏替换与校验规则 |
2026-10-28 |
| v2.0.14 枚举(已部署) | 1.1 节完整列出平台枚举:adType 14 个取值、interactionType 14 个取值、downloadAd/nativeAdType/htmlType、deviceType/carrier/orientation、视频 videoType/delivery/mimeType/skip;后续新增广告服务统一转换为该值域 |
2026-10-21 |
| v2.0.15(已部署) | 明确洗包场景下有预算包与无预算填充包的区分方式:无预算填充包的 price 恒为 "0",有预算包为大于 0 的 CPM;明确洗包场景的 pkgWhitelist/installPkgs/unstallPkgs 规则:洗包按 pkgWhitelist 填充,返回条数不再固定为 8,平台不返回 installPkgs 中的包;明确返回顺序与同包名去重;新增 4.8 节与 6.8 节示例。imp 缺失或为空时无法识别接入方,仅校验 requestId/auth 的格式并返回 204(3 节);bidList[].id 在同一曝光位内唯一,有预算包为 ad- 开头(4.1 节,示例同步);竞败通知的占位符参数名带 macro. 前缀,与 4.6 节一致(4.3 节)。不新增请求或响应字段 |
2026-10-29,2026-10-30 补充 |
| v2.0.16(已部署) | 新增纯目录洗包广告位:由平台按接入方需求开通,不向预算方请求,响应只含无预算填充包(price 恒为 "0"),见 4.8 节。不新增请求或响应字段,鉴权与监测上报不变 |
2026-10-30 |
| v2.0.17(已部署) | 恢复请求字段 imp[].reqadnum(3.1 节):限制该曝光位最多返回的广告条数。缺省或小于等于 0 时,推荐位等非洗包场景只返回 1 条(此前固定最多 8 条);填写后返回不超过该值的条数,推荐位上限 8。洗包场景:未填写时保持按 pkgWhitelist 填充(条数不变),填写后最多返回该条数。响应结构不变 |
2026-11-03 |
1. 文档说明
本文档定义应用分发广告的请求格式、响应字段及事件监测方式。
1.1 平台枚举定义
以下枚举由本平台定义,媒体按此填写和解析。平台对不同广告服务使用统一取值,不会在响应中暴露其他编码;后续新增广告服务也使用同一套取值。
1.1.1 adType 广告类型
| 值 | 含义 |
|---|---|
| 0 | 未知 |
| 1 | 原生图文广告 |
| 2 | 信息流广告 |
| 3 | 开屏广告 |
| 4 | 插屏广告 |
| 5 | 原生视频广告 |
| 6 | 激励视频广告 |
| 8 | Banner 广告 |
| 9 | 其他广告 |
| 10 | 微信小程序广告 |
| 14 | 原生广告(图文或视频) |
| 15 | 搜索广告 |
| 16 | 商店广告 |
| 17 | 图标 |
1.1.2 interactionType 交互类型
| 值 | 含义 |
|---|---|
| 0 | 未知 |
| 7 | 普通网址 |
| 9 | 微信小程序 SDK 调起 |
| 10 | deeplink 打开微信小程序广告 |
| 11 | 快应用广告 |
| 12 | 拉活拉新广告(APK) |
| 13 | 拉活拉新广告(商店) |
| 14 | 拉活广告 |
| 15 | 快游戏广告 |
| 16 | deeplink 拉活 + 普通网址兜底 |
| 17 | 微信小游戏 SDK 调起 + 普通网址兜底 |
| 18 | 自定义 H5 + 应用下载(商店) |
| 19 | 应用下载(商店) |
| 20 | 自定义 H5 + 应用下载(APK) |
请求固定使用 20;响应为广告实际交互类型,平台原样返回,下载类常见 19、20,兼容值 14、16 也可能出现。
1.1.3 downloadAd / nativeAdType / htmlType
| 枚举 | 取值 |
|---|---|
| downloadAd | 0=非下载类,1=下载类。实测下载类广告也可能返回 0,判断是否为下载广告请以非空 downloadUrl 为准 |
| nativeAdType | adType=1 时有值:1=small(小图),2=big(大图),3=group(组图),9=其他 |
| htmlType | adType=7 时有值(当前 adType 枚举无 7,按原文保留):1=script 标签,2=meta 标签 |
1.1.4 设备与网络
| 枚举 | 取值 |
|---|---|
| deviceType | 1=手机,2=平板,3=OTT 终端(互联网电视/机顶盒),4=PC,9=其他 |
| os | 0=未知/其他,1=iOS,2=Android,3=Windows,4=macOS,5=Linux,6=Windows Phone |
| carrier | 1=中国移动,2=中国联通,3=中国电信,9=其他 |
| connectionType | -1=有线网络/宽带,0=未知,1=WIFI,2=2G,3=3G,4=4G,5=5G |
| orientation | 1=竖屏,2=横屏 |
| gpstype | WGS-84、GCJ-02、BD-09、CGCS2000 |
1.1.5 视频
| 枚举 | 取值 |
|---|---|
| videoType(请求) | 1=原生视频,2=激励视频 |
| videoType(响应) | 1=原生视频,2=激励视频,3=VAST,4=HTML |
| delivery | 0=不限,1=实时,2=预加载 |
| mimeType(响应) | 1=video/mp4,2=video/3gpp,3=video/x-msvideo,4=video/x-flv,5=video/x-ms-wmv,6=video/quicktime |
| skip | 0=不允许跳过,1=允许跳过 |
| duration / skipMinTime | 毫秒 |
| length | KB |
当前平台不投放视频,以上字段仅协议兼容。
1.1.6 eventType
1–20,编号见 4.3 节。
2. 接入准备
2.1 请求地址
POST https://adhit.cn/rtb/bid
开始开发前取得以下配置:
| 配置 | 获取方式 | 用途 |
|---|---|---|
| 请求地址 | 正式地址如上,测试地址由商务侧提供 | 发起广告请求 |
| 鉴权 token | 每个媒体独立分配,存放于媒体服务端;平台新分配的 token 为 64 位十六进制字符串(32 字节),区分大小写 | 生成请求签名,不与其他媒体共用 |
广告位 tagId |
产品侧提供并完成开通;联调可先用测试广告位 test-ad,见 2.4 节 |
填入 imp[].tagId |
| 模板 ID、宽高 | 与产品侧确认 | 填入 imp[].templateList |
| 请求来源应用名称、包名 | 媒体提供真实值 | 填入 app |
竞价请求由媒体服务端发起;设备字段填写实际用户终端的信息。鉴权 token 不放入客户端或前端代码。
2.2 请求格式
- 请求类型:POST
- 数据格式:JSON,请求头需设置
Content-Type: application/json - 字符编码:UTF-8;字段名区分大小写
- Gzip 压缩:支持;压缩请求体时设置
Content-Encoding: gzip,不压缩时省略该请求头 - 请求体上限:未压缩请求为 4 MiB;gzip 请求压缩后为 4 MiB,解压后为 2 MiB
- JSON 数字字段传数字,字符串字段传字符串;例如
os: 2、targetTypeStr: "2" - 可选字段无值时省略;
ext如需填写,传字符串形式的 JSON,例如"ext": "{\"key\":\"value\"}" - 广告按实际需求实时请求,不缓存响应供后续请求复用
2.3 请求鉴权
每个请求只需在 URL query 中携带 requestId、auth,无需传接入方 ID。平台根据请求体 imp[].tagId 识别接入方,再用该接入方的 token 校验签名。未开通广告位、停用接入方、签名错误,或一次请求混用不同接入方的广告位时返回 HTTP 401,不调用广告服务:
| 参数名称 | 说明 | 是否必须 | 数据类型 |
|---|---|---|---|
| requestId | 本次请求唯一 ID,UTF-8 编码长度 1–64 字节;建议使用 ASCII 字母、数字或连字符 | true | String |
| auth | 签名:MD5(requestId + token),32 位十六进制,建议发送大写(服务端比较不区分大小写);token 由平台分配(64 位十六进制),测试与正式环境不同 |
true | String |
示例:
POST https://adhit.cn/rtb/bid?requestId=20261012120000000001&auth=<MD5("20261012120000000001"+本媒体token) 转大写>
签名步骤:
- 生成本次请求的
requestId。 - 将
requestId原文与 token 原文直接拼接,不加分隔符、空格或换行;token 按平台下发的字符串原样使用,区分大小写,不做 hex 解码或大小写转换。 - 对拼接结果的 UTF-8 字节计算 MD5,将十六进制结果转为大写。
- 将
requestId、auth作为 URL query 参数发送,JSON 请求体按第 3 节填写。
建议 query 中的 requestId 与请求体的 id 使用同一值;响应 id 回显请求体的 id。签名不包含请求体,token 不在请求中传输,必须使用 HTTPS。
每个 tagId 由平台分配,只能属于一个接入方;一个请求中的所有非空 tagId 必须属于同一接入方。广告位停用后不会转给其他接入方,签名正确但广告位已停用时返回 204。requestId、auth 各只能传一次。监测回调仅使用响应中的完整 URL,每条广告的 token 已绑定接入方身份。
以下仅用于本地核对签名算法,示例 token 不能用于真实接口:
| 输入/输出 | 值 |
|---|---|
| requestId | 20261012120000000001 |
| 示例 token | 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef |
| 待计算字符串 | 202610121200000000010123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef |
| auth | D46E2E58C722B1424FC243FB88E6CF07 |
2.4 测试广告位 test-ad
存量接入方保留使用 test-ad,其他接入方由平台分配独立的 test-ad-<接入方ID>,例如 test-ad-m2。测试位需先为接入方开通,不与其他接入方共享;未开通的广告位返回 401,已开通但停用的广告位在签名正确时返回 204。开发阶段可使用分配的测试位验证签名、响应解析和监测回调,再切换正式 tagId。
| 项目 | 取值/说明 |
|---|---|
| 请求地址与鉴权 | 与正式接口相同:POST https://adhit.cn/rtb/bid,query 携带 requestId/auth,签名使用平台分配的 token(64 位十六进制,见 2.1、2.3 节) |
imp[].tagId |
平台分配的测试位;存量接入方为 test-ad,其他接入方例如 test-ad-m2(区分大小写) |
imp[].templateList[0] |
templateId: "1"、width: 320、height: 480、targetTypeStr: "2";使用其他模板或尺寸不保证有填充 |
| 其余必填字段 | 与正式请求一致:device.w/h、app.version 缺失返回 HTTP 400(见第 3 节);设备信号字段格式须合法,联调可用 6.1 节的样例设备信息 |
| 返回结果 | 接入方已开通测试位且请求合法时返回 HTTP 200:有竞价结果时返回真实广告,没有(无填充、超时或异常)时返回平台默认测试广告;未开通返回 401,已开通但停用返回 204;每次返回的应用、素材、价格可能不同 |
| 默认测试广告 | bidList[].id 为 test-ad-default,source 为 test,price 为 "100",interactionType 为 20;iconUrl/landingUrl/downloadUrl 指向平台的占位页,没有可安装的应用包;imp/clk 监测 URL 带 __down_x__/__down_y__/__up_x__/__up_y__ 宏,notice 带 __bid_lose__/__lose_reason__ 宏,有真实值可替换,没有也可原样请求(见 4.6 节) |
price |
仅用于验证字段解析,不代表真实报价 |
使用限制:
- 仅用于接口联调,不用于正式放量,不做压测;请低频、少量请求。
- 默认测试广告的回调不转发、不计费;其他广告的回调规则与正式广告位一致。测试广告位的回调都不作为对账或收入核对依据。
- 回调时只请求本次响应中的完整监测 URL,且只在对应事件真实发生时请求(见 4.3 节)。
- 上线前把
tagId与模板改为商务、产品侧开通的正式配置,并重新验证第 7 节各项。
联调检查项:
| 步骤 | 预期 |
|---|---|
用 6.1 节请求体,将 tagId 改为 test-ad、模板改为上表取值并签名发送 |
HTTP 200 或 204 |
收到 200 时校验响应 id 与请求 id 一致、bidList[].impId 与请求 imp[].id 一致 |
一致 |
检查 track[0] 中的 imp/clk/del/finishDle/install/finishInstall 均为平台 URL |
每项各 1 条 |
模拟展示后请求 imp URL(有真实值的宏替换,没有的保留原文) |
HTTP 204 |
故意去掉 auth 发送 |
HTTP 401 |
3. 广告请求-Bid Request
| 参数名称 | 说明 | 是否必需 | 数据类型 |
|---|---|---|---|
| id | 请求唯一 ID | true | String |
| imp | 曝光位信息 | true | Array<Imp> |
| device | 设备信息 | true | Device |
| app | 请求来源 APP 信息 | true | App |
| timeout | 本次请求的竞价处理时间预算,单位毫秒;默认 300,上限 5000 | false | int |
| ext | 保留字段 | false | JSON String |
“必需”表示接入时应提交的字段;条件必需的字段按表内说明填写。无值的设备信号不得编造。
id必须非空,device、app必须为非 null 对象;device.w、device.h、app.version必须为正值/非空;缺失时返回 HTTP 400。imp缺失或为空时返回 HTTP 204。此时没有tagId,无法识别接入方,平台只校验requestId、auth的格式(各出现一次,requestId为 1–64 字节,auth为 32 位十六进制),不校验签名内容;格式不符仍返回 HTTP 401。该请求不调用广告服务。timeout缺省或小于等于 0 时使用 300ms,大于 5000 时按 5000ms 处理。该时间预算由整个请求共享;客户端网络超时应额外留出传输时间。- 一次请求可包含多个广告位,每个
imp.id应在本次请求中唯一;各广告位按顺序处理,共享同一timeout。 - 非空但未开通的
tagId无法识别接入方,整单返回 401;同一请求中属于不同接入方的tagId同样返回 401,不先处理其中的曝光位。 - 签名通过后,缺失
tagId、templateList为空或广告位已停用的曝光位被跳过;全部跳过或无填充返回 204。若所有曝光位均缺失tagId,仅保留存量接入方 token 的兼容校验。
3.1 Imp 对象
| 参数名称 | 参数说明 | 是否必需 | 数据类型 | Schema |
|---|---|---|---|---|
| id | 本次请求内的曝光位唯一 ID;响应通过 impId 关联 |
true | string | |
| tagId | 已开通的广告位 ID,与产品侧约定;大小写须一致 | true | string | |
| templateList | 广告位支持的模板列表,至少包含一个模板 | true | array | Template |
| reqadnum | 该曝光位最多返回的广告条数,数字或数字字符串。缺省或小于等于 0 时,推荐位等非洗包场景按 1 处理;洗包场景不填则仍按 pkgWhitelist 填充(见 pkgWhitelist),填写后最多返回该条数。上限:推荐位 8;洗包带 pkgWhitelist 时为列表覆盖的包数(最多 100),不带时 8;超过上限按上限处理,实际返回可能少于该值。返回的是价格最高的前几条 |
false | int | |
| searchKeyword | 保留字段,当前不参与广告召回 | false | string | |
| pkgWhitelist | 洗包广告位的目标应用包名列表,英文逗号分隔,例如 com.example.a,com.example.b,按包名精确匹配,去重后最多取前 100 个。平台按该列表填充:每个包优先由预算方出价(有预算包),预算方没有的由平台目录补充(无预算填充包;纯目录广告位不请求预算方,见 4.8 节);同一包名只返回一次,返回条数不超过列表条数,详见 4.8 节。洗包广告位应填写;省略时洗包最多返回 8 条,来源与顺序由平台决定。其他场景中该字段只用于限定返回的应用 |
false | string | |
| bundle | 保留字段;请求来源应用包名填写在顶层 app.bundle |
false | string | |
| titleMaxLen | 标题最大长度,有值时生效 | false | int | |
| descMaxLen | 描述最大长度,有值时生效 | false | int | |
| adType | 广告类型 id,取值见 1.1;不填表示不限,填写时按广告位支持的下载类 id 传 | false | int | |
| impId | 曝光位补充标识;响应的 impId 仍是 imp[].id |
false | string | |
| video | 视频素材需求,请求视频类广告时提供,见 3.2.1 节 | false | object | Video |
| customizedInfo | 定制信息,见 3.2.2 节 | false | object | CustomizedInfo |
3.2 Template 对象
| 参数名称 | 参数说明 | 是否必需 | 数据类型 |
|---|---|---|---|
| width | 模板宽度,像素;填写已约定的实际尺寸,无自动默认值 | true | int |
| height | 模板高度,像素;填写已约定的实际尺寸,无自动默认值 | true | int |
| templateId | 已约定的模板 ID;响应回显选中的模板 ID,无自动默认值 | true | string |
| targetTypeStr | 当前支持 "2"(应用下载);多值用英文逗号分隔 |
true | string |
模板按列表顺序选择第一个 targetTypeStr 包含 "2" 的条目;如无此条目则选择第一项。请显式填写 "2",并使用已约定的模板和尺寸。选中模板的 width/height 作为请求尺寸使用,templateId 在响应中回显;templateList 中的其余模板不参与匹配。
3.2.1 Video 对象(请求)
请求视频类广告时在 imp[].video 提供。平台当前不投放视频广告,本节字段为协议兼容保留,不参与召回,媒体无需填写。
| 参数名称 | 参数说明 | 是否必需 | 数据类型 |
|---|---|---|---|
| minDuration | 最短时长,毫秒 | false | int |
| maxDuration | 最长时长,毫秒 | false | int |
| mimeTypes | 可接受的媒体类型 | false | Array<string> |
| sizes | 视频尺寸列表,元素为 {width, height}(像素) |
false | Array<Size> |
| maxLength | 视频文件最大长度,字节 | false | int |
| videoType | 视频类型,1=原生视频,2=激励视频;当前不投放视频,无需填写 | false | int |
| delivery | 投放方式,0=不限,1=实时,2=预加载;当前不投放视频,无需填写 | false | int |
| orientation | 视频方向,1=竖屏,2=横屏;当前不投放视频,无需填写 | false | int |
3.2.2 CustomizedInfo 对象
| 参数名称 | 参数说明 | 是否必需 | 数据类型 |
|---|---|---|---|
| hitStrategys | 命中策略 | false | Array<string> |
| installPkgs | 设备已安装的应用包名列表,示例 ["com.taobao.taobao"]。平台不会返回其中的包(有预算包与无预算填充包均排除),同时原样透传给预算方。洗包场景建议填写 |
false | Array<string> |
| unstallPkgs | 设备未安装或已卸载的应用包名列表;JSON key 为 unstallPkgs(少一个 "i"),拼写以此为准,不是笔误。仅原样透传给预算方,平台不用它筛选无预算填充包,不会因其出现而限定或排除返回的应用 |
false | Array<string> |
3.3 Device 对象
| 参数名称 | 参数说明 | 是否必需 | 数据类型 |
|---|---|---|---|
| ua | 浏览器用户代理 | true | string |
| geo | 设备当前位置信息 | false | Geo |
| ip | 用户终端公网 IPv4;与 ipv6 至少提供一个,不填写代理服务器 IP |
条件必需 | string |
| ipv6 | 用户终端公网 IPv6;仅有 IPv6 时可省略 ip |
条件必需 | string |
| deviceType | 设备类型:1=手机,2=平板,3=OTT 终端(互联网电视/机顶盒),4=PC,9=其他(见 1.1.4) | true | int |
| make | 设备制造厂商 | true | string |
| model | 设备型号 | true | string |
| mobileModel | 保留字段;机型填写在 model |
false | string |
| os | 操作系统:0=未知/其他,1=iOS,2=Android,3=Windows,4=macOS,5=Linux,6=Windows Phone(见 1.1.4) | true | int |
| osv | 操作系统版本 | true | string |
| hwv | 设备硬件版本号 | false | string |
| h | 屏幕高度物理像素;必填,缺失影响广告填充 | true | int |
| w | 屏幕宽度物理像素;必填,缺失影响广告填充 | true | int |
| ppi | 屏幕像素密度(每英寸像素) | false | int |
| pxRatio | 物理像素和设备独立像素比例 | false | double |
| language | 浏览器语言,ISO-639-1-alpha-2 编码 | false | string |
| carrier | 运营商:1=中国移动,2=中国联通,3=中国电信,9=其他(见 1.1.4),按原值使用 | false | int |
| connectionType | 网络连接类型:-1=有线网络/宽带,0=未知,1=WIFI,2=2G,3=3G,4=4G,5=5G | true | int |
| did | Android IMEI 原值,纯数字;与 didMd5、oaId、oaIdMd5 至少提供一个 |
条件必需 | string |
| didMd5 | IMEI 原值的 MD5,32 位十六进制;与其他 Android 标识至少提供一个 | 条件必需 | string |
| oaId | Android OAID 原值,注意字段大小写;与其他 Android 标识至少提供一个 | 条件必需 | string |
| oaIdMd5 | OAID 原值的 MD5,32 位十六进制;与其他 Android 标识至少提供一个 | 条件必需 | string |
| idfa | iOS IDFA 原值;当前 iOS 请求需与 idfaMd5 至少提供一个 |
条件必需 | string |
| idfaMd5 | IDFA 原值的 MD5,32 位十六进制;当前 iOS 请求需与 idfa 至少提供一个 |
条件必需 | string |
| caidList | iOS CAID 列表,可补充多个版本;当前不能单独替代 IDFA 标识 | false | Array<CaidBase> |
| mac | MAC 地址原值,有真实值时填写 | false | string |
| macMd5 | MAC 原值的 MD5,32 位十六进制,有真实值时填写 | false | string |
| ext | 保留字段 | false | JSON String |
| androidId | Android ID 原值,辅助信号,不能替代 IMEI/OAID | false | string |
| androidIdMd5 | Android ID 的 MD5,32 位十六进制 | false | string |
| orientation | 屏幕方向:1=竖屏,2=横屏(见 1.1.4) | false | int |
| paid | 保留字段 | false | string |
| paid14 | 反作弊推荐字段(厂商付费标识) | false | string |
| bootMark | 反作弊推荐字段(开机标识) | false | string |
| updateMark | 反作弊推荐字段(系统更新标识) | false | string |
| birthTime | 反作弊推荐字段 | false | string |
| syscoreVersion | 反作弊推荐字段 | false | string |
| appstoreVersion | 反作弊推荐字段 | false | string |
设备标识填写规则:
- 原值和 MD5 至少提供一种;同时提供时须对应同一原值。已有 MD5 不再二次哈希,大小写均可接收,建议统一使用小写。
- Android 同时提供 IMEI 和 OAID 时,IMEI 标识优先;iOS 使用 IDFA 标识。
did原值与 MD5 都会使用;只提供其中一种时,由平台补全另一种(MD5 统一转大写)。androidId及paid~appstoreVersion反作弊字段仅在有真实值时填写,不得编造;未提供时不下发。- 未提供可用设备标识会影响广告填充;仅填写
caidList不能满足当前 iOS 请求的设备标识要求。 h、w为物理像素,不填写 CSS 像素或逻辑分辨率。hwv、ppi、pxRatio、language为保留信号,当前不参与广告召回。
3.4 Geo 对象
| 参数名称 | 参数说明 | 是否必需 | 数据类型 |
|---|---|---|---|
| city | 保留字段,当前不参与广告召回 | false | String |
| country | 保留字段,当前不参与广告召回 | false | String |
| lat | 纬度 -90.0~+90.0,负值代表南半球 | false | double |
| lon | 经度 -180.0~+180.0,负值代表西半球 | false | double |
| gpstype | 坐标系:WGS-84、GCJ-02、BD-09、CGCS2000(见 1.1.4) | false | string |
| region | 保留字段,当前不参与广告召回 | false | String |
| type | 保留字段,当前不参与广告召回 | false | int |
3.5 App 对象
| 参数名称 | 参数说明 | 是否必需 | 数据类型 |
|---|---|---|---|
| name | 请求来源的应用名称 | true | String |
| bundle | 请求来源 App 的唯一标识:Android 应用是 packagename,iOS 应用是 bundle id | true | String |
| version | 请求来源的应用版本号;必填,缺失影响广告填充 | true | String |
| ext | 保留字段 | false | JSON String |
| category | 应用分类 | false | String |
| fit | 保留字段 | false | long |
| queryWord | 查询关键词,搜索场景使用 | false | String |
| queryPkgname | 查询包名列表,搜索场景使用 | false | Array<String> |
3.6 CaidBase 对象
| 参数名称 | 参数说明 | 是否必需 | 数据类型 |
|---|---|---|---|
| version | 广协版本号,如 20230330 | true | String |
| caid | 广协 caid,对于无 idfa 的 iOS 流量,填充时使用 caid 进行用户识别 | true | String |
4. 广告响应-Bid Response
- HTTP 200:响应体为 JSON,包含
bidList。 - HTTP 204:无广告,响应体为空,不进行 JSON 解析。
- 其他状态:按第 5 节处理,不展示该响应中的广告。
响应处理规则
- 校验响应
id与本次请求体的id一致。 - 按
impId将每条广告关联到请求中的曝光位,使用响应的templateId渲染。 - 同一曝光位可能返回多条广告;未出现的曝光位按无广告处理。广告位之间可能仅有部分返回,单个曝光位返回条数不固定,不超过
reqadnum:推荐位等非洗包场景未填reqadnum时返回 1 条,填写后最多reqadnum条(上限 8);洗包按pkgWhitelist填充时,未填reqadnum的条数等于被覆盖的包数(不超过 100,也不超过列表条数),填写后最多reqadnum条;洗包未带pkgWhitelist时未填reqadnum最多 8 条。 - 可选字段缺失、监测数组为空时跳过相应操作;解析时允许出现新增字段。
- Android 下载使用非空的
downloadUrl。缺少下载地址时,只有已有可用下载渠道才展示下载入口,否则跳过该广告。 price按十进制字符串读取,无需解密;不同计价口径的价格不直接比较。- 返回顺序:有预算包在前、无预算填充包在后;同一包名在同一曝光位只出现一次,有预算包优先。区分两类广告见 4.1 节
price与 4.8 节。
| 参数名称 | 参数说明 | 类型 | Schema |
|---|---|---|---|
| id | 对应请求 ID | string | |
| bidList | 创意列表 | array | BidBase |
| ext | 保留字段 | string |
4.1 BidBase 对象
| 参数名称 | 参数说明 | 类型 | Schema |
|---|---|---|---|
| id | 广告标识,在同一曝光位(同一 impId)的 bidList 内唯一。有预算包以 ad- 开头,按安装计费的广告以 free- 开头(见下),平台默认测试广告为 test-ad-default;除前缀外格式不作约定,不要解析。不作为监测 token,也不能用于跨请求去重 |
string | |
| price | 明文十进制价格字符串,单位:分;有预算包为大于 0 的 CPM(千次曝光价格),无预算填充包没有预算,恒为 "0",据此可区分两类广告;两者不可比较;仅供展示参考,不作为结算或监测参数 |
string | |
| bidAdContent | 广告创意物料信息对象 | object | BidAdContent |
| track | 监测链接对象数组 | array | TrackBase |
| impId | 对应请求中 imp[].id |
string | |
| tagId | 对应请求中 imp[].tagId |
string | |
| targetType | 交互类型,平台固定返回 2(应用下载) | int | |
| templateId | 本次选中的请求模板 ID | string | |
| creativeId | 创意 ID,可选 | string | |
| title | 创意标题,可选;可能含控制字符,展示前自行清洗 | string | |
| desc | 创意描述,可选 | string | |
| quickLink | 备用跳转地址,可选,可能为空 | string | |
| cat | 广告分类,可选 | array | string |
| appBrand | 应用品牌,可选 | string | |
| adWidth | 素材宽度,像素,可选 | int | |
| adHeight | 素材高度,像素,可选 | int | |
| adType | 广告类型,取值见 1.1.1 | int | |
| interactionType | 交互类型,取值见 1.1.2 | int | |
| downloadAd | 是否下载类广告,0=非下载类,1=下载类(见 1.1.3) | int | |
| source | 广告来源标识,可选;平台默认测试广告为 test,有预算包为投放渠道标识,无预算填充包不返回 |
string | |
| nativeAdType | 原生广告类型,adType=1 时有值,取值见 1.1.3 |
int | |
| imgs | 图片素材列表,可选 | array | Image |
| video | 视频素材,视频类广告返回,可选 | object | Video |
| matterIcon | 素材图标备用地址,可选 | string | |
| actionUrl | 动作跳转地址,可选;可能含未替换宏,见 4.6 节 | string | |
| phoneNo | 电话类广告的号码,可选 | string | |
| htmlType | HTML 片段类型,1=script 标签,2=meta 标签(见 1.1.3),当前未返回 | int | |
| admHtml | HTML 片段内容,可选;媒体渲染前自行做安全处理 | string | |
| ext | 保留字段,可选 | string |
以上创意字段无值时一律省略,媒体不得假定其存在;按安装计费的广告(id 以 free- 开头)只含 4.1 前八个字段与 4.2 的 appName/pkgName/iosAppid/iconUrl/downloadUrl。
枚举字段按 1.1 节解析;targetType 恒为 2,adType/interactionType 可能有多个取值,媒体渲染不依赖具体值。
4.2 BidAdContent 对象
| 参数名称 | 参数说明 | 类型 |
|---|---|---|
| appName | app 名称,文字 | string |
| pkgName | 应用包名:Android 应用是 packagename,iOS 应用是 bundle id | string |
| iosAppid | 当前固定返回空字符串,不能依赖该字段生成 App Store 跳转地址 | string |
| iconUrl | 广告素材图标地址,可选,可能省略 | string |
| downloadUrl | 应用下载地址,可选,可能省略;返回时可直接使用该地址下载应用 | string |
| deepLink | 应用调起地址,可选;存在时先尝试调起,失败后使用 landingUrl,仅在实际启动下载时上报下载事件 |
string |
| landingUrl | 调起失败时的落地页地址,可选 | string |
| appId | 应用 ID,可选 | string |
| md5 | 应用包 MD5,可选 | string |
| logoUrl | 应用图标地址,可选;与 iconUrl 是两个独立字段,不互为备用 |
string |
| softCorpName | 开发者名称,可选 | string |
| sensitiveUrl | 敏感权限页地址,可选 | string |
| usesPermission | 权限说明,可选 | string |
| version | 应用版本名,可选 | string |
| versionCode | 应用版本号,可选 | int |
| size | 应用包大小,字节,可选 | long |
| intro | 应用简介,可选 | string |
| universalLink | iOS Universal Link,可选;iosAppid 仍固定为空 |
string |
| miniProgram | 小程序信息,可选 | object |
| wechatExt | 微信扩展信息,可选 | object |
调起顺序:deepLink → 失败后 downloadUrl → 最后 landingUrl。universalLink 是 iOS 的另一个调起地址,它与 deepLink 的先后未作规定,iOS 端接入时需联调确认。
4.2.1 Image / Video / MiniProgram / WechatExt 对象
| 对象 | 字段 | 说明 |
|---|---|---|
| Image | url、width、height、desc | 图片地址、宽高(像素)、描述 |
| Video | duration、mimeType、width、height、videoUrl、coverUrl、length、videoType、skip、skipMinTime | 时长(毫秒)、媒体类型(1–6,见 1.1.5)、宽高、视频地址、封面地址、文件大小(KB)、视频类型(见 1.1.5)、是否可跳过(0=否,1=是)、可跳过的最短观看时长(毫秒)。当前不投放视频,本对象可忽略;视频播放事件监测统一在 track[].eventTracks |
| MiniProgram | miniProgramLink、miniProgramId、miniProgramName | 小程序跳转地址、ID、名称 |
| WechatExt | wechatExtData | 微信扩展数据 |
字段缺失时省略;平台不校验素材地址是否可访问。
4.3 TrackBase 对象
track 为对象数组;六个常规事件字段是 URL 数组,eventTracks 是带事件编号的对象数组。事件发生时,遍历所有 track 对象,逐个请求对应事件的全部 URL。
| 字段 | 触发时机 | 请求方法 | 接口路径 | 类型 |
|---|---|---|---|---|
| imp | 广告实际展示给用户时;收到竞价响应不算曝光 | GET | /rtb/track/impression |
Array<string> |
| clk | 用户实际点击广告时 | GET | /rtb/track/click |
Array<string> |
| del | 应用下载实际开始时 | GET | /rtb/track/download-start |
Array<string> |
| finishDle | 应用下载成功完成时;下载失败不触发 | GET | /rtb/track/download-finish |
Array<string> |
| install | 应用安装实际开始时 | GET | /rtb/track/install-start |
Array<string> |
| finishInstall | 应用成功安装完成时;安装失败不触发 | GET | /rtb/track/install-finish |
Array<string> |
| eventTracks | 按下面 eventType 对应的实际事件触发 |
GET | /rtb/track/event |
Array<EventTrack> |
| notice | 竞败通知:该广告在媒体自己的竞价中落败、未被展示时;见下文 | GET | /rtb/track/notice |
Array<string> |
eventTracks 可选;每项包含 eventType(int)和 eventTrackUrls(URL 数组)。事件发生时,只请求同编号项中的全部链接。未返回的编号不请求;禁止把下载、安装或点击当作调起成功。
notice 仅在该广告支持竞败通知时出现(按安装计费的广告没有)。URL 携带 macroVersion=1 与 macro.__bid_lose__(竞败标识)、macro.__lose_reason__(竞败原因)、macro.__type__(通知类型)、macro.__ext__(扩展信息)占位符参数,参数名带 macro. 前缀,规则与 4.6 节其他宏一致:有真实值就替换参数值,没有就保留占位符原文。请求是否产生效果以线下确认为准;它与曝光、点击、安装回调相互独立,不能互相替代,也不触发结算。
计费与结算事件:
| 广告类型 | 计费事件 | 说明 |
|---|---|---|
| 按曝光计费的广告 | imp 曝光回调 |
同一广告重复回调不重复计费 |
按安装计费的广告(id 以 free- 开头) |
finishInstall 安装完成回调 |
其余事件不计费;漏报则该次安装不计费 |
点击、下载、安装开始、通用事件、竞败通知均不计费。
| eventType | 触发时机 |
|---|---|
| 11 | 检测到 deepLink 对应应用未安装 |
| 12 | 检测到 deepLink 对应应用已安装 |
| 13 | deepLink 调起应用失败 |
| 14 | deepLink 成功调起应用,不能仅凭点击推定成功 |
当前物料协议未提供视频素材或视频宏参数,媒体不应模拟视频事件;以下编号仅供解析响应时识别。
| 视频 eventType | 事件 |
|---|---|
| 1 / 5 | 开始播放 / 播放完成 |
| 2 / 3 / 4 | 播放至 25% / 50% / 75% |
| 6 / 16 | 开启静音 / 关闭静音 |
| 7 / 19 | 进入全屏 / 退出全屏 |
| 8 / 9 / 20 | 跳过 / 关闭 / 播放中途关闭 |
| 10 / 15 | 加载成功 / 播放失败 |
| 17 / 18 | 暂停 / 重新播放 |
监测请求规则:
- 使用 HTTP GET,不使用 POST 或 HEAD。每条链接独立请求,无请求体。
- 原样使用响应返回的完整 URL;不要自行拼接路径、替换 token、追加竞价鉴权参数或修改价格。URL 上带有
macro.<宏名>占位符参数时:有真实端侧值就替换参数值(每个值做一次 URL 编码),没有就保留占位符原文,不要删除参数,见 4.6 节。 - URL 中的
token是本条广告的监测凭据,与生成竞价签名的鉴权 token 不同。 - 监测不需要额外提供
requestId/auth;曝光价格宏由平台加密后替换,媒体不提交价格或执行价格加密。监测 URL 上的其他宏按 4.6 节的要求级别处理。 - 对未展示或未被用户操作的广告不上报;每条广告的每次真实事件只触发一次。客户端应按本次响应中的广告及监测链接关联事件,不以广告
id做全局去重。 track对象中的事件字段缺失或 URL 数组为空时跳过;下载或安装阶段不能用点击事件代替。
| 监测结果 | 处理方式 |
|---|---|
| HTTP 204 | 请求结束,无响应体;不解析 JSON,不持续重试。该状态不证明 token 有效或第三方已收到事件,也不作为结算确认。 |
| HTTP 500 | 服务异常,可对原 URL 做有限重试并记录失败。 |
| 网络超时或连接失败 | 交付状态不确定,避免无限重试;点击、下载/安装和通用事件的重复请求可能产生重复上报。 |
4.4 Track 上报接口公共参数
各上报接口的域名和完整 URL 均以本次竞价响应为准。以曝光上报为例:
GET /rtb/track/impression?token=rtb-0123456789abcdef0123456789abcdef HTTP/1.1
Host: adhit.cn
| 参数/请求项 | 位置 | 是否必需 | 说明 |
|---|---|---|---|
| token | URL query | 是 | 响应监测 URL 已包含的广告凭据;原样使用,不自行生成 |
| eventType | URL query | 仅通用事件必需 | /rtb/track/event 使用,范围 1–20;响应 URL 已包含,不自行追加或修改 |
| macroVersion | URL query | 响应 URL 已包含时原样保留 | 监测 URL 的宏协议版本,当前为 1;以响应 URL 为准,原样保留 |
| macro.<宏名> | URL query | 响应 URL 已包含时保留 | 有真实端侧值就把参数值替换为该值并做一次 URL 编码,没有就保留占位符原文;不要删除参数;平台不校验该参数;规则见 4.6 节 |
| 请求体 | Body | 无 | 不发送 JSON、表单或广告信息 |
| 鉴权签名 | — | 无 | 不追加竞价请求的 requestId、auth 或鉴权 token |
| Content-Type | Header | 不要求 | GET 请求无请求体,无需设置 application/json |
通用事件缺失、重复或非法 eventType 返回 HTTP 400;宏参数不参与校验。
同一广告的各事件 URL 可能使用同一监测 token,但路径不同;必须使用对应事件的完整 URL。缺失或无法识别的 token 也会返回 HTTP 204,但不会完成对应广告的上报。
4.5 Track 上报代码示例(Python 3)
调用方保存本次响应的广告对象 ad,真实事件发生后调用 report_event(ad, "imp");点击使用 "clk",其余事件使用 4.3 节对应字段。成功调起应用后使用 report_event(ad, "eventTracks", 14)。以下函数逐条发送 GET,不自动重试。
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen
def report_event(ad, event, event_type=None):
allowed = {"imp", "clk", "del", "finishDle", "install", "finishInstall", "eventTracks"}
if event not in allowed:
raise ValueError("未知广告事件")
if event == "eventTracks" and (type(event_type) is not int or not 1 <= event_type <= 20):
raise ValueError("通用事件编号须为 1–20")
statuses = []
for track in ad.get("track", []):
if event == "eventTracks":
urls = [url for item in track.get("eventTracks", [])
if item.get("eventType") == event_type
for url in item.get("eventTrackUrls", [])]
else:
urls = track.get(event, [])
for url in urls:
try:
with urlopen(Request(url, method="GET"), timeout=5) as response:
statuses.append(response.status)
except HTTPError as error:
statuses.append(error.code)
except (URLError, TimeoutError):
statuses.append(None) # 交付状态不确定,交由调用方记录与处理。
return statuses
返回值按每条 URL 给出 HTTP 状态码;网络失败为 None,没有该事件链接则返回空列表。HTTP 204 的含义见 4.3 节。
4.6 宏定义与要求级别(v2.0.14)
宏定义由本文档约定,不在响应体中下发;每次响应实际携带哪些宏,以监测 URL 上的 macro.<宏名> 占位符参数为准。
要求级别取自 360 对接文档「宏替换」一节;该节的内嵌表格在 360 的在线文档里可能更新,以其在线版本为准。
| 宏 | 含义(依据 360 文档) | 360 要求级别 | 媒体缺值时平台的处理 | 出现位置(示例) |
|---|---|---|---|---|
__win_price__ |
成交价(分),平台加密后替换 | 必须替换,由平台完成 | 媒体不提交,提交也会被忽略 | imp |
__down_time__ / __up_time__ |
按下 / 抬起时间戳(UTC 毫秒) | 必须上报(__sld__ 为 0 或 1 时) |
转发上游原占位符 | imp、clk |
__down_x__ / __down_y__ |
按下触点 X / Y 坐标 | 无法获取时填 -999 |
填 -999 |
imp、clk |
__DOWN_X__ / __DOWN_Y__ |
同上;与上一行大小写不同,是两个独立占位符,取值差异未确认 | 同上 | 填 -999 |
仅 clk |
__up_x__ / __UP_X__、__up_y__ / __UP_Y__ |
抬起触点 X / Y 坐标 | 无法获取时填 -999 |
填 -999 |
imp、clk |
__x_max_acc__ / __y_max_acc__ / __z_max_acc__ |
摇动点击时三轴加速度峰值 | 推荐(__sld__=2 时) |
转发上游原占位符 | imp、clk |
__turn_x__ / __turn_y__ / __turn_z__、__turn_time__ |
扭动角度(-180 到 180)与时长(毫秒) | 推荐(__sld__ 为 3 或 4 且涉及屏幕角度变化时) |
转发上游原占位符 | imp、clk |
__sld__ / __SLD__ |
交互方式:0 正常触屏点击、1 引导滑动、2 摇一摇、3 自定义手势、4 触屏或滑动、5 扭动、6 擦除;大小写为两个独立占位符 | 未写要求 | 转发上游原占位符 | __sld__:imp、clk;__SLD__:仅 clk |
__density__ |
屏幕密度 | 未写要求 | 转发上游原占位符 | imp、clk |
__utc_tms__ / __utc_end_tms__ |
业务开始 / 结束时刻 UTC 时间戳(毫秒) | 未写要求 | 转发上游原占位符 | imp、clk |
__WIDTH__ / __HEIGHT__ |
实际广告位宽 / 高 | 未写要求 | 转发上游原占位符 | 仅 clk |
{WIN_POS} |
展示位置标识;360 宏表未定义,含义未确认 | 未写要求 | 转发上游原占位符 | imp、clk |
__CLICK_LPP__ |
落地页点击参数;除 landingUrl 外也出现在 clk 监测 URL 中 |
未写要求 | 转发上游原占位符(landingUrl 中由客户端在跳转前处理) |
landingUrl、clk |
__bid_lose__ / __lose_reason__ / __type__ / __ext__ |
竞败标识 / 原因(优先文字)/ 类型(竞胜 2、竞败 1)/ 扩展信息 | 竞败通知要求替换;原因和竞败码用自己的即可 | 转发上游原占位符 | notice |
上表为一次响应的示例,不代表每次响应都相同;每次响应携带的宏以 URL 上的 macro.<宏名> 参数为准。
「必须」「推荐」是 360 对媒体的要求,平台不强制:缺值不会被拒绝,但上游收到占位符原文或 -999 可能不符合 360 的要求,影响其归因与反作弊,所以必须类宏请尽量提供真实值。
带宏监测 URL 的处理规则(macroVersion=1):
- 平台监测 URL 携带
macroVersion=1和每个客户端宏一个占位符参数,参数名与参数值均为宏原文,例如...?token=...¯o.__down_x__=__down_x__¯o.__DOWN_X__=__DOWN_X__。 - 触发事件时,媒体把有真实端侧值的占位符参数的值替换为该值,并对该值做一次 URL 编码;没有真实值的参数保留占位符原文,不要删除参数;URL 的其余部分(路径、其他参数、
macroVersion)原样保留。真实字符串"0"是有效值。 - 平台不校验
macro.*参数。下列情形一律按「缺值」处理,回调仍按正常回调受理(HTTP 204,计费与转发规则不变):参数缺失、值为空、重复(含百分号编码别名)、超过 2048 字节、值仍含自己的占位符原文、该监测 URL 未携带的宏。 - 平台向上游转发时,有真实值的宏解码一次后按原链接所在组件编码替换;缺值的宏:触点坐标(
__down_x__、__down_y__、__up_x__、__up_y__及大写变体)填-999,其余保留上游原占位符。宏名严格匹配、区分大小写。同一宏可出现在多个事件中,各事件独立处理;通用事件按eventType汇总同编号全部监测链接的宏。 - 曝光回调首次携带的可用宏值固定为快照;因失败重试的曝光请求可不再携带宏参数,沿用该快照。
- 物料链接(
landingUrl/deepLink)中的宏按原样下发,由客户端在跳转前处理;平台不参与落地页宏替换,也不能从后续点击回调反推。
仍会返回 HTTP 400 的情形: macroVersion 取值不是本协议支持的版本。除此之外宏不参与校验。
v2.0.8 及更早签发的不带宏监测 URL 不受影响,行为与历史版本一致。
宏所在位置: 只有位于单层查询参数值内的宏才会被替换。宏出现在 scheme/host/port、查询参数名、路径、fragment,或在参数值内被二次编码时,平台不做替换也不拒绝,按原样转发。
媒体接入边界:
- 曝光价格由平台加密替换,媒体不提交或修改价格;提交价格宏会被忽略。
- 能提供真实值的宏请提供,坐标与时间按事件发生时的真实值填写,不要把屏幕或请求模板尺寸当作实际点击时广告尺寸,也不要用
tagId、数组下标等替代值伪造数据;不能提供时保留占位符原文即可。 landingUrl中的宏未替换,不能假定是可直接使用的落地页链接。- 竞败通知
track[].notice同样按本节处理:媒体回传竞败原因等真实值,平台转发给上游;不要把曝光、点击或安装回调当作竞败通知。
在完成真实端侧数据的联合验收前,不把"有填充"验收当作"事件上报、归因和结算全链路"验收,也不自行构造或替换监测 URL 绕过平台。
4.7 下载图文广告兼容扩展(待发布)
本节尚未发布到生产;启用前由对接双方确认对应广告位的明示展示、单次展示和原有回调能力。未完成验收的广告位继续使用原有广告来源。
| BidAdContent 新增字段 | 类型 | 含义与媒体处理 |
|---|---|---|
| privacyUrl | string,可选 | 应用隐私协议页面;有值时提供可访问入口 |
| permissionUrl | string,可选 | 应用所需权限页面;有值时提供可访问入口,不作为权限正文显示 |
| appIntroductionUrl | string,可选 | 应用产品功能介绍页面;有值时提供可访问入口,不作为 intro 正文显示 |
| adLogoUrl | string,可选 | 广告来源标识图片;该类物料返回时须在广告区域展示,不替代应用图标 |
四个字段只包含 URL,无值时省略。现有 sensitiveUrl、usesPermission、intro、iconUrl 保持原含义。首期仅支持安卓下载图文,不包含视频、激励视频或 iOS。
| 行为 | 验收要求 |
|---|---|
| 请求与鉴权 | 沿用 v2.0.13,不新增必填输入或版本参数 |
| 竞胜 | 平台完成本地竞胜通知;媒体无需增加 win 调用,也无需计算、加密或回传价格 |
| 曝光 | 按现有 track[].imp 上报实际曝光;一次请求的物料仅展示一次,之后再次展示须重新请求。相同 URL 重试不重复计费 |
| 点击与竞败 | 沿用 track[].clk、track[].notice 及 URL 中已声明的原宏;不要自行增加额外占位符或改写 URL |
| HTTP 204 | 平台已接收事件;曝光结算和通知任务已持久化。通知失败由平台补投,媒体无需为服务故障重复上报;204 不代表广告服务已收到 |
| 旧客户端 | 原请求、回调、金额语义不变;不向尚未实现上述展示要求的广告位下发依赖新字段的物料 |
示例仅展示新增字段,完整响应结构仍以 6.3 节为准:
{
"bidAdContent": {
"privacyUrl": "https://assets.example.com/privacy",
"permissionUrl": "https://assets.example.com/permissions",
"appIntroductionUrl": "https://assets.example.com/introduction",
"adLogoUrl": "https://assets.example.com/ad-logo.png"
}
}
联调须检查四个入口/标识的实际展示、重复曝光回调仅计费一次、再次展示重新请求,以及未升级广告位继续收到原有字段结构;不能仅以 HTTP 200/204 判定通过。
4.8 洗包场景说明(v2.0.15)
适用于洗包广告位。请求字段与平台行为:
| 请求字段 | 平台行为 |
|---|---|
imp[].pkgWhitelist |
目标应用包名列表,去重后按顺序最多取前 100 个。平台按列表填充:每个包优先由预算方出价(有预算包),预算方没有的由平台目录补充(无预算填充包;纯目录广告位不请求预算方,见 4.8 节)。省略时洗包最多返回 8 条,来源与顺序由平台决定 |
imp[].customizedInfo.installPkgs |
设备已安装的包。平台不返回其中的包(两类广告均排除),同时原样透传给预算方;列表中的包全部已安装时返回 HTTP 204 |
imp[].customizedInfo.unstallPkgs |
原样透传给预算方;平台不据此筛选无预算填充包 |
区分有预算包与无预算填充包(4.1 节 price):
price |
含义 | source |
|---|---|---|
| 大于 0 | 有预算包:预算方付费竞价,price 为 CPM,单位分 |
投放渠道标识 |
"0" |
无预算填充包:平台目录填充,没有预算 | 不返回 |
平台默认测试广告(见 2.4 节)不属于以上两类,price 与 source 见 2.4 节。
返回规则:
- 返回条数等于被覆盖的包数,不超过 100,也不超过列表条数;预算方和平台目录都没有的包不返回,平台不保证覆盖全部列表。
- 顺序:有预算包在前,按价格从高到低;无预算填充包在后,有价目的在前,其余按请求列表的顺序。
- 同一包名只返回一次,有预算包优先。
- 两类广告的监测上报方式完全相同:媒体按 4.3 至 4.6 节对每条广告的全部监测 URL 照常上报,不得因
price为"0"跳过任何上报。是否计费或结算由平台决定。
纯目录广告位(v2.0.16)
平台可按接入方需求开通纯目录洗包广告位,tagId 由平台提供。请求与响应的字段、鉴权、监测上报方式与上文一致,不新增字段。
| 项 | 纯目录广告位的行为 |
|---|---|
| 广告来源 | 不向预算方请求,响应中只有无预算填充包,price 恒为 "0",不返回 source |
imp[].pkgWhitelist |
规则同上表:去重后按顺序最多取前 100 个,平台目录有的包才返回,返回条数不超过列表条数;省略时最多返回 8 条,来源与顺序由平台决定 |
imp[].customizedInfo.installPkgs |
平台不返回其中的包;列表中的包全部已安装时返回 HTTP 204 |
| 无广告 | 平台目录没有列表中的任何包,或没有可返回的包时返回 HTTP 204 |
| 联调 | test-ad 不是纯目录广告位,不能用它验证;请用平台提供的 tagId |
5. 状态码
| 状态码 | 说明 |
|---|---|
| 200 | 有广告响应 |
| 204 | 无广告,响应体为空;本次请求结束,不立即循环重试 |
| 400 | JSON 格式、字段类型或必需对象错误(含缺失 device.w/device.h/app.version),或 gzip 数据无效;修正请求后再发起 |
| 401 | requestId/auth 缺失、requestId 超过 64 字节或签名错误;核对 token 与拼接方式(签名比较不区分大小写),见 2.3 节 |
| 403 | 访问被拒绝,由接入层网关返回,应用本身不产生;联系对接方核查访问限制 |
| 404 | 请求地址不存在;核对环境、域名和路径 |
| 405 | 请求方法错误;竞价使用 POST,监测使用 GET |
| 413 | 请求体超限;按 2.2 节缩小请求体 |
| 500 | 服务异常;保留请求 ID、时间及状态码供排查,可按业务时效有限重试 |
6. 请求响应示例
6.1 Android 请求示例
将以下内容保存为 bid-request.json。示例设备信号仅用于演示字段格式;真实调用须换成实际用户终端信息,广告位及模板须使用已开通的配置。
{
"id": "20261012120000000001",
"imp": [
{
"id": "imp-1",
"tagId": "YOUR_TAG_ID",
"templateList": [
{
"templateId": "YOUR_TEMPLATE_ID",
"targetTypeStr": "2",
"width": 258,
"height": 258
}
],
"reqadnum": 1
}
],
"device": {
"ua": "Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 Chrome/120.0.0.0 Mobile Safari/537.36",
"ip": "203.0.113.10",
"deviceType": 1,
"make": "Google",
"model": "Pixel 8",
"os": 2,
"osv": "14",
"w": 1080,
"h": 2400,
"connectionType": 1,
"oaId": "23E3BA8B-75E7-423D-BF8F-69C72AAF7986"
},
"app": {
"name": "媒体应用名称",
"bundle": "com.example.media",
"version": "1.0.0"
},
"timeout": 800
}
iOS 请求使用 os: 1、真实 iOS UA/机型/系统版本,并将 oaId 替换为 idfa 或 idfaMd5。是否展示下载入口按 4.2 节处理。
6.2 可运行的签名与请求示例(Python 3)
保存为 bid-client.py,与 bid-request.json 放在同一目录。设置本环境 token 后运行;仅使用标准库。脚本不自动触发监测请求。
export BID_TOKEN='本环境的鉴权 token'
# 测试时设置商务侧提供的完整地址;正式环境可省略。
export BID_URL='https://adhit.cn/rtb/bid'
python3 bid-client.py
import hashlib
import json
import os
import uuid
from decimal import Decimal
from pathlib import Path
from urllib.error import HTTPError, URLError
from urllib.parse import urlencode
from urllib.request import Request, urlopen
def main():
token = os.environ["BID_TOKEN"]
endpoint = os.environ.get("BID_URL", "https://adhit.cn/rtb/bid")
body = json.loads(Path("bid-request.json").read_text(encoding="utf-8"))
request_id = uuid.uuid4().hex
body["id"] = request_id
auth = hashlib.md5((request_id + token).encode("utf-8")).hexdigest().upper()
url = endpoint + "?" + urlencode({"requestId": request_id, "auth": auth})
request = Request(
url,
data=json.dumps(body, ensure_ascii=False).encode("utf-8"),
headers={"Content-Type": "application/json"},
method="POST",
)
try:
# 示例使用 10 秒网络超时,覆盖本次 800ms 预算及传输时间。
with urlopen(request, timeout=10) as response:
if response.status == 204:
print("无广告", request_id)
return
result = json.load(response)
except HTTPError as error:
print("HTTP 错误", error.code, "requestId=", request_id)
return
except (URLError, TimeoutError) as error:
print("网络错误", type(error).__name__, "requestId=", request_id)
return
if result["id"] != request_id:
raise ValueError("响应 id 与请求不一致")
for ad in result.get("bidList", []):
price = Decimal(ad["price"])
print("广告", ad["impId"], ad["tagId"], ad["id"], "价格", price)
# 保存该广告的物料和 track,实际事件发生时按 4.3 节请求对应链接。
if __name__ == "__main__":
main()
6.3 HTTP 200 平台响应示例
以下为请求测试广告位 test-ad(见 2.4 节)得到的平台响应示例。监测 token 已替换为未签发的 rtb-example-not-issued,不能用于实际监测。
该样例的监测 URL 不带宏占位符参数;带宏响应示例见 6.6 节,回传示例见 6.7 节。
本次响应对应的请求参数如下,与 6.1 节通用请求示例独立:
| 请求字段 | 取值 |
|---|---|
query requestId / 请求体 id |
test-ad-check-6df1e79dddf345cebd1f188bec88649e |
imp[0].id / imp[0].tagId |
imp_check / test-ad |
imp[0].templateList[0] |
templateId: "1"、width: 320、height: 480、targetTypeStr: "2" |
timeout |
5000 毫秒 |
联调设备参数为样例,不代表真实用户流量;正式请求必须填写真实设备信息。test-ad 的使用范围与限制见 2.4 节;签名使用媒体调用本平台的鉴权 token。
{
"id": "test-ad-check-6df1e79dddf345cebd1f188bec88649e",
"bidList": [
{
"id": "ad-360test-1",
"price": "618",
"bidAdContent": {
"appName": "示例应用",
"pkgName": "com.example.app",
"iosAppid": "",
"iconUrl": "https://assets.example.com/icon.png",
"downloadUrl": "https://cdn.example.com/download?packageName=com.example.app&appId=100000000",
"landingUrl": "https://land.example.com/click?packageName=com.example.app&ad_id=100000001&clklpp=__CLICK_LPP__"
},
"track": [
{
"imp": [
"https://adhit.cn/rtb/track/impression?token=rtb-example-not-issued"
],
"clk": [
"https://adhit.cn/rtb/track/click?token=rtb-example-not-issued"
],
"del": [
"https://adhit.cn/rtb/track/download-start?token=rtb-example-not-issued"
],
"finishDle": [
"https://adhit.cn/rtb/track/download-finish?token=rtb-example-not-issued"
],
"install": [
"https://adhit.cn/rtb/track/install-start?token=rtb-example-not-issued"
],
"finishInstall": [
"https://adhit.cn/rtb/track/install-finish?token=rtb-example-not-issued"
],
"eventTracks": [
{
"eventType": 14,
"eventTrackUrls": [
"https://adhit.cn/rtb/track/event?token=rtb-example-not-issued&eventType=14"
]
}
]
}
],
"impId": "imp_check",
"tagId": "test-ad",
"targetType": 2,
"templateId": "1"
}
]
}
| 字段 | 使用规则 |
|---|---|
id / impId / tagId / templateId |
对应上表的请求;使用其他请求参数时,响应回显相应标识,不应写死示例值 |
appName / pkgName |
本次实际返回「示例应用」/ com.example.app,不保证后续请求仍返回相同广告 |
price |
618 分 CPM,即每千次曝光 6.18 元;仅供展示参考,不能作为回调参数或直接作为单次曝光费用 |
iconUrl / downloadUrl / landingUrl |
均为本次实际返回地址;链接可能过期,不请求这些示例链接,也不缓存响应复用。下载时使用当次非空 downloadUrl |
deepLink |
本次未返回,因此示例不包含该字段;其他响应如返回,按 4.2 节处理 |
landingUrl 中的 __CLICK_LPP__ |
落地页地址原样下发,宏由客户端在跳转前处理,见 4.6 节 |
track |
六个常规事件及 eventType=14 均为平台监测地址,示例 token 未签发;实际事件只使用当次响应中的完整 URL,规则见 4.3 节 |
平台响应按 bidList 解析,响应体即为上文的 id 与 bidList 结构,没有额外的 code / data / groups 外层。示例仅为广告请求结果,不包含曝光等监测回调。
6.4 HTTP 204 响应示例
HTTP/1.1 204 No Content
无 JSON 响应体。400、401、413 等错误也可能无响应体,按状态码处理。
6.5 监测请求示例
在真实事件发生后,将对应 track 数组中的完整 URL 设置为 TRACK_URL 再执行;例如曝光使用 imp 中的 URL。不要使用 6.3 节的示例 token 请求接口。
curl --request GET --max-time 5 --silent --show-error \
--output /dev/null --write-out 'HTTP %{http_code}\n' "$TRACK_URL"
正常返回 HTTP 204,无需读取响应体。同一事件有多条 URL 时逐条执行。
6.6 HTTP 200 带宏响应示例
以下为请求测试广告位 test-ad(见 2.4 节)得到的带宏平台响应示例。监测 token 已替换为未签发的 rtb-example-not-issued,不能用于实际监测。
要点:曝光(imp)与点击(clk)监测 URL 携带的宏集合不同——imp 携带 18 个宏(小写触点/时间/传感器宏与 {WIN_POS}),clk 携带 26 个宏(另含全部大写变体 __DOWN_X__/__DOWN_Y__/__UP_X__/__UP_Y__/__WIDTH__/__HEIGHT__/__SLD__ 与 __CLICK_LPP__)。macro.<宏名> 参数名区分大小写,参数值为占位符原文,媒体有真实值就替换,没有就保留。
{
"bidList": [
{
"id": "ad-360test-1",
"price": "618",
"impId": "imp-1",
"tagId": "test-ad",
"bidAdContent": {
"appName": "示例应用",
"pkgName": "com.example.app",
"iconUrl": "https://assets.example.com/icon.png",
"downloadUrl": "https://cdn.example.com/download?packageName=com.example.app&appId=100000000",
"deepLink": "",
"landingUrl": "https://land.example.com/click?packageName=com.example.app&ad_id=100000001&clklpp=__CLICK_LPP__"
},
"track": [
{
"imp": [
"https://adhit.cn/rtb/track/impression?token=rtb-example-not-issued¯oVersion=1¯o.%7BWIN_POS%7D=%7BWIN_POS%7D¯o.__density__=__density__¯o.__down_time__=__down_time__¯o.__x_max_acc__=__x_max_acc__¯o.__y_max_acc__=__y_max_acc__¯o.__z_max_acc__=__z_max_acc__¯o.__sld__=__sld__¯o.__down_x__=__down_x__¯o.__down_y__=__down_y__¯o.__up_x__=__up_x__¯o.__up_y__=__up_y__¯o.__turn_time__=__turn_time__¯o.__turn_x__=__turn_x__¯o.__turn_y__=__turn_y__¯o.__turn_z__=__turn_z__¯o.__up_time__=__up_time__¯o.__utc_end_tms__=__utc_end_tms__¯o.__utc_tms__=__utc_tms__"
],
"clk": [
"https://adhit.cn/rtb/track/click?token=rtb-example-not-issued¯oVersion=1¯o.__density__=__density__¯o.__down_time__=__down_time__¯o.__x_max_acc__=__x_max_acc__¯o.__y_max_acc__=__y_max_acc__¯o.__z_max_acc__=__z_max_acc__¯o.__sld__=__sld__¯o.__down_x__=__down_x__¯o.__down_y__=__down_y__¯o.__up_x__=__up_x__¯o.__up_y__=__up_y__¯o.__turn_time__=__turn_time__¯o.__turn_x__=__turn_x__¯o.__turn_y__=__turn_y__¯o.__turn_z__=__turn_z__¯o.__up_time__=__up_time__¯o.__utc_end_tms__=__utc_end_tms__¯o.__utc_tms__=__utc_tms__¯o.__DOWN_X__=__DOWN_X__¯o.__DOWN_Y__=__DOWN_Y__¯o.__HEIGHT__=__HEIGHT__¯o.__SLD__=__SLD__¯o.__UP_X__=__UP_X__¯o.__UP_Y__=__UP_Y__¯o.__WIDTH__=__WIDTH__¯o.__CLICK_LPP__=__CLICK_LPP__¯o.%7BWIN_POS%7D=%7BWIN_POS%7D"
],
"del": [
"https://adhit.cn/rtb/track/download-start?token=rtb-example-not-issued"
],
"finishDle": [
"https://adhit.cn/rtb/track/download-finish?token=rtb-example-not-issued"
],
"install": [
"https://adhit.cn/rtb/track/install-start?token=rtb-example-not-issued"
],
"finishInstall": [
"https://adhit.cn/rtb/track/install-finish?token=rtb-example-not-issued"
],
"eventTracks": [
{
"eventType": 14,
"eventTrackUrls": [
"https://adhit.cn/rtb/track/event?token=rtb-example-not-issued&eventType=14"
]
}
]
}
]
}
]
}
| 字段 | 使用规则 |
|---|---|
price |
618 分 CPM;仅供展示参考,不作为回调参数或单次曝光费用 |
landingUrl |
含 __CLICK_LPP__ 宏,由客户端跳转前处理,见 4.6 节 |
imp 的 macro.* 参数 |
18 个宏,要求级别与缺值处理见 4.6 节;曝光回传示例见 6.7 节 |
clk 的 macro.* 参数 |
26 个宏,比 imp 多大写变体与 __CLICK_LPP__;说明大小写是独立宏、且同一宏在不同事件的集合可能不同——以每次响应 URL 实际携带为准 |
eventTracks |
eventType=14 平台监测地址;本广告未返回视频类事件 |
| token | 已脱敏;实际事件只使用当次响应中的完整 URL |
上例仅保留与宏相关的字段,不是完整响应:实际响应的每条广告恒含 id、bidAdContent.iosAppid、targetType、templateId,空的 deepLink 会被省略而不是返回空串;完整字段形态以 6.3 节为准。
6.7 带宏回传示例
回传示例(宏值为演示值,非真实端侧数据):
曝光回传(有真实值的宏替换,没有的保留原文,平台受理 HTTP 204):
curl --request GET --max-time 5 --silent --show-error \
--output /dev/null --write-out 'HTTP %{http_code}\n' \
"https://adhit.cn/rtb/track/impression?token=<当次响应中的token>¯oVersion=1¯o.%7BWIN_POS%7D=%7BWIN_POS%7D¯o.__density__=3¯o.__down_time__=1791959414599¯o.__down_x__=528.5¯o.__down_y__=<演示值>¯o.__up_time__=1791959414599¯o.__up_x__=<演示值>¯o.__up_y__=761.5¯o.__x_max_acc__=__x_max_acc__&..."
示例里 {WIN_POS}、__x_max_acc__ 没有真实值,保留了原文;__down_x__ 等有真实值,已替换。
缺值回传(全部保留占位符原文,平台同样受理 HTTP 204):
curl --request GET --max-time 5 --silent --show-error \
--output /dev/null --write-out 'HTTP %{http_code}\n' \
"https://adhit.cn/rtb/track/impression?token=<当次响应中的token>¯oVersion=1¯o.%7BWIN_POS%7D=%7BWIN_POS%7D¯o.__density__=__density__&..."
平台不因缺值返回 400;转发上游时,触点坐标填 -999,其余保留上游原占位符。毫秒/秒级时间戳、小数坐标、dpi 密度、超界值、Unicode 等宏值形态均可传输,宏值单位以 360 文档为准。
6.8 洗包响应示例(有预算包与无预算填充包)
请求洗包广告位,imp[0].pkgWhitelist 为 com.example.paid,com.example.fill。以下为响应片段(省略部分可选字段):第一条为有预算包(price 为 CPM),第二条为无预算填充包(price 为 "0")。监测 token 已替换为未签发的 rtb-example-not-issued,不能用于实际监测。
{
"id": "wash-check-001",
"bidList": [
{
"id": "ad-360-1",
"price": "618",
"impId": "imp-1",
"tagId": "wash-tag",
"targetType": 2,
"templateId": "1",
"bidAdContent": {
"appName": "示例应用 A",
"pkgName": "com.example.paid",
"iconUrl": "https://assets.example.com/paid-icon.png",
"downloadUrl": "https://cdn.example.com/download?packageName=com.example.paid"
},
"track": [
{
"imp": ["https://adhit.cn/rtb/track/impression?token=rtb-example-not-issued"],
"clk": ["https://adhit.cn/rtb/track/click?token=rtb-example-not-issued"],
"finishInstall": ["https://adhit.cn/rtb/track/install-finish?token=rtb-example-not-issued"]
}
]
},
{
"id": "free-com.example.fill",
"price": "0",
"impId": "imp-1",
"tagId": "wash-tag",
"targetType": 2,
"templateId": "1",
"bidAdContent": {
"appName": "示例应用 B",
"pkgName": "com.example.fill",
"iconUrl": "https://assets.example.com/fill-icon.png",
"downloadUrl": "https://cdn.example.com/download?packageName=com.example.fill"
},
"track": [
{
"imp": ["https://adhit.cn/rtb/track/impression?token=rtb-example-not-issued"],
"clk": ["https://adhit.cn/rtb/track/click?token=rtb-example-not-issued"],
"finishInstall": ["https://adhit.cn/rtb/track/install-finish?token=rtb-example-not-issued"]
}
]
}
]
}
两条广告的上报方式相同;有预算包的 price 为 CPM,无预算填充包的 price 恒为 "0",据此区分。
7. 联调验收
| 检查项 | 输入/操作 | 验收结果 |
|---|---|---|
| 请求签名 | 使用 2.3 节固定输入计算签名 | 与表中 auth 一致 |
| 正常请求 | 已开通广告位、真实设备信号、正确签名;联调阶段可用 test-ad(见 2.4 节) |
返回 200 或 204;200 时 id 匹配且响应字段可解析 |
| 鉴权失败 | 测试环境发送缺失或错误的 auth |
HTTP 401 |
| 参数错误 | 测试环境发送缺失 device 的已签名请求 |
HTTP 400 |
| 无曝光位 | 测试环境发送 imp: [] 的已签名请求 |
HTTP 204,无响应体 |
| 响应关联 | 请求包含不同 imp.id 的多个曝光位 |
按 impId 分组,正确处理仅部分曝光位返回 |
| 下载地址缺失 | 使用不含 downloadUrl 的本地响应样例 |
不生成无效下载链接,不导致解析失败 |
| 事件监测 | 用一次真实展示及后续实际操作触发对应事件 | 请求匹配的原始 URL,方法为 GET,不额外签名 |
| 宏回调(v2.0.14) | 把有真实值的宏参数替换为该值后触发曝光和点击 | 平台按 204 受理,上游收到替换后的值 |
| 宏缺值(v2.0.14) | 保留全部宏参数的占位符原文后触发曝光和点击 | 平台按 204 受理;上游收到触点坐标 -999,其余为占位符原文 |
| 宏参数不校验(v2.0.14) | 删除、清空、重复或篡改 macro.* 参数后请求 |
仍按 204 受理,计费与转发规则不变 |
| 竞败通知(v2.0.11) | 响应含 track[].notice 时,回传竞败原因等真实值后请求该 URL |
平台按 204 受理并转发,上游收到替换后的值;缺值时收到占位符原文 |
| 字段透传(v2.0.11) | 请求携带第 3 节新增的可选字段 | 不触发 400,请求被正常受理 |
| 洗包两类广告(v2.0.15) | 洗包广告位请求带 pkgWhitelist |
有预算包(price 大于 0)在前,无预算填充包(price 为 "0")在后;同一包名只出现一次 |
| 已装包不返回(v2.0.15) | 洗包请求带 pkgWhitelist,并把其中一个包放进 customizedInfo.installPkgs |
响应中不含该包;列表全部已装时返回 HTTP 204 |
| 填充包上报(v2.0.15) | 对 price 为 "0" 的广告也按 4.3 节上报曝光、点击等 |
与有预算包一致,请求被正常受理(HTTP 204) |
联调失败时提供请求体 id、query requestId、请求时间、tagId、HTTP 状态码及脱敏请求体;不提供鉴权 token。