From 30242a6e579a73836fefb0c30608815cded23325 Mon Sep 17 00:00:00 2001 From: Eugene Dorfman Date: Tue, 26 May 2026 00:01:20 +0200 Subject: [PATCH 1/4] optable-targeting update doc --- .../pbs-modules/optable-targeting.md | 117 +++++++++++++----- 1 file changed, 88 insertions(+), 29 deletions(-) diff --git a/prebid-server/pbs-modules/optable-targeting.md b/prebid-server/pbs-modules/optable-targeting.md index 7b66e91077..e787dbebdd 100644 --- a/prebid-server/pbs-modules/optable-targeting.md +++ b/prebid-server/pbs-modules/optable-targeting.md @@ -28,10 +28,11 @@ Targeting API endpoint is configurable per publisher. ### Execution Plan -This module runs at two stages: +This module runs at three stages: -* Processed Auction Request: to enrich `user.eids` and `user.data`. -* Auction Response: to inject ad server targeting. +* Raw Auction Request: initiates a non-blocking Optable API call early in the auction lifecycle. +* Bidder Request: awaits the API response and enriches individual bidder requests with `user.eids` and `user.data`. +* Auction Response: injects ad server targeting. We recommend defining the execution plan in the account config so the module is only invoked for specific accounts. See below for an example. @@ -55,10 +56,8 @@ Note the endpoint contains 2 macros: {{TENANT}} and {ORIGIN} - the values for wh ### Account-Level Config -To start using current module in PBS-Java you have to enable module and add -`optable-targeting-processed-auction-request-hook` and `optable-targeting-auction-response-hook` into hooks execution -plan inside your config file: -Here's a general template for the account config used in PBS-Java: +To start using the module in PBS-Java you have to enable it and add the hooks into the execution plan in your config +file. Here's the recommended account config: ```yaml hooks: @@ -66,6 +65,14 @@ hooks: api-key: key tenant: optable origin: web-sdk-demo + enrichment-percentage: 100 + bidder-enrichment-percentages: + appnexus: 75 + rubicon: 75 + pubmatic: 100 + criteo: 0 + enrich-web: true + enrich-app: true ppid-mapping: { "pubcid.org": "c" } adserver-targeting: true cache: @@ -76,14 +83,27 @@ hooks: "endpoints": { "/openrtb2/auction": { "stages": { - "processed-auction-request": { + "raw-auction-request": { "groups": [ { - "timeout": 100, + "timeout": 50, "hook-sequence": [ { "module-code": "optable-targeting", - "hook-impl-code": "optable-targeting-processed-auction-request-hook" + "hook-impl-code": "optable-targeting-raw-auction-request-hook" + } + ] + } + ] + }, + "bidder-request": { + "groups": [ + { + "timeout": 50, + "hook-sequence": [ + { + "module-code": "optable-targeting", + "hook-impl-code": "optable-targeting-bidder-request-hook" } ] } @@ -108,18 +128,53 @@ hooks: } ``` +### Migrating from legacy configuration + +Previous versions of the module used a `processed-auction-request` hook (alongside the `auction-response` hook) that both +made the API call and enriched the request synchronously in one step, blocking the auction pipeline. The new +configuration replaces it with two hooks: `raw-auction-request` (initiates the API call early) and `bidder-request` +(awaits the result and enriches per-bidder), while the `auction-response` hook remains unchanged. + +If your execution plan contains the following fragment, it should be replaced with the `raw-auction-request` and +`bidder-request` hooks shown above: + +```json +"processed-auction-request": { + "groups": [ + { + "timeout": 600, + "hook-sequence": [ + { + "module-code": "optable-targeting", + "hook-impl-code": "optable-targeting-processed-auction-request-hook" + } + ] + } + ] +} +``` + +The `processed-auction-request` hook is still supported for backwards compatibility. It detects whether the new hooks +(`raw-auction-request` and `bidder-request`) are present in the execution plan. If both are active, it passes through +immediately without blocking the pipeline. If the new hooks are absent, it falls back to the legacy synchronous +behavior. This means the legacy fragment can be kept during migration without negating the latency benefit of the new +configuration. + ### Timeout considerations -The timeout value specified in the execution plan for the `processed-auction-request` hook is very important to be -picked such that the hook has enough time to make a roundtrip to Optable Targeting Edge API over HTTP. +The `bidder-request` hook timeout is used as the timeout budget for the Optable Targeting API call Future that is +initiated in the `raw-auction-request` stage. The API call runs in parallel with other auction processing, so the +effective wait time at the `bidder-request` stage is typically much shorter than the full API roundtrip. The +`raw-auction-request` hook timeout only needs to cover its own lightweight setup (validation, sampling) and can be kept +short. **Note:** Do not confuse hook timeout value with the module timeout parameter which is optional. The hook timeout value would depend on the cloud/region where the PBS instance is hosted and the latency to reach the Optable's servers. This will need to be verified experimentally upon deployment. The timeout value for the `auction-response` can be set to 10 ms - usually it will be sub-millisecond time as there are -no HTTP calls made in this hook - Optable-specific keywords are cached on the `processed-auction-request` stage and -retrieved from the module invocation context later. +no HTTP calls made in this hook - Optable-specific keywords are cached on earlier stages and retrieved from the module +invocation context later. ### Caching @@ -142,21 +197,25 @@ would result in this nesting in the JSON configuration: {: .table .table-bordered .table-striped } -| Param Name | Required | Type | Default value | Description | -|:-------------------|:---------|:--------|:---------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| api-endpoint | yes | string | none | Host-Level. Optable Targeting Edge API endpoint URL. Note it must: include {{TENANT}} and {ORIGIN} macros that are substituted from account-level config values | -| tenant | yes | string | none | Account-Level. Your Optable tenant aka account ID. | -| origin | yes | string | none | Account-Level. Optable data `origin` aka `source`. | -| api-key | no | string | none | Account-Level. If the API is protected with a key - this param needs to be specified to be sent in the auth header | -| ppid-mapping | no | map | none | Account-Level. This specifies PPID source (`user.ext.eids[].source`) to a custom identifier prefix mapping, f.e. `{"example.com" : "c"}`. See the section on ID Mapping below for more detail. | -| adserver-targeting | no | boolean | false | Account-Level. If set to true - will add the Optable-specific adserver targeting keywords into the PBS response for every `seatbid[].bid[].ext.prebid.targeting` | -| timeout | no | integer | false | Account-Level. A soft timeout (in ms) sent as a hint to the Targeting API endpoint to limit the request times to Optable's external tokenizer services | -| id-prefix-order | no | string | none | Account-Level. An optional string of comma separated id prefixes that prioritizes and specifies the order in which ids are provided to Targeting API in a query string. F.e. "c,c1,id5" will guarantee that Targeting API will see id=c:...,c1:...,id5:... if these ids are provided. id-prefixes not mentioned in this list will be added in arbitrary order after the priority prefix ids. This affects Targeting API processing logic | -| cache.enabled | no | string | false | Account-Level. Optionally use [Prebid Cache Storage](https://docs.prebid.org/prebid-server/features/pbs-pbc-storage.html) feature - this significantly reduces the processing time when the Targeting API response has been cached | -| cache.ttlseconds | no | int | 86400 | Account-Level. The TTL in seconds for the Targeting API response to live in cache - by default is equal to 24 hours | -| optable-inserter-eids-merge | no | array of strings | none | Account-Level. List of EID source names for which the module should **merge** the incoming server-side EIDs with those returned by the Targeting API. | -| optable-inserter-eids-replace | no | array of strings | none | Account-Level. List of EID source names for which the module should **replace** the incoming EID entirely with the one from the Targeting API. | -| optable-inserter-eids-ignore | no | array of strings | none | Account-Level. List of EID source names for which the module should **remove** the EID entirely. | +| Param Name | Required | Type | Default value | Description | +|:-------------------------------|:---------|:-----------------|:--------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| api-endpoint | yes | string | none | Host-Level. Optable Targeting Edge API endpoint URL. Note it must include {{TENANT}} and {ORIGIN} macros that are substituted from account-level config values | +| tenant | yes | string | none | Account-Level. Your Optable tenant aka account ID. | +| origin | yes | string | none | Account-Level. Optable data `origin` aka `source`. | +| api-key | no | string | none | Account-Level. If the API is protected with a key - this param needs to be specified to be sent in the auth header | +| ppid-mapping | no | map | none | Account-Level. This specifies PPID source (`user.ext.eids[].source`) to a custom identifier prefix mapping, f.e. `{"example.com" : "c"}`. See the section on ID Mapping below for more detail. | +| adserver-targeting | no | boolean | false | Account-Level. If set to true - will add the Optable-specific adserver targeting keywords into the PBS response for every `seatbid[].bid[].ext.prebid.targeting` | +| timeout | no | integer | none | Account-Level. A soft timeout (in ms) sent as a hint to the Targeting API endpoint to limit the request times to Optable's external tokenizer services | +| id-prefix-order | no | string | none | Account-Level. An optional string of comma separated id prefixes that prioritizes and specifies the order in which ids are provided to Targeting API in a query string. F.e. "c,c1,id5" will guarantee that Targeting API will see id=c:...,c1:...,id5:... if these ids are provided. Id-prefixes not mentioned in this list will be added in arbitrary order after the priority prefix ids. This affects Targeting API processing logic | +| enrichment-percentage | no | integer | 100 | Account-Level. Default percentage (0-100) of bid requests per bidder that will receive enrichment data. Set to 100 to enrich all requests, 0 to disable enrichment by default. | +| bidder-enrichment-percentages | no | map | none | Account-Level. Per-bidder overrides for `enrichment-percentage`. Keys are bidder names, values are percentages (0-100). F.e. `{"appnexus": 75, "criteo": 0}` enriches 75% of appnexus requests and none for criteo. | +| enrich-web | no | boolean | true | Account-Level. Whether to enrich web traffic (requests with a `site` object). | +| enrich-app | no | boolean | true | Account-Level. Whether to enrich app traffic (requests with an `app` object). | +| cache.enabled | no | string | false | Account-Level. Optionally use [Prebid Cache Storage](https://docs.prebid.org/prebid-server/features/pbs-pbc-storage.html) feature - this significantly reduces the processing time when the Targeting API response has been cached | +| cache.ttlseconds | no | int | 86400 | Account-Level. The TTL in seconds for the Targeting API response to live in cache - by default is equal to 24 hours | +| optable-inserter-eids-merge | no | array of strings | none | Account-Level. List of EID source names for which the module should **merge** the incoming server-side EIDs with those returned by the Targeting API. | +| optable-inserter-eids-replace | no | array of strings | none | Account-Level. List of EID source names for which the module should **replace** the incoming EID entirely with the one from the Targeting API. | +| optable-inserter-eids-ignore | no | array of strings | none | Account-Level. List of EID source names for which the module should **remove** the EID entirely. | ## ID Mapping From ad9f9f28ed09989c3d170b003bed6bb5717ea377 Mon Sep 17 00:00:00 2001 From: Eugene Dorfman Date: Tue, 2 Jun 2026 13:57:59 +0200 Subject: [PATCH 2/4] improve doc --- prebid-server/pbs-modules/optable-targeting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prebid-server/pbs-modules/optable-targeting.md b/prebid-server/pbs-modules/optable-targeting.md index e787dbebdd..c7343672eb 100644 --- a/prebid-server/pbs-modules/optable-targeting.md +++ b/prebid-server/pbs-modules/optable-targeting.md @@ -208,7 +208,7 @@ would result in this nesting in the JSON configuration: | timeout | no | integer | none | Account-Level. A soft timeout (in ms) sent as a hint to the Targeting API endpoint to limit the request times to Optable's external tokenizer services | | id-prefix-order | no | string | none | Account-Level. An optional string of comma separated id prefixes that prioritizes and specifies the order in which ids are provided to Targeting API in a query string. F.e. "c,c1,id5" will guarantee that Targeting API will see id=c:...,c1:...,id5:... if these ids are provided. Id-prefixes not mentioned in this list will be added in arbitrary order after the priority prefix ids. This affects Targeting API processing logic | | enrichment-percentage | no | integer | 100 | Account-Level. Default percentage (0-100) of bid requests per bidder that will receive enrichment data. Set to 100 to enrich all requests, 0 to disable enrichment by default. | -| bidder-enrichment-percentages | no | map | none | Account-Level. Per-bidder overrides for `enrichment-percentage`. Keys are bidder names, values are percentages (0-100). F.e. `{"appnexus": 75, "criteo": 0}` enriches 75% of appnexus requests and none for criteo. | +| bidder-enrichment-percentages | no | map | none | Account-Level. Per-bidder overrides for `enrichment-percentage`. Keys are bidder names, values are percentages (0-100). F.e. `{"appnexus": 75, "criteo": 0}` enriches 75% of appnexus requests and none for criteo. Bidders not listed in this map fall back to the default `enrichment-percentage` (100% unless overridden). | | enrich-web | no | boolean | true | Account-Level. Whether to enrich web traffic (requests with a `site` object). | | enrich-app | no | boolean | true | Account-Level. Whether to enrich app traffic (requests with an `app` object). | | cache.enabled | no | string | false | Account-Level. Optionally use [Prebid Cache Storage](https://docs.prebid.org/prebid-server/features/pbs-pbc-storage.html) feature - this significantly reduces the processing time when the Targeting API response has been cached | From 27ab331bb39dc94a7b31252eca8020b100ce39ac Mon Sep 17 00:00:00 2001 From: Eugene Dorfman Date: Fri, 31 Jul 2026 16:09:33 +0200 Subject: [PATCH 3/4] optable-targeting doc: document hid, app bundle/ver and id5_signature Adds the hid-prefixes parameter, a Resolver Hints section explaining how hid differs from id, and a Targeting API Query Attributes section covering bundle, ver and id5_signature in both directions. Also adds id5_signature to the Optable input erasure note. --- .../pbs-modules/optable-targeting.md | 70 ++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/prebid-server/pbs-modules/optable-targeting.md b/prebid-server/pbs-modules/optable-targeting.md index c7343672eb..ac87fb65d0 100644 --- a/prebid-server/pbs-modules/optable-targeting.md +++ b/prebid-server/pbs-modules/optable-targeting.md @@ -207,6 +207,7 @@ would result in this nesting in the JSON configuration: | adserver-targeting | no | boolean | false | Account-Level. If set to true - will add the Optable-specific adserver targeting keywords into the PBS response for every `seatbid[].bid[].ext.prebid.targeting` | | timeout | no | integer | none | Account-Level. A soft timeout (in ms) sent as a hint to the Targeting API endpoint to limit the request times to Optable's external tokenizer services | | id-prefix-order | no | string | none | Account-Level. An optional string of comma separated id prefixes that prioritizes and specifies the order in which ids are provided to Targeting API in a query string. F.e. "c,c1,id5" will guarantee that Targeting API will see id=c:...,c1:...,id5:... if these ids are provided. Id-prefixes not mentioned in this list will be added in arbitrary order after the priority prefix ids. This affects Targeting API processing logic | +| hid-prefixes | no | string | none | Account-Level. An optional string of comma separated id prefixes that should additionally be sent to the Targeting API as resolver hints in `hid=prefix:value` query parameters. See the section on Resolver Hints below for more detail. | | enrichment-percentage | no | integer | 100 | Account-Level. Default percentage (0-100) of bid requests per bidder that will receive enrichment data. Set to 100 to enrich all requests, 0 to disable enrichment by default. | | bidder-enrichment-percentages | no | map | none | Account-Level. Per-bidder overrides for `enrichment-percentage`. Keys are bidder names, values are percentages (0-100). F.e. `{"appnexus": 75, "criteo": 0}` enriches 75% of appnexus requests and none for criteo. Bidders not listed in this map fall back to the default `enrichment-percentage` (100% unless overridden). | | enrich-web | no | boolean | true | Account-Level. Whether to enrich web traffic (requests with a `site` object). | @@ -249,8 +250,8 @@ on identifier types. Targeting API accepts multiple id parameters - and their or ### Optable input erasure -**Note**: `user.ext.optable.email`, `.phone`, `.zip`, `.vid` fields will be removed by the module from the original -OpenRTB request before being sent to bidders. +**Note**: `user.ext.optable.email`, `.phone`, `.zip`, `.vid` and `.id5_signature` fields will be removed by the module +from the original OpenRTB request before being sent to bidders. ### Publisher Provided IDs (PPID) Mapping @@ -273,6 +274,71 @@ ppid-mapping: {"id5-sync.com": "c1"} This will lead to id5 ID supplied as `id=c1:...` to the Targeting API. +### Resolver Hints (`hid`) + +In addition to the regular `id=prefix:value` parameters, the module can forward selected identifiers to the Targeting +API as hint identifiers, using the `hid=prefix:value` query parameter form. + +The two parameters serve different purposes. `id=` values are used for the Optable identity graph lookup, while `hid=` +values are passed on to the external resolvers, such as ID5, that the Targeting API calls on your behalf. An identifier +that a resolver needs therefore has to be listed in `hid-prefixes` even when it is already being sent as an `id=` +parameter; sending it only as `id=` will not make it available to the resolvers. + +The set of prefixes to send as hints is configured with `hid-prefixes`, a comma-separated list of prefix names from the +ID Mapping table above. Whitespace around the entries is ignored, and prefixes that are not present on the request are +skipped: + +```yaml +hid-prefixes: "c, i6" +``` + +Each hint is sent as its own repeated `hid=` parameter rather than as a single comma-separated value, so the +configuration above produces `&hid=c:...&hid=i6:...`. The IPv6 address is a special case: it is never sent as an `id=` +parameter, as noted in the table above, so `i6` appears only as a hint. + +## Targeting API Query Attributes + +In addition to the identifier parameters, the module forwards the following attributes as query string parameters to +the Targeting API: + +{: .table .table-bordered .table-striped } + +| Attribute | Source | +|:----------------|:---------------------------------------------------------------------------------------------------------------------| +| `gdpr` | `1` if GDPR applies to the request, `0` otherwise. | +| `gdpr_consent` | TCF consent string, sent when available and the consent is valid. | +| `gpp` | GPP string, sent when available in the resolved GPP context. | +| `gpp_sid` | Comma-separated list of active GPP section IDs, limited to the first two, sent when the set is non-empty. | +| `timeout` | Soft timeout hint in ms, suffixed with `ms`, sent when the account-level `timeout` parameter is configured. | +| `osdk` | Always set to `prebid-server`, identifying the caller. | +| `bundle` | App bundle identifier, URL-encoded. Sent when the incoming request has an `app` object and `app.bundle` is non-empty. | +| `ver` | App version, URL-encoded. Sent only when `bundle` is non-empty and `app.ver` is present and non-empty. | +| `id5_signature` | ID5 signature, URL-encoded. Sent when `user.ext.optable.id5_signature` is present in the incoming request. | + +### App bundle and version + +For app traffic, requests carrying an `app` object, the module forwards the application's bundle identifier as the +`bundle=` query parameter and, when available, its version as `ver=`. Both values are URL-encoded. The `ver` parameter +is only sent alongside a non-empty `bundle`, so a request with a version but no bundle produces neither parameter. + +### ID5 signature + +The ID5 signature is propagated in two directions: + +1. **Request-side.** When the incoming OpenRTB request carries `user.ext.optable.id5_signature`, that value is sent to + the Targeting API as the `id5_signature=` query parameter. Blank values are not sent. +2. **Response-side.** When the Targeting API response carries an ID5 signature, the module resolves it through the + matching Optable-inserted EID and writes it into the bid response at + `ext.prebid.passthrough.optable.id5_signature`, where the client can read it and send it back up on the next + request. + +The response-side signature is written whenever the module enriched the request, and is independent of +`adserver-targeting`: that parameter controls the ad server targeting keywords, while the signature is a separate +value that is only stored on the client for the next Targeting API call. Conversely, if nothing was enriched there is +no signature to return and the module leaves the bid response untouched. + +The `id5_signature` field is also part of the Optable input erasure described above. + ## Analytics Tags The following 2 activities are recorded by the module in the corresponding ATags on the corresponding stages: From 04826f1179027f1473083b8f5e263a1a1c250904 Mon Sep 17 00:00:00 2001 From: Eugene Dorfman Date: Fri, 14 Aug 2026 13:05:37 +0200 Subject: [PATCH 4/4] optable-targeting doc clarifications --- .../pbs-modules/optable-targeting.md | 116 ++++++++++++++---- 1 file changed, 92 insertions(+), 24 deletions(-) diff --git a/prebid-server/pbs-modules/optable-targeting.md b/prebid-server/pbs-modules/optable-targeting.md index ac87fb65d0..9bc12b46fc 100644 --- a/prebid-server/pbs-modules/optable-targeting.md +++ b/prebid-server/pbs-modules/optable-targeting.md @@ -61,24 +61,25 @@ file. Here's the recommended account config: ```yaml hooks: - optable-targeting: - api-key: key - tenant: optable - origin: web-sdk-demo - enrichment-percentage: 100 - bidder-enrichment-percentages: - appnexus: 75 - rubicon: 75 - pubmatic: 100 - criteo: 0 - enrich-web: true - enrich-app: true - ppid-mapping: { "pubcid.org": "c" } - adserver-targeting: true - cache: - enabled: false - ttlseconds: 86400 - host-execution-plan: > + modules: + optable-targeting: + api-key: key + tenant: optable + origin: web-sdk-demo + enrichment-percentage: 100 + bidder-enrichment-percentages: + appnexus: 75 + rubicon: 75 + pubmatic: 100 + criteo: 0 + enrich-web: true + enrich-app: true + ppid-mapping: { "pubcid.org": "c" } + adserver-targeting: true + cache: + enabled: false + ttlseconds: 86400 + execution-plan: > { "endpoints": { "/openrtb2/auction": { @@ -160,6 +161,11 @@ immediately without blocking the pipeline. If the new hooks are absent, it falls behavior. This means the legacy fragment can be kept during migration without negating the latency benefit of the new configuration. +**Note:** `enrichment-percentage` and `bidder-enrichment-percentages` only take effect on the new configuration. The +legacy `processed-auction-request` hook enriches the whole bid request before it is split per bidder, so it cannot +sample per bidder: on the legacy path every bidder receives the enrichment, including bidders configured at `0`. If you +rely on per-bidder sampling, migrate to the `raw-auction-request` and `bidder-request` hooks. + ### Timeout considerations The `bidder-request` hook timeout is used as the timeout budget for the Optable Targeting API call Future that is @@ -341,14 +347,76 @@ The `id5_signature` field is also part of the Optable input erasure described ab ## Analytics Tags -The following 2 activities are recorded by the module in the corresponding ATags on the corresponding stages: +The following activities are recorded by the module in the corresponding ATags on the corresponding stages: + +* `optable-enrich-bidder-request` - recorded on the `bidder-request` stage, once per bidder. +* `optable-enrich-response` - recorded on the `auction-response` stage. +* `optable-enrich-request` - recorded on the `processed-auction-request` stage, on the legacy configuration only. + +The `status` is either `success` or `failure`. Where it is `failure` a `results[0].value.reason` is provided. +For the `optable-enrich-request` activity the `execution-time` value is logged. + +The `optable-enrich-bidder-request` activity is emitted separately for each bidder that the module considered, and +names that bidder in `results[0].appliedto.bidders`. Its `results[0].values` carries an `outcome` alongside the +`execution-time` (in ms, measured from the moment the Targeting API call was initiated in the `raw-auction-request` +stage): + +{: .table .table-bordered .table-striped } + +| `outcome` | Meaning | +|:-----------|:--------------------------------------------------------------------------------------------| +| `enriched` | The Targeting API returned data and the bidder request was enriched. `status` is `success`. | +| `no-data` | The call succeeded but returned nothing to enrich with. `status` is `failure`. | +| `timeout` | The call did not complete within the `bidder-request` hook timeout. `status` is `failure`. | +| `error` | The call failed. `status` is `failure`. | + +A bidder that was sampled out by `bidder-enrichment-percentages` produces no activity at all, so absence is expected +rather than an error. -* `optable-enrich-request` -* `optable-enrich-response` +Example, showing a bidder enriched on the new configuration: + +```json +{ + "analytics": + { + "tags": + [ + { + "stage": "bidder-request", + "module": "optable-targeting", + "analyticstags": + { + "activities": + [ + { + "name": "optable-enrich-bidder-request", + "status": "success", + "results": + [ + { + "values": + { + "outcome": "enriched", + "execution-time": "275" + }, + "appliedto": + { + "bidders": ["appnexus"], + "request": true + } + } + ] + } + ] + } + } + ] + } +} +``` -The `status` is either `success` or `failure`. Where it is `failure` a `results[0].value.reason` is provided. -For the `optable-enrich-request` activity the `execution-time` value is logged. -Example: +On the legacy configuration the `optable-enrich-request` activity is recorded once for the whole request instead. The +`auction-response` stage tag below is the same on both configurations: ```json {