Skip to content

optable-targeting new features: non-blocking early network call + hid + id5 - #4601

Open
justadreamer wants to merge 56 commits into
prebid:masterfrom
Optable:optable-targeting-features
Open

optable-targeting new features: non-blocking early network call + hid + id5#4601
justadreamer wants to merge 56 commits into
prebid:masterfrom
Optable:optable-targeting-features

Conversation

@justadreamer

Copy link
Copy Markdown
Contributor

Type of changes

  • module update

What's the context?

Two related improvements to the optable-targeting module: the Optable API call no longer
blocks the auction pipeline, and the Targeting API request now carries the parameters needed
for mobile in-app resolution (hid, bundle/ver, ID5).

Latency: non-blocking early network call

The API call starts at raw-auction-request and runs in parallel with the rest of the auction.
The result is consumed per bidder at bidder-request, where enrichment is actually injected,
so the pipeline never waits on the network.

Traffic controls

  • enrichment-percentage / bidder-enrichment-percentages: sampling rate (0-100) applied per
    bidder. A bidder with no entry falls back to the account default; 0 disables it entirely.
  • enrich-web / enrich-app: select which traffic sources are enriched.

Sampling applies to the split plan only. The legacy processed-auction-request hook enriches
the whole bid request before bidders split out, so it cannot sample per bidder.

Targeting API request parameters

  • hid-prefixes (new config entry): comma-separated id prefixes to emit as hid=, in the
    given order (e.g. "e,p,i6,a,g,c"). Independent of id-prefix-order, and selective rather
    than merely ordering: only the listed prefixes are sent as hid.
  • bundle / ver: emitted from bidRequest.app when present.
  • id5_signature in: read from user.ext.optable, forwarded as a Targeting API query
    attribute alongside email/phone/zip/vid.
  • id5_signature out: returned in ext.prebid.passthrough.optable.id5_signature. PBS
    cannot persist the signature between requests, so it round-trips through the client, which
    caches it and replays it on the next auction.

Backwards compatibility

No breaking changes. The processed-auction-request hook is retained and detects whether both
new hooks are present in the execution plan: if so it passes through immediately, otherwise it
falls back to the previous synchronous behavior. The legacy fragment can therefore be left in
place during migration without negating the latency benefit.

Configuration (recommended)

hooks:
  modules:
    optable-targeting:
      enrichment-percentage: 100
      bidder-enrichment-percentages:
        appnexus: 75
        pubmatic: 0
      enrich-web: true
      enrich-app: true
      id-prefix-order: "e,v,c"
      hid-prefixes: "a,c,i6"

  execution-plan:
    endpoints:
      "/openrtb2/auction":
        stages:
          raw-auction-request:
            groups:
              - timeout: 50
                hook-sequence:
                  - module-code: "optable-targeting"
                    hook-impl-code: "optable-targeting-raw-auction-request-hook"
          bidder-request:
            groups:
              - timeout: 500
                hook-sequence:
                  - module-code: "optable-targeting"
                    hook-impl-code: "optable-targeting-bidder-request-hook"
          auction-response:
            groups:
              - timeout: 10
                hook-sequence:
                  - module-code: "optable-targeting"
                    hook-impl-code: "optable-targeting-auction-response-hook"

The bidder-request group timeout bounds the wait on the API call, so it must accommodate
round-trip latency to the Optable edge. The raw-auction-request timeout only covers dispatch.

To migrate, drop the legacy fragment:

          processed-auction-request:
            groups:
              - timeout: 600
                hook-sequence:
                  - module-code: "optable-targeting"
                    hook-impl-code: "optable-targeting-processed-auction-request-hook"

Test plan

  • Unit tests
  • Semi-automated integration tests against the live Optable edge, covering enrichment with eids,
    per-bidder sampling (including a bidder pinned at 0%), ad server targeting keywords,
    ID5 signature passthrough, and the legacy execution plan

Quality check

  • Are your changes following our code style guidelines?
  • Are there any breaking changes in your code? No
  • Does your test coverage exceed 90%?
  • Are there any erroneous console logs, debuggers or leftover code in your changes? No

cc: @jrosendahl-opt @softcoder594

softcoder and others added 30 commits August 13, 2026 22:38
return early from the hook if (hasRawAuctionRequestHook && hasBidderRequestHook) - the new mode
random is 0-99, percentage is 0-100.  enrich when random < (strictly less than) percentage.  so if we specify percentage 0 we never enrich, if we specify percentage 100 we always enrich.
…ntage property is specified and it's value is 100%
The account config node is deserialized with the prebid mapper, which uses
SNAKE_CASE, so the unannotated fields bound to enrich_web and enrich_app while
the documented account keys are enrich-web and enrich-app. Per-account
overrides of both were silently dropped and the global value kept.
…change

Core changed ExecutionPlan.endpoints key type from Endpoint to
HookHttpEndpoint. Map.get accepts Object, so the stale lookup kept
compiling but always returned null against the EnumMap: the module read
a bidder-request hook timeout of 0, so the targeting API call inherited
only the raw-auction-request stage budget (50ms) instead of the
configured 500ms and timed out on every auction.
softcoder and others added 25 commits August 14, 2026 00:39
…re not participate in targeting enrichment process.
The test named for the NOBID branch stubbed a bid response that has a bid,
so with non-empty targeting the validator returned SUCCESS and the test
exercised the full enrichment chain instead of the signature-only one.
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