处理请求

当 Google 向您的应用发送出价请求时,实时出价互动便会开始。本指南介绍了如何编写应用代码以处理出价请求。

解析 Protobuf 请求

Google 会将出价请求作为序列化协议缓冲区发送,并将其附加为 HTTP POST 请求的二进制载荷。Content-Type 已设置为 application/octet-stream。如需查看示例,请参阅出价请求示例

您必须将此请求解析为 BidRequest 消息的实例。BidRequestopenrtb.proto 或已废弃的 realtime-bidding.proto 中定义,具体取决于您选择的协议。您可以从参考数据页面获取 realtime-bidding.proto。您可以使用为 BidRequest 生成的类中的 ParseFromString() 方法解析消息。例如,以下 C++ 代码会解析字符串中的 POST 载荷所对应的请求:

string post_payload = /* the payload from the POST request */;
BidRequest bid_request;
if (bid_request.ParseFromString(post_payload)) {
  // Process the request.
}

获取 BidRequest 后,您可以将其作为对象进行处理,提取和解读所需的字段。例如,在 C++ 中,对 OpenRTB `BidRequest` 中的交易进行迭代可能如下所示:

for (const BidRequest::Imp::Pmp::Deal& deal : pmp.deals()) {
  DoSomething(deal.id(), deal.wseat());
}

结算 ID

当您的一个或多个 预定位配置定位到发布商的广告资源时,您就会收到出价请求。BidRequest.imp.ext.billing_id 将填充所有符合条件的买方的结算 ID 和相关的预定位配置。此外,对于交易广告资源,您可以使用 BidRequest.imp.pmp.deal.ext.billing_id 查找与相关买方关联的结算 ID。在出价时,只能指定出价请求中包含的买方的结算 ID。

如果出价请求中包含多个结算 ID,您必须使用 BidResponse.seatbid.bid.ext.billing_id 字段指定您打算将出价归因到的买方的结算 ID。

字典文件

出价请求使用字典文件中定义的标识符,这些标识符可在参考数据页面上找到。

Google RTB 协议出价网址宏

您可以选择将 BidRequest 的某些字段插入到 HTTP POST 请求中使用的网址中。例如,如果您使用轻量级前端,并使用请求中的值在多个后端之间进行负载均衡,这就会非常有用。请与您的技术支持客户经理联系,请求获得有关新宏的支持。

说明
%%GOOGLE_USER_ID%%

已替换为 BidRequest 中的 google_user_id。例如,出价方网址

http://google.bidder.com/path?gid=%%GOOGLE_USER_ID%%
将替换为类似于以下内容
http://google.bidder.com/path?gid=dGhpyBhbiBleGFtGxl
(在请求时)。

如果 Google 用户 ID 未知,系统会使用空字符串进行替换,结果类似于

http://google.bidder.com/path?gid=
%%HAS_MOBILE%%

在调用 BidRequesthas_mobile() 时,会替换为 10

%%HAS_VIDEO%%

调用 BidRequesthas_video() 时,此值会替换为 1(true)或 0(false)。

%%HOSTED_MATCH_DATA%%

已替换为 BidRequest 中的 hosted_match_data 字段的值。

%%MOBILE_IS_APP%%

替换为 BidRequestmobile.is_app 字段中的 1(true)或 0(false)。

从交易网址查找移动应用 ID

移动应用交易会报告如下网址:

mbappgewtimrzgyytanjyg4888888.com

使用以 32 为底数的解码器解码粗体显示的字符串部分 (gewtimrzgyytanjyg4888888)。

您可以使用在线解码器,但必须将字母转换为大写,并将尾随 8 替换为 = 值。

因此,解码此值:

GEWTIMRZGYYTANJYG4======
会产生以下结果:
1-429610587
字符串 429610587 是 iOS 应用 iFunny 的应用 ID。

再看下面一个示例。举报的网址是:

mbappgewtgmjug4ytmmrtgm888888.com
解码此值:
GEWTGMJUG4YTMMRTGM======
会产生以下结果:
1-314716233
结果 314716233 是 iOS 应用 TextNow 的应用 ID。

从交易网址查找移动应用名称

下面是获取应用名称的示例。报告的网址如下所示:

mbappMFUXELTDN5WS42DZOBQWQLTJN4XHG3DJORUGK4Q888.com
解码此值:
MFUXELTDN5WS42DZOBQWQLTJN4XHG3DJORUGK4Q===
会产生以下结果:
air.com.hypah.io.slither
结果等同于 Android 应用 slither.io

公开出价字段

发送给参与公开出价的广告交易平台和广告联盟出价方的出价请求与参与标准实时出价的 Authorized Buyers 买方的出价请求类似。公开出价功能的客户将会收到少量额外的字段,并且部分现有字段可能有其他用途。其中包括:

OpenRTB Authorized Buyers 详细信息
BidRequest.imp[].ext.dfp_ad_unit_code BidRequest.adslot[].dfp_ad_unit_code

包含发布商的 Ad Manager 广告资源网代码,后跟广告单元层次结构,以正斜线分隔。

例如,其格式类似于 /1234/cruises/mars

BidRequest.user.data[].segment[] BidRequest.adslot[].exchange_bidding.key_value[]

从发布商发送到广告交易平台出价方的重复键值对。

BidRequest.user.data[].name 设置为 “Publisher Passed” 时,您可以确定这些值是发布商发送的键值对。

声明允许的供应商

提供调研、再营销和广告投放等服务的技术供应商可能会在买卖双方互动中发挥作用。只有 Google 已审核并批准参与 Authorized Buyers 互动的供应商才可以使用此 API。

如需了解 BidRequest 并创建 BidResponse,您需要了解声明技术供应商的两种不同方式:

  1. 某些供应商无需声明;这些供应商已列在经过 Ad Manager 认证的外部供应商中。
  2. 其他供应商只有在 BidRequest 中声明后才能参与:
    • BidRequest 中,BidRequest.imp.ext.allowed_vendor_type 字段指定卖方允许的供应商。将在 allowed_vendor_type 中发送的供应商列在 vendors.txt 字典文件中。

出价请求示例

以下示例展示了 Protobuf 和 JSON 请求的可读取示例。

OpenRTB Protobuf

OpenRTB JSON

Google(已弃用)

如需将出价请求转换为二进制形式(就像从真实请求中的 POST 载荷中获取的一样),您可以执行以下操作(使用 C++)。不过,请注意,这不适用于 OpenRTB JSON。

string text_format_example = /* example from above */;
BidRequest bid_request;
if (TextFormat::ParseFromString(text_format_example, &bid_request)) {
  string post_payload;
  if (bid_request.SerializeToString(&post_payload)) {
    // post_payload is a binary serialization of the protocol buffer
  }
}

实时反馈

实时反馈适用于 Authorized Buyers 买方,以及使用公开出价的广告交易平台和广告联盟。

无论是 OpenRTB 还是已废弃的 Google RTB 协议,后续出价请求都支持出价响应反馈。对于 OpenRTB,此值会在 BidRequest.ext.bid_feedback 中发送。

除了在出价响应反馈中发送的默认字段之外,您还可以使用 BidResponse.seatbid.bid.ext.event_notification_token 字段在出价响应中发送自定义数据。event_notification_token 是仅供出价方知晓的任意数据,可能有助于调试,例如:代表新策略的新定位 ID 或出价 ID,或与广告素材相关联且仅供出价方知晓的元数据。如需了解详情,请参阅适用于 OpenRTB 的 OpenRTB 扩展协议缓冲区或已废弃的 Google RTB 协议

当 Authorized Buyers 向出价方发送出价请求时,出价方会回复 BidResponse。如果出价方启用了实时反馈,那么在后续出价请求中,Authorized Buyers 会在 BidFeedback 消息中发送有关响应的反馈:

message BidFeedback {
  // The unique id from BidRequest.id.
  optional string request_id = 1;

  // The status code for the ad. See creative-status-codes.txt in the
  // technical documentation for a list of ids.
  optional int32 creative_status_code = 2;

  // Deprecated. This field is not populated and will be removed after March,
  // 2025. If the bid won the auction, this is the price paid in your account
  // currency. If the bid participated in the auction but was out-bid, this
  // is the CPM that should have been exceeded in order to win. This is not
  // set if the bid was filtered prior to the auction, if the publisher or
  // winning bidder has opted out of price feedback or if your account has
  // opted out of sharing winning prices with other bidders. For first-price
  // auctions, minimum_bid_to_win is populated instead of this field.
  optional double price = 3 [deprecated = true];

  // The minimum bid value necessary to have won the auction, in your account
  // currency. If your bid won the auction, this is the second highest bid
  // that was not filtered (including the floor price). If your bid didn't win
  // the auction, this is the winning candidate's bid. This field will only be
  // populated if your bid participated in a first-price auction, and will not
  // be populated if your bid was filtered prior to the auction.
  optional double minimum_bid_to_win = 6;

  // The minimum bid value necessary to have won the server-side component of
  // the overall auction given that there was also an interest group bidding
  // component to the overall auction which ran using the Protected Audience
  // API. The value is expressed in CPM of the buyer account currency. The
  // minimum bid to win for the overall auction, including bids from the
  // server-side and the on-device interest group components, is populated in
  // the minimum_bid_to_win field of the same BidFeedback object.
  optional double sscminbidtowin = 14;

  // Billable event rate multiplier that was applied to this bid during
  // ranking. The adjustment reflects the likelihood that your bid would
  // generate a billable event (namely, the ad renders successfully) if it won
  // the auction, relative to the probability that other bids generate a
  // billable event if they won the auction. This adjustment can be larger or
  // smaller than 1. This affects the final ranking in the auction only; in
  // particular, this multiplier does not affect the payment or whether the
  // bid clears any floor price.
  optional float billable_event_rate_bid_adjustment = 13 [default = 1];

  // When a publisher uses an RTB auction and waterfall-based SDK mediation on
  // the same query, the winner of the real-time auction must also compete in
  // a mediation waterfall (which is ordered by price) to win the impression.
  // If the bid participated in the auction and there was no waterfall, the
  // value of this field is 0. If the bid participated in the auction and
  // there was a waterfall, the value of this field is a price representing a
  // sample bid from the eligible mediation networks that were higher than the
  // auction winner, weighted by expected fill rate. This field can be used
  // in conjunction with minimum_bid_to_win to train bidding models. The CPM
  // is in your account currency.
  optional double sampled_mediation_cpm_ahead_of_auction_winner = 8;

  message EventNotificationToken {
    // The contents of the token.
    optional string payload = 1;
  }

  // The token included in the corresponding bid.
  optional EventNotificationToken event_notification_token = 4;

  // The creative ID included in the corresponding bid.
  optional string buyer_creative_id = 5;

  // Possible types of bid response feedback objects.
  enum FeedbackType {
    FEEDBACK_TYPE_UNSPECIFIED = 0;

    // Feedback for a bid that was submitted on a bid response.
    BID_FEEDBACK = 1;

    // Feedback for an interest group buyer submitted on a bid response to
    // particpate in an interest group bidding component of the auction run
    // using the Protected Audience API.
    INTEREST_GROUP_BUYER_FEEDBACK = 2;
  }

  // The type of the BidFeedback message. Google will send separate
  // BidFeedback objects for:
  // a) Each bid submitted on a bid response
  // b) Each buyer submitted on a bid response to particpate in an interest
  // group bidding component of the auction run using the Protected Audience
  // API.
  optional FeedbackType feedbacktype = 15;

  // Origin of an interest group buyer that was included in the bid response.
  // This field is populated only for feedback where a bidder opted in an
  // interest group buyer to participate in the interest group bidding
  // component of the overall auction run using the Protected Audience API.
  // To learn more about origins, see https://www.rfc-editor.org/rfc/rfc6454.
  // To learn more about interest group bidding and the Protected Audience
  // API, see
  // https://developers.google.com/authorized-buyers/rtb/fledge-origin-trial.
  optional string buyerorigin = 16;

  // The status code for the submitted interest group buyer. This field is
  // only populated in the feedback for an interest group buyer that a bidder
  // requested to enter into the interest group auction through the bid
  // response. Individual creative status codes of bids submitted by the buyer
  // in the on-device interest group auction are not available. See
  // https://storage.googleapis.com/adx-rtb-dictionaries/interest-group-buyer-status-codes.txt
  // for a list of interest group buyer status codes.
  optional int32 igbuyerstatus = 17;
}

在此消息中,您应首先检查 bid_feedback.creative_status_code 字段;您可以在 creative-status-codes.txt 中找到代码含义。请注意,如果您在竞价中胜出,则可以选择不接收价格反馈。如需了解详情,请参阅如何停用

实时反馈包含出价请求 ID 和以下任一项:

竞价结果 实时反馈
买方未提交出价。 什么都不会发生。
买方提交的出价在进入竞价之前被滤除。 广告素材状态代码 (creative-status-codes.txt)。
买方提交了出价,但在竞价中落败。 广告素材状态代码 79(竞价中出价过高)。
买方提交的出价赢得了竞价。 结算价格和广告素材状态代码 1

对于应用展示和广告素材状态代码为 83 的情况,应用发布商可能使用的是中介广告瀑布流,因此胜出的出价将与发布商回传广告瀑布流链中的其他需求竞争。了解如何在出价时使用 sampled_mediation_cpm_ahead_of_auction_winner

示例

以下是支持的协议中显示的实时反馈示例:

OpenRTB Protobuf

OpenRTB JSON

Google(已弃用)

为最高出价竞价构建出价模型

在最高出价竞价中出价后,如果出价未从竞价中滤除,您将收到实时反馈,其中包括 minimum_bid_to_winsampled_mediation_cpm_ahead_of_auction_winner 字段。这些信号可用于为出价逻辑提供参考,让您了解出价可以提高或降低多少才能赢得展示机会。

  • minimum_bid_to_win:能赢得实时出价竞价的最低出价。如果您赢得了竞价,则此值将是您可以出价的最低值,同时仍能赢得竞价。如果您在竞价中落败,则此出价将是胜出出价。
  • sampled_mediation_cpm_ahead_of_auction_winner:如果中介链中还有其他广告联盟,则此字段的值表示某个符合条件的中介广告联盟的样本出价,该出价高于竞价胜出方,并按预期填充率加权。如果中介链中的所有广告联盟都预计不会填充广告,或者发布商不使用 SDK 中介,则此值将设为 0。

运作方式

为了描述用于确定 minimum_bid_to_winsampled_mediation_cpm_ahead_of_auction_winner 可能值的计算,我们首先需要定义以下内容:

  • 以下是中介链中的 CPM,按降序排列:
    \[C_1, C_2, …, C_n\]
  • 以下是中介链中 CPM 的相应填充率:
    \[f_1, f_2, …, f_n\]
  • 以下函数用于根据给定的填充率,从中介链元素 \(i\)确定预期每千次展示费用及其概率:
    \(X_i = \{C_i\) 概率 \(f_i\); \(0\) 概率 \(1 - f_i\}\)
  • 最终胜出的中介链将如下所示:
    \[\{C_1, C_2, …, C_K, W\}\]
    其中, \(W\) 是胜出出价, \(C_K > W >= C_{K+1}\)
  • 预设价格(即底价)表示为 \(F\)。
  • 次优出价记为 \(R\)。
竞价胜出者的计算
字段 计算
minimum_bid_to_win
\(max\{F, R, X_{K+1}, …, X_n\}\)
sampled_mediation_cpm_ahead_
of_auction_winner
\(\{C_i\) 概率 \(\prod_{j=1}^{i-1}(1-f_j) \cdot f_i \div \prod_{j=1}^{K}(1-f_j)\}\)
\(1 <= i <= K\)。

计算竞价落败方
字段 计算
minimum_bid_to_win
\(max\{F, W\}\)
sampled_mediation_cpm_ahead_
of_auction_winner
\(max\{X_1, …, X_K\}\)

使用简单中介链的示例

假设发布商同时使用实时出价和 SDK 中介链,如下所示:

SDK 中介链 预计 CPM 填充率
网络 1 \(C_1 = $3.00\) \(f_1 = 5\%\)
广告联盟 2 \(C_2 = $2.00\) \(f_2 = 45\%\)
影音平台 3 \(C_3 = $0.50\) \(f_3 = 80\%\)
影音平台 4 \(C_4 = $0.10\) \(f_4 = 85\%\)

假设实时出价竞价的结果如下:

RTB 竞价 每千次展示费用
竞价胜出者 (W) $1.00
竞价亚军 (R) $0.05
预订价格 / 底价 (F) $0
在竞价中胜出的出价

以下示例展示了如何针对胜出的出价计算 minimum_bid_to_winsampled_mediation_cpm_ahead_of_auction_winner 的值和概率。

minimum_bid_to_win Probability
\(max(F, R, C_3) = $0.50\) \(f_3 = 80\%\)
\(max(F, R, C_4) = $0.10\) \((1-f_3) \cdot f_4 = 17\%\)
\(max(F, R, 0) = $0.05\) \((1-f_3) \cdot (1-f_4) = 3\%\)
sampled_mediation_cpm_
ahead_of_auction_winner
Probability
\(C_1 = $3.00\) \(f_1 \div (1-(1-f_1) \cdot (1-f_2)) =~ 10.5\%\)
\(C_2 = $2.00\) \(((1-f_1) \cdot f_2) \div (1-(1-f_1) \cdot (1-f_2)) =~ 89.5\%\)
竞价失败的出价

以下示例展示了如何针对未胜出的出价计算 minimum_bid_to_winsampled_mediation_cpm_ahead_of_auction_winner 的值和概率。

minimum_bid_to_win Probability
\(max(F, W) = $1.00\) \(100\%\)
sampled_mediation_cpm_
ahead_of_auction_winner
Probability
\(C_1 = $3.00\) \(f_1 = 5\%\)
\(C_2 = $2.00\) \((1-f_1) \cdot f_2 =~ 42.8\%\)
\(0\) \((1-f_1) \cdot (1-f_2) =~ 52.2\%\)

出价拆分

出价扁平化是指将单个复杂的 BidRequest 处理成发送到应用的多个出价请求。展开出价请求后,您可以确定哪些出价请求属于原始出价请求,因为它们的 BidRequest.ext.google_query_id 字段值相同。

出价扁平化功能默认处于启用状态,但如果您想停用该功能,可以与您的客户经理联系。

广告格式

某些广告展示位置可以接受多种格式。启用出价展平后,系统会通过单独的出价请求发送每种格式,其中符合条件的结算 ID 等属性与请求中指定的格式相关。

包含以下格式的出价请求将拆分为不同的出价请求:

  • 横幅
  • 视频
  • 音频
  • 原生

广告格式扁平化示例

以下示例展示了未扁平化广告格式的简化版 OpenRTB JSON 出价请求,以及与等效的扁平化请求的对比:

预先扁平化

扁平化后

特惠

除了公开竞价之外,给定出价方的广告机会还可适用于各种交易类型。启用按交易拆分出价功能后,系统会为公开竞价发送一个出价请求,并为每种类型的固定价格交易发送一个出价请求。在实践中,竞价和固定价格交易类型的广告限制可能不同。例如,对于同时可用于公开竞价和固定价格交易的给定视频广告展示机会,出价方会分别收到针对这两种交易类型的不同出价请求,其中广告时长上限和是否允许投放可跳过广告等限制可能会有所不同。因此,对广告机会应用扁平化后,您可以更轻松地辨别公开竞价和固定价格交易的广告约束条件。

可跳过视频广告的时长上限

Google 的协议和 OpenRTB 实现支持以下视频时长和可跳过性字段:

时长 可跳过的时长 可跳过性
Google 协议 max_ad_duration skippable_max_ad_duration video_ad_skippable
OpenRTB maxduration 不适用 skip

这意味着,虽然 Google 协议可以具有精细的可跳过时长和不可跳过时长,但 OpenRTB 实现只有单个时长上限值。

在出价扁平化之前,OpenRTB 的 maxduration 会设为 Google 协议的 max_ad_durationskippable_max_ad_duration 字段中的较小者。此行为现已更改为,当这两个值不同时时,发送两个单独的出价请求:一个代表可跳过式广告展示机会的 maxduration,另一个代表不可跳过式广告展示机会的 maxduration

以下示例展示了在出价扁平化之前和之后,Google 协议请求如何转换为 OpenRTB。等效的 Google 协议请求的 max_ad_duration15skippable_max_ad_duration60

示例 max_ad_duration skip(true 或 false)
未展平的原始请求 15 true
扁平化请求 1:不可跳过 15 false
扁平化请求 2:可跳过 60 true

只有在满足以下条件时,系统才会对可跳过的视频广告时长出价请求进行扁平化处理:

  • 请求允许使用视频。
  • 允许投放可跳过和不可跳过的视频广告,并且这两个上限时长值不同。
  • 此请求符合私下竞价或公开竞价的条件。
  • 出价方账号具有有效的 OpenRTB 端点。

您可以与您的技术支持客户经理联系,选择停用此类展平功能。

视频广告连播

包含多个广告机会的视频连播的出价请求会被展平,这样每个出价请求都针对该连播中的单个广告机会。这样,您就可以针对给定连播的多个广告展示机会进行出价。

Open Measurement

借助 Open Measurement,您可以指定为投放到移动应用环境的广告提供独立衡量和验证服务的第三方供应商。

您可以通过检查广告机会是否排除了可供发布商排除的广告素材属性中所列的 OmsdkType: OMSDK 1.0 属性,来确定发布商是否支持出价请求中的 Open Measurement。您可以在横幅广告视频广告battr 属性下找到此值,具体取决于广告格式。

如需详细了解如何解读包含公开衡量信号的出价请求,请参阅 Open Measurement SDK 帮助中心文章。

出价请求示例

以下部分显示了不同广告类型的出价请求示例。

应用横幅广告

OpenRTB Protobuf

OpenRTB JSON

Google(已弃用)

应用插页式广告

OpenRTB Protobuf

OpenRTB JSON

Google(已弃用)

应用插页式视频广告

OpenRTB Protobuf

OpenRTB JSON

Google(已弃用)

原生应用

OpenRTB Protobuf

OpenRTB JSON

Google(已弃用)

网络视频

OpenRTB Protobuf

OpenRTB JSON

Google(已弃用)

适用于广告交易平台出价方的移动网站横幅广告

OpenRTB Protobuf

OpenRTB JSON

多格式原生广告和视频广告

OpenRTB Protobuf

OpenRTB JSON

Google(已弃用)