Skip to content

Yahoo Ads: Migrate to OpenRTB 2.6#4521

Open
MananRPatel wants to merge 5 commits into
prebid:masterfrom
MananRPatel:YahooAds26
Open

Yahoo Ads: Migrate to OpenRTB 2.6#4521
MananRPatel wants to merge 5 commits into
prebid:masterfrom
MananRPatel:YahooAds26

Conversation

@MananRPatel
Copy link
Copy Markdown

@MananRPatel MananRPatel commented May 29, 2026

🔧 Type of changes

  • new bid adapter
  • bid adapter update
  • new feature
  • new analytics adapter
  • new module
  • module update
  • bugfix
  • documentation
  • configuration
  • dependency update
  • tech debt (test coverage, refactorings, etc.)

Migrates the Yahoo Ads bidder (and its yssp / yahoossp / yahooAdvertising
aliases) from OpenRTB 2.5 to OpenRTB 2.6 on the wire. Three changes, in the
bidder and its Spring config:

  1. HTTP header x-openrtb-version: 2.52.6 in
    src/main/java/org/prebid/server/bidder/yahooads/YahooAdsBidder.java.
  2. Remove the in-bidder down-conversion. The bidder explicitly converted the
    request back to 2.5 before serializing it
    (conversionManager.convertFromAuctionSupportedVersion(bidRequest, OrtbVersion.ORTB_2_5)).
    That call is removed, along with the now-unused
    BidRequestOrtbVersionConversionManager dependency in the bidder and its
    YahooAdsConfiguration.
  3. Legacy ext→top promotion for regs.{gpp, gpp_sid, coppa}. The old
    modifyRegs / resolveExtRegs block re-buried these (and gdpr/us_privacy)
    into regs.ext. It is replaced with promoteRegsExtToTopLevel: a field is
    promoted only when it is absent at top-level and present and well-formed in
    regs.ext, and a key is removed from regs.ext if and only if that field
    was promoted. Typed ext-only fields (gpc, dsa), unknown regs.ext
    properties, a value already present at top-level, and any of the three that
    could not be promoted (e.g. a malformed, non-textual gpp, or a gpp_sid
    array with a non-integer element) are all left in regs.ext untouched, so
    no value is silently dropped. The strip decision uses a single per-field
    signal, so it does not depend on whether a sibling field triggered the
    rebuild.

No publisher-facing config change is required bidder params (dcn, pos) are
unchanged, and bidder-config/yahooAds.yaml already declared ortb-version: "2.6".

Why

PBS-Java core up-converts every incoming request to its canonical 2.6 form
(BidRequestOrtb25To26Converter) before bidders run. The Yahoo bidder then
explicitly down-converted that back to 2.5 and re-buried
gpp / gpp_sid / coppa into regs.ext, and sent x-openrtb-version: 2.5.
Net effect: even fully 2.6-aware publishers had privacy/addressability fields
buried in .ext on the wire.

Removing the in-bidder down-conversion lets core's existing promotion reach the
wire. The new promoteRegsExtToTopLevel additionally promotes the three
regulatory fields that neither converter handles.

Field(s) Legacy (2.5-ext) location 2.6 location Promoted by
regs.gdpr, regs.us_privacy regs.ext.* top-level on Regs core up-converter
user.consent, user.eids user.ext.* top-level on User core up-converter
source.schain source.ext.schain top-level on Source core up-converter
imp.rwdd imp.ext.prebid.is_rewarded_inventory top-level on Imp core up-converter
regs.gpp, regs.gpp_sid regs.ext.* top-level on Regs this PR (bidder)
regs.coppa top-level (since 2.0) or regs.ext.coppa (legacy) top-level on Regs this PR (bidder)

What this means for publishers

Publisher integration shape Before After
2.6-shape (e.g. regs.gpp top-level) bidder re-buried fields into .ext; header was 2.5 top-level fields stay top-level; header 2.6
Legacy 2.5-ext shape values stayed in .ext on the wire core promotes gdpr, us_privacy, consent, eids, schain, rwdd; the bidder additionally promotes gpp, gpp_sid, coppa; everything else passes through in .ext

Non-regulatory 2.6 fields the bidder does not transform (e.g. device.sua,
user.kwarray, site/app.inventorypartnerdomain, content.network,
content.channel) pass through in whatever shape the publisher sent.

What changed

File Insertions Deletions
src/main/java/org/prebid/server/bidder/yahooads/YahooAdsBidder.java 91 51
src/main/java/org/prebid/server/spring/config/bidder/YahooAdsConfiguration.java 2 4
src/test/java/org/prebid/server/bidder/yahooads/YahooAdsBidderTest.java 210 34
src/test/resources/org/prebid/server/it/openrtb2/yahooads/test-yahooads-bid-request.json 3 5
Total (4 files) 306 94

YahooAdsBidder.java bumps the header literal, removes the down-converter call
and dependency, and replaces the regs re-bury logic with
promoteRegsExtToTopLevel + gppToPromote / gppSidToPromote /
coppaToPromote (each returns the value to lift, or null) and
removePromotedKeys. The helpers operate on a toBuilder() copy of Regs
(the bidder already rebuilds the request per-impression), so they cannot affect
the request other bidders see.

Test plan

Automated

  • mvn test -Dtest=YahooAdsBidderTest 29 unit tests pass. New cases cover:
    ext→top promotion, mixed publisher shapes (some fields top-level, some in
    ext), wrong-typed regs.ext values (no promotion), a malformed value left in
    ext while a sibling field promotes, a gpp_sid array with a non-integer
    element left in ext untouched, the same field present at both top-level and
    ext (ext copy left untouched), and the no-ext short-circuit.
  • mvn test -Dtest=YahooAdsTest integration test passes against the
    updated 2.6 wire fixture.

End-to-end against the Yahoo Ads SSP

A build of this branch was run as a local PBS-Java process (not Docker) and
pointed at the Yahoo Ads SSP endpoint. For each scenario a request was POSTed to
/openrtb2/auction with ext.prebid.debug: 1, and the exact bytes the bidder
put on the wire were read back from ext.debug.httpcalls.yahooAds[*] (request
body + headers). Every outbound carried x-openrtb-version: 2.6 and the SSP
returned HTTP 200.
Bid presence varies with demand and is not asserted here.

Scenario What it confirms (wire shape)
Site banner, 2.6-native top-level privacy/addressability fields forwarded unchanged (no re-bury)
Site banner, legacy 2.5-ext regs.gpp / regs.gpp_sid / regs.coppa promoted to top-level and removed from regs.ext; core-promoted fields (gdpr, us_privacy) at top-level; unrelated regs.ext keys (gpc, dsa) left in regs.ext
Video, plcmt=2 and plcmt=4 video request serialized with the 2.6 header
Video ad pod, 3 slots per-impression split produces one outbound per slot with pod fields (podid, podseq, slotinpod, maxseq, poddur, mincpmpersec, rqddurs) intact
App banner / video / ad pod app.id override applied (same mechanism as site.id); 2.6 wire
Multi-bidder (yahooAds + 2 other SSPs in one imp) the yahooAds outbound is byte-identical to the standalone case; adding other bidders does not change what PBS sends to Yahoo

How to verify locally

mvn package -DskipTests
java -jar target/prebid-server.jar \
  --spring.config.additional-location=<your-config>.yaml

curl -s -X POST http://localhost:8080/openrtb2/auction \
  -H 'Content-Type: application/json' \
  -d @your-yahooAds-request.json \
  | jq '.ext.debug.httpcalls.yahooAds[0].requestheaders["x-openrtb-version"]'
# → ["2.6"]

Test fixture changes

  • test-yahooads-bid-request.json (integration): expected outbound now carries
    regs.gpp / regs.gpp_sid / regs.gdpr at top-level (previously under
    regs.ext).
  • YahooAdsBidderTest.java: header assertion 2.52.6; the
    "remove/overwrite regs ext" tests are replaced with promotion + passthrough
    tests described above.

Backward compatibility

No breaking changes.

  • Bidder-param schema (dcn, pos) unchanged.
  • Bid-response handling (makeBids) unchanged.
  • 2.6-shape requests are forwarded without re-burying.
  • Legacy 2.5-ext requests get the core-promoted fields plus gpp / gpp_sid /
    coppa at top-level; all other fields pass through unchanged in .ext.

Aliases

yssp, yahoossp and yahooAdvertising are declared as aliases of yahooAds
in bidder-config/yahooAds.yaml and share the same YahooAdsBidder instance,
so all alias codes send the 2.6 wire after this PR.


For contact: prebid-tech-team@yahooinc.com

Implemented with assistance from Claude Code.

MananRPatel added 2 commits May 29, 2026 14:32
Bump the x-openrtb-version header from 2.5 to 2.6 and stop down-converting
the auction request inside the bidder. The bidder now passes the 2.6 request
through, relying on the PBS-Java up-converter to normalize gdpr, us_privacy,
consent, eids, schain and rwdd to their 2.6 top-level slots.

For the three privacy/regulatory fields that neither converter handles
(gpp, gpp_sid, coppa), add ext->top promotion in modifyRegs: read the 2.6
top-level value, falling back to the legacy 2.5 regs.ext property, and strip
the promoted keys from ext. Typed ext-only fields (gpc, dsa) and any other
ext properties are preserved. No cattax default is synthesized.

Remove the now-unused BidRequestOrtbVersionConversionManager dependency from
the bidder and its Spring configuration.

Update unit tests for the 2.6 wire shape and add coverage for the ext->top
promotion, mixed publisher shapes, wrong-type ext guards, and the
no-ext short-circuit. Update the integration fixture to the 2.6 wire shape.
Make stripPromotedFromExt remove a regs.ext key only when its value was
actually promoted to top-level (resolved value non-null). A malformed,
non-promotable value (e.g. a non-textual gpp) is now left untouched in
regs.ext instead of being dropped when a sibling field triggers the
rebuild.

Add a test covering the mixed case (valid coppa promoted, malformed gpp
kept in ext) and trim redundant comments.
@MananRPatel MananRPatel marked this pull request as ready for review June 1, 2026 08:43
MananRPatel added 3 commits June 1, 2026 14:43
resolveGppSid now promotes regs.ext.gpp_sid only when every element is an
integer. If any element is non-integral the whole array is left in regs.ext
untouched rather than promoting a filtered subset, matching the gpp and coppa
handling so no value is silently dropped. Adds a test for the mixed-array case.
Restructure the regs handling so a single per-field signal decides both the
promotion and the ext strip. A field is promoted only when it is absent at
top-level and present and well-formed in ext; a key is removed from regs.ext
if and only if that field was promoted. This removes the previous dependency
on whether a sibling field triggered the rebuild (e.g. a value present at both
top-level and in ext is now handled the same regardless of siblings).

Rename for clarity: modifyRegs -> promoteRegsExtToTopLevel, resolveX ->
xToPromote (return the value to lift or null), stripPromotedFromExt ->
removePromotedKeys. Add a test for the same field present at both top-level
and ext.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant