Mobile app bidding is currently only available to select publishers.
In-house mediation is not publicly available
In-house bidding with Audience Network is currently in Closed Beta and is not publicly available. We'll provide further updates if this changes.
As an alternative, you can access Audience Network Bidding through one of the mediation platforms we partner with.
Facebook Audience Network supports bidding in mobile apps as well as mobile websites. Mobile app bidding integrations can be from the mobile client to our server or from your server to our server. This overview will cover the general concepts of app bidding.
App Bidding is a way for publishers to establish an impartial and open auction over their ad inventory by offering every ad opportunity to multiple demand sources in real time. Every demand source has the opportunity to compete and win every impression, when the value is the highest.
App bidding is offered through an endpoint that implements the Open Real-Time Bidding (ORTB) protocol to provide bids on individual impression opportunities. The Audience Network SDK is required in app bidding to perform the following actions:
buyeruid
(named bidderToken
in the Audience Network SDK). This token is a required field in the bid request, and is unique both per user and per app; the token is not valid for another user or app.adm
field from the bid response to the Audience Network SDK on the user's device. Note that the adm
field does not contain the actual ad; it contains information that allows the SDK to retrieve the ad from the Audience Network server.When running auction (the 3rd step in above bidding flow), it can be hosted on Client-Side or Server-Side. Below are 3 different integration types:
Server-to-Server Integration Architecture
In server-to-server integration, an auction server calls Facebook Audience Network bidding endpoint and all other demand sources to get bid responses. Then the auction server runs the auction and picks the winning bid. This auction server could be an in-house server running auction logic that you built or it could be a 3rd party server that is integrated with Audience Network's app bidding. This allows you to utilize the server's resources and available network to call the demand sources' bidding endpoints. It also allows you to make changes to these endpoint integrations without necessarily requiring client updates.
External Ad Server Integration
The external ad server integration allows you to bridge today's world of waterfall mediation with app bidding. This works by doing a server-to-server integration with the demand sources that support app bidding and then passing the auction winner to the waterfall mediation platform which runs the waterfall and chooses the overall winning demand source. This integration is meant as an interim bridge between the worlds of waterfall mediation and app bidding. With this integration type you do not need to write your own auction logic.
Our bidding endpoint supports a subset of OpenRTB protocol v2.5.
Note: Please see full sample request on Auction Server Setup Guide
'id' => string, // platform's auction identifier, 'imp' => vec< // slots to bid on shape( 'id' => string, // platform's identifier for this slot auction // only for banner impression opportunities 'banner' => shape( 'w' => int, // width 'h' => int, // height ), // only for native impression opportunities 'native' => shape( 'w' => int, // width 'h' => int, // height ), // only for video impression opportunities 'video' => shape( 'w' => int, // width 'h' => int, // height 'linearity' => int, // 1 = instream, optional 'ext' => shape( 'videotype' => string, // 'rewarded' for Rewarded Video impression opportunities, optional ), ), 'tagid' => string, // Placement ID 'instl' => int, // interstitial flag, 1 = On, 0 = Off, optional ) >, // app details (in-app bidding only) 'app' => shape( 'publisher' => shape( 'id' => string, // publisher app ID ), ), 'device' => shape( 'ua' => string, // device user-agent 'ifa' => string, // ID sanctioned for advertiser use // Do not send ip or ipv6 if you are requesting bids from the client device. // For server-side bid requests set ip or ipv6. 'ip' => string, // device IPv4 'ipv6' => string, // device IPv6 'dnt' => int, // "do not track", 1 = On, 0 = Off, optional 'lmt' => int, // "limit ad tracking", 1 = On, 0 = Off ), 'regs' => shape( // regulations object 'coppa' => int, // US FTC regulations for Children's Online Privacy Protection Act, 1 = On, 0 = Off, optional ), 'user' => shape( 'buyeruid' => string, // Audience Network Identity Token, mandatory ), 'ext' => shape( 'platformid' => string, // Mediation partner Platform ID or publisher FB app ID, mandatory 'authentication_id' => string // Authentication token to validate the originator of the request ), 'at' => int, // auction type: 1 = First Price, 2 = Second Price 'tmax' => int, // auction timeout in milliseconds 'test' => int, // 0 = normal, 1 = test-mode (we bid $99.99, but don't pay out), optional
We currently support four types of ads that can be requested through OpenRTB: banner, native (native or native banner) and video (rewarded or instream video), and interstitial. Note: the banner, native and video objects are mutually exclusive, but one of them is required.
Here is a list of supported ad formats in bid request:
Ad Format | Parameters in Bid Request |
---|---|
Native |
|
Native Banner |
|
Interstitial |
|
Rewarded Video |
|
Rewarded Interstitial |
|
Banner - Height: 50 |
|
Banner - Height: 250* |
|
*You can create a Banner or a Medium Rectangle placement in the Monetization Manager for this Ad Format
A bid response is valid for 30 minutes. You can request the ad at any time within 30 minutes from receiving the bid response. Any impressions based on a bid more than 30 minutes won't be paid.
Note: once you request an ad with bid response, the ad can be cached on the client but must be shown within 60 minutes of when they are loaded. Any impressions based on an ad that is cached more than 60 minutes won't be paid..
1 'id' => string // platform's request identifier 'seatbid' => vec< shape( 'bid' => vec< shape( 'id' => string, // Our identifier for this bid 'impid' => string, // platform's identifier for this slot auction 'price' => float, // Our bid price on CPM basis, in USD 'adm' => string, // Our creative - see Rendering The Ad 'nurl' => string, // URL to get if we win the impression 'lurl' => string, // URL to get if we lose the impression ) >, ), >, 'bidid' => string, // Our identifier for this response 'cur' => string, // bid currency: USD
We require win, loss, timeout and display notifications with the appropriate loss codes as defined in ORTB. ORTB nurl and lurl are provided in the bid response. Please check previous section for bid response example. In case of bid timeout, we provide you with an alternative reporting route.
The win nurl will be provided in the bid response. You need populate Clearing Price in nurl:
"https://www.facebook.com/audiencenetwork/nurl/?partner=${PARTNER_FBID}&app=${APP_FBID}&placement=${PLACEMENT_FBID}&auction=${AUCTION_ID}&impression=${IMPRESSION_ID}&request=${BID_REQUEST_ID}&bid=${BID_ID}&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&phase=${PHASE}"
${AUCTION_PRICE}
: This should be replaced with the Clearing Price for the auction in the same unit as our bid (i.e. USD on CPM basis).${PHASE}
: This should be replaced with 'auction' for win notification at auction time. For notifications at display time, please see Display Notification section belowOur loss lurl contains 3 flags you need populate:
"https://www.facebook.com/audiencenetwork/nurl/?partner=${PARTNER_FBID}&app=${APP_FBID}&placement=${PLACEMENT_FBID}&auction=${AUCTION_ID}&impression=${IMPRESSION_ID}&request=${BID_REQUEST_ID}&bid=${BID_ID}&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&phase=${PHASE}"
${AUCTION_LOSS}
: This should be replaced with ORTB Loss Code.${AUCTION_PRICE}
: This should be replaced with the Clearing Price for the auction in the same unit as our bid (i.e. USD on CPM basis). For loss code 100 case, this could be auction floor price.${PHASE}
: This should be replaced with 'auction' for loss notification at auction time. For notifications at display time, please see Display Notification section belowBelow is a list of different Loss Codes and corresponding Loss Reasons.
Loss Reason | Description | ORTB v2.5 Loss Code |
---|---|---|
Internal error | Internal error (e.g. when we won the auction, but our ad failed to load) | 1 |
Invalid bid response | Bid is invalid (but on-time, not a no-bid, and valid enough that you can extract the nurl) | 3 |
Bid timeout * | Bid response received, but too late for auction cutoff | 2 |
No bid * | No-bids are indicated as HTTP 204 (i.e. no nurl to call), but you may interpret our response as a no-bid (likely an integration issue). You may also request bids for several impressions, and we bid on some but not all. No need to send loss notification for this reason. No bid should be used as loss reason with timeout construction of lurl in cases where lurl is not available or unusable. | 9 |
Bid was Below Auction Floor | Bidding price was below current auction floor. ${AUCTION_PRICE} will be auction floor price or clearing price. | 100 |
Not highest RTB bidder | Another bidder beat us, including synthetic bids (e.g. non-RTB exchanges), if they are entered into the same auction. | 102 |
Lost to a Bid for a PMP Deal | A PMP (tag or traditional waterfall) deal was picked over the bidders in the auction. | 103 |
Inventory didn't materialise | Our bid won the auction, but the impression didn't materialize (e.g. page wasn't long enough to include this slot, or the user exited the app before the cached ad was used.) Not all partners can provide this (it's a non-event), so we will infer it if not provided. | 4902 |
Sent to ad server | Send this if the last touchpoint you have with the decision process is sending our high bid to the ad server. The impression may still be lost through missing line items, the ad server overruling the auction, or the inventory not materializing. | 4900 |
RTB winner not picked by ad server | We won the RTB auction, but the ad server overruled the auction (e.g. direct). | 4903 |
Win | We won the full decision tree, and tag was placed on page (web) or ad object was cached (app). Viewable impression may still not result. | 0 |
For the case of bid timeout or no bid due to unusable bid response (missing/unusable lurl), we provide you with an alternative reporting route. It is the generic nurl which might be called upon without the need to wait for the bid to arrive. The format is as follows:
"https://www.facebook.com/audiencenetwork/nurl/?partner=${PARTNER_FBID}&app=${APP_FBID}&auction=${AUCTION_ID}&ortb_loss_code=2"
Note: ${PARTNER_FBID}
, ${APP_FBID}
and ${AUCTION_ID}
should be populated with appropriate values. The table below provides explanation about those values.
Param | Type | Description |
---|---|---|
PARTNER_FBID | Int | Ad auction server id issued by Facebook. Use your app id here if you don't have a dedicated ad auction partner. |
APP_FBID | Int | Facebook-issued Id of the application/business which initiated an auction. |
AUCTION_ID | String | Client-generated id of the auction you used for issuing a bid request. |
We encourage publishers to send display notifications to Facebook bidder when they're about to show the ad. If the bid from Facebook bidder won the auction, use the nurl to send display notifications
"https://www.facebook.com/audiencenetwork/nurl/?partner=${PARTNER_FBID}&app=${APP_FBID}&placement=${PLACEMENT_FBID}&auction=${AUCTION_ID}&impression=${IMPRESSION_ID}&request=${BID_REQUEST_ID}&bid=${BID_ID}&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&phase=${PHASE}"
${AUCTION_PRICE}
: Similar to win notification at auction time, this should be replaced with the Clearing Price for the auction in the same unit as our bid (i.e. USD on CPM basis).${PHASE}
: This should be replaced with 'display' for win notifications at display time. If the bid from Facebook bidding didn't won the auction, use the lurl to send display notifications
"https://www.facebook.com/audiencenetwork/nurl/?partner=${PARTNER_FBID}&app=${APP_FBID}&placement=${PLACEMENT_FBID}&auction=${AUCTION_ID}&impression=${IMPRESSION_ID}&request=${BID_REQUEST_ID}&bid=${BID_ID}&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&phase=${PHASE}"
${AUCTION_LOSS}
: Similar to loss notification at auction time, this should be replaced with ORTB Loss Code.${AUCTION_PRICE}
: Similar to loss notification at auction time, this should be replaced with the Clearing Price for the auction in the same unit as our bid (i.e. USD on CPM basis). For loss code 100 case, this could be auction floor price.${PHASE}
: This should be replaced with 'display' for loss notifications at display time. Prices are quoted in USD on a CPM basis (e.g. 4.25 means we'll pay $4.25/1000 impressions if we win). The same unit must be used for the clearing price in nurl and lurl. Payouts are made directly to the publisher.
We always bid on a first-price basis, meaning we pay the amount we bid and we bid assuming we'll pay the full amount. This means we are at a disadvantage in a second-price auction, where other bidders can bid assuming they'll pay less than the amount bid.
For app impressions, we only pay out if the impression is viewed, regardless of whether we were the highest bidder.