# 1. RTB接口
# 1.1. 通信方式
交易平台和DSP之间的基础通信协议采用HTTP协议,使用POST方法发送BidRequest消息。使用GET方法发送Win Notice消息。
# 1.2. HTTP请求头
Content-Type:application/x-protobuf
# 1.3. HTTP状态码
正常出价响应包的返回状态码为HTTP 200 OK,不出价的则为204 no content。其余情况均认为不正常。
# 1.4. 响应耗时
响应时间要求:
平均时长 < 最大120ms
# 1.5. 对DSP的要求
- DSP需提供实时竞价服务URL,例如: http://www.thirdDSP.com/bid (opens new window)。
- DSP需要提供默认获胜通知url接口用于曝光。
- DSP竞价服务所能承受的的最大QPS(Queries Per Second)。
# 2. 竞价请求
# 2.1. Bid Request涉及的结构
支持两种类型的广告,分别为:框内广告和页面广告
框内广告包括:贴片、暂停、通用浮层、触点广告 video对象
页面广告包括:信息流、开机图、猜你喜欢、视频关联位、触点广告、焦点图、巨幕 banner对象
触点广告 出现位置:前贴、中贴、短视频频道后贴
# 2.2. BidRequest对象详细字段及含义
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
id | optional | string | 每次请求的唯一标识 |
user | optional | User Object | 用户信息 |
site | optional | Site Object | 站点频道信息 |
device | optional | Device Object | 描述用户的设备信息 |
imp | repeated | Impression Object | 广告位曝光Imp对象列表 |
source_id | optional | int32 | 渠道ID 0:爱奇艺 |
m_id | optional | string | 合作方ID |
# 2.3. Impression Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
id | optional | string | 广告返回时的Bid.impid应该对应此id(一次session中唯一),表示竞价此曝光机会 |
banner | optional | Banner Object | 页面广告曝光机会相关信息 |
video | optional | Video Object | 贴片广告曝光机会相关信息 |
floor_price | repeated | FloorPrice Object | 不同行业设置不同底价。暂不下发 |
bidfloor | optional | int32 | CPM底价,单位:分。当在floor_price找不到所需行业的底价的时候,就用bidfloor作为当前的流量的底价。此部分适用于通用浮层类、信息流、猜你喜欢广告投放类型。 |
campaign_id | optional | int32 | 交易ID, 暂无。 |
blocked_ad_tag | optional | int32 | 标签过滤,暂不下发。 |
blocked_ad_attribute | repeated | int32 | 属性过滤,暂不下发。 |
is_pmp | optional | bool | 用于区分PDB和RTB流量,仅在PDB流量中有此字段,true为PDB流量,暂无。 |
extended_ads_position | optional | int32 | 是否支持5秒广告。0代表不支持,1代表支持正一,2代表支持倒一,3代表正一和倒一都支持。 |
impression_date | optional | int32 | 开机屏预计曝光时间,存在两种情况 1.请求中有该字段:开机屏为预加载请求,同时适用于移动端开机屏和部分OTT端开机屏;2.请求中无该字段:开机屏为实时请求,进适用于OTT端开机屏的部分请求。如:20211119 |
max_skippable_roll_ads | optional | int32 | 最多可投放的可跳过贴片数量 用于判断是否可以投放触点广告-RTB |
skippable_roll_bidfloor | optional | int32 | 无参考行业时的Trueview广告的参考底价,单位:分 |
info_stream_max_bids_allowed | optional | int32 | 信息流广告单次请求可允许投放的最大广告数,当大于1时可返回多个广告。 |
width | optional | int32 | 广告位宽,爱奇艺渠道暂不支持下发 |
height | optional | int32 | 广告位高,爱奇艺渠道暂不支持下发 |
# 2.4. FloorPrice Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
industry | optional | int64 | 行业 |
price | optional | int32 | 底价 |
skippable_roll_price | optional | int32 | Trueview广告底价,非贴片曝光机会无此字段 |
bidfloor ,skippable_roll_bidfloor和 floor_price 组合的三种情况:
情况一,bidrequest中只传送了bidfloor和skippable_roll_bidfloor,此时bidfloor是无参考行业时普通贴片底价,skippable_roll_bidfloor是无参考行业时Trueview广告底价;
情况二,bidrequest中同时传送了包括了全部行业(共六个)的floor_price数组(包括price和skippable_roll_price),此时以显示出来不同行业的price和skippable_roll_price的数值为准;
情况三,bidrequest中只传送部分行业的floor_price数组、bidfloor和skippable_roll_bidfloor,此时已显示出来的行业以floor_price数组为准,没有显示的行业以bidfloor和skippable_roll_bidfloor为准。
举例如下:
floor_price {`
`industry: 600000000`
`price: 1000000`
`skippable_roll_price: 1500000`
`}`
`bidfloor: 5000`
`skippable_roll_bidfloor: 10000
此时的含义代表600000000这个行业的普通贴片底价是1000000,Trueview广告底价为1500000,其他行业的普通贴片底价都是5000,Trueview广告底价都是10000。
# 2.5. Video Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
ad_zone_id | optional | string | 广告位id,ad_zone_id字典表见附录五 |
linearity | optional | int32 | 是否是串行在正片中的广告,1表示是,2不是 |
ad_type | optional | int32 | 广告类型,ad_type字典表见附录十一 |
minduration | optional | int32 | 广告最小时长 |
maxduration | optional | int32 | 广告最大时长 |
protocol | optional | int32 | 协议版本号 |
startdelay | optional | int32 | 本次广告自第几秒开始。 |
is_entire_roll | optional | bool | 本次曝光机会是否为完整流量 |
video_startdelay | optional | int32 | 播放进度(单位:秒) |
# 2.6. Banner Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
ad_zone_id | optional | string | 广告位id,ad_zone_id字典表见附录五 |
ad_type | optional | int32 | 广告类型,ad_type字典表见附录十一 |
# 2.7. User Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
id | optional | string | 用户ID,详细命名规则见附录一 |
is_privacy_protected | optional | bool | 标识当前用户的隐私应被保护 |
# 2.8. Site Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
id | optional | int32 | 站点ID |
content | optional | Content Object | 网站内容(也用作视频内容) |
# 2.9. Content Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
title | optional | string | 标题 |
url | optional | string | 网址 |
keyword | repeated | string | 关键字 |
len | optional | int32 | 视频时长 |
album_id | optional | int64 | 剧目信息 |
channel_id | optional | int64 | 频道信息,channel_id字典表见附录十 |
tag | repeated | string | 标签信息,通用浮层(创可贴)【即场景广告】专用识别字段 |
video_tag | repeated | int64 | 视频定向标签。 |
video_clip_id | optional | string | 用户标识该次流量请求的点位。通用浮层(创可贴)【即场景广告】专用识别字段 |
# 2.10. Device Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
ua | optional | string | User agent,app流量不支持传输此字段 |
ip | optional | string | 设备ip地址,使用广协ip库 |
geo | optional | Geo Object | 地理信息 |
connection_type | optional | int32 | 网络接入字段,connection_type字典表见附录十二 |
platform_id | optional | int32 | 平台信息,platform_id字典表见附录八 |
android_id | optional | string | Android设备的专用id信息,非必须发送字段 |
model | optional | string | 型号,如“vivoX6”,“iPhone 15.1” |
os | optional | string | 操作系统,取值如下:iOS,Windows,Android,UWP |
os_version | optional | string | 操作系统版本号,如“5.1.1” |
app_version | optional | string | App版本,如7.9 |
ipv6 | optional | string | 设备ipv6地址,使用广协ipv6库。 |
idfa | optional | string | IOS设备idfa,默认不发送 |
openudid | optional | string | IOS设备OpenUDID,默认不发送 |
imei | optional | string | Android设备imei,MD5后值,默认不发送 |
mac | optional | string | Mac地址,去掉“:”后MD5值 |
oaid | optional | string | 安卓Q设备ID,取原值,未取到则此字段为空。 |
screen_width | optional | int32 | 设备的屏幕分辨率的宽度,单位是像素。 |
screen_height | optional | int32 | 设备的屏幕分辨率的高度,单位是像素。 |
manufacturer | optional | string | 设备的制造厂商名称。如“huawei","xiaomi"。 |
carrier_name | optional | string | 运营商名称,UTF8编码。如”中国移动“。目前该字段只IOS系统有值。 |
idfv | optional | string | IOS设备idfv。目前该字段只IOS系统有值。 |
local_timezone | optional | string | 设备本地时区。如”Asia/Shanghai“。目前该字段只IOS系统有值。 |
os_update_time | optional | int64 | 设备系统更新时间,单位微秒,从1970年1月1日起的时间戳。目前该字段只IOS系统有值。 |
startup_time | optional | int64 | 设备开机时间,单位微秒,从1970年1月1日起的时间戳。目前该字段只IOS系统有值。 |
cpu_num | optional | int32 | 设备CPU数目,获取错误为0。目前该字段只IOS系统有值。 |
disk_total | optional | int64 | 设备总磁盘总空间,单位字节。目前该字段只IOS系统有值。 |
mem_total | optional | int64 | 设备总内存空间,单位字节。目前该字段只IOS系统有值。 |
auth_status | optional | int32 | 设备⼴告标识授权情况。目前该字段只IOS系统有值。-1无法获取 0未弹出弹窗之前 1被限制 2拒绝 3授权 |
# 2.11. Geo Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
country | optional | int32 | 国家信息,使用广协ip库表,最新广协地域编码表及IP类型地址库见文件夹中excel文件 |
metro | optional | int32 | 省份信息,使用广协ip库,最新更新时间:2019年12月份 |
city | optional | int32 | 城市信息,使用广协ip库,最新更新时间:2019年12月份 |
geohash | optional | string | LBS地理位置信息,geohash加密后的数据,例经度116.396262,纬度39.885565,加密后wx4fbsv |
# 3. 竞价返回
# 3.1. BidResponse对象详细字段及含义
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
id | required | string | response id,一般和request id相同,可以关联对应的请求,dsp必填 |
seatbid | repeated | Seatbid Object | Seatbid对象列表,每个Seatbid里可包含若干Bid |
注意事项:DSP需要根据bid request里impression信息返回相应的bid response。如不能返回超出impression时长的素材;不能返回类型不匹配的素材;不能返回离线素材等。
# 3.2 Seatbid Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
Bid | repeated | Bid Object | 和impression对应; |
# 3.3. Bid Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
id | required | string | 竞拍者生成的竞价id,用于记录日志或者行为追踪 |
impid | required | string | 与request中的imp.id对应,且保持一致,表示竞价该impression id的曝光机会 |
price | required | int32 | 出价价格,单位分/CPM |
adm | required | Adm Object | 物料数据,保存曝光、点击、跳转链接等 |
startdelay | optional | int32 | 指定广告的播放时间,贴片广告有效.当一个曝光机会的开始时间是X时,如果希望获得更多曝光机会,不要设置该字段 |
deeplink_url | optional | string | (原生唤醒必填字段)用于指定deeplink url,采用原生唤醒形式时返回 |
universal_link_url | optional | string | 用于指定universal link url,采用universal link唤醒形式时返回。只对IOS端有效 |
apk_ name | optional | string | 走厂商应用商店下载时必填,用于走厂商应用商店下载时指定要下载的应用程序包名。 |
creative_content | optional | string | 创意内容。 |
feed_back_info | optional | string | 广告反馈信息。 |
download_from_store | optional | bool | app是否走厂商应用商店下载。 |
mini_app_name | optional | string | 微信小程序唤醒必填字段)微信小程序原始id |
mini_app_path | optional | string | (微信小程序唤醒必填字段)微信小程序页面路径 |
img_url | optional | string | 素材图片地址 |
video_url | optional | string | 素材视频地址 |
width | optional | string | 素材宽 |
height | optional | string | 素材高 |
# 3.4 Adm Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
native_title | optional | string | 标题 |
native_desc | optional | string | 描述 |
win_notice_url | required | string | dsp侧广告曝光监测链接;建议DSP必填,其中可选添加价格宏,不支持https |
ck_monitior_url | required | string | dsp侧广告点击监测链接,建议DSP必填。 |
pmo | repeated | string | 第三方曝光监测链接列表,最多3个,超出的监测不会收到请求 |
cmo | repeated | string | 第三方点击监测链接列表,最多3个,超出的监测不会收到请求 |
duration | optional | int64 | 视频播放时长 |
click_throughs | required | ClickThroughs Object | 落地页信息 |
icon | optional | string | dsp LOGO要求:25*25像素尺寸的PNG格式文件,背景色透明、图片清晰、识别度高 |
tracking_events | optional | Events Object | 广告跟踪信息 |
version | optional | string | 协议版本号 |
adid | required | string | dsp侧创意ID |
dsp_info | optional | DspInfo Object | dsp名称 |
# 3.5. ClickThroughs Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
click_type | required | string | 广告点击类型 0:默认类型,4:app下载,11:app直接下载不会弹出 14:原生唤醒15:universalLink 67:小程序 |
url | required | string | 送审模式下跳转地址使用送审时填充的click_url字段的值,不使用实时返回的跳转地址 |
A:Android端下载类广告(click type 4、11、15),采取“按钮点击”方式;
B:Android端非下载类广告(click type 0)及IOS所有广告,采用“按钮+全屏点击”方式;
# 3.6. Events Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
event | optional | Enum | TrackingEvent见下方说明 |
percent | optional | double | 播放进度,例如:0.25,0.5,0.75,1分别代表播放25%,50%,75%,100%。 |
tracking_url | optional | string | 事件监控URL |
enum TrackingEvent {
firstQuartile = 0; // "播放25%" 只对贴片有效
midpoint = 1; // "播放50%" 只对贴片有效
thirdQuartile = 2; // "播放75% " 只对贴片有效
complete = 3; // "播放100%结束" 只对贴片有效
downloadStart = 4; // 下载开始
downloaded = 5; // 下载结束
installed = 6; // 安装
}
# 3.7. DspInfo Object
字段名 | 修饰符 | 数据类型 | 参数说明 |
---|---|---|---|
version | optional | string | dsp api version |
name | optional | string | dsp name |
# 4. 数据监测
麦晗方目前对竞价成功的DSP由服务端触发发送win notice url,为了节省空间,dsp可以只对监测参数敏感数据进行base64加密。
参数 | 宏 | 描述 |
---|---|---|
price | ${SETTLEMENT} | 最终成交价格,对象类型,单位分cpc竞价表示分/每次点击cpm竞价表示分/每千次曝光 |
message Settlement {
// Algorithm for price and auth.
optional uint32 version = 1;
// Encrypted price.
required bytes price = 2;
// Authentication information for bidid and price.
optional bytes auth = 3;
}
# 4.1. 成交价加密方法
1:每个DSP有一个唯一的解密密钥, 密钥是长度为32个字符的字符串.
2:加密算法 aes 256位的ecb模式,padding方式为 PKCS5。
3:需要明确加解密是针对price进行的
4:返回url参数中必须携带 ${SETTLEMENT} 宏
5:竞价成功后${SETTLEMENT} 宏 会被(settlement 的结构体 经过proto序列化,再经过base64编码后的字符串替换)
需要注意的是我们使用的base64 编码字典是自己定制的 和常用的不一致,字典表如下 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_- (填充字符是!,不是=)
# 4.2 解密举例
价格明文:"123456.78"
key: "aab087fcbbff83e231562c73fa3ec789"
经过base64编码过得settlement : "EhAdwiU_BJLKOs8QUtAQWrex"
解码出来message中的price是:1dc2253e0492ca3acf1052d0105ab7b1 (hex string 后)
此值再经过解密可得到 价格明文:"123456.78"
注: 上面的key为测试用例,为了统一规范,token可同时用于上传和价格解密,测试和正式价格解密token不一样,联调或投放时请联系产品提供。
解密函数示例(go语言)
func Decrypt(cipher, ekey, ikey []byte, args ...interface{}) (float64, error) {
debase, err := b64Decode(string(cipher), '!')
if err != nil {
return 0, err
}
settlement := &qax.Settlement{}
err = proto.Unmarshal(debase, settlement)
if err != nil {
return 0, err
}
price, err := aesECBModeDecrypt(settlement.Price, ekey)
if err != nil {
return 0, err
}
length := len(price)
pad := int(price[length-1])
oprice := price[:(length - pad)]
return strconv.ParseFloat(string(oprice), 64)
}
func b64Decode(s string, pad rune) ([]byte, error) {
base64str := strings.Map(func(r rune) rune {
switch r {
case '-':
return '/'
case '_':
return '+'
case pad:
return '='
}
return r
}, s)
return base64.StdEncoding.DecodeString(base64str)
}
func aesECBModeDecrypt(cipher, ekey []byte) ([]byte, error) {
if len(cipher)%aes.BlockSize != 0 {
return nil, errInvalidCipherLen
}
//decode block by block
b, err := aes.NewCipher(ekey)
if err != nil {
return nil, err
}
var plain []byte
for len(cipher) > 0 {
text := make([]byte, aes.BlockSize)
b.Decrypt(text, cipher)
cipher = cipher[aes.BlockSize:]
plain = append(plain, text...)
}
return plain, nil
}
解密示例(java) 报错参考: https://blog.csdn.net/dafeige8/article/details/76019911
package utils;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import myhayo.Myhayo;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
public class price {
public static String decryptBytes3(byte[] encrypted, byte[] key) {
try {
// 判断Key是否正确
if (key == null) {
return null;
}
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
try {
byte[] original = cipher.doFinal(encrypted);
return new String(original, "utf-8");
} catch (Exception e) {
e.printStackTrace();
return null;
}
} catch (Exception ex) {
return null;
}
}
public static void main(String[] args) throws InvalidProtocolBufferException, UnsupportedEncodingException {
String priceEncode="EhAdwiU_BJLKOs8QUtAQWrex";
String demoToken = "aab087fcbbff83e231562c73fa3ec789";
byte[] priceDecodeBase64 = MyBase64.decodeBase64(priceEncode.getBytes("UTF-8"));
Myhayo.Settlement settlement = Myhayo.Settlement.parseFrom(priceDecodeBase64);
ByteString encodedPrice = settlement.getPrice();
String price = AESUtil.decryptBytes3(encodedPrice.toByteArray(), demoToken.getBytes());
System.out.println("price:" + price);
}
}
# 5. 样例
贴片位置的请求和返回样例
# 5.1. 请求数据样例
{ "id": "08b89281c1e421fd1c87964c4d97a58b", "user": { "id": "f3aeb7621afc4872" }, "site": { "id": 1, "content": { "url": "www.pps.tv", "channel_id": 1 } }, "device": { "ua": "Cupid/5.45.003;NetType/wifi", "ip": "171.121.60.175", "geo": { "country": 86, "metro": 8614, "city": 861411, "geohash": "7zzzzzz" }, "connection_type": 2, "platform_id": 33, "android_id": "f3aeb7621afc4872", "model": "Dalvik/2.1.0 (Linux; U; Android 11; V2066A Build/RP1A.200720.012)", "os": "android", "os_version": "11", "mac": "e639e9de0757a6eec668c6274cbdbbd8", "oaid": "377aa22dac3b470e0eb3950f898d0765728a091a04f1e54c3aacdd1c4e22f640" }, "imp": [{ "id": "1b", "video": { "ad_zone_id": 30002, "linearity": 1, "ad_type": 1, "minduration": 15, "maxduration": 60, "protocol": 3, "startdelay": 0, "is_entire_roll": true }, "bidfloor": 400, "blocked_ad_attribute": [12, 101], "extended_ads_position": 0, "max_skippable_roll_ads": 3, "skippable_roll_bidfloor": 100 }] }
# 5.2. 返回数据样例
{
"id": "08b89281c1e421fd1c87964c4d97a58b",
"seatbid": [{
"bid": [{
"id": "1b",
"impid": "1b",
"price": 640,
"adm": {
"native_title": "",
"native_desc": "",
"win_notice_url": "http://tyaqy.m.cn.miaozhen.com/x/k=2252923\u0026p=7viJ9\u0026dx=__IPDX__\u0026rt=2\u0026pro=s\u0026ns=__IP__\u0026ni=__IESID__\u0026v=__LOC__\u0026xa=__ADPLATFORM__\u0026tr=__REQUESTID__\u0026vg=__AUTOPLAY__\u0026nh=__AUTOREFRESH__\u0026mo=__OS__\u0026m0=__OPENUDID__\u0026m0a=__DUID__\u0026m1=__ANDROIDID1__\u0026m1a=__ANDROIDID__\u0026m2=__IMEI__\u0026m4=__AAID__\u0026m5=__IDFA__\u0026m6=__MAC1__\u0026m6a=__MAC__\u0026m11=__OAID__\u0026m14=__CAID__\u0026m5a=__IDFV__\u0026mn=__ANAME__\u0026o=",
"ck_monitior_url": "http://cktest.optaim.com/c?info=CmsKLTA4Yjg5MjgxYzFlNDIxZmQxYzg3OTY0YzRkOTdhNThiXzFiXzIzNTg0MjkyNRINMTAwMDAwMDAwMDM4MRjyqwgglYHmASjAsGgwsGdAgApI0AVQAljHCWCAgPqIBmjExYSJBnDEov-IBhIDcWF4GI2j04wGIhgIARCgBhj0AygBMAE4oAZ5AAAAAAAAiUAqQAgDEiAxODk2MzFiNTE1YTZlZWY3YjIwMjVmNzgwYWMyZGVlNhgIIgdhbmRyb2lkKgE5OgZQREJNMDBAAVAFWAIwYzoZZGV2X2Rldk1hY2hpbmUuZG9tYWluLmNvbUABShRodHRwOi8vd3d3LmlxaXlpLmNvbVAAYABpAAAAAAAA8D9wmvswggEBMYoBATCiAQczYjIxMDkzwgEAyAEC0gERCAEVAACAPx0AAAAAJQAAAADaAQDiAQoxMTU2NDIwNTAw6AEE-gEAlQIAAIA_ogIBMbICAOICAA%3D%3D\u0026isPb=1",
"pmo": ["http://tyaqy.m.cn.miaozhen.com/x/k=2252657\u0026p=7vX8P\u0026dx=__IPDX__\u0026rt=2\u0026pro=s\u0026ns=__IP__\u0026ni=__IESID__\u0026v=__LOC__\u0026xa=__ADPLATFORM__\u0026tr=__REQUESTID__\u0026vg=__AUTOPLAY__\u0026nh=__AUTOREFRESH__\u0026mo=__OS__\u0026m0=__OPENUDID__\u0026m0a=__DUID__\u0026m1=__ANDROIDID1__\u0026m1a=__ANDROIDID__\u0026m2=__IMEI__\u0026m4=__AAID__\u0026m5=__IDFA__\u0026m6=__MAC1__\u0026m6a=__MAC__\u0026m11=__OAID__\u0026m14=__CAID__\u0026m5a=__IDFV__\u0026mn=__ANAME__\u0026o=", "http://tyaqy.m.cn.miaozhen.com/x/k=2252923\u0026p=7viJ9\u0026dx=__IPDX__\u0026rt=2\u0026pro=s\u0026ns=__IP__\u0026ni=__IESID__\u0026v=__LOC__\u0026xa=__ADPLATFORM__\u0026tr=__REQUESTID__\u0026vg=__AUTOPLAY__\u0026nh=__AUTOREFRESH__\u0026mo=__OS__\u0026m0=__OPENUDID__\u0026m0a=__DUID__\u0026m1=__ANDROIDID1__\u0026m1a=__ANDROIDID__\u0026m2=__IMEI__\u0026m4=__AAID__\u0026m5=__IDFA__\u0026m6=__MAC1__\u0026m6a=__MAC__\u0026m11=__OAID__\u0026m14=__CAID__\u0026m5a=__IDFV__\u0026mn=__ANAME__\u0026o="],
"duration": 30,
"click_throughs": {
"click_type": "0",
"url": "http://tyaqy.m.cn.miaozhen.com/r/k=2252657\u0026p=7vX8P\u0026dx=__IPDX__\u0026rt=2\u0026pro=s\u0026ns=__IP__\u0026ni=__IESID__\u0026v=__LOC__\u0026xa=__ADPLATFORM__\u0026tr=__REQUESTID__\u0026mo=__OS__\u0026m0=__OPENUDID__\u0026m0a=__DUID__\u0026m1=__ANDROIDID1__\u0026m1a=__ANDROIDID__\u0026m2=__IMEI__\u0026m4=__AAID__\u0026m5=__IDFA__\u0026m6=__MAC1__\u0026m6a=__MAC__\u0026m11=__OAID__\u0026m14=__CAID__\u0026m5a=__IDFV__\u0026mn=__ANAME__\u0026o=https://tyaqy.m.cn.miaozhen.com/r/k=2252923\u0026p=7viJ9\u0026dx=__IPDX__\u0026rt=2\u0026pro=s\u0026ns=__IP__\u0026ni=__IESID__\u0026v=__LOC__\u0026xa=__ADPLATFORM__\u0026tr=__REQUESTID__\u0026mo=__OS__\u0026m0=__OPENUDID__\u0026m0a=__DUID__\u0026m1=__ANDROIDID1__\u0026m1a=__ANDROIDID__\u0026m2=__IMEI__\u0026m4=__AAID__\u0026m5=__IDFA__\u0026m6=__MAC1__\u0026m6a=__MAC__\u0026m11=__OAID__\u0026m14=__CAID__\u0026m5a=__IDFV__\u0026mn=__ANAME__\u0026o=https://www.dyk.com.cn/vehicles/sportage-ace/?utm_source=1570059\u0026utm_content=patch-30"
},
"adid": "136690"
},
"startdelay": 0,
"download_from_store": false
}]
}]
}
# 6. proto内容
syntax = "proto2";
package myhayo;
message FloorPrice {
optional int64 industry = 1;
optional int32 price = 2;
optional int32 skippable_roll_price = 3;
}
message UserFeature {
optional string key = 1;
optional string value = 2;
}
message UserSession {
repeated uint64 delivered_creative_numeralization_value = 2;
}
message Banner {
// 广告位ID
optional int64 ad_zone_id = 4;
// 广告类型
optional int32 ad_type = 12;
repeated int64 creative_template = 13;
extensions 100 to max;
}
message Video {
optional int64 ad_zone_id = 1;
optional int32 linearity = 3;
optional int32 ad_type = 13;
optional int32 minduration = 4;
optional int32 maxduration = 5;
optional int32 protocol = 6;
optional int32 startdelay = 9;
optional bool is_entire_roll = 14 [default = false];
optional int32 video_startdelay = 15;
}
message Impression {
optional string id = 1;
optional Banner banner = 2;
optional Video video = 3;
repeated FloorPrice floor_price = 9;
optional int32 bidfloor = 4 [default = 0];
optional int32 campaign_id = 5;
repeated int32 blocked_ad_tag = 6;
repeated int32 blocked_ad_attribute = 7;
optional bool is_pmp = 8 [default = false];
optional int32 extended_ads_position = 10 [default = 0];
optional int32 impression_date = 11;
optional int32 max_skippable_roll_ads = 12;
optional int32 skippable_roll_bidfloor = 13;
optional int32 info_stream_max_bids_allowed = 15;
optional int32 width = 16;
optional int32 height = 17;
extensions 100 to max;
}
message Site {
optional int32 id = 1;
optional string app_bundle_id = 2;
optional Content content = 11;
}
message Content {
optional string title = 3;
optional string url = 6;
repeated string keyword = 9;
optional int32 len = 16;
optional int64 album_id = 20;
optional int64 channel_id = 22;
repeated string region = 23;
repeated string category = 24;
optional string release_date = 25;
repeated string starring = 26;
repeated string video_quality = 27;
repeated string tag = 28;
repeated int64 video_tag = 29;
optional string video_clip_id = 31;
}
message Device {
optional string ua = 2;
optional string ip = 3;
optional Geo geo = 4;
optional int32 connection_type = 15;
optional int32 platform_id = 18;
repeated int64 feature = 19;
optional string android_id = 20;
optional string model = 21;
optional string os = 22;
optional string os_version = 23;
optional string app_version = 24;
optional string ipv6 = 25;
optional string idfa = 26;
optional string openudid = 27;
optional string imei = 28;
optional string mac = 29;
optional string oaid = 30;
optional int32 screen_height = 32;
optional int32 screen_width = 33;
repeated int64 installed_app = 34;
optional string manufacturer = 35;
optional string carrier_name = 36;
optional string idfv = 37;
optional string local_timezone = 38;
optional int64 os_update_time = 39;
optional int64 startup_time = 40;
optional int32 cpu_num = 41;
optional int64 disk_total = 42;
optional int64 mem_total = 43;
// -1 Not Supported
// 0 Not Determined
// 1 Restricted
// 2 Denied
// 3 Authorized
optional int32 auth_status = 44;
}
message Geo {
optional int32 country = 3;
optional int32 metro = 5;
optional int32 city = 6;
optional double longitude = 7;
optional double latitude = 8;
optional string geohash = 9;
}
message ViewingHistory {
optional string video_title = 1;
repeated string video_tag = 2;
repeated int64 multi_publish_channel_ids = 3;
}
message User {
// The unique identifier of this user on the exchange.
// For IOS, this is IDFA, UDID or MAC address.
// For Android, this is IMEI, AndroidID or MAC address.
optional string id = 1;
//This field will be set true if the privacy of the current user should be protected.
optional bool is_privacy_protected = 2 [default = false];
repeated int32 dmp_id = 4;
// Each UserFeature contains key and value fields.
// For example,
// UserFeature {
// key: "f1",
// value: "10"
// }
repeated UserFeature feature = 5;
optional UserSession session = 6;
// This field indicates viewing histories of the user ordered by date.
repeated ViewingHistory viewing_history = 7;
repeated string interest_tag = 8;
}
message BidRequest {
// Note, the value of this field is not unique.
optional string id = 1;
optional User user = 2;
optional Site site = 3;
optional Device device = 5;
// The list of impression objects. Multiple impression auctions may be
// specified in a single bid request. At least one impression is required
// for a valid bid request.
repeated Impression imp = 8;
optional bool is_test = 9 [default = false];
optional bool is_ping = 10 [default = false];
optional int32 source_id = 11;
optional string m_id = 12;
extensions 100 to max;
}
message Settlement {
optional uint32 version = 1;
required bytes price = 2;
optional bytes auth = 3;
}
message Bid {
required string id = 1;
required string impid = 2;
required int32 price = 3;
required Adm adm = 4;
optional int32 startdelay = 5;
optional string deeplink_url = 6;
optional string apk_name = 7;
optional string creative_content = 8;
optional string universal_link_url = 9;
optional string feed_back_info = 10;
optional bool download_from_store = 11;
// gender and so on, this field should be set to true.
optional bool is_precision_advertising = 12 [default = false];
optional string mini_app_name = 13; // 微信小程序唤醒必填字段)微信小程序原始id,参数值需要进行URL encode
optional string mini_app_path = 14; // (微信小程序唤醒必填字段)微信小程序页面路径,参数值需要进行URL encode
optional string img_url = 15; // sourceid=1时必填 贴片选填
optional string video_url = 16; // sourceid=1时必填 贴片必填
optional string width = 17; // sourceid=1时必填
optional string height = 18; // sourceid=1时必填
extensions 100 to max;
}
message Adm {
// The list of adm objects. describing the advertisement of this bid.
optional string native_title = 1; // 广告标题
optional string native_desc = 2; // 广告描述
required string win_notice_url = 3; // 竞价胜出反馈的url,其中可选添加宏${SETTLEMENT},会替换为结算价格(解密方式见“曝光监测接口与解密方式”,不支持https), 也可以当作曝光监测来计数,但与im_monitior_url不能重复曝光计数。
required string ck_monitior_url = 4; // dsp侧 点击监测
repeated string pmo = 5; // 第三方曝光监测
repeated string cmo = 6; // 第三方点击监测
optional int64 duration = 7; // 视频播放时长 单位:秒
optional ClickThroughs click_throughs = 8; // 落地页
optional string icon = 9; // dsp logo图
repeated Events tracking_events = 10; // 追踪事件
optional string version = 11; // 协议版本号
required string adid = 12; // dsp侧创意ID
optional DspInfo dsp_info= 13; // dsp名称
repeated string win_notice_list = 14; // dsp侧 曝光监测
}
message DspInfo {
optional string version = 1; //
optional string name = 2; // dsp name
}
message Events {
// 落地页类型
enum TrackingEvent {
firstQuartile = 0; // "播放25%" 只对贴片有效
midpoint = 1; // "播放50%" 只对贴片有效
thirdQuartile = 2; // "播放75% " 只对贴片有效
complete = 3; // "播放100%结束" 只对贴片有效
downloadStart = 4; // 下载开始
downloaded = 5; // 下载结束
installed = 6; // 安装
}
optional TrackingEvent event = 1;
optional double percent = 2;
optional string tracking_url = 3;
}
message ClickThroughs {
// 落地页类型
optional string click_type = 1; // 67:小程序 88:广点通下载
optional string url = 2; // 落地页
}
message Seatbid {
// The list of bid objects. Each bid object should be related to an impression
// object in the bid request.
repeated Bid bid = 1;
}
message BidResponse {
// This id should be the same as the id of the corresponding BidRequest.
required string id = 1;
// The list of seatbid objects.
repeated Seatbid seatbid = 2;
extensions 100 to max;
}
# 附录一:【user id】命名规则
平台 | 取值规则 |
---|---|
PC网页端/PC客户端/IphoneH5/IpadH5/ Android手机H5 | cookie |
Iphone/Ipad客户端 | idfa/openudid/ mac_address |
Android手机端/Android平板客户端/ 智能音箱 | Imei/android id/ mac_address |
电视(android端) | mac_address |
UWP Phone/ UWP Pad/ UWP Xbox | Advertising Id/Guid/ASHWID |
# 附录二: 【设备ID】取值顺序
平台 | 取值规则 | 名词解释 | 备注 |
---|---|---|---|
iOS | 优先使用 IDFA 如果 IDFA 不可用,使用IDFV,如果IDFV不可用,使用openUDID 如果 openUDID 不可用,使用 MAC 地址 | IDFA: 广告标识符 ,128位(16个字节), 示例: 1E2DFA89-496A-47FD-9941-DF1FC4E6484A OpenUDID: 由40个字母和数字的组合组成,示例: 0d943976b24c85900c764dd9f75ce054dc5986ff Mac Address: MAC地址共48位( 6个字节),ios7 以后禁用, ios7及以后的版本调用接口返回的都是02:00:00:00:00:00 | IDFA 使用原始值 openUDID使用原始值 MAC 地址格式:去分隔符,转大写,然后 MD5 |
Android | 优先使用 IMEI 如果 IMEI 不可用,使用AndroidID 如果 AndroidID 不可用,使用 MAC 地址 | IMEI: 15位纯数字,示例: 357071052902590, 注意:获取此值时需要动态检查一下权限, 部分手机返回的不是15位数字,例如某些小米手机上返回的是14位数字, GSM和WCDMA制式手机会使用此id MEID: 14个十六进制字符标识表示,例如:A000005EE4634D, CDMA制式手机会使用此id ESN: 不同设备不一样,示例:47QDU16C11000573, CDMA制式手机可能会使用此id,部分pad上没有IMEI和MEID时会使用此id Android Id: ANDROID_ID是Android系统第一次启动时产生的一个64bit数,示例: 63cfb1479595ab56, 注意:获取此值时需要动态检查一下权限 Mac Address: MAC地址共48位(6个字节),十六进制,示例: 34:23:BA:96:D3:E9, 注意:Android 6.0 以后返回的都 是02:00:00:00:00:00 | 其中,标准的15位和非标准的14位IMEI(不包含MEID、ESN)都会切换成MD5 后的值,小写。如果是其他位数的IMEI则会传原始值;MEID传原始值 IMEI 值有三种形式:IMEI、MEID、ESN,其中 GSM 和WCDMA制式手机会返回IMEI,CDMA 制式手机会返回 MEID或ESN,具体取值格式见左侧“名词解释” AndroidID使用原始值 MAC 地址格式:去分隔符,转大写,然后 MD5 |
UWP | 优先使用 Advertising Id 如果 Advertising Id不可用,使用Guid 如果 Guid 不可用,使用 ASHWID 地址 | Advertising Id: 广告标识符,每设备唯一用户可以关闭、重置此ID,由字母和数字组成,示例:898af4c74d13338a8bdca5b9c9c5968a;用户关闭时,返回空字符串 Guid: 本地设备的标识符(16个字节),每一设备每一应用唯一,示例:1042e226-be06-828e-bbf5-240823d40d49; ASHWID: 硬件Id,每一设备每一应用唯一,此ID字符长度不固定,示例:05-00-DB-48-06-00-01-00-04-00-69-25-01-00-24-12-02-00-7E-7B-09-00-FE-92 |
# 附录三:第三方监测说明补充信息
移动客户端回传设备 id 取值规则: 同附录一1.2
默认使用API上报
移动客户端操作系统标志值
0表示Android
1表示iOS
2表示Windows
3表示其他
MMA API 监测宏替换定义:
__OS__
:操作系统,替换值见附录3__IMEI__
:MD5 加密__MAC__
:去分隔符“:”,转大写,然后 MD5 加密__MAC1__
:保留分隔符“:”,转大写,然后 MD5 加密__IDFA__
:取原值__OPENUDID__
:取原值__ANDROIDID__
:MD5 加密__IP__
:取原值__TS__
:UTC 时间戳,自1970年起的毫秒数_OAID_
: Android Q及更高版本的设备号,取原值
# 附录四:TrackingEvents(监测事件)节点使用规则:
支持 firstQuartile(四分之一)、midpoint(二分之一)、thirdQuartile(四分之三)、complete(完成)、close(关闭或跳过广告) 这5个监测事件,只对贴片广告有效
每个事件支持多个 Tracking 节点,比如:若需要对 firstQuartile 事件添加多条监测 URL,可以通过添加多个 event="firstQuartile" 的 Tracking 节点实现,条数没有上限,请按照需要添加相应的监测事件节点,比如:若只需要监测 firstQuartile事件,则只添加 event=" firstQuartile " 的 Tracking 节点即可
相应事件的监测 URL 请填写到 tracking_url 里
在Android平台下,和11(APP直接下载)的下载方式时,支持下载时间点的监测。
具体添加方式:监测下载开始事件,需要添加event="downloaded",监测下载完成
Android端支持监控广告点击下载后的APP安装情况,交互场景为通过广告下载app后进行了app安装,安装完成回传该字段
具体添加方式:监测下载安装时需添加 event="installed"
若没有任何事件监测需求,可以没有 TrackingEvents 节点
miaozhen.com、admaster.com.cn、cr-nielsen.com、mma.ctrmi.com 的点击监测都默认由MMA SDK发送
# 附录五:广告位ID列表
请联系运营。
# 附录六: 行业
请联系运营。
# 附录七: 模版ID
请联系运营
# 附录八: Platform_id 说明
平台id(Platform_id) | 说明 |
---|---|
11 | PC网页端 |
12 | PC客户端 |
13 | Mac客户端(不支持RTB) |
21 | IPad H5(贴片可点击) |
22 | iPad客户端 |
23 | Android平板客户端 |
25 | win平板客户端(不支持RTB) |
32 | iPhone客户端 |
33 | Android手机端 |
35 | win手机客户端(不支持RTB) |
311 | Android手机H5 |
312 | iPhoneH5(贴片不可点击) |
5201 | 电视(android端) |
61 | UWP Phone(不支持RTB) |
62 | UWP Pad(不支持RTB) |
63 | UWP Xbox(不支持RTB) |
27 | Android平板H5 |
28 | 智能音箱 (不支持RTB) |
# 附录十: 频道ID
请联系运营。
# 附录十一: 广告类型 id
广告类型 id(ad_type_id) | 值 |
---|---|
页面 | 0 |
前贴 | 1 |
中贴 | 2 |
后贴 | 3 |
暂停 | 6 |
通用浮层 | 10 |
# 附录十二: 网络接入字段
网络接入字段(connection_id) | 说明 |
---|---|
0 | Unknown |
1 | Ethernet |
2 | Wifi |
3 | Cellular date-2G |
4 | Cellular date-3G |
5 | Cellular date-4G |
6 | Cellular date-5G |
版本信息 →