# Extra Feature module

Should you require a specific configuration for your tagId, you can utilize the Extra Feature module.

The feature is accessible at the tagID level via the "Extra Feature" box. Once selected, you can input your code.

The following options are available:

```typescript
export type ExtraFeatures = {
  auctionForcedPrice?: {
    cpm: number,
    currency: 'EUR' | 'USD',
  },
  auctionFixedPrice?: {
    cpm: number
    currency: 'EUR' | 'USD',
  },
  sspFixedPrice?: {
    [K in SspList]?: {
      cpm: number
      currency: 'EUR' | 'USD',
    }
  },
  formatRestriction?: {
    [K in SspList]?: Mediatype[]
  },
  appnexusPmtRule?: boolean,
  stailaPmtRule?: boolean,
  sspAdjustment?: {
    [K in SspList]?: number
  },
  dealidAdjustment?: Record<string, number>,
  dealidFixedPrice?: Record<string, {
    cpm: number,
    currency: 'EUR' | 'USD',
  }>,
  videoPlcmtOverride?: number,
  sspFloorPrice?: {
    [K in SspList]?: {
      cpm: number,
      currency: 'EUR' | 'USD',
    }
  },
  countryFloorPrice?: Record<string, {
    cpm: number,
    currency: 'EUR' | 'USD',
  }>,
  sspCountryWhitelist?: {
    [K in SspList]?: string[]
  },
  sspCountryBlacklist?: {
    [K in SspList]?: string[]
  },
  sspDomainWhitelist?: {
    [K in SspList]?: string[]
  },
  sspDomainBlacklist?: {
    [K in SspList]?: string[]
  },
  schain?: {
    [K in SspList]?: { asi: string, sid: string }
  },
};
```

***

## Feature Descriptions

### Price Adjustment Features

#### auctionForcedPrice

**Purpose:** Forces a specific CPM price for all winning bids in the auction, regardless of the actual bid price.

**Behavior:**

* Overrides ALL other price adjustments (account, site, SSP adjustments)
* The final price is set to the specified CPM value, converted to the bid currency
* Bids are always eligible after adjustment (no minimum threshold check)
* Has the highest priority among all price adjustment features

**Example:**

```json
{"auctionForcedPrice":{"cpm":100,"currency":"USD"}}
```

This sets all winning bids to $100 CPM regardless of the original bid price.

***

#### auctionFixedPrice

**Purpose:** Sets a fixed ceiling price for all winning bids in the auction.

**Behavior:**

* Overrides other price adjustments (account, site, SSP adjustments)
* The final price is set to the specified CPM value
* **Bid eligibility check:** If the adjustment would increase the bid price (i.e., original bid is lower than fixed price), the bid becomes ineligible
* Lower priority than `auctionForcedPrice` and `dealidFixedPrice`

**Example:**

```json
{"auctionFixedPrice":{"cpm":5,"currency":"EUR"}}
```

All winning bids will be priced at €5 CPM. Bids originally below €5 will be rejected.

***

#### sspFixedPrice

**Purpose:** Sets a fixed price for bids from a specific SSP partner.

**Behavior:**

* Applies on top of other adjustments (account, site, SSP, stored request adjustments)
* The fixed price is multiplied with existing adjustments
* **Bid eligibility check:** If the final adjusted price is lower than the SSP fixed price, the bid is rejected
* Only affects the specified SSP partner(s)
* Lower priority than `auctionForcedPrice`, `auctionFixedPrice`, and `dealidFixedPrice`

**Example:**

```json
{"sspFixedPrice":{"criteo":{"cpm":3,"currency":"EUR"}}}
```

Sets a €3 CPM fixed price specifically for Criteo bids.

***

#### sspAdjustment

**Purpose:** Applies a multiplier adjustment to bids from a specific SSP partner.

**Behavior:**

* The bid price is multiplied by the adjustment value
* Value of `0.8` means the bid is reduced by 20%
* Value of `1.2` means the bid is increased by 20%
* Applied in combination with account-level and site-level CPM adjustments

**Example:**

```json
{"sspAdjustment":{"criteo":0.8}}
```

Reduces all Criteo bids by 20%.

***

#### dealidAdjustment

**Purpose:** Applies a multiplier adjustment to bids with a specific deal ID.

**Behavior:**

* When a bid contains a matching deal ID, the adjustment multiplier is applied
* Works similarly to `sspAdjustment` but targets specific deals
* Value of `0.9` means the bid is reduced by 10%

**Example:**

```json
{"dealidAdjustment":{"testdealid":0.9}}
```

Reduces bids with deal ID "testdealid" by 10%.

***

#### dealidFixedPrice

**Purpose:** Sets a fixed price for bids with a specific deal ID.

**Behavior:**

* Overrides other price adjustments when the bid contains a matching deal ID
* **Bid eligibility check:** If the fixed price would increase the bid (original bid is lower), the bid becomes ineligible
* Higher priority than `auctionFixedPrice` but lower than `auctionForcedPrice`

**Example:**

```json
{"dealidFixedPrice":{"testdealid":{"cpm":3,"currency":"EUR"}}}
```

Sets a €3 CPM fixed price for bids with deal ID "testdealid".

***

### Floor Price Features

#### sspFloorPrice

**Purpose:** Sets a minimum bid floor price for a specific SSP partner.

**Behavior:**

* Sets the `bidfloor` value sent in the OpenRTB request to the specified SSP
* The floor price is converted to USD before being sent
* Takes priority over the default position bidfloor
* Only affects outgoing requests to the specified SSP(s)

**Example:**

```json
{"sspFloorPrice":{"criteo":{"cpm":3,"currency":"EUR"}}}
```

Sets a €3 floor price for requests sent to Criteo.

***

#### countryFloorPrice

**Purpose:** Sets a minimum bid floor price based on the user's country.

**Behavior:**

* Uses the user's geo-located country (ISO 3166-1 alpha-2 code)
* If the user is in a matching country, the position's bidfloor is overridden
* The floor price is converted to USD
* Applies to all SSPs for that position

**Example:**

```json
{"countryFloorPrice":{"FR":{"cpm":3,"currency":"EUR"},"DE":{"cpm":2.5,"currency":"EUR"}}}
```

Sets a €3 floor for users in France and €2.50 for users in Germany.

***

### SSP Restriction Features

#### formatRestriction

**Purpose:** Restricts which media types an SSP can bid on for this position.

**Behavior:**

* If the position's mediatype is NOT in the allowed list, the SSP is blocked with status `FORMATBLOCKED`
* Available mediatypes: `"banner"`, `"video"`, `"audio"`, `"native"`
* If no restriction is defined for an SSP, all formats are allowed

**Example:**

```json
{"formatRestriction":{"appnexus":["video","audio"]}}
```

AppNexus will only be called for video and audio positions. Banner and native requests will be blocked.

***

#### sspCountryWhitelist

**Purpose:** Restricts an SSP to only receive requests from users in specific countries.

**Behavior:**

* Uses the user's geo-located country (ISO 3166-1 alpha-2 code)
* If the user's country is NOT in the whitelist, the SSP is blocked with status `GEOBLOCKED`
* Country codes must be uppercase (e.g., "FR", "US", "DE")
* If the whitelist is empty or not defined, no country restriction is applied

**Example:**

```json
{"sspCountryWhitelist":{"criteo":["FR","ES","DE"]}}
```

Criteo will only be called for users in France, Spain, or Germany.

***

#### sspCountryBlacklist

**Purpose:** Blocks an SSP from receiving requests from users in specific countries.

**Behavior:**

* Uses the user's geo-located country (ISO 3166-1 alpha-2 code)
* If the user's country IS in the blacklist, the SSP is blocked with status `GEOBLOCKED`
* Country codes must be uppercase (e.g., "FR", "US", "DE")
* If the blacklist is empty or not defined, no country restriction is applied

**Example:**

```json
{"sspCountryBlacklist":{"criteo":["RU","CN"]}}
```

Criteo will be blocked for users in Russia or China.

***

#### sspDomainWhitelist

**Purpose:** Restricts an SSP to only receive requests from specific domains.

**Behavior:**

* If the request domain is NOT in the whitelist, the SSP is blocked with status `DOMAINBLOCKED`
* Supports wildcard matching with `*.` prefix for subdomains
* Domain matching ignores `www.` prefix (e.g., "example.com" matches "[www.example.com](http://www.example.com)")
* Wildcard example: `"*.example.com"` matches `"sub.example.com"` and `"example.com"`

**Example:**

```json
{"sspDomainWhitelist":{"criteo":["example.com","*.partner.net"]}}
```

Criteo will only be called for requests from example.com or any subdomain of partner.net.

***

#### sspDomainBlacklist

**Purpose:** Blocks an SSP from receiving requests from specific domains.

**Behavior:**

* If the request domain IS in the blacklist, the SSP is blocked with status `DOMAINBLOCKED`
* Supports wildcard matching with `*.` prefix for subdomains
* Domain matching ignores `www.` prefix
* Wildcard example: `"*.blocked.com"` blocks `"sub.blocked.com"` and `"blocked.com"`

**Example:**

```json
{"sspDomainBlacklist":{"criteo":["competitor.com","*.spam.net"]}}
```

Criteo will be blocked for requests from competitor.com or any subdomain of spam.net.

***

### Partner-Specific Features

#### appnexusPmtRule / stailaPmtRule

**Purpose:** Enables Publisher-Managed Targeting (PMT) rules for AppNexus/Xandr requests.

**Behavior:**

* When set to `true`, the `use_pmt_rule: true` flag is added to the AppNexus bid request
* This enables AppNexus PMT rules configured in the AppNexus console
* Both `appnexusPmtRule` and `stailaPmtRule` have the same effect (legacy naming)
* Either flag being `true` will enable the PMT rule

**Example:**

```json
{"appnexusPmtRule":true}
```

or

```json
{"stailaPmtRule":true}
```

***

#### videoPlcmtOverride

**Purpose:** Overrides the video placement type (plcmt) value in OpenRTB video requests.

**Behavior:**

* Sets the `video.plcmt` field in the OpenRTB bid request
* Valid values according to OpenRTB 2.6:
  * `1` = In-Stream (Pre/Mid/Post-roll)
  * `2` = Accompanying Content
  * `3` = Interstitial
  * `4` = No Content/Standalone

**Example:**

```json
{"videoPlcmtOverride":1}
```

Forces all video requests for this position to be marked as in-stream pre/mid/post-roll.

***

### Supply Chain Features

#### schain

**Purpose:** Adds a per-SSP supply chain (schain) node to the bid request at the tagId level.

**Behavior:**

* Appends an additional schain node to the supply chain sent to the specified SSP(s)
* The node is added **after** the site-level schain node (most granular last)
* **Independent of site-level schain exclusion** — even if an SSP is excluded from the site schain, the extraFeatures schain node will still be included
* Duplicate nodes are automatically deduplicated by `asi`
* The `hp` (hosted/published) field is automatically set to `1`

**Example:**

```json
{"schain":{"appnexus":{"asi":"publisher.com","sid":"12345"}}}
```

This adds a supply chain node with `asi: "publisher.com"` and `sid: "12345"` to all bid requests sent to AppNexus for this tagId.

**Multiple SSPs:**

```json
{"schain":{"appnexus":{"asi":"publisher.com","sid":"12345"},"criteo":{"asi":"reseller.com","sid":"67890"}}}
```

Different schain nodes can be configured per SSP partner.

***

## Priority Order

When multiple price adjustment features are configured, they are evaluated in this priority order (highest first):

1. **auctionForcedPrice** - Always sets the exact price, overrides everything
2. **dealidFixedPrice** - Applied if bid has matching deal ID
3. **auctionFixedPrice** - Applied if no forced price or deal fixed price
4. **sspFixedPrice** - Applied in combination with other adjustments
5. **Basic adjustments** (account, site, SSP, stored request, deal adjustments) - Applied multiplicatively

***

## Examples

### Combining Multiple Features

You can combine multiple features in a single JSON configuration:

```json
{
  "sspFloorPrice": {"criteo": {"cpm": 2, "currency": "EUR"}},
  "sspCountryWhitelist": {"criteo": ["FR", "DE", "ES"]},
  "sspAdjustment": {"appnexus": 0.9}
}
```

This configuration:

* Sets a €2 floor price for Criteo
* Only calls Criteo for users in France, Germany, or Spain
* Reduces all AppNexus bids by 10%

### Complex Geo-Targeting Setup

```json
{
  "countryFloorPrice": {
    "US": {"cpm": 5, "currency": "USD"},
    "GB": {"cpm": 3, "currency": "EUR"},
    "FR": {"cpm": 2.5, "currency": "EUR"}
  },
  "sspCountryBlacklist": {
    "rubicon": ["CN", "RU"],
    "appnexus": ["IN"]
  }
}
```
