Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prebid 7: update docs related to first-party data #3823

Merged
merged 4 commits into from
Jun 20, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions dev-docs/add-rtd-submodule.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,16 +176,33 @@ submodule('realTimeData', subModuleObj);
This is the function that will allow RTD sub-modules to modify the AdUnit object for each auction. It's called as part of the requestBids hook.

1. RTD-core will call this function with:
- reqBidsConfigObj: the object that's passed to [`pbjs.requestBids`](). Note that several auctions can happen concurrently, so the sub-module must be ready to support this.
- reqBidsConfigObj: a sligtly modified version of the object that's passed to `pbjs.requestBids` (see [below](#reqBidsConfigObj)). Note that several auctions can happen concurrently, so the sub-module must be ready to support this.
dgirardi marked this conversation as resolved.
Show resolved Hide resolved
- callback: lets RTD-core know which auction the sub-module is done with.
- config: the sub-module's config params provided by the publisher
- userConsent object (see above)
2. Your sub-module may update the reqBidsConfigObj and hit the callback. To inject data into the bid requests, you should follow one of these conventions:
- Recommended: use one of these [First Party Data](/features/firstPartyData.html) conventions:
- For AdUnit-specific first party data, set AdUnit.ortb2Imp.ext.data.ATTRIBUTES
- For global first party data, call 'pbjs.[mergeConfig](/dev-docs/publisher-api-reference/mergeConfig.html)()'
- If the data is not meant to go to all bidders, the module should use 'pbjs.[mergeBidderConfig](/dev-docs/publisher-api-reference/mergeBidderConfig.html)()' and support a parameter to allow the publisher to define which bidders are to receive the data.
- For global first party data, including bidder-specific data, modify the `reqBidsConfigObj` as shown [below](#reqBidsConfigObj)
- Not recommended: Place your data in bidRequest.rtd.RTDPROVIDERCODE.ATTRIBUTES and then get individual adapters to specifically read that location. Note that this method won't pass data to Prebid Server adapters.

<a id="reqBidsConfigObj" />

The `reqBidsConfigObj` parameter is a copy of the object passed to [`requestBids`](/dev-docs/publisher-api-reference/requestBids.html), except for:

- `adUnits` and `timeout` are always defined (if the publisher didn't provide them, the default values are filled in - `pbjs.adUnits` and `getConfig('bidderTimeout')` respectively)
- `ortb2` is replaced with an `ortb2Fragments` object, intended to be inspected and / or modified by your module.

The `ortb2Fragments` parameter is an object containing two properties:

- `global`, an object containing global (not bidder-specific) first party data in the same OpenRTB format used by `setConfig({ortb2})`
- `bidder`, a map from bidder code to bidder-specific, OpenRTB-formatted first party data.

Your module may modify either or both with additional data. If adding bidder-specific data in `ortb2Fragments.bidder`, it should also support a parameter to allow the publisher to define which bidders are to receive the data.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that favoring a specific bidder is a rules violation; if an rtd module formats data in a way for a specific bidder endpoint, it must also support the standard formatting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

integrating in any way other than the standard way is always favoring a specific bidder IMO. the RTD module is in some way making it easier for one particular adapter to work with it (otherwise why would they do it?)
should we remove that option entirely?


{: .alert.alert-warning :}
Before version 7, the pattern for first party data inspection and enrichment by RTD modules was `getConfig({ortb2])` / `mergeConfig({ortb2})`. With the introduction of [auction-specific data](/features/firstPartyData.html#supplying-auction-specific-data) in 7, the global `getConfig({ortb2})` is "frozen"
at the time `requestBids` is called, and RTD submodules that need to modify it are required to work on `ortb2Fragments` instead - as any additional call to `mergeConfig` will only take effect on the *next* auction.

**Code Example**

Expand All @@ -205,7 +222,12 @@ function init(config, userConsent) {

function alterBidRequests(reqBidsConfigObj, callback, config, userConsent) {
// do stuff
// put data in AdUnit.ortb2Imp.ext.data.* or rtd.RTDPROVIDERCODE.*
// put data in adUnits' ortb2Imp:
reqBidsConfigObj.adUnits.forEach((adUnit) => mergeDeep(adUnit, 'ortb2Imp.ext', myCustomData);
// or in global first party data:
mergeDeep(reqBidsConfigObj.ortb2Fragments.global, myCustomData);
// or in bidder-specific first party data:
config.bidders.forEach((bidderCode) => mergeDeep(reqBidsConfigObj.ortb2Fragments.bidder, {[bidderCode]: myCustomData});
callback();
}

Expand Down
35 changes: 20 additions & 15 deletions dev-docs/bidder-adaptor.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ buildRequests: function(validBidRequests, bidderRequest) {
Building the request will use data from several places:

* **Ad Unit Params**: The arguments provided by the page are in `validBidRequests[]`.
* **BidRequest Params**: Several important parameters such as userId, GDPR, USP, and supply chain values are on the `bidderRequest` object.
* **BidRequest Params**: Several important parameters such as first-party data, userId, GDPR, USP, and supply chain values are on the `bidderRequest` object.
* **Prebid Config**: Publishers can set a number of config values that bid adapters should consider reading.


Expand All @@ -235,19 +235,20 @@ Here is a sample array entry for `validBidRequests[]`:

{% highlight js %}
[{
adUnitCode: "test-div"
auctionId: "b06c5141-fe8f-4cdf-9d7d-54415490a917"
bidId: "22c4871113f461"
bidder: "rubicon"
bidderRequestId: "15246a574e859f"
bidRequestsCount: 1
bidderRequestsCount: 1
bidderWinsCount: 0
userId: {...}
schain: {...}
mediaTypes: {banner: {...}}
params: {...}
src: "client"
adUnitCode: "test-div",
auctionId: "b06c5141-fe8f-4cdf-9d7d-54415490a917",
bidId: "22c4871113f461",
bidder: "rubicon",
bidderRequestId: "15246a574e859f",
bidRequestsCount: 1,
bidderRequestsCount: 1,
bidderWinsCount: 0,
userId: {...},
userIdAsEid: {...},
schain: {...},
mediaTypes: {banner: {...}},
params: {...},
src: "client",
transactionId: "54a58774-7a41-494e-9aaf-fa7b79164f0c"
}]
{% endhighlight %}
Expand All @@ -260,6 +261,8 @@ Other notes:
- **Bid Request Count** is the number of times `requestBids()` has been called for this ad unit.
- **Bidder Request Count** is the number of times `requestBids()` has been called for this ad unit and bidder.
- **userId** is where bidders can look for IDs offered by the various [User ID modules](/dev-docs/modules/userId.html#prebidjs-adapters).
- **userIdAsEid** is the EID-formatted version of `userId`.
- **ortb2** a copy of `bidderRequest.ortb2` (see below), provided here for convenience.
- **schain** is where bidders can look for any [Supply Chain](/dev-docs/modules/schain.html) data that they should pass through to the endpoint.

#### bidderRequest Parameters
Expand All @@ -274,6 +277,7 @@ Here is a sample bidderRequest object:
bidderRequestId: "15246a574e859f",
bids: [{...}],
gdprConsent: {consentString: "BOtmiBKOtmiBKABABAENAFAAAAACeAAA", vendorData: {...}, gdprApplies: true},
ortb2: {...},
refererInfo: {
canonicalUrl: undefined,
numIframes: 0,
Expand All @@ -288,6 +292,7 @@ Notes on parameters in the bidderRequest object:
- **refererInfo** is provided so you don't have to call any utils functions. See below for more information.
- **gdprConsent** is the object containing data from the [GDPR ConsentManagement](/dev-docs/modules/consentManagement.html) module. For TCF2+, it will contain both the tcfString and the addtlConsent string if the CMP sets the latter as part of the TCData object.
- **uspConsent** is the object containing data from the [US Privacy ConsentManagement](/dev-docs/modules/consentManagementUsp.html) module
- **ortb2** is the global (not specific to any adUnit) [first party data](/features/firstPartyData.html) to use for all requests in this auction.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might also include other standard ortb2 fields and extensions that might not typically be considered first party data, such as user agent client hints (device.sua) or information on applicable regulations eg ( regs.ext.gpc )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated, but I'll accept suggestions on how to word it less clunkily.


<a name="std-param-location"></a>

Expand All @@ -301,7 +306,7 @@ There are a number of important values that a publisher expects to be handled in
| Ad Server Currency | If your endpoint supports responding in different currencies, read this value. | config.getConfig('currency.adServerCurrency') |
| Bidder Timeout | Use if your endpoint needs to know how long the page is allowing the auction to run. | config.getConfig('bidderTimeout'); |
| COPPA | If your endpoint supports the Child Online Privacy Protection Act, you should read this value. | config.getConfig('coppa'); |
| First Party Data | The publisher may provide [first party data](/dev-docs/publisher-api-reference/setConfig.html#setConfig-fpd) (e.g. page type). | config.getConfig('fpd'); |
| First Party Data | The publisher, as well as a number of modules, may provide [first party data](/features/firstPartyData.html) (e.g. page type). | bidderRequest.ortb2; validBidRequests[].ortb2Imp|
| Floors | Adapters that accept a floor parameter must also support the [floors module](https://docs.prebid.org/dev-docs/modules/floors.html) | [`getFloor()`](/dev-docs/modules/floors.html#bid-adapter-interface) |
| Page Referrer | Intead of building your own function to find the page referrer, look in the standard bidRequest location. | bidderRequest.refererInfo.referer |
| Publisher Domain | The page may declare its domain, useful in cross-iframe scenarios. | config.getConfig('publisherDomain') |
Expand Down
14 changes: 4 additions & 10 deletions dev-docs/modules/enrichmentFpdModule.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,16 @@ pbjs.setConfig({

## How it works

When the first auction on the page is run, this module merges a number of values into the `ortb2` object. Specific details below.

If the publisher needs to refresh the enriched FPD after the first auction, this can be done using a function provided by this module:

```
pbjs.refreshFpd();
```
At the beginning of each auction, this module merges a number of values into the `ortb2` [requestBids parameter](/dev-docs/publisher-api-reference/requestBids.html). Specific details below.

## Enrichments

{: .table .table-bordered .table-striped }
| Page Source | ortb2 field | Notes |
|---+---+---|
| page URL | site.page | Uses pbjs getRefererInfo().canonicalUrl |
| referer URL | site.ref | Uses pbjs getRefererInfo().referer |
| host domain | site.domain | Pulled from the getRefererInfo().canonicalUrl the host domain is used with the www component dropped. |
| page URL | site.page | Uses pbjs getRefererInfo().page |
| referer URL | site.ref | Uses pbjs getRefererInfo().ref |
| host domain | site.domain | Pulled from the getRefererInfo().page the host domain is used with the www component dropped. |
| aggregated domain | site.publisher.domain | The highest level domain in which cookies can be set. |
| viewport width | device.w | Hunts for window.innerWidth, window.document.documentElement.clientWidth, window.document.body.clientWidth |
| viewport height | device.w | Hunts for window.innerHeight, window.document.documentElement.clientHeight, window.document.body.clientHeight |
Expand Down
2 changes: 1 addition & 1 deletion dev-docs/modules/validationFpdModule.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pbjs.setConfig({

## Validations

This module does its checks only once at the first auction. The checks can be re-run anytime by calling `pbjs.refreshFpd()`.
This module does its checks at the beginning of each auction.

When a data field doesn't meet the defined validations, it will be removed. In addition, the module will look for the _pubcid_optout cookie (or local storage),
and if it exists, certain fields will be removed.
Expand Down
1 change: 1 addition & 0 deletions dev-docs/publisher-api-reference/requestBids.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Request bids. When `adUnits` or `adUnitCodes` are not specified, request bids fo
| requestObj.bidsBackHandler | Optional | `function` | Callback to execute when all the bid responses are back or the timeout hits. Callback will be passed three parameters, the [bidResponses](#module_pbjs.getBidResponses) themselves, a `timedOut` flag (true if any bidders timed out) and the `auctionId`. |
| requestObj.labels | Optional | `Array of strings` | Defines [labels](#labels) that may be matched on ad unit targeting conditions. |
| requestObj.auctionId | Optional | `String` | Defines an auction ID to be used rather than having the system generate one. This can be useful if there are multiple wrappers on a page and a single auction ID is desired to tie them together in analytics. |
| requestObj.ortb2 | Optional | `Object` | Additional [first-party data](/features/firstPartyData.html) to use for this auction only |

Example call
```
Expand Down
8 changes: 6 additions & 2 deletions dev-docs/publisher-api-reference/setConfig.md
Original file line number Diff line number Diff line change
Expand Up @@ -1052,11 +1052,15 @@ The `ortb2` JSON structure reflects the OpenRTB standard:
- Segments should go in site.content.data[] or user.data[].
- Any other OpenRTB 2.5 field could be added here as well, e.g. site.content.language.

**Scenario 2** - Global (cross-adunit) First Party Data open only to a subset of bidders
**Scenario 2** - Auction (cross-adunit) First Party Data open to all bidders

If a page needs to specify multiple different sets of top-level data (`site`, `user`, or `app`), use the `ortb2` parameter of [`requestBids`](/dev-docs/publisher-api-reference/setConfig.html) ([example](/features/firstPartyData.html#supplying-auction-specific-data)

**Scenario 3** - Global (cross-adunit) First Party Data open only to a subset of bidders

If a publisher only wants certain bidders to receive the data, use the [setBidderConfig](/dev-docs/publisher-api-reference/setBidderConfig.html) function.

**Scenario 3** - AdUnit-specific First Party Data
**Scenario 4** - AdUnit-specific First Party Data

See the [AdUnit Reference](/dev-docs/adunit-reference.html) for AdUnit-specific first party data.

Expand Down
43 changes: 38 additions & 5 deletions features/firstPartyData.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ which can be used for more than just First Party Data.
Publishers supply First Party Data (FPD) by specifying attributes as
configuration or on a Prebid.js AdUnit:

- Global site or user data that applies to all AdUnits and all bidders. Use [`setConfig()`](/dev-docs/publisher-api-reference/setConfig.html#setConfig-fpd)
- AdUnit-specific data that applies to all bidders. Define [AdUnit.ortb2Imp](/dev-docs/adunit-reference.html#first-party-data)
- Bidder-specific site or user data that applies to all AdUnits. Use [`setBidderConfig()`](/dev-docs/publisher-api-reference/setBidderConfig.html)
- Global site or user data that applies to all AdUnits, bidders, and auctions. Use [`setConfig()`](/dev-docs/publisher-api-reference/setConfig.html#setConfig-fpd)
- Auction-specific site or user data that applies to all AdUnits and bidders in that auction. Use the `ortb2` parameter of [`requestBids()`](/dev-docs/publisher-api-reference/requestBids.html)
- AdUnit-specific data that applies to all bidders and auctions. Define [AdUnit.ortb2Imp](/dev-docs/adunit-reference.html#first-party-data)
- Bidder-specific site or user data that applies to all AdUnits and auctions. Use [`setBidderConfig()`](/dev-docs/publisher-api-reference/setBidderConfig.html)

## In-Page Examples

Expand Down Expand Up @@ -110,6 +111,36 @@ of user data as part of its GDPR or CCPA modules.
{: .alert.alert-warning :}
If you're using PBJS version 4.29 or before, replace the following in the example above: 'ortb' with 'fpd', 'site' with 'context' and 'site.ext.data' with 'context.data'.

### Supplying Auction-Specific Data

In some situations the same page may wish to supply different `site` data for some of its sections,
for example in infinite scroll or instream video scenarios where multiple pieces of content that would benefit from different contexts are served together.

To support this use case, Prebid version 7 and above accepts auction-specific first-party data as a parameter to `requestBids`. For example:

{% highlight js %}
pbjs.requestBids({
ortb2: {
site: {
content: {
data: [{
name: 'www.iris.com',
ext: {
segtax: 500,
cids: ['iris_c73g5jq96mwso4d8']
},
segment: [
{id: '687'},
{id: '123'}
]
}]
}
}
}
});
{% endhighlight %}


### Supplying AdUnit-Specific Data

If an attribute is specific to an AdUnit, it can be passed this way:
Expand Down Expand Up @@ -293,10 +324,12 @@ segment taxonomies they support.

## How Bid Adapters Should Read First Party Data

To access global data, a Prebid.js bid adapter needs only to call [`getConfig()`](/dev-docs/publisher-api-reference/getConfig.html), like this:
Prebid.js bid adapters are supplied global data in the `ortb2` property of [bid requests](/dev-docs/bidder-adaptor.html#building-the-request):

{% highlight js %}
config.getConfig('ortb2'))
buildRequests: function(validBidRequests, bidderRequest) {
const firstPartyData = bidderRequest.ortb2;
}
{% endhighlight %}

AdUnit-specific values must be parsed out of the AdUnit object.
Expand Down