Skip to content

Add bidder param zone overrides and per-provider auction details#347

Open
ChristianPavilonis wants to merge 10 commits intomainfrom
feature/override-prebid-bidder-params
Open

Add bidder param zone overrides and per-provider auction details#347
ChristianPavilonis wants to merge 10 commits intomainfrom
feature/override-prebid-bidder-params

Conversation

@ChristianPavilonis
Copy link
Collaborator

@ChristianPavilonis ChristianPavilonis commented Feb 19, 2026

Closes #340

Summary

  • Bidder param zone overrides: Allow per-zone overrides of bidder parameters in the Prebid config (bid_param_zone_overrides). Publishers can configure different placement IDs per ad zone (e.g., header vs sidebar vs in-content) via TOML. The JS adapter reads the zone from mediaTypes.banner.name on each ad unit and sends it to the server, which shallow-merges the matching override into the bidder params before dispatching to Prebid Server.
  • Per-provider auction response details: Add a provider_details array to the /auction response at ext.orchestrator. Each entry is a ProviderSummary with provider name, bid status, bid count, unique bidder/seat names, response time, and provider-specific metadata. For Prebid, the metadata includes responsetimemillis (per-bidder timing for all invited bidders, not just those that bid) and errors from the Prebid Server response ext — making it easy to see which bidders were in the auction stream but returned no bids.

Feature 1: Bidder Param Zone Overrides

The JS adapter reads mediaTypes.banner.name (a non-standard Prebid.js field used as a temporary workaround) and includes it as a zone field in the trustedServer bid params. On the server side, bid_param_zone_overrides is a nested map of bidder → zone → params that is shallow-merged into the incoming bidder params when a match is found.

Config example:

[integrations.prebid.bid_param_zone_overrides.kargo]
header       = {placementId = "_s2sHeaderPlacement"}
in_content   = {placementId = "_s2sContentPlacement"}
fixed_bottom = {placementId = "_s2sBottomPlacement"}

Behavior:

  • Override params are shallow-merged (override values win on key conflicts)
  • Non-conflicting incoming fields are preserved
  • Unknown zone or missing zone → incoming params pass through unchanged
  • Only configured bidders are affected; other bidders are untouched

Feature 2: Per-Provider Auction Response Details

The /auction response now includes a provider_details array in ext.orchestrator:

{
  "ext": {
    "orchestrator": {
      "strategy": "parallel_only",
      "providers": 1,
      "total_bids": 2,
      "time_ms": 145,
      "provider_details": [
        {
          "name": "prebid",
          "status": "success",
          "bid_count": 2,
          "bidders": ["ix", "kargo"],
          "time_ms": 142,
          "metadata": {
            "responsetimemillis": {
              "appnexus": 0,
              "ix": 120,
              "kargo": 98,
              "openx": 0,
              "rubicon": 0
            },
            "errors": {
              "openx": [{"code": 1, "message": "timeout"}]
            }
          }
        }
      ]
    }
  }
}

Note how responsetimemillis includes entries for bidders like appnexus and rubicon that returned 0ms (no bid), while bidders only lists those that actually bid (ix, kargo). The errors object surfaces Prebid Server-reported errors per bidder.

Changes

File Change
crates/common/src/integrations/prebid.rs Add bid_param_zone_overrides config field, zone extraction from trustedServer params, shallow-merge logic, responsetimemillis/errors metadata extraction, new tests and test helpers
crates/common/src/auction/types.rs Add ProviderSummary struct with From<&AuctionResponse> impl; add provider_details field to OrchestratorExt
crates/common/src/auction/formats.rs Build provider_details vec from orchestration result and include in response
crates/common/src/openrtb.rs Update test fixture to include provider_details: vec![]
crates/js/lib/src/integrations/prebid/index.ts Read mediaTypes.banner.name as zone, include zone key in trustedServer params, handle stale zone cleanup
crates/js/lib/test/integrations/prebid/index.test.ts Add tests for zone inclusion, omission, and stale zone cleanup
docs/guide/integrations/prebid.md Document bid_param_zone_overrides config, behavior, and example
trusted-server.toml Add example Kargo zone overrides

Test plan

  • cargo test --workspace
  • cargo clippy --all-targets --all-features -- -D warnings
  • cargo fmt --all -- --check
  • JS tests: cd crates/js/lib && npx vitest run
  • JS format: cd crates/js/lib && npm run format
  • Docs format: cd docs && npm run format
  • WASM build: cargo build --bin trusted-server-fastly --release --target wasm32-wasip1
  • Manual testing via fastly compute serve

Checklist

  • Changes follow CLAUDE.md conventions
  • No unwrap() in production code — use expect("should ...")
  • Uses tracing macros (not println!)
  • New code has tests
  • No secrets or credentials committed

@ChristianPavilonis ChristianPavilonis force-pushed the feature/override-prebid-bidder-params branch from 7fade76 to 5d90d1f Compare February 24, 2026 19:41
Adds ProviderSummary struct to expose bid counts and bidder names (e.g. kargo, pubmatic) from each auction provider. Includes provider-specific metadata via AuctionResponse.metadata field for future integration data.

Response now includes provider_details array in ext.orchestrator with one summary per provider showing status, bid count, unique bidders, and response time.
@ChristianPavilonis ChristianPavilonis changed the title Adds configuration for bidder param overrides Add bidder param zone overrides and per-provider auction details Feb 24, 2026
@ChristianPavilonis ChristianPavilonis marked this pull request as ready for review February 24, 2026 21:39
Copy link
Collaborator

@prk-Jr prk-Jr left a comment

Choose a reason for hiding this comment

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

Summary

This PR adds useful Prebid zone-based bidder parameter overrides and richer per-provider auction details in ext.orchestrator. The overall direction is solid, and CI is green.

👍 Highlights

  • The zone override path is well-covered across Rust and JS tests, including stale-zone cleanup behavior in the adapter shim.
  • Adding per-provider diagnostics (provider_details) is a strong observability improvement for auction debugging.

Findings

🤔 Medium (P2)

  • ProviderSummary.metadata currently serializes with skip_serializing_if = "HashMap::is_empty" but deserialization still requires the field. This can fail round-trip deserialization for valid payloads that omit empty metadata.

⛏ Low (P3)

  • parse_response now maps ext.responsetimemillis and ext.errors into AuctionResponse.metadata, but there is no direct regression test for this path.

CI Status

  • fmt: PASS
  • clippy: PASS (Analyze (rust) check passed)
  • rust tests: PASS
  • js tests: PASS

…test

Address PR #347 review comments:
- Add #[serde(default)] to ProviderSummary.metadata and
  OrchestratorExt.provider_details for backward-compatible deserialization
- Add regression test for responsetimemillis and errors metadata extraction
  from Prebid Server response 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.

As publisher I want to able to override prebid request parameters with configuration defined in Trusted Server

2 participants