Repository: prebid/prebid-server
Pull request #3411 (2024-01-17 22:28:17)

Optimize GZIP Compression
By utilizing Golang Sync Pools, I was able to optimize the process of GZIP Compression within PBS.

Benchmark tests are added in this PR to test the difference between how GZIP used to be compressed, and the updated version.

Here are the results (After Latest Refactor):

Non-Optimized:
**BenchmarkCompressToGZIPNotOptimized-8**   	   11616	    100384 ns/op	  813992 B/op	      19 allocs/op

Optimized:
**BenchmarkCompressToGZIPOptimized-8**  	   84913	     12657 ns/op	     128 B/op	       3 allocs/op

From left to right, each value represents the following: Operations per Second, Average Time per Operation, Bytes Allocated per Operation, and Allocations per Operations

The optimized version shows significant improvements across the board

SyntaxNode: > Non-Optimized:
BenchmarkCompressToGZIPNotOptimized-8 12116 101629 ns/op 807642 B/op 23 allocs/op
> 
> Optimized:
BenchmarkCompressToGZIPOptimized-8 75381 15264 ns/op 802 B/op 9 allocs/op

That's a significant decrease of allocated memory, 99.9%.

Patch:
diff --git a/.github/workflows/adapter-code-coverage.yml b/.github/workflows/adapter-code-coverage.yml
index b4c3f074..b5fbd557 100644
--- a/.github/workflows/adapter-code-coverage.yml
+++ b/.github/workflows/adapter-code-coverage.yml
@@ -36,8 +36,9 @@ jobs:
               return ""
             }
             const helper = utils.diffHelper({github, context})
-            const files = await helper.getDirectories(directoryExtractor)
-            return files.length == 0 ? "" : JSON.stringify(files);
+            const directories = await helper.getDirectories(directoryExtractor)
+            // run coverage for maximum of 2 directories
+            return (directories.length == 0 || directories.length > 2) ? "" : JSON.stringify(directories)
 
       - name: Run coverage tests
         id: run_coverage
diff --git a/README.md b/README.md
index cb64ed9a..77443318 100644
--- a/README.md
+++ b/README.md
@@ -2,78 +2,106 @@
 [![Go Report Card](https://goreportcard.com/badge/github.com/prebid/prebid-server?style=flat-square)](https://goreportcard.com/report/github.com/prebid/prebid-server)
 ![Go Version](https://img.shields.io/github/go-mod/go-version/prebid/prebid-server?style=flat-square)
 
-# Prebid Server
+<br />
+<br />
+<p align="center"><img alt="Prebid Server Logo" src="/static/pbs-logo.svg" style="width:80%; max-width:600px;"></p>
+<br />
 
-Prebid Server is an open source implementation of Server-Side Header Bidding.
-It is managed by [Prebid.org](https://prebid.org/about/),
-and upholds the principles from the [Prebid Code of Conduct](https://prebid.org/code-of-conduct/).
+<a href="https://prebid.org/product-suite/prebid-server/">Prebid Server</a> is an open-source solution for running real-time advertising auctions in the cloud. This project is part of the <a href="https://prebid.org/">Prebid</a> ecosystem, seamlessly integrating with  <a href="https://prebid.org/product-suite/prebidjs/">Prebid.js</a> and the <a href="https://prebid.org/product-suite/prebid-mobile/">Prebid Mobile SDKs</a> to deliver world-class header bidding for any ad format and for any type of digital media.
 
-This project does not support the same set of Bidders as Prebid.js, although there is overlap.
-The current set can be found in the [adapters](./adapters) package. If you don't see the one you want, feel free to [contribute it](https://docs.prebid.org/prebid-server/developers/add-new-bidder-go.html).
+## Getting Started
+- [What is Prebid Server](https://docs.prebid.org/prebid-server/overview/prebid-server-overview.html)
+- [Intro to Header Bidding](https://docs.prebid.org/overview/intro-to-header-bidding.html)
+- [Header Bidding with Prebid](https://docs.prebid.org/overview/intro.html#header-bidding-with-prebid)
+- [API Endpoints](https://docs.prebid.org/prebid-server/endpoints/pbs-endpoint-overview.html)
+  
+## Configuring
 
-For more information, see:
+When hosting Prebid Server or developing locally, **you must set a default GDPR value**. This configuration determines whether GDPR is enabled when no regulatory signal is available in the request, where a value of `"0"` disables it by default and a value of `"1"` enables it. This is required as there is no consensus on a good default.
 
-- [What is Prebid?](https://docs.prebid.org/overview/intro.html)
-- [Prebid Server Overview](https://docs.prebid.org/prebid-server/overview/prebid-server-overview.html)
-- [Current Bidders](https://docs.prebid.org/dev-docs/pbs-bidders.html)
+Refer to the [configuration guide](docs/developers/configuration.md) for additional information and a list of available configuration options.
 
-Please consider [registering your Prebid Server](https://docs.prebid.org/prebid-server/hosting/pbs-hosting.html#optional-registration) to get on the mailing list for updates, etc.
+## Hosting Prebid Server
+> [!NOTE]
+> Please consider [registering as a Prebid Server host](https://docs.prebid.org/prebid-server/hosting/pbs-hosting.html#optional-registration) to join the mailing list for updates and feedback.
 
-## Installation
+The quickest way to host Prebid Server is to deploy our [official Docker image](https://hub.docker.com/r/prebid/prebid-server). If you're hosting the container with Kubernetes, you can configure Prebid Server with environment variables [using a pod file](https://kubernetes.io/docs/tasks/inject-data-application/define-interdependent-environment-variables/) or [using a config map](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#configure-all-key-value-pairs-in-a-configmap-as-container-environment-variables). Alternatively, you can use a configuration file [embedded in a config map](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#populate-a-volume-with-data-stored-in-a-configmap) which Prebid Server will read from at the path `/etc/config`.
 
-First install [Go](https://golang.org/doc/install) version 1.19 or newer.
+For deploying a fork, you can create a custom Docker container using the command:
+``` bash
+docker build --platform linux/amd64 -t prebid-server .
+```
+or compile a standalone binary using the command:
+``` bash
+go build .
+```
+Ensure that you deploy the `/static` directory, as Prebid Server requires those files at startup.
 
-Note that prebid-server is using [Go modules](https://blog.golang.org/using-go-modules).
-We officially support the most recent two major versions of the Go runtime. However, if you'd like to use a version <1.13 and are inside GOPATH `GO111MODULE` needs to be set to `GO111MODULE=on`.
+## Developing
 
-Download and prepare Prebid Server:
+Prebid Server requires [Go](https://go.dev) version 1.19 or newer. You can develop on any operating system that Go supports; however, please note that our helper scripts are written in bash.
 
-```bash
-cd YOUR_DIRECTORY
-git clone https://github.com/prebid/prebid-server src/github.com/prebid/prebid-server
-cd src/github.com/prebid/prebid-server
+1. Clone The Repository
+``` bash
+git clone git@github.com:prebid/prebid-server.git
+cd prebid-server
 ```
 
-Run the automated tests:
+3. Download Dependencies
+``` bash
+go mod download
+```
 
+3. Verify Tests Pass
 ```bash
 ./validate.sh
 ```
 
-Or just run the server locally:
-
+4. Run The Server
 ```bash
-go build .
-./prebid-server
+go run .
 ```
 
-Run format:
-```
-make format
-```
-or
-```bash
-./scripts/format.sh -f true
-```
+By default, Prebid Server will attach to port 8000. To confirm the server is running, visit `http://localhost:8000/` in your web browser.
+
+### Code Style
+To maintain consistency in the project's code, please:
+ 
+- Follow the recommendations set by [Effective Go](https://go.dev/doc/effective_go). This article provides a comprehensive guide on how to write idiomatic Go code, covering topics such as naming and formatting. Many IDEs will automatically format your code upon save. If you need to manaully format your code, either run the bash script or execute the make step:
+   ```
+   ./scripts/format.sh -f true
+   ```
+   ```
+   make format
+   ```
+
+- Prefer small functions with descriptive names instead of complex functions with comments. This approach helps make the code more readable, maintainable, and testable.
+
+- Do not discard errors. You should implement appropriate error handling, such as gracefully falling back to a default behavior or bubbling up an error.
+   
+### IDE Recommendation
 
-Load the landing page in your browser at `http://localhost:8000/`.
-For the full API reference, see [the endpoint documentation](https://docs.prebid.org/prebid-server/endpoints/pbs-endpoint-overview.html)
+An option for developing Prebid Server in a reproducible environment isolated from your host OS is using Visual Studio Code with [Remote Container Setup](devcontainer.md). This is a recommendation, not a requirement. This approach is especially useful if you are developing on Windows, since the Remote Container runs within WSL providing you with the capability to execute bash scripts.
 
-## Go Modules
+## Importing Prebid Server
 
-The packages within this repository are intended to be used as part of the Prebid Server compiled binary. If you
-choose to import Prebid Server packages in other projects, please understand we make no promises on the stability
-of exported types.
+Prebid Server is not currently intended to be imported by other projects. Go Modules is used to manage dependencies, which also makes it possible to import Prebid Server packages. This is not supported. We offer no guarantees regarding the stability of packages and do not adhere to semantic versioning guidelines.
 
 ## Contributing
+> [!IMPORTANT]
+> All contributions must follow the [Prebid Code of Conduct](https://prebid.org/code-of-conduct/) and the [Prebid Module Rules](https://docs.prebid.org/dev-docs/module-rules.html).
 
-Want to [add an adapter](https://docs.prebid.org/prebid-server/developers/add-new-bidder-go.html)? Found a bug? Great!
+### Bid Adapter
+Bid Adapters transform OpenRTB requests and responses for communicating with a bidding server. This may be as simple as a passthrough or as complex as mapping to a custom data model. We invite you to contribute an adapter for your company. Consult our guide on [building a bid adapter](https://docs.prebid.org/prebid-server/developers/add-new-bidder-go.html) for more information.
 
-Report bugs, request features, and suggest improvements [on Github](https://github.com/prebid/prebid-server/issues).
+### Analytics Module
+Analytics Modules enable business intelligence tools to collect data from Prebid Server to provide publishers and hosts with valuable insights into their header bidding traffic. We welcome you to contribute a module for your platform. Refer to our guide on [building an analytics module](https://docs.prebid.org/prebid-server/developers/pbs-build-an-analytics-adapter.html) for further information.
 
-Or better yet, [open a pull request](https://github.com/prebid/prebid-server/compare) with the changes you'd like to see.
+### Auction Module
+Auction Modules allow hosts to extend the behavior of Prebid Server at specfic spots in the auction pipeline using existing modules or by developing custom functionality. Auction Modules may provide creative validation, traffic optimization, and real time data services amoung many other potential uses. We welcome vendors and community members to contribute modules that publishers and hosts may find useful. Consult our guide on [building an auction module](https://docs.prebid.org/prebid-server/developers/add-a-module.html) for more information.
 
-## IDE Recommendations
+### Feature
+We welcome everyone to contribute to this project by implementing a specification or by proposing a new feature. Please review the [prioritized project board](https://github.com/orgs/prebid/projects/4), where you can select an issue labeled "Ready For Dev". To avoid redundant effort, kindly leave a comment on the issue stating your intention to take it on. To propose a feature, [open a new issue](https://github.com/prebid/prebid-server/issues/new/choose) with as much detail as possible for consideration by the Prebid Server Committee.
 
-The quickest way to start developing Prebid Server in a reproducible environment isolated from your host OS
-is by using Visual Studio Code with [Remote Container Setup](devcontainer.md).
+### Bug Fix
+Bug reports may be submitted by [opening a new issue](https://github.com/prebid/prebid-server/issues/new/choose) and describing the error in detail with the steps to reproduce and example data. A member of the core development team will validate the bug and discuss next steps. You're encouraged to open an exploratory draft pull request to either demonstrate the bug by adding a test or offering a potential fix.
diff --git a/adapters/adkernel/adkernel.go b/adapters/adkernel/adkernel.go
index e8ccc360..11ab006d 100644
--- a/adapters/adkernel/adkernel.go
+++ b/adapters/adkernel/adkernel.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"net/http"
 	"strconv"
+	"strings"
 	"text/template"
 
 	"github.com/prebid/openrtb/v19/openrtb2"
@@ -15,6 +16,14 @@ import (
 	"github.com/prebid/prebid-server/v2/openrtb_ext"
 )
 
+const (
+	mf_suffix        = "__mf"
+	mf_suffix_banner = "b" + mf_suffix
+	mf_suffix_video  = "v" + mf_suffix
+	mf_suffix_audio  = "a" + mf_suffix
+	mf_suffix_native = "n" + mf_suffix
+)
+
 type adkernelAdapter struct {
 	EndpointTemplate *template.Template
 }
@@ -78,9 +87,6 @@ func validateImpression(imp *openrtb2.Imp, impExt *openrtb_ext.ExtImpAdkernel) e
 	if impExt.ZoneId < 1 {
 		return newBadInputError(fmt.Sprintf("Invalid zoneId value: %d. Ignoring imp id=%s", impExt.ZoneId, imp.ID))
 	}
-	if imp.Video == nil && imp.Banner == nil && imp.Native == nil {
-		return newBadInputError(fmt.Sprintf("Invalid imp id=%s. Expected imp.banner / imp.video / imp.native", imp.ID))
-	}
 	return nil
 }
 
@@ -90,54 +96,75 @@ func dispatchImpressions(imps []openrtb2.Imp, impsExt []openrtb_ext.ExtImpAdkern
 	errors := make([]error, 0)
 	for idx := range imps {
 		imp := imps[idx]
-		err := compatImpression(&imp)
-		if err != nil {
-			errors = append(errors, err)
-			continue
-		}
+		imp.Ext = nil
 		impExt := impsExt[idx]
 		if res[impExt] == nil {
 			res[impExt] = make([]openrtb2.Imp, 0)
 		}
-		res[impExt] = append(res[impExt], imp)
+		if isMultiFormatImp(&imp) {
+			splImps := splitMultiFormatImp(&imp)
+			res[impExt] = append(res[impExt], splImps...)
+		} else {
+			res[impExt] = append(res[impExt], imp)
+		}
 	}
 	return res, errors
 }
 
-// Alter impression info to comply with adkernel platform requirements
-func compatImpression(imp *openrtb2.Imp) error {
-	imp.Ext = nil //do not forward ext to adkernel platform
-	if imp.Banner != nil {
-		return compatBannerImpression(imp)
-	}
+func isMultiFormatImp(imp *openrtb2.Imp) bool {
+	count := 0
 	if imp.Video != nil {
-		return compatVideoImpression(imp)
+		count++
+	}
+	if imp.Audio != nil {
+		count++
+	}
+	if imp.Banner != nil {
+		count++
 	}
 	if imp.Native != nil {
-		return compatNativeImpression(imp)
+		count++
 	}
-	return newBadInputError("Invalid impression")
+	return count > 1
 }
 
-func compatBannerImpression(imp *openrtb2.Imp) error {
-	imp.Audio = nil
-	imp.Video = nil
-	imp.Native = nil
-	return nil
-}
+func splitMultiFormatImp(imp *openrtb2.Imp) []openrtb2.Imp {
+	splitImps := make([]openrtb2.Imp, 0, 4)
+	if imp.Banner != nil {
+		impCopy := *imp
+		impCopy.Video = nil
+		impCopy.Native = nil
+		impCopy.Audio = nil
+		impCopy.ID += mf_suffix_banner
+		splitImps = append(splitImps, impCopy)
+	}
+	if imp.Video != nil {
+		impCopy := *imp
+		impCopy.Banner = nil
+		impCopy.Native = nil
+		impCopy.Audio = nil
+		impCopy.ID += mf_suffix_video
+		splitImps = append(splitImps, impCopy)
+	}
 
-func compatVideoImpression(imp *openrtb2.Imp) error {
-	imp.Banner = nil
-	imp.Audio = nil
-	imp.Native = nil
-	return nil
-}
+	if imp.Native != nil {
+		impCopy := *imp
+		impCopy.Banner = nil
+		impCopy.Video = nil
+		impCopy.Audio = nil
+		impCopy.ID += mf_suffix_native
+		splitImps = append(splitImps, impCopy)
+	}
 
-func compatNativeImpression(imp *openrtb2.Imp) error {
-	imp.Banner = nil
-	imp.Audio = nil
-	imp.Video = nil
-	return nil
+	if imp.Audio != nil {
+		impCopy := *imp
+		impCopy.Banner = nil
+		impCopy.Video = nil
+		impCopy.Native = nil
+		impCopy.ID += mf_suffix_audio
+		splitImps = append(splitImps, impCopy)
+	}
+	return splitImps
 }
 
 func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpAdkernel, error) {
@@ -232,19 +259,45 @@ func (adapter *adkernelAdapter) MakeBids(internalRequest *openrtb2.BidRequest, e
 	bidResponse.Currency = bidResp.Cur
 	for i := 0; i < len(seatBid.Bid); i++ {
 		bid := seatBid.Bid[i]
+		origImpId := bid.ImpID
+		typeSuffix := ""
+		if strings.HasSuffix(origImpId, mf_suffix) {
+			sfxStart := len(origImpId) - len(mf_suffix) - 1
+			typeSuffix = origImpId[sfxStart:]
+			bid.ImpID = origImpId[:sfxStart]
+		}
 		bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
 			Bid:     &bid,
-			BidType: getMediaTypeForImpID(bid.ImpID, internalRequest.Imp),
+			BidType: getMediaTypeForImpID(bid.ImpID, typeSuffix, internalRequest.Imp),
 		})
 	}
 	return bidResponse, nil
 }
 
 // getMediaTypeForImp figures out which media type this bid is for
-func getMediaTypeForImpID(impID string, imps []openrtb2.Imp) openrtb_ext.BidType {
-	for _, imp := range imps {
-		if imp.ID == impID && imp.Banner != nil {
+func getMediaTypeForImpID(impID string, typeSuffix string, imps []openrtb2.Imp) openrtb_ext.BidType {
+	if len(typeSuffix) > 0 {
+		if typeSuffix == mf_suffix_banner {
 			return openrtb_ext.BidTypeBanner
+		} else if typeSuffix == mf_suffix_video {
+			return openrtb_ext.BidTypeVideo
+		} else if typeSuffix == mf_suffix_audio {
+			return openrtb_ext.BidTypeAudio
+		} else if typeSuffix == mf_suffix_native {
+			return openrtb_ext.BidTypeNative
+		}
+	}
+	for _, imp := range imps {
+		if imp.ID == impID {
+			if imp.Banner != nil {
+				return openrtb_ext.BidTypeBanner
+			} else if imp.Video != nil {
+				return openrtb_ext.BidTypeVideo
+			} else if imp.Audio != nil {
+				return openrtb_ext.BidTypeAudio
+			} else if imp.Native != nil {
+				return openrtb_ext.BidTypeNative
+			}
 		}
 	}
 	return openrtb_ext.BidTypeVideo
diff --git a/adapters/aidem/aidem.go b/adapters/aidem/aidem.go
index dc8d42a0..79238c1b 100644
--- a/adapters/aidem/aidem.go
+++ b/adapters/aidem/aidem.go
@@ -4,16 +4,18 @@ import (
 	"encoding/json"
 	"fmt"
 	"net/http"
+	"text/template"
 
 	"github.com/prebid/openrtb/v19/openrtb2"
 	"github.com/prebid/prebid-server/v2/adapters"
 	"github.com/prebid/prebid-server/v2/config"
 	"github.com/prebid/prebid-server/v2/errortypes"
+	"github.com/prebid/prebid-server/v2/macros"
 	"github.com/prebid/prebid-server/v2/openrtb_ext"
 )
 
 type adapter struct {
-	endpoint string
+	EndpointTemplate *template.Template
 }
 
 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
@@ -23,12 +25,22 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E
 		return nil, []error{err}
 	}
 
+	impExt, err := getImpressionExt(&request.Imp[0])
+	if err != nil {
+		return nil, []error{err}
+	}
+
+	url, err := a.buildEndpointURL(impExt)
+	if err != nil {
+		return nil, []error{err}
+	}
+
 	headers := http.Header{}
 	headers.Add("Content-Type", "application/json;charset=utf-8")
 
 	return []*adapters.RequestData{{
 		Method:  "POST",
-		Uri:     a.endpoint,
+		Uri:     url,
 		Body:    reqJson,
 		Headers: headers,
 	}}, nil
@@ -81,9 +93,15 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest
 
 // Builder builds a new instance of the AIDEM adapter for the given bidder with the given config.
 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
-	return &adapter{
-		endpoint: config.Endpoint,
-	}, nil
+	urlTemplate, err := template.New("endpointTemplate").Parse(config.Endpoint)
+	if err != nil {
+		return nil, fmt.Errorf("unable to parse endpoint url template: %v", err)
+	}
+
+	bidder := &adapter{
+		EndpointTemplate: urlTemplate,
+	}
+	return bidder, nil
 }
 
 func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
@@ -100,3 +118,25 @@ func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
 		return "", fmt.Errorf("Unable to fetch mediaType in multi-format: %s", bid.ImpID)
 	}
 }
+
+func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpAidem, error) {
+	var bidderExt adapters.ExtImpBidder
+	if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
+		return nil, &errortypes.BadInput{
+			Message: err.Error(),
+		}
+	}
+	var AIDEMExt openrtb_ext.ExtImpAidem
+	if err := json.Unmarshal(bidderExt.Bidder, &AIDEMExt); err != nil {
+		return nil, &errortypes.BadInput{
+			Message: err.Error(),
+		}
+	}
+	return &AIDEMExt, nil
+}
+
+// Builds enpoint url based on adapter-specific pub settings from imp.ext
+func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtImpAidem) (string, error) {
+	endpointParams := macros.EndpointTemplateParams{PublisherID: params.PublisherId}
+	return macros.ResolveMacros(a.EndpointTemplate, endpointParams)
+}
diff --git a/adapters/bizzclick/bizzclick.go b/adapters/bizzclick/bizzclick.go
index fee2829d..4f16268c 100644
--- a/adapters/bizzclick/bizzclick.go
+++ b/adapters/bizzclick/bizzclick.go
@@ -104,7 +104,15 @@ func (a *adapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtBizzclick
 }
 
 func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtBizzclick) (string, error) {
-	endpointParams := macros.EndpointTemplateParams{AccountID: params.AccountID, SourceId: params.PlacementID}
+	host := "us-e-node1"
+	if params.Host != "" {
+		host = params.Host
+	}
+	sourceId := params.SourceID
+	if params.SourceID == "" {
+		sourceId = params.PlacementID
+	}
+	endpointParams := macros.EndpointTemplateParams{AccountID: params.AccountID, SourceId: sourceId, Host: host}
 	return macros.ResolveMacros(a.endpoint, endpointParams)
 }
 
diff --git a/adapters/minutemedia/minutemedia.go b/adapters/minutemedia/minutemedia.go
new file mode 100644
index 00000000..0d0bceea
--- /dev/null
+++ b/adapters/minutemedia/minutemedia.go
@@ -0,0 +1,121 @@
+package minutemedia
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"net/http"
+	"net/url"
+	"strings"
+
+	"github.com/prebid/openrtb/v19/openrtb2"
+
+	"github.com/prebid/prebid-server/v2/adapters"
+	"github.com/prebid/prebid-server/v2/config"
+	"github.com/prebid/prebid-server/v2/errortypes"
+	"github.com/prebid/prebid-server/v2/openrtb_ext"
+)
+
+// adapter is a MinuteMedia implementation of the adapters.Bidder interface.
+type adapter struct {
+	endpointURL string
+}
+
+func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) {
+	return &adapter{
+		endpointURL: config.Endpoint,
+	}, nil
+}
+
+// MakeRequests prepares the HTTP requests which should be made to fetch bids.
+func (a *adapter) MakeRequests(openRTBRequest *openrtb2.BidRequest, _ *adapters.ExtraRequestInfo) (requestsToBidder []*adapters.RequestData, errs []error) {
+	org, err := extractOrg(openRTBRequest)
+	if err != nil {
+		return nil, append(errs, fmt.Errorf("failed to extract org: %w", err))
+	}
+
+	openRTBRequestJSON, err := json.Marshal(openRTBRequest)
+	if err != nil {
+		return nil, append(errs, err)
+	}
+
+	headers := http.Header{}
+	headers.Add("Content-Type", "application/json;charset=utf-8")
+
+	return append(requestsToBidder, &adapters.RequestData{
+		Method:  http.MethodPost,
+		Uri:     a.endpointURL + "?publisher_id=" + url.QueryEscape(org),
+		Body:    openRTBRequestJSON,
+		Headers: headers,
+	}), nil
+}
+
+// MakeBids unpacks the server's response into Bids.
+func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+	if adapters.IsResponseStatusCodeNoContent(responseData) {
+		return nil, nil
+	}
+
+	if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil {
+		return nil, []error{err}
+	}
+
+	var response openrtb2.BidResponse
+	if err := json.Unmarshal(responseData.Body, &response); err != nil {
+		return nil, []error{err}
+	}
+
+	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
+	bidResponse.Currency = response.Cur
+
+	var errs []error
+
+	for _, seatBid := range response.SeatBid {
+		for i, bid := range seatBid.Bid {
+			bidType, err := getMediaTypeForBid(bid)
+			if err != nil {
+				errs = append(errs, err)
+				continue
+			}
+
+			bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
+				Bid:     &seatBid.Bid[i],
+				BidType: bidType,
+			})
+		}
+	}
+
+	return bidResponse, errs
+}
+
+func extractOrg(openRTBRequest *openrtb2.BidRequest) (string, error) {
+	var err error
+	for _, imp := range openRTBRequest.Imp {
+		var bidderExt adapters.ExtImpBidder
+		if err = json.Unmarshal(imp.Ext, &bidderExt); err != nil {
+			return "", fmt.Errorf("failed to unmarshal bidderExt: %w", err)
+		}
+
+		var impExt openrtb_ext.ImpExtMinuteMedia
+		if err = json.Unmarshal(bidderExt.Bidder, &impExt); err != nil {
+			return "", fmt.Errorf("failed to unmarshal ImpExtMinuteMedia: %w", err)
+		}
+
+		return strings.TrimSpace(impExt.Org), nil
+	}
+
+	return "", errors.New("no imps in bid request")
+}
+
+func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
+	switch bid.MType {
+	case openrtb2.MarkupBanner:
+		return openrtb_ext.BidTypeBanner, nil
+	case openrtb2.MarkupVideo:
+		return openrtb_ext.BidTypeVideo, nil
+	default:
+		return "", &errortypes.BadServerResponse{
+			Message: fmt.Sprintf("unsupported MType %d", bid.MType),
+		}
+	}
+}
diff --git a/adapters/yandex/yandex.go b/adapters/yandex/yandex.go
new file mode 100644
index 00000000..23f90f79
--- /dev/null
+++ b/adapters/yandex/yandex.go
@@ -0,0 +1,339 @@
+package yandex
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"net/url"
+	"strconv"
+	"strings"
+	"text/template"
+
+	"github.com/prebid/openrtb/v19/openrtb2"
+	"github.com/prebid/prebid-server/v2/adapters"
+	"github.com/prebid/prebid-server/v2/config"
+	"github.com/prebid/prebid-server/v2/errortypes"
+	"github.com/prebid/prebid-server/v2/macros"
+	"github.com/prebid/prebid-server/v2/openrtb_ext"
+)
+
+const (
+	refererQueryKey  = "target-ref"
+	currencyQueryKey = "ssp-cur"
+	impIdQueryKey    = "imp-id"
+)
+
+// Composite id of an ad placement
+type yandexPlacementID struct {
+	PageID string
+	ImpID  string
+}
+
+type adapter struct {
+	endpoint *template.Template
+}
+
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
+	template, err := template.New("endpointTemplate").Parse(config.Endpoint)
+	if err != nil {
+		return nil, fmt.Errorf("unable to parse endpoint url template: %v", err)
+	}
+
+	bidder := &adapter{
+		endpoint: template,
+	}
+
+	return bidder, nil
+}
+
+func (a *adapter) MakeRequests(requestData *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+	var (
+		requests []*adapters.RequestData
+		errors   []error
+	)
+
+	referer := getReferer(requestData)
+	currency := getCurrency(requestData)
+
+	for i := range requestData.Imp {
+		imp := requestData.Imp[i]
+
+		placementId, err := getYandexPlacementId(imp)
+		if err != nil {
+			errors = append(errors, err)
+			continue
+		}
+
+		if err := modifyImp(&imp); err != nil {
+			errors = append(errors, err)
+			continue
+		}
+
+		resolvedUrl, err := a.resolveUrl(*placementId, referer, currency)
+		if err != nil {
+			errors = append(errors, err)
+			continue
+		}
+
+		splittedRequestData := splitRequestDataByImp(requestData, imp)
+
+		requestBody, err := json.Marshal(splittedRequestData)
+		if err != nil {
+			errors = append(errors, err)
+			continue
+		}
+
+		requests = append(requests, &adapters.RequestData{
+			Method:  "POST",
+			Uri:     resolvedUrl,
+			Body:    requestBody,
+			Headers: getHeaders(&splittedRequestData),
+		})
+	}
+
+	return requests, errors
+}
+
+func getHeaders(request *openrtb2.BidRequest) http.Header {
+	headers := http.Header{}
+
+	if request.Device != nil && request.Site != nil {
+		addNonEmptyHeaders(&headers, map[string]string{
+			"Referer":         request.Site.Page,
+			"Accept-Language": request.Device.Language,
+			"User-Agent":      request.Device.UA,
+			"X-Forwarded-For": request.Device.IP,
+			"X-Real-Ip":       request.Device.IP,
+			"Content-Type":    "application/json;charset=utf-8",
+			"Accept":          "application/json",
+		})
+	}
+
+	return headers
+}
+
+func addNonEmptyHeaders(headers *http.Header, headerValues map[string]string) {
+	for key, value := range headerValues {
+		if len(value) > 0 {
+			headers.Add(key, value)
+		}
+	}
+}
+
+// Request is in shared memory, so we have to make a shallow copy for further modification (imp is already a shallow copy)
+func splitRequestDataByImp(request *openrtb2.BidRequest, imp openrtb2.Imp) openrtb2.BidRequest {
+	requestCopy := *request
+	requestCopy.Imp = []openrtb2.Imp{imp}
+
+	return requestCopy
+}
+
+func getYandexPlacementId(imp openrtb2.Imp) (*yandexPlacementID, error) {
+	var ext adapters.ExtImpBidder
+	if err := json.Unmarshal(imp.Ext, &ext); err != nil {
+		return nil, &errortypes.BadInput{
+			Message: fmt.Sprintf("imp %s: unable to unmarshal ext", imp.ID),
+		}
+	}
+
+	var yandexExt openrtb_ext.ExtImpYandex
+	if err := json.Unmarshal(ext.Bidder, &yandexExt); err != nil {
+		return nil, &errortypes.BadInput{
+			Message: fmt.Sprintf("imp %s: unable to unmarshal ext.bidder: %v", imp.ID, err),
+		}
+	}
+
+	placementID, err := mapExtToPlacementID(yandexExt)
+	if err != nil {
+		return nil, err
+	}
+
+	return placementID, nil
+}
+
+func mapExtToPlacementID(yandexExt openrtb_ext.ExtImpYandex) (*yandexPlacementID, error) {
+	var placementID yandexPlacementID
+
+	if len(yandexExt.PlacementID) == 0 {
+		placementID.ImpID = strconv.Itoa(int(yandexExt.ImpID))
+		placementID.PageID = strconv.Itoa(int(yandexExt.PageID))
+		return &placementID, nil
+	}
+
+	idParts := strings.Split(yandexExt.PlacementID, "-")
+
+	numericIdParts := []string{}
+
+	for _, idPart := range idParts {
+		if _, err := strconv.Atoi(idPart); err == nil {
+			numericIdParts = append(numericIdParts, idPart)
+		}
+	}
+
+	if len(numericIdParts) < 2 {
+		return nil, &errortypes.BadInput{
+			Message: fmt.Sprintf("invalid placement id, it must contain two parts: %s", yandexExt.PlacementID),
+		}
+	}
+
+	placementID.ImpID = numericIdParts[len(numericIdParts)-1]
+	placementID.PageID = numericIdParts[len(numericIdParts)-2]
+
+	return &placementID, nil
+}
+
+func modifyImp(imp *openrtb2.Imp) error {
+	if imp.Banner != nil {
+		banner, err := modifyBanner(*imp.Banner)
+		if banner != nil {
+			imp.Banner = banner
+		}
+		return err
+	}
+
+	if imp.Native != nil {
+		return nil
+	}
+
+	return &errortypes.BadInput{
+		Message: fmt.Sprintf("Unsupported format. Yandex only supports banner and native types. Ignoring imp id #%s", imp.ID),
+	}
+}
+
+func modifyBanner(banner openrtb2.Banner) (*openrtb2.Banner, error) {
+	format := banner.Format
+
+	if banner.W == nil || banner.H == nil || *banner.W == 0 || *banner.H == 0 {
+		if len(format) == 0 {
+			return nil, &errortypes.BadInput{
+				Message: "Invalid size provided for Banner",
+			}
+		}
+
+		firstFormat := format[0]
+		banner.H = &firstFormat.H
+		banner.W = &firstFormat.W
+	}
+
+	return &banner, nil
+}
+
+// "Un-templates" the endpoint by replacing macroses and adding the required query parameters
+func (a *adapter) resolveUrl(placementID yandexPlacementID, referer string, currency string) (string, error) {
+	params := macros.EndpointTemplateParams{PageID: placementID.PageID}
+
+	endpointStr, err := macros.ResolveMacros(a.endpoint, params)
+	if err != nil {
+		return "", err
+	}
+
+	parsedUrl, err := url.Parse(endpointStr)
+	if err != nil {
+		return "", err
+	}
+
+	addNonEmptyQueryParams(parsedUrl, map[string]string{
+		refererQueryKey:  referer,
+		currencyQueryKey: currency,
+		impIdQueryKey:    placementID.ImpID,
+	})
+
+	return parsedUrl.String(), nil
+}
+
+func addNonEmptyQueryParams(url *url.URL, queryMap map[string]string) {
+	query := url.Query()
+	for key, value := range queryMap {
+		if len(value) > 0 {
+			query.Add(key, value)
+		}
+	}
+
+	url.RawQuery = query.Encode()
+}
+
+func getReferer(request *openrtb2.BidRequest) string {
+	if request.Site == nil {
+		return ""
+	}
+
+	return request.Site.Domain
+}
+
+func getCurrency(request *openrtb2.BidRequest) string {
+	if len(request.Cur) == 0 {
+		return ""
+	}
+
+	return request.Cur[0]
+}
+
+func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+
+	if adapters.IsResponseStatusCodeNoContent(responseData) {
+		return nil, nil
+	}
+
+	if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil {
+		return nil, []error{err}
+	}
+
+	var bidResponse openrtb2.BidResponse
+	if err := json.Unmarshal(responseData.Body, &bidResponse); err != nil {
+		return nil, []error{&errortypes.BadServerResponse{
+			Message: fmt.Sprintf("Bad server response: %d", err),
+		}}
+	}
+
+	bidResponseWithCapacity := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
+
+	var errors []error
+
+	impMap := map[string]*openrtb2.Imp{}
+	for i := range request.Imp {
+		imp := request.Imp[i]
+
+		impMap[imp.ID] = &imp
+	}
+
+	for _, seatBid := range bidResponse.SeatBid {
+		for i := range seatBid.Bid {
+			bid := seatBid.Bid[i]
+
+			imp, exists := impMap[bid.ImpID]
+			if !exists {
+				errors = append(errors, &errortypes.BadInput{
+					Message: fmt.Sprintf("Invalid bid imp ID #%s does not match any imp IDs from the original bid request", bid.ImpID),
+				})
+				continue
+			}
+
+			bidType, err := getBidType(*imp)
+			if err != nil {
+				errors = append(errors, err)
+				continue
+			}
+
+			bidResponseWithCapacity.Bids = append(bidResponseWithCapacity.Bids, &adapters.TypedBid{
+				Bid:     &bid,
+				BidType: bidType,
+			})
+		}
+	}
+
+	return bidResponseWithCapacity, errors
+}
+
+func getBidType(imp openrtb2.Imp) (openrtb_ext.BidType, error) {
+	if imp.Native != nil {
+		return openrtb_ext.BidTypeNative, nil
+	}
+
+	if imp.Banner != nil {
+		return openrtb_ext.BidTypeBanner, nil
+	}
+
+	return "", &errortypes.BadInput{
+		Message: fmt.Sprintf("Processing an invalid impression; cannot resolve impression type for imp #%s", imp.ID),
+	}
+}
diff --git a/adapters/zmaticoo/zmaticoo.go b/adapters/zmaticoo/zmaticoo.go
new file mode 100644
index 00000000..b5c85c47
--- /dev/null
+++ b/adapters/zmaticoo/zmaticoo.go
@@ -0,0 +1,149 @@
+package zmaticoo
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/prebid/openrtb/v19/openrtb2"
+	"github.com/prebid/prebid-server/v2/adapters"
+	"github.com/prebid/prebid-server/v2/config"
+	"github.com/prebid/prebid-server/v2/errortypes"
+	"github.com/prebid/prebid-server/v2/openrtb_ext"
+	"net/http"
+)
+
+type adapter struct {
+	endpoint string
+}
+
+// Builder builds a new instance of the zmaticoo adapter for the given bidder with the given config.
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
+	return &adapter{
+		endpoint: config.Endpoint,
+	}, nil
+}
+
+func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+	adapterRequest, errs := a.makeRequest(request)
+	if errs != nil {
+		return nil, errs
+	}
+	return []*adapters.RequestData{adapterRequest}, nil
+
+}
+
+func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, []error) {
+	errs := validateZmaticooExt(request)
+	if errs != nil {
+		return nil, errs
+	}
+	err := transform(request)
+	if err != nil {
+		return nil, append(errs, err)
+	}
+	reqBody, err := json.Marshal(request)
+	if err != nil {
+		return nil, append(errs, err)
+	}
+	headers := http.Header{}
+	headers.Add("Content-Type", "application/json;charset=utf-8")
+	return &adapters.RequestData{
+		Method:  "POST",
+		Uri:     a.endpoint,
+		Body:    reqBody,
+		Headers: headers,
+	}, errs
+}
+
+func transform(request *openrtb2.BidRequest) error {
+	for i, imp := range request.Imp {
+		if imp.Native != nil {
+			var nativeRequest map[string]interface{}
+			nativeCopyRequest := make(map[string]interface{})
+			if err := json.Unmarshal([]byte(request.Imp[i].Native.Request), &nativeRequest); err != nil {
+				return err
+			}
+			_, exists := nativeRequest["native"]
+			if exists {
+				continue
+			}
+			nativeCopyRequest["native"] = nativeRequest
+			nativeReqByte, err := json.Marshal(nativeCopyRequest)
+			if err != nil {
+				return err
+			}
+			nativeCopy := *request.Imp[i].Native
+			nativeCopy.Request = string(nativeReqByte)
+			request.Imp[i].Native = &nativeCopy
+		}
+	}
+	return nil
+}
+
+func validateZmaticooExt(request *openrtb2.BidRequest) []error {
+	var extImpZmaticoo openrtb_ext.ExtImpZmaticoo
+	var errs []error
+	for _, imp := range request.Imp {
+		var extBidder adapters.ExtImpBidder
+		err := json.Unmarshal(imp.Ext, &extBidder)
+		if err != nil {
+			errs = append(errs, err)
+			continue
+		}
+		err = json.Unmarshal(extBidder.Bidder, &extImpZmaticoo)
+		if err != nil {
+			errs = append(errs, err)
+			continue
+		}
+		if extImpZmaticoo.ZoneId == "" || extImpZmaticoo.PubId == "" {
+			errs = append(errs, fmt.Errorf("imp.ext.pubId or imp.ext.zoneId required"))
+			continue
+		}
+	}
+	return errs
+
+}
+
+// MakeBids make the bids for the bid response.
+func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+	if adapters.IsResponseStatusCodeNoContent(response) {
+		return nil, nil
+	}
+	if err := adapters.CheckResponseStatusCodeForErrors(response); err != nil {
+		return nil, []error{&errortypes.BadInput{
+			Message: fmt.Sprintf("Unexpected status code: %d.", response.StatusCode),
+		}}
+	}
+	var bidResp openrtb2.BidResponse
+	if err := json.Unmarshal(response.Body, &bidResp); err != nil {
+		return nil, []error{err}
+	}
+	var errs []error
+	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(internalRequest.Imp))
+	for _, sb := range bidResp.SeatBid {
+		for i := range sb.Bid {
+			mediaType, err := getMediaTypeForBid(sb.Bid[i])
+			if err != nil {
+				errs = append(errs, err)
+				continue
+			}
+			bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
+				Bid:     &sb.Bid[i],
+				BidType: mediaType,
+			})
+		}
+	}
+	return bidResponse, errs
+}
+
+func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
+	switch bid.MType {
+	case openrtb2.MarkupBanner:
+		return openrtb_ext.BidTypeBanner, nil
+	case openrtb2.MarkupNative:
+		return openrtb_ext.BidTypeNative, nil
+	case openrtb2.MarkupVideo:
+		return openrtb_ext.BidTypeVideo, nil
+	default:
+		return "", fmt.Errorf("unrecognized bid type in response from zmaticoo for bid %s", bid.ImpID)
+	}
+}
diff --git a/analytics/build/build.go b/analytics/build/build.go
index 7fc577da..cd0b870f 100644
--- a/analytics/build/build.go
+++ b/analytics/build/build.go
@@ -8,6 +8,8 @@ import (
 	"github.com/prebid/prebid-server/v2/analytics/filesystem"
 	"github.com/prebid/prebid-server/v2/analytics/pubstack"
 	"github.com/prebid/prebid-server/v2/config"
+	"github.com/prebid/prebid-server/v2/openrtb_ext"
+	"github.com/prebid/prebid-server/v2/ortb"
 	"github.com/prebid/prebid-server/v2/privacy"
 )
 
@@ -46,8 +48,10 @@ type enabledAnalytics map[string]analytics.Module
 
 func (ea enabledAnalytics) LogAuctionObject(ao *analytics.AuctionObject, ac privacy.ActivityControl) {
 	for name, module := range ea {
-		component := privacy.Component{Type: privacy.ComponentTypeAnalytics, Name: name}
-		if ac.Allow(privacy.ActivityReportAnalytics, component, privacy.ActivityRequest{}) {
+		if isAllowed, cloneBidderReq := evaluateActivities(ao.RequestWrapper, ac, name); isAllowed {
+			if cloneBidderReq != nil {
+				ao.RequestWrapper = cloneBidderReq
+			}
 			module.LogAuctionObject(ao)
 		}
 	}
@@ -55,10 +59,13 @@ func (ea enabledAnalytics) LogAuctionObject(ao *analytics.AuctionObject, ac priv
 
 func (ea enabledAnalytics) LogVideoObject(vo *analytics.VideoObject, ac privacy.ActivityControl) {
 	for name, module := range ea {
-		component := privacy.Component{Type: privacy.ComponentTypeAnalytics, Name: name}
-		if ac.Allow(privacy.ActivityReportAnalytics, component, privacy.ActivityRequest{}) {
+		if isAllowed, cloneBidderReq := evaluateActivities(vo.RequestWrapper, ac, name); isAllowed {
+			if cloneBidderReq != nil {
+				vo.RequestWrapper = cloneBidderReq
+			}
 			module.LogVideoObject(vo)
 		}
+
 	}
 }
 
@@ -76,8 +83,10 @@ func (ea enabledAnalytics) LogSetUIDObject(so *analytics.SetUIDObject) {
 
 func (ea enabledAnalytics) LogAmpObject(ao *analytics.AmpObject, ac privacy.ActivityControl) {
 	for name, module := range ea {
-		component := privacy.Component{Type: privacy.ComponentTypeAnalytics, Name: name}
-		if ac.Allow(privacy.ActivityReportAnalytics, component, privacy.ActivityRequest{}) {
+		if isAllowed, cloneBidderReq := evaluateActivities(ao.RequestWrapper, ac, name); isAllowed {
+			if cloneBidderReq != nil {
+				ao.RequestWrapper = cloneBidderReq
+			}
 			module.LogAmpObject(ao)
 		}
 	}
@@ -91,3 +100,31 @@ func (ea enabledAnalytics) LogNotificationEventObject(ne *analytics.Notification
 		}
 	}
 }
+
+func evaluateActivities(rw *openrtb_ext.RequestWrapper, ac privacy.ActivityControl, componentName string) (bool, *openrtb_ext.RequestWrapper) {
+	// returned nil request wrapper means that request wrapper was not modified by activities and doesn't have to be changed in analytics object
+	// it is needed in order to use one function for all analytics objects with RequestWrapper
+	component := privacy.Component{Type: privacy.ComponentTypeAnalytics, Name: componentName}
+	if !ac.Allow(privacy.ActivityReportAnalytics, component, privacy.ActivityRequest{}) {
+		return false, nil
+	}
+	blockUserFPD := !ac.Allow(privacy.ActivityTransmitUserFPD, component, privacy.ActivityRequest{})
+	blockPreciseGeo := !ac.Allow(privacy.ActivityTransmitPreciseGeo, component, privacy.ActivityRequest{})
+
+	if !blockUserFPD && !blockPreciseGeo {
+		return true, nil
+	}
+
+	cloneReq := ortb.CloneBidderReq(rw.BidRequest)
+
+	if blockUserFPD {
+		privacy.ScrubUserFPD(cloneReq)
+	}
+	if blockPreciseGeo {
+		ipConf := privacy.IPConf{IPV6: ac.IPv6Config, IPV4: ac.IPv4Config}
+		privacy.ScrubGeoAndDeviceIP(cloneReq, ipConf)
+	}
+
+	cloneReq.RebuildRequest()
+	return true, cloneReq
+}
diff --git a/docs/developers/configuration.md b/docs/developers/configuration.md
index 9a22fd1a..39789d49 100644
--- a/docs/developers/configuration.md
+++ b/docs/developers/configuration.md
@@ -1,14 +1,160 @@
 # Configuration
 
-Configuration is handled by [Viper](https://github.com/spf13/viper), which supports [many ways](https://github.com/spf13/viper#why-viper) of setting config values.
+Prebid Server is configured using environment variables, a `pbs.json` file, or a `pbs.yaml` file, in that order of precedence. Configuration files are read from either the application directory or `/etc/config`. 
 
-As a general rule, Prebid Server will log its resolved config values on startup and exit immediately if they're not valid.
+Upon starting, Prebid Server logs the resolved configuration to standard out with passwords and secrets redacted. If there's an error with the configuration, the application will log the error and exit.
 
-For development, it's easiest to define your config inside a `pbs.yaml` file in the project root.
+# Sections
+> [!IMPORTANT]
+> As we are still developing this guide, please refer to the [configuration structures in code](../../config/config.go) for a complete definition of the options.
 
-## Available options
+- [General](#general)
+- [Privacy](#privacy)
+  - [GDPR](#gdpr)
 
-For now, see [the contract classes](../../config/config.go) in the code.
 
-Also note that `Viper` will also read environment variables for config values. Prebid Server will look for the prefix `PBS_` on the environment variables, and map underscores (`_`)
-to periods. For example, to set `host_cookie.ttl_days` via an environment variable, set `PBS_HOST_COOKIE_TTL_DAYS` to the desired value.
+# General
+
+### `external_url`
+String value that specifies the external url to reach your Prebid Server instance. It's used for event tracking and user sync callbacks, and is shared with bidders in outgoing requests at `req.ext.prebid.server.externalurl`. Defaults to empty.
+
+<details>
+  <summary>Example</summary>
+  <p>
+
+  JSON:
+  ```
+  {
+    "external_url": "https://your-pbs-server.com"
+  }
+  ```
+
+  YAML:
+  ```
+  external_url: https://your-pbs-server.com
+  ```
+
+  Environment Variable:
+  ```
+  PBS_EXTERNAL_URL: https://your-pbs-server.com
+  ```
+
+  </p>
+</details>
+
+### `host`
+String value that specifies the address the server will listen to for connections.  If the value is empty, Prebid Server will listen on all available addresses, which is a common configuration. This value is also used for the Prometheus endpoint, if enabled. Defaults to empty.
+
+<details>
+  <summary>Example</summary>
+  <p>
+
+  JSON:
+  ```
+  {
+    "host": "127.0.0.1"
+  }
+  ```
+
+  YAML:
+  ```
+  host: 127.0.0.1
+  ```
+
+  Environment Variable:
+  ```
+  PBS_HOST: 127.0.0.1
+  ```
+
+  </p>
+</details>
+
+### `port`
+Integer value that specifies the port the server will listen to for connections. Defaults to `8000`.
+
+<details>
+  <summary>Example</summary>
+  <p>
+
+  JSON:
+  ```
+  {
+    "port": 8000
+  }
+  ```
+
+  YAML:
+  ```
+  port: 8000
+  ```
+
+  Environment Variable:
+  ```
+  PBS_PORT: 8000
+  ```
+
+  </p>
+</details>
+
+# Privacy
+
+## GDPR
+
+### `gdpr.enabled`
+Boolean value that determines if GDPR processing for TCF signals is enabled. Defaults to `true`.
+<details>
+  <summary>Example</summary>
+  <p>
+
+  JSON:
+  ```
+  {
+    "gdpr": {
+      "enabled": true
+    }
+  }
+  ```
+
+  YAML:
+  ```
+  gdpr:
+    enabled: true
+  ```
+
+  Environment Variable:
+  ```
+  PBS_GDPR_ENABLED: true
+  ```
+
+  </p>
+</details>
+
+
+### `gdpr.default_value` (required)
+String value that determines whether GDPR is enabled when no regulatory signal is available in the request. A value of `"0"` disables it by default and a value of `"1"` enables it. This is a required configuration value with no default.
+<details>
+  <summary>Example</summary>
+  <p>
+
+  JSON:
+  ```
+  {
+    "gdpr": {
+      "default_value": "0"
+    }
+  }
+  ```
+
+  YAML:
+  ```
+  gdpr:
+    default_value: "0"
+  ```
+
+  Environment Variable:
+  ```
+  PBS_GDPR_DEFAULT_VALUE: 0
+  ```
+
+  </p>
+</details>
diff --git a/docs/developers/features.md b/docs/developers/features.md
deleted file mode 100644
index b9bb9053..00000000
--- a/docs/developers/features.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Features
-
-Prebid Server documentation has been moved to the prebid.org website:
-
-- [Adding a new bidder](https://docs.prebid.org/prebid-server/developers/add-new-bidder-go.html)
-- [Adding a new analytics module](https://docs.prebid.org/prebid-server/developers/pbs-build-an-analytics-adapter.html)
-- [Currency](https://docs.prebid.org/prebid-server/features/pbs-currency.html)
-- [Prebid Server and GDPR](https://docs.google.com/document/d/1g0zAYc_EfqyilKD8N2qQ47uz0hdahY-t8vfb-vxZL5w/edit#heading=h.8zebax5ncz0t)
-- [Prebid and TCF2](https://docs.google.com/document/d/1fBRaodKifv1pYsWY3ia-9K96VHUjd8kKvxZlOsozm8E/edit#heading=h.hlpacpauqwkx)
-- [Prebid Server User ID Sync](https://docs.prebid.org/prebid-server/developers/pbs-cookie-sync.html)
-- [Cookie Sync](https://docs.prebid.org/prebid-server/developers/pbs-cookie-sync.html)
-- [Default Request](https://docs.prebid.org/prebid-server/features/pbs-default-request.html)
diff --git a/docs/endpoints.md b/docs/endpoints.md
deleted file mode 100644
index 88116144..00000000
--- a/docs/endpoints.md
+++ /dev/null
@@ -1,1 +0,0 @@
-Endpoint documentation has been moved to prebid.org: [https://docs.prebid.org/prebid-server/endpoints/pbs-endpoint-overview.html](https://docs.prebid.org/prebid-server/endpoints/pbs-endpoint-overview.html)
diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go
index 0e85a39a..7d998a77 100755
--- a/exchange/adapter_builders.go
+++ b/exchange/adapter_builders.go
@@ -115,12 +115,13 @@ import (
 	"github.com/prebid/prebid-server/v2/adapters/logan"
 	"github.com/prebid/prebid-server/v2/adapters/logicad"
 	"github.com/prebid/prebid-server/v2/adapters/lunamedia"
-	mabidder "github.com/prebid/prebid-server/v2/adapters/mabidder"
+	"github.com/prebid/prebid-server/v2/adapters/mabidder"
 	"github.com/prebid/prebid-server/v2/adapters/madvertise"
 	"github.com/prebid/prebid-server/v2/adapters/marsmedia"
 	"github.com/prebid/prebid-server/v2/adapters/medianet"
 	"github.com/prebid/prebid-server/v2/adapters/mgid"
 	"github.com/prebid/prebid-server/v2/adapters/mgidX"
+	"github.com/prebid/prebid-server/v2/adapters/minutemedia"
 	"github.com/prebid/prebid-server/v2/adapters/mobfoxpb"
 	"github.com/prebid/prebid-server/v2/adapters/mobilefuse"
 	"github.com/prebid/prebid-server/v2/adapters/motorik"
@@ -185,12 +186,14 @@ import (
 	"github.com/prebid/prebid-server/v2/adapters/vrtcal"
 	"github.com/prebid/prebid-server/v2/adapters/xeworks"
 	"github.com/prebid/prebid-server/v2/adapters/yahooAds"
+	"github.com/prebid/prebid-server/v2/adapters/yandex"
 	"github.com/prebid/prebid-server/v2/adapters/yeahmobi"
 	"github.com/prebid/prebid-server/v2/adapters/yieldlab"
 	"github.com/prebid/prebid-server/v2/adapters/yieldmo"
 	"github.com/prebid/prebid-server/v2/adapters/yieldone"
 	"github.com/prebid/prebid-server/v2/adapters/zeroclickfraud"
 	"github.com/prebid/prebid-server/v2/adapters/zeta_global_ssp"
+	"github.com/prebid/prebid-server/v2/adapters/zmaticoo"
 	"github.com/prebid/prebid-server/v2/openrtb_ext"
 )
 
@@ -320,6 +323,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderMedianet:          medianet.Builder,
 		openrtb_ext.BidderMgid:              mgid.Builder,
 		openrtb_ext.BidderMgidX:             mgidX.Builder,
+		openrtb_ext.BidderMinuteMedia:       minutemedia.Builder,
 		openrtb_ext.BidderMobfoxpb:          mobfoxpb.Builder,
 		openrtb_ext.BidderMobileFuse:        mobilefuse.Builder,
 		openrtb_ext.BidderMotorik:           motorik.Builder,
@@ -384,11 +388,13 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderVrtcal:            vrtcal.Builder,
 		openrtb_ext.BidderXeworks:           xeworks.Builder,
 		openrtb_ext.BidderYahooAds:          yahooAds.Builder,
+		openrtb_ext.BidderYandex:            yandex.Builder,
 		openrtb_ext.BidderYeahmobi:          yeahmobi.Builder,
 		openrtb_ext.BidderYieldlab:          yieldlab.Builder,
 		openrtb_ext.BidderYieldmo:           yieldmo.Builder,
 		openrtb_ext.BidderYieldone:          yieldone.Builder,
 		openrtb_ext.BidderZeroClickFraud:    zeroclickfraud.Builder,
 		openrtb_ext.BidderZetaGlobalSsp:     zeta_global_ssp.Builder,
+		openrtb_ext.BidderZmaticoo:          zmaticoo.Builder,
 	}
 }
diff --git a/exchange/bidder.go b/exchange/bidder.go
index ce502e53..ebe1d5d3 100644
--- a/exchange/bidder.go
+++ b/exchange/bidder.go
@@ -13,6 +13,7 @@ import (
 	"net/http/httptrace"
 	"regexp"
 	"strings"
+	"sync"
 	"time"
 
 	"github.com/golang/glog"
@@ -523,12 +524,12 @@ func (bidder *bidderAdapter) doRequest(ctx context.Context, req *adapters.Reques
 func (bidder *bidderAdapter) doRequestImpl(ctx context.Context, req *adapters.RequestData, logger util.LogMsg, bidderRequestStartTime time.Time, tmaxAdjustments *TmaxAdjustmentsPreprocessed) *httpCallInfo {
 	var requestBody []byte
 
-	switch strings.ToUpper(bidder.config.EndpointCompression) {
-	case Gzip:
-		requestBody = compressToGZIP(req.Body)
-		req.Headers.Set("Content-Encoding", "gzip")
-	default:
-		requestBody = req.Body
+	requestBody, err := getRequestBody(req, bidder.config.EndpointCompression)
+	if err != nil {
+		return &httpCallInfo{
+			request: req,
+			err:     err,
+		}
 	}
 	httpReq, err := http.NewRequest(req.Method, req.Uri, bytes.NewBuffer(requestBody))
 	if err != nil {
@@ -716,14 +717,6 @@ func prepareStoredResponse(impId string, bidResp json.RawMessage) *httpCallInfo
 	return respData
 }
 
-func compressToGZIP(requestBody []byte) []byte {
-	var b bytes.Buffer
-	w := gzip.NewWriter(&b)
-	w.Write([]byte(requestBody))
-	w.Close()
-	return b.Bytes()
-}
-
 func getBidTypeForAdjustments(bidType openrtb_ext.BidType, impID string, imp []openrtb2.Imp) string {
 	if bidType == openrtb_ext.BidTypeVideo {
 		for _, imp := range imp {
@@ -751,3 +744,40 @@ func hasShorterDurationThanTmax(ctx bidderTmaxContext, tmaxAdjustments TmaxAdjus
 	}
 	return false
 }
+
+func getRequestBody(req *adapters.RequestData, endpointCompression string) ([]byte, error) {
+	var requestBody []byte
+
+	switch strings.ToUpper(endpointCompression) {
+	case Gzip:
+		// Compress to GZIP
+		var b bytes.Buffer
+
+		w := gzipWriterPool.Get().(*gzip.Writer)
+		defer gzipWriterPool.Put(w)
+
+		w.Reset(&b)
+		_, err := w.Write(req.Body)
+		if err != nil {
+			return nil, err
+		}
+		err = w.Close()
+		if err != nil {
+			return nil, err
+		}
+		requestBody = b.Bytes()
+
+		// Set Header
+		req.Headers.Set("Content-Encoding", "gzip")
+
+		return requestBody, nil
+	default:
+		return req.Body, nil
+	}
+}
+
+var gzipWriterPool = sync.Pool{
+	New: func() interface{} {
+		return gzip.NewWriter(nil)
+	},
+}
diff --git a/exchange/exchange.go b/exchange/exchange.go
index 446dfaf9..16f8017f 100644
--- a/exchange/exchange.go
+++ b/exchange/exchange.go
@@ -579,8 +579,9 @@ func applyDealSupport(bidRequest *openrtb2.BidRequest, auc *auction, bidCategory
 		for bidder, topBidsPerBidder := range topBidsPerImp {
 			bidderNormalized, bidderFound := openrtb_ext.NormalizeBidderName(bidder.String())
 			if !bidderFound {
-				continue
+				bidderNormalized = bidder
 			}
+
 			maxBid := bidsToUpdate(multiBid, bidderNormalized.String())
 			for i, topBid := range topBidsPerBidder {
 				if i == maxBid {
diff --git a/macros/macros.go b/macros/macros.go
index 609e72cd..bbee7271 100644
--- a/macros/macros.go
+++ b/macros/macros.go
@@ -15,6 +15,7 @@ type EndpointTemplateParams struct {
 	AdUnit      string
 	MediaType   string
 	GvlID       string
+	PageID      string
 }
 
 // UserSyncPrivacy specifies privacy policy macros, represented as strings, for user sync urls.
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index 4f5aaeba..438d2281 100644
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -139,6 +139,7 @@ var coreBidderNames []BidderName = []BidderName{
 	BidderMedianet,
 	BidderMgid,
 	BidderMgidX,
+	BidderMinuteMedia,
 	BidderMobfoxpb,
 	BidderMobileFuse,
 	BidderMotorik,
@@ -203,12 +204,14 @@ var coreBidderNames []BidderName = []BidderName{
 	BidderVrtcal,
 	BidderXeworks,
 	BidderYahooAds,
+	BidderYandex,
 	BidderYeahmobi,
 	BidderYieldlab,
 	BidderYieldmo,
 	BidderYieldone,
 	BidderZeroClickFraud,
 	BidderZetaGlobalSsp,
+	BidderZmaticoo,
 }
 
 func GetAliasBidderToParent() map[BidderName]BidderName {
@@ -226,10 +229,6 @@ func SetAliasBidderName(aliasBidderName string, parentBidderName BidderName) err
 	return nil
 }
 
-func (name BidderName) MarshalJSON() ([]byte, error) {
-	return []byte(name), nil
-}
-
 func (name *BidderName) String() string {
 	if name == nil {
 		return ""
@@ -418,6 +417,7 @@ const (
 	BidderMedianet          BidderName = "medianet"
 	BidderMgid              BidderName = "mgid"
 	BidderMgidX             BidderName = "mgidX"
+	BidderMinuteMedia       BidderName = "minutemedia"
 	BidderMobfoxpb          BidderName = "mobfoxpb"
 	BidderMobileFuse        BidderName = "mobilefuse"
 	BidderMotorik           BidderName = "motorik"
@@ -482,12 +482,14 @@ const (
 	BidderVrtcal            BidderName = "vrtcal"
 	BidderXeworks           BidderName = "xeworks"
 	BidderYahooAds          BidderName = "yahooAds"
+	BidderYandex            BidderName = "yandex"
 	BidderYeahmobi          BidderName = "yeahmobi"
 	BidderYieldlab          BidderName = "yieldlab"
 	BidderYieldmo           BidderName = "yieldmo"
 	BidderYieldone          BidderName = "yieldone"
 	BidderZeroClickFraud    BidderName = "zeroclickfraud"
 	BidderZetaGlobalSsp     BidderName = "zeta_global_ssp"
+	BidderZmaticoo          BidderName = "zmaticoo"
 )
 
 // CoreBidderNames returns a slice of all core bidders.
diff --git a/openrtb_ext/deal_tier.go b/openrtb_ext/deal_tier.go
index bd8d681d..b268e775 100644
--- a/openrtb_ext/deal_tier.go
+++ b/openrtb_ext/deal_tier.go
@@ -40,6 +40,8 @@ func ReadDealTiersFromImp(imp openrtb2.Imp) (DealTierBidderMap, error) {
 		if param.DealTier != nil {
 			if bidderNormalized, bidderFound := NormalizeBidderName(bidder); bidderFound {
 				dealTiers[bidderNormalized] = *param.DealTier
+			} else {
+				dealTiers[BidderName(bidder)] = *param.DealTier
 			}
 		}
 	}
diff --git a/openrtb_ext/imp_aidem.go b/openrtb_ext/imp_aidem.go
index 59457f1e..3fe00b40 100644
--- a/openrtb_ext/imp_aidem.go
+++ b/openrtb_ext/imp_aidem.go
@@ -1,8 +1,8 @@
 package openrtb_ext
 
-type ImpExtFoo struct {
-	SiteID      string `json:"siteId"`
-	PublisherID string `json:"publisherId"`
-	PlacementID string `json:"placementId"`
+type ExtImpAidem struct {
+	PlacementId string `json:"placementId"`
+	SiteId      string `json:"siteId"`
+	PublisherId string `json:"publisherId"`
 	RateLimit   string `json:"rateLimit"`
 }
diff --git a/openrtb_ext/imp_bizzclick.go b/openrtb_ext/imp_bizzclick.go
index 5090a822..15a8c2d0 100644
--- a/openrtb_ext/imp_bizzclick.go
+++ b/openrtb_ext/imp_bizzclick.go
@@ -2,5 +2,7 @@ package openrtb_ext
 
 type ExtBizzclick struct {
 	AccountID   string `json:"accountId"`
+	SourceID    string `json:"sourceId"`
+	Host        string `json:"host"`
 	PlacementID string `json:"placementId"`
 }
diff --git a/openrtb_ext/imp_minutemedia.go b/openrtb_ext/imp_minutemedia.go
new file mode 100644
index 00000000..197f3b0a
--- /dev/null
+++ b/openrtb_ext/imp_minutemedia.go
@@ -0,0 +1,6 @@
+package openrtb_ext
+
+// ImpExtMinuteMedia defines the contract for bidrequest.imp[i].ext.prebid.bidder.minutemedia
+type ImpExtMinuteMedia struct {
+	Org string `json:"org"`
+}
diff --git a/openrtb_ext/imp_yandex.go b/openrtb_ext/imp_yandex.go
new file mode 100644
index 00000000..8439d95f
--- /dev/null
+++ b/openrtb_ext/imp_yandex.go
@@ -0,0 +1,16 @@
+package openrtb_ext
+
+type ExtImpYandex struct {
+	/*
+		Possible formats
+			- `R-I-123456-2`
+			- `R-123456-1`
+			- `123456-789`
+	*/
+	PlacementID string `json:"placement_id"`
+
+	// Deprecated: in favor of `PlacementID`
+	PageID int64 `json:"page_id"`
+	// Deprecated: in favor of `PlacementID`
+	ImpID int64 `json:"imp_id"`
+}
diff --git a/openrtb_ext/imp_zmaticoo.go b/openrtb_ext/imp_zmaticoo.go
new file mode 100644
index 00000000..67464937
--- /dev/null
+++ b/openrtb_ext/imp_zmaticoo.go
@@ -0,0 +1,7 @@
+package openrtb_ext
+
+// ExtImpZmaticoo defines the contract for bidrequest.imp[i].ext.prebid.bidder.zmaticoo
+type ExtImpZmaticoo struct {
+	PubId  string `json:"pubId"`
+	ZoneId string `json:"zoneId"`
+}
diff --git a/privacy/activitycontrol.go b/privacy/activitycontrol.go
index 1bb3fc6c..7d1e16e9 100644
--- a/privacy/activitycontrol.go
+++ b/privacy/activitycontrol.go
@@ -37,7 +37,9 @@ func (r ActivityRequest) IsBidRequest() bool {
 }
 
 type ActivityControl struct {
-	plans map[Activity]ActivityPlan
+	plans      map[Activity]ActivityPlan
+	IPv6Config config.IPv6
+	IPv4Config config.IPv4
 }
 
 func NewActivityControl(cfg *config.AccountPrivacy) ActivityControl {
@@ -58,6 +60,9 @@ func NewActivityControl(cfg *config.AccountPrivacy) ActivityControl {
 	plans[ActivityTransmitTIDs] = buildPlan(cfg.AllowActivities.TransmitTids)
 	ac.plans = plans
 
+	ac.IPv4Config = cfg.IPv4Config
+	ac.IPv6Config = cfg.IPv6Config
+
 	return ac
 }
 
diff --git a/static/bidder-info/adkernel.yaml b/static/bidder-info/adkernel.yaml
index 1afbdc8d..22be7bee 100644
--- a/static/bidder-info/adkernel.yaml
+++ b/static/bidder-info/adkernel.yaml
@@ -1,15 +1,20 @@
-endpoint: "https://pbs.adksrv.com/hb?zone={{.ZoneID}}"
+endpoint: "http://pbs.adksrv.com/hb?zone={{.ZoneID}}"
 maintainer:
   email: "prebid-dev@adkernel.com"
 gvlVendorID: 14
 capabilities:
   app:
     mediaTypes:
-      - banner      
+      - banner
+      - video
+      - audio
+      - native
   site:
     mediaTypes:
       - banner
       - video
+      - audio
+      - native
 userSync:
   redirect:
     url: "https://sync.adkernel.com/user-sync?t=image&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&r={{.RedirectURL}}"
diff --git a/static/bidder-info/aidem.yaml b/static/bidder-info/aidem.yaml
index 35ea898a..70f63526 100644
--- a/static/bidder-info/aidem.yaml
+++ b/static/bidder-info/aidem.yaml
@@ -1,4 +1,4 @@
-endpoint: "https://zero.aidemsrv.com/ortb/v2.6/bid/request"
+endpoint: "https://zero.aidemsrv.com/ortb/v2.6/bid/request?billing_id={{.PublisherID}}"
 maintainer:
   email: prebid@aidem.com
 modifyingVastXmlAllowed: true
@@ -15,5 +15,5 @@ capabilities:
       - native
 userSync:
   redirect:
-    url: https://gum.aidemsrv.com/prebid_sync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}
+    url: https://gum.aidemsrv.com/prebid_sync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}
     userMacro: "$UID"
diff --git a/static/bidder-info/alkimi.yaml b/static/bidder-info/alkimi.yaml
index c27e2ca4..2e36aebb 100644
--- a/static/bidder-info/alkimi.yaml
+++ b/static/bidder-info/alkimi.yaml
@@ -13,3 +13,7 @@ capabilities:
       - banner
       - video
       - audio
+userSync:
+  redirect:
+    url: "https://user-sync.alkimi-onboarding.com/ssp-sync?gdpr={{.GDPR}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}"
+    userMacro: "${UID}"
diff --git a/static/bidder-info/bizzclick.yaml b/static/bidder-info/bizzclick.yaml
index 28ff0d44..9d0103bc 100644
--- a/static/bidder-info/bizzclick.yaml
+++ b/static/bidder-info/bizzclick.yaml
@@ -1,6 +1,14 @@
-endpoint: "http://us-e-node1.bizzclick.com/bid?rtb_seat_id={{.SourceId}}&secret_key={{.AccountID}}"
+# Contact support@bizzclick.com to connect with Bizzclick exchange.
+# We have the following regional endpoint sub-domains: US East - us-e-node1, EU: n1, APAC: n3
+# Use Host macro to resolve the endpoint based on the datacenter.
+# By default, we will use the US East sub-domain.
+# Please deploy this config in each of your datacenters with the appropriate regional subdomain
+endpoint: 'http://{{.Host}}.bizzclick.com/bid?rtb_seat_id={{.SourceId}}&secret_key={{.AccountID}}'
 maintainer:
-  email: "support@bizzclick.com"
+  email: 'support@bizzclick.com'
+geoscope:
+  - global
+endpointCompression: "GZIP"
 capabilities:
   app:
     mediaTypes:
diff --git a/static/bidder-info/kargo.yaml b/static/bidder-info/kargo.yaml
index e73eabe9..e1022032 100644
--- a/static/bidder-info/kargo.yaml
+++ b/static/bidder-info/kargo.yaml
@@ -13,4 +13,6 @@ userSync:
   redirect:
     url: "https://crb.kargo.com/api/v1/dsync/PrebidServer?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}"
     userMacro: "$UID"
-endpointCompression: "GZIP"
\ No newline at end of file
+endpointCompression: "GZIP"
+openrtb:
+  gpp-supported: true
diff --git a/static/bidder-info/minutemedia.yaml b/static/bidder-info/minutemedia.yaml
new file mode 100644
index 00000000..efe58e57
--- /dev/null
+++ b/static/bidder-info/minutemedia.yaml
@@ -0,0 +1,18 @@
+endpoint: "https://pbs.minutemedia-prebid.com/pbs-mm"
+maintainer:
+  email: hb@minutemedia.com
+gvlVendorID: 918
+modifyingVastXmlAllowed: true
+capabilities:
+  app:
+    mediaTypes:
+      - banner
+      - video
+  site:
+    mediaTypes:
+      - banner
+      - video
+userSync:
+  iframe:
+    url: https://pbs-cs.minutemedia-prebid.com/pbs-iframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}
+    userMacro: "[PBS_UID]"
diff --git a/static/bidder-info/rtbhouse.yaml b/static/bidder-info/rtbhouse.yaml
index b80cc0ff..1f8b1316 100644
--- a/static/bidder-info/rtbhouse.yaml
+++ b/static/bidder-info/rtbhouse.yaml
@@ -4,6 +4,10 @@ maintainer:
 endpointCompression: gzip
 gvlVendorID: 16
 capabilities:
+  app:
+    mediaTypes:
+      - banner
+      - native
   site:
     mediaTypes:
       - banner
diff --git a/static/bidder-info/yahooAds.yaml b/static/bidder-info/yahooAds.yaml
index a2581387..c53d1b14 100644
--- a/static/bidder-info/yahooAds.yaml
+++ b/static/bidder-info/yahooAds.yaml
@@ -1,6 +1,6 @@
 endpoint: "https://s2shb.ssp.yahoo.com/admax/bid/partners/PBS"
 maintainer:
-  email: "hb-fe-tech@yahooinc.com"
+  email: "prebid-tech-team@yahooinc.com"
 gvlVendorID: 25
 capabilities:
   app:
diff --git a/static/bidder-info/yandex.yaml b/static/bidder-info/yandex.yaml
new file mode 100644
index 00000000..8c5be2f7
--- /dev/null
+++ b/static/bidder-info/yandex.yaml
@@ -0,0 +1,13 @@
+endpoint: "https://bs-metadsp.yandex.ru/prebid/{{.PageID}}?ssp-id=10500"
+endpointCompression: gzip
+maintainer:
+  email: "prebid@yandex-team.ru"
+capabilities:
+  site:
+    mediaTypes:
+      - banner
+      - native
+userSync:
+  redirect:
+    url: https://yandex.ru/an/mapuid/yandex/?ssp-id=10500&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&location={{.RedirectURL}}
+    userMacro: "{YANDEXUID}"
diff --git a/static/bidder-info/zmaticoo.yaml b/static/bidder-info/zmaticoo.yaml
new file mode 100644
index 00000000..ae7d3eb0
--- /dev/null
+++ b/static/bidder-info/zmaticoo.yaml
@@ -0,0 +1,9 @@
+endpoint: "https://bid.zmaticoo.com/prebid/bid"
+maintainer:
+  email: "adam.li@eclicktech.com.cn"
+capabilities:
+  app:
+    mediaTypes:
+      - banner
+      - video
+      - native
\ No newline at end of file
diff --git a/static/bidder-params/bizzclick.json b/static/bidder-params/bizzclick.json
index 429e2948..3f16e990 100644
--- a/static/bidder-params/bizzclick.json
+++ b/static/bidder-params/bizzclick.json
@@ -9,11 +9,34 @@
       "description": "Account id",
       "minLength": 1
     },
+    "sourceId": {
+      "type": "string",
+      "description": "Source id",
+      "minLength": 1
+    },
+    "host": {
+      "type": "string",
+      "description": "Server region",
+      "minLength": 1
+    },
     "placementId": {
       "type": "string",
-      "description": "PlacementId id",
+      "description": "Deprecated, use sourceId instead",
       "minLength": 1
     }
   },
-  "required": ["accountId", "placementId"]
+  "oneOf": [
+    {
+      "required": [
+        "accountId",
+        "placementId"
+      ]
+    },
+    {
+      "required": [
+        "accountId",
+        "sourceId"
+      ]
+    }
+  ]
 }
\ No newline at end of file
diff --git a/static/bidder-params/minutemedia.json b/static/bidder-params/minutemedia.json
new file mode 100644
index 00000000..c4c475b1
--- /dev/null
+++ b/static/bidder-params/minutemedia.json
@@ -0,0 +1,14 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "title": "MinuteMedia Adapter Params",
+  "description": "A schema which validates params accepted by the MinuteMedia adapter",
+  "type": "object",
+  "properties": {
+    "org": {
+      "type": "string",
+      "description": "The organization ID.",
+      "minLength": 1
+    }
+  },
+  "required": ["org"]
+}
\ No newline at end of file
diff --git a/static/bidder-params/yandex.json b/static/bidder-params/yandex.json
new file mode 100644
index 00000000..ca777077
--- /dev/null
+++ b/static/bidder-params/yandex.json
@@ -0,0 +1,43 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "title": "Yandex Adapter Params",
+  "description": "A schema which validates params accepted by the Yandex adapter",
+  "type": "object",
+  "oneOf": [
+    {
+      "type": "object",
+      "description": "Deprecated composite ad placement identifier",
+      "properties": {
+        "page_id": {
+          "type": "integer",
+          "minLength": 1,
+          "minimum": 1,
+          "description": "Special Page Id provided by Yandex Manager"
+        },
+        "imp_id": {
+          "type": "integer",
+          "minLength": 1,
+          "minimum": 1,
+          "description": "Special identifier provided by Yandex Manager"
+        }
+      },
+      "required": [
+        "page_id",
+        "imp_id"
+      ]
+    },
+    {
+      "type": "object",
+      "properties": {
+        "placement_id": {
+          "type": "string",
+          "description": "Ad placement identifier",
+          "pattern": "(\\S+-)?\\d+-\\d+"
+        }
+      },
+      "required": [
+        "placement_id"
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/static/bidder-params/zmaticoo.json b/static/bidder-params/zmaticoo.json
new file mode 100644
index 00000000..fc89e5be
--- /dev/null
+++ b/static/bidder-params/zmaticoo.json
@@ -0,0 +1,22 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "title": "zMaticoo Adapter Params",
+  "description": "A schema which validates params accepted by the zMaticoo adapter",
+  "type": "object",
+  "properties": {
+    "pubId": {
+      "type": "string",
+      "description": "Publisher ID",
+      "minLength": 1
+    },
+    "zoneId": {
+      "type": "string",
+      "description": "Zone Id",
+      "minLength": 1
+    }
+  },
+  "required": [
+    "pubId",
+    "zoneId"
+  ]
+}
\ No newline at end of file


Test patch:
diff --git a/adapters/adkernel/adkernel_test.go b/adapters/adkernel/adkernel_test.go
index 2639eb25..e7ff02e4 100644
--- a/adapters/adkernel/adkernel_test.go
+++ b/adapters/adkernel/adkernel_test.go
@@ -11,7 +11,7 @@ import (
 
 func TestJsonSamples(t *testing.T) {
 	bidder, buildErr := Builder(openrtb_ext.BidderAdkernel, config.Adapter{
-		Endpoint: "https://pbs.adksrv.com/hb?zone={{.ZoneID}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
+		Endpoint: "http://pbs.adksrv.com/hb?zone={{.ZoneID}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
 
 	if buildErr != nil {
 		t.Fatalf("Builder returned unexpected error %v", buildErr)
diff --git a/adapters/adkernel/adkerneltest/exemplary/multiformat-impression.json b/adapters/adkernel/adkerneltest/exemplary/multiformat-impression.json
index b8fd88dc..49c5249f 100644
--- a/adapters/adkernel/adkerneltest/exemplary/multiformat-impression.json
+++ b/adapters/adkernel/adkerneltest/exemplary/multiformat-impression.json
@@ -14,6 +14,10 @@
         "banner" : {
           "format": [{"w": 300,"h": 250}]
         },
+        "native" : {
+          "request": "{native: \"request\"}",
+          "ver": "1.2"
+        },
         "ext": {
           "bidder": {
             "zoneId": 102,
@@ -36,15 +40,30 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "https://pbs.adksrv.com/hb?zone=102",
+        "uri": "http://pbs.adksrv.com/hb?zone=102",
         "body": {
           "id": "0000000000001",
           "imp": [
             {
-              "id": "multi-adunit",
+              "id": "multi-adunitb__mf",
               "banner": {
                 "format": [{"w": 300, "h": 250}]
               }
+            },
+            {
+              "id": "multi-adunitv__mf",
+              "video": {
+                "mimes": ["video/mp4"],
+                "w": 640,
+                "h": 480
+              }
+            },
+            {
+              "id": "multi-adunitn__mf",
+              "native" : {
+                "request": "{native: \"request\"}",
+                "ver": "1.2"
+              }
             }
           ],
           "app": {
@@ -65,7 +84,7 @@
               "bid": [
                 {
                   "id": "bid02",
-                  "impid": "multi-adunit",
+                  "impid": "multi-adunitb__mf",
                   "price": 2.25,
                   "cid": "1001",
                   "crid": "2002",
@@ -74,6 +93,30 @@
                   "adomain": [
                     "tag-example.com"
                   ]
+                },
+                {
+                  "id": "bid03",
+                  "impid": "multi-adunitn__mf",
+                  "price": 1.25,
+                  "cid": "601",
+                  "crid": "702",
+                  "adid": "702",
+                  "adm": "<!-- native response -->",
+                  "adomain": [
+                    "tag-example.com"
+                  ]
+                },
+                {
+                  "id": "bid04",
+                  "impid": "multi-adunita__mf",
+                  "price": 1.0,
+                  "cid": "161",
+                  "crid": "172",
+                  "adid": "172",
+                  "nurl": "http://adkernel.com/win?f=nurl",
+                  "adomain": [
+                    "tag-example.com"
+                  ]
                 }
               ]
             }
@@ -101,6 +144,36 @@
             "crid": "2002"
           },
           "type": "banner"
+        },
+        {
+          "bid": {
+            "id": "bid03",
+            "impid": "multi-adunit",
+            "price": 1.25,
+            "adm": "<!-- native response -->",
+            "adomain": [
+              "tag-example.com"
+            ],
+            "cid": "601",
+            "crid": "702",
+            "adid": "702"
+          },
+          "type": "native"
+        },
+        {
+          "bid": {
+            "id": "bid04",
+            "impid": "multi-adunit",
+            "price": 1.0,
+            "nurl": "http://adkernel.com/win?f=nurl",
+            "adomain": [
+              "tag-example.com"
+            ],
+            "cid": "161",
+            "crid": "172",
+            "adid": "172"
+          },
+          "type": "audio"
         }
       ]
     }
diff --git a/adapters/adkernel/adkerneltest/exemplary/single-banner-impression.json b/adapters/adkernel/adkerneltest/exemplary/single-banner-impression.json
index 24f86378..6a01b847 100644
--- a/adapters/adkernel/adkerneltest/exemplary/single-banner-impression.json
+++ b/adapters/adkernel/adkerneltest/exemplary/single-banner-impression.json
@@ -30,7 +30,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "https://pbs.adksrv.com/hb?zone=101",
+        "uri": "http://pbs.adksrv.com/hb?zone=101",
         "body": {
           "id": "0000000000001",
           "imp": [
diff --git a/adapters/adkernel/adkerneltest/exemplary/single-video-impression.json b/adapters/adkernel/adkerneltest/exemplary/single-video-impression.json
index b13d9746..cd458826 100644
--- a/adapters/adkernel/adkerneltest/exemplary/single-video-impression.json
+++ b/adapters/adkernel/adkerneltest/exemplary/single-video-impression.json
@@ -33,7 +33,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "https://pbs.adksrv.com/hb?zone=102",
+        "uri": "http://pbs.adksrv.com/hb?zone=102",
         "body": {
           "id": "0000000000001",
           "imp": [
diff --git a/adapters/aidem/aidem_test.go b/adapters/aidem/aidem_test.go
index 8cf6e3d1..558b1c04 100644
--- a/adapters/aidem/aidem_test.go
+++ b/adapters/aidem/aidem_test.go
@@ -12,7 +12,7 @@ import (
 
 func TestJsonSamples(t *testing.T) {
 	bidder, buildErr := Builder(openrtb_ext.BidderAidem, config.Adapter{
-		Endpoint: "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request",
+		Endpoint: "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request?billing_id={{.PublisherID}}",
 	}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
 
 	if buildErr != nil {
@@ -26,5 +26,5 @@ func TestEndpointTemplateMalformed(t *testing.T) {
 	_, buildErr := Builder(openrtb_ext.BidderAidem, config.Adapter{
 		Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
 
-	assert.Nil(t, buildErr)
+	assert.Error(t, buildErr)
 }
diff --git a/adapters/aidem/aidemtest/exemplary/multi-format.json b/adapters/aidem/aidemtest/exemplary/multi-format.json
index 0c940d4b..bc0c467b 100644
--- a/adapters/aidem/aidemtest/exemplary/multi-format.json
+++ b/adapters/aidem/aidemtest/exemplary/multi-format.json
@@ -35,7 +35,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request",
+                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request?billing_id=1234",
                 "body": {
                     "id": "test-request-id",
                     "imp": [
diff --git a/adapters/aidem/aidemtest/exemplary/multi-imps-multi-bid.json b/adapters/aidem/aidemtest/exemplary/multi-imps-multi-bid.json
index 5c2b3694..68c87ee1 100644
--- a/adapters/aidem/aidemtest/exemplary/multi-imps-multi-bid.json
+++ b/adapters/aidem/aidemtest/exemplary/multi-imps-multi-bid.json
@@ -41,7 +41,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request",
+                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request?billing_id=1234",
                 "body": {
                     "id": "test-request-id",
                     "imp": [
diff --git a/adapters/aidem/aidemtest/exemplary/multi-imps-single-bid.json b/adapters/aidem/aidemtest/exemplary/multi-imps-single-bid.json
index 9eae7101..e628323a 100644
--- a/adapters/aidem/aidemtest/exemplary/multi-imps-single-bid.json
+++ b/adapters/aidem/aidemtest/exemplary/multi-imps-single-bid.json
@@ -41,7 +41,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request",
+                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request?billing_id=1234",
                 "body": {
                     "id": "test-request-id",
                     "imp": [
diff --git a/adapters/aidem/aidemtest/exemplary/no-bid.json b/adapters/aidem/aidemtest/exemplary/no-bid.json
index 7418425f..c67a205e 100644
--- a/adapters/aidem/aidemtest/exemplary/no-bid.json
+++ b/adapters/aidem/aidemtest/exemplary/no-bid.json
@@ -24,7 +24,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request",
+                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request?billing_id=1234",
                 "body": {
                     "id": "test-request-id",
                     "imp": [
diff --git a/adapters/aidem/aidemtest/exemplary/optional-params.json b/adapters/aidem/aidemtest/exemplary/optional-params.json
index 69511fb5..856e0c5c 100644
--- a/adapters/aidem/aidemtest/exemplary/optional-params.json
+++ b/adapters/aidem/aidemtest/exemplary/optional-params.json
@@ -25,7 +25,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request",
+                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request?billing_id=1234",
                 "body": {
                     "id": "test-request-id",
                     "imp": [
diff --git a/adapters/aidem/aidemtest/exemplary/simple-banner.json b/adapters/aidem/aidemtest/exemplary/simple-banner.json
index 73db297e..d39ac30e 100644
--- a/adapters/aidem/aidemtest/exemplary/simple-banner.json
+++ b/adapters/aidem/aidemtest/exemplary/simple-banner.json
@@ -24,7 +24,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request",
+                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request?billing_id=1234",
                 "body": {
                     "id": "test-request-id",
                     "imp": [
diff --git a/adapters/aidem/aidemtest/exemplary/simple-video.json b/adapters/aidem/aidemtest/exemplary/simple-video.json
index 0daaffaa..94eb98cd 100644
--- a/adapters/aidem/aidemtest/exemplary/simple-video.json
+++ b/adapters/aidem/aidemtest/exemplary/simple-video.json
@@ -27,7 +27,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request",
+                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request?billing_id=1234",
                 "body": {
                     "id": "test-request-id",
                     "imp": [
diff --git a/adapters/aidem/aidemtest/supplemental/invalid-req-400-status-code-bad-request.json b/adapters/aidem/aidemtest/supplemental/invalid-req-400-status-code-bad-request.json
index 3dea13ef..e0a1f6e9 100644
--- a/adapters/aidem/aidemtest/supplemental/invalid-req-400-status-code-bad-request.json
+++ b/adapters/aidem/aidemtest/supplemental/invalid-req-400-status-code-bad-request.json
@@ -41,7 +41,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request",
+                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request?billing_id=1234",
                 "body": {
                     "id": "some-request-id",
                     "imp": [
diff --git a/adapters/aidem/aidemtest/supplemental/invalid-res-200-status-code-empty-bids.json b/adapters/aidem/aidemtest/supplemental/invalid-res-200-status-code-empty-bids.json
index dd64125f..33b412b4 100644
--- a/adapters/aidem/aidemtest/supplemental/invalid-res-200-status-code-empty-bids.json
+++ b/adapters/aidem/aidemtest/supplemental/invalid-res-200-status-code-empty-bids.json
@@ -41,7 +41,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request",
+                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request?billing_id=1234",
                 "body": {
                     "id": "some-request-id",
                     "imp": [
diff --git a/adapters/aidem/aidemtest/supplemental/invalid-resp-multi-imp-type.json b/adapters/aidem/aidemtest/supplemental/invalid-resp-multi-imp-type.json
index 95f97d31..0c390f65 100644
--- a/adapters/aidem/aidemtest/supplemental/invalid-resp-multi-imp-type.json
+++ b/adapters/aidem/aidemtest/supplemental/invalid-resp-multi-imp-type.json
@@ -57,7 +57,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request",
+                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request?billing_id=1234",
                 "body": {
                     "id": "test-request-id",
                     "imp": [
diff --git a/adapters/aidem/aidemtest/supplemental/valid-req-200-bid-response-from-aidem.json b/adapters/aidem/aidemtest/supplemental/valid-req-200-bid-response-from-aidem.json
index cbd534cd..16cb98ba 100644
--- a/adapters/aidem/aidemtest/supplemental/valid-req-200-bid-response-from-aidem.json
+++ b/adapters/aidem/aidemtest/supplemental/valid-req-200-bid-response-from-aidem.json
@@ -44,7 +44,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request",
+                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request?billing_id=1234",
                 "body": {
                     "id": "test-request-id",
                     "imp": [
diff --git a/adapters/aidem/aidemtest/supplemental/valid-req-204-response-from-aidem.json b/adapters/aidem/aidemtest/supplemental/valid-req-204-response-from-aidem.json
index ddd4e5a7..d51c6da9 100644
--- a/adapters/aidem/aidemtest/supplemental/valid-req-204-response-from-aidem.json
+++ b/adapters/aidem/aidemtest/supplemental/valid-req-204-response-from-aidem.json
@@ -28,7 +28,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request",
+                "uri": "https://fakezero.aidemsrv.com/ortb/v2.6/bid/request?billing_id=1234",
                 "body": {
                     "app": {
                         "bundle": "com.example.app"
diff --git a/adapters/bizzclick/bizzclick_test.go b/adapters/bizzclick/bizzclick_test.go
index 971f06ae..5933ee55 100644
--- a/adapters/bizzclick/bizzclick_test.go
+++ b/adapters/bizzclick/bizzclick_test.go
@@ -11,7 +11,7 @@ import (
 
 func TestJsonSamples(t *testing.T) {
 	bidder, buildErr := Builder(openrtb_ext.BidderBizzclick, config.Adapter{
-		Endpoint: "http://us.example.com/bid?rtb_seat_id={{.SourceId}}&secret_key={{.AccountID}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
+		Endpoint: "http://{{.Host}}.bizzclick.com/bid?rtb_seat_id={{.SourceId}}&secret_key={{.AccountID}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
 
 	if buildErr != nil {
 		t.Fatalf("Builder returned unexpected error %v", buildErr)
diff --git a/adapters/bizzclick/bizzclicktest/exemplary/banner-app.json b/adapters/bizzclick/bizzclicktest/exemplary/banner-app.json
index 1ba1d155..3875d70c 100644
--- a/adapters/bizzclick/bizzclicktest/exemplary/banner-app.json
+++ b/adapters/bizzclick/bizzclicktest/exemplary/banner-app.json
@@ -34,7 +34,8 @@
         "ext": {
           "bidder": {
             "accountId": "accountId",
-            "placementId": "placementId"
+            "sourceId": "sourceId",
+            "host": "host"
           }
         }
       }
@@ -60,7 +61,7 @@
             "123.123.123.123"
           ]
         },
-        "uri": "http://us.example.com/bid?rtb_seat_id=placementId&secret_key=accountId",
+        "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId",
         "body": {
           "id": "some-request-id",
           "device": {
diff --git a/adapters/bizzclick/bizzclicktest/exemplary/banner-web.json b/adapters/bizzclick/bizzclicktest/exemplary/banner-web.json
index 5c2baba6..fa9ba4d4 100644
--- a/adapters/bizzclick/bizzclicktest/exemplary/banner-web.json
+++ b/adapters/bizzclick/bizzclicktest/exemplary/banner-web.json
@@ -22,27 +22,29 @@
         "id": "some-impression-id1",
         "tagid": "ogTAGID",
         "banner": {
-          "w":320,
-          "h":50
+          "w": 320,
+          "h": 50
         },
         "ext": {
           "bidder": {
             "accountId": "accountId",
-            "placementId": "placementId"
+            "sourceId": "sourceId",
+            "host": "host"
           }
         }
-      },     
-       {
+      },
+      {
         "id": "some-impression-id2",
         "tagid": "ogTAGID",
         "banner": {
-          "w":320,
-          "h":50
+          "w": 320,
+          "h": 50
         },
         "ext": {
           "bidder": {
             "accountId": "accountId",
-            "placementId": "placementId"
+            "sourceId": "sourceId",
+            "host": "host"
           }
         }
       }
@@ -68,7 +70,7 @@
             "123.123.123.123"
           ]
         },
-        "uri": "http://us.example.com/bid?rtb_seat_id=placementId&secret_key=accountId",
+        "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId",
         "body": {
           "id": "some-request-id",
           "device": {
@@ -82,16 +84,16 @@
               "id": "some-impression-id1",
               "tagid": "ogTAGID",
               "banner": {
-                "w":320,
-                "h":50
+                "w": 320,
+                "h": 50
               }
             },
             {
               "id": "some-impression-id2",
               "tagid": "ogTAGID",
               "banner": {
-                "w":320,
-                "h":50
+                "w": 320,
+                "h": 50
               }
             }
           ],
@@ -150,9 +152,9 @@
   ],
   "expectedBidResponses": [
     {
-      "bids":[
+      "bids": [
         {
-          "bid":  {
+          "bid": {
             "id": "a3ae1b4e2fc24a4fb45540082e98e161",
             "impid": "some-impression-id1",
             "price": 3.5,
@@ -167,7 +169,7 @@
           "type": "banner"
         },
         {
-          "bid":  {
+          "bid": {
             "id": "a3ae1b4e2fc24a4fb45540082e98e162",
             "impid": "some-impression-id2",
             "price": 3.5,
@@ -184,4 +186,4 @@
       ]
     }
   ]
-}
+}
\ No newline at end of file
diff --git a/adapters/bizzclick/bizzclicktest/exemplary/default-host-param.json b/adapters/bizzclick/bizzclicktest/exemplary/default-host-param.json
new file mode 100644
index 00000000..d1188389
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/exemplary/default-host-param.json
@@ -0,0 +1,150 @@
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "device": {
+      "ua": "test-user-agent",
+      "ip": "123.123.123.123",
+      "language": "en",
+      "dnt": 0
+    },
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "app": {
+      "publisher": {
+        "id": "123456789"
+      },
+      "cat": [
+        "IAB22-1"
+      ],
+      "bundle": "com.app.awesome",
+      "name": "Awesome App",
+      "domain": "awesomeapp.com",
+      "id": "123456789"
+    },
+    "imp": [
+      {
+        "id": "some-impression-id",
+        "tagid": "ogTAGID",
+        "banner": {
+          "w": 320,
+          "h": 50
+        },
+        "ext": {
+          "bidder": {
+            "accountId": "accountId",
+            "placementId": "placementId"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "headers": {
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Accept": [
+            "application/json"
+          ],
+          "X-Openrtb-Version": [
+            "2.5"
+          ],
+          "User-Agent": [
+            "test-user-agent"
+          ],
+          "X-Forwarded-For": [
+            "123.123.123.123"
+          ]
+        },
+        "uri": "http://us-e-node1.bizzclick.com/bid?rtb_seat_id=placementId&secret_key=accountId",
+        "body": {
+          "id": "some-request-id",
+          "device": {
+            "ua": "test-user-agent",
+            "ip": "123.123.123.123",
+            "language": "en",
+            "dnt": 0
+          },
+          "imp": [
+            {
+              "id": "some-impression-id",
+              "banner": {
+                "w": 320,
+                "h": 50
+              },
+              "tagid": "ogTAGID"
+            }
+          ],
+          "app": {
+            "id": "123456789",
+            "name": "Awesome App",
+            "bundle": "com.app.awesome",
+            "domain": "awesomeapp.com",
+            "cat": [
+              "IAB22-1"
+            ],
+            "publisher": {
+              "id": "123456789"
+            }
+          },
+          "user": {
+            "buyeruid": "awesome-user"
+          },
+          "tmax": 1000
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "awesome-resp-id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+                  "impid": "1",
+                  "price": 3.5,
+                  "adm": "awesome-markup",
+                  "adomain": [
+                    "awesome.com"
+                  ],
+                  "crid": "20",
+                  "w": 320,
+                  "h": 50
+                }
+              ],
+              "type": "banner",
+              "seat": "bizzclick"
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+            "impid": "1",
+            "price": 3.5,
+            "adm": "awesome-markup",
+            "adomain": [
+              "awesome.com"
+            ],
+            "crid": "20",
+            "w": 320,
+            "h": 50
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/bizzclick/bizzclicktest/exemplary/native-app.json b/adapters/bizzclick/bizzclicktest/exemplary/native-app.json
index 764f6006..7b94970d 100644
--- a/adapters/bizzclick/bizzclicktest/exemplary/native-app.json
+++ b/adapters/bizzclick/bizzclicktest/exemplary/native-app.json
@@ -1,147 +1,147 @@
 {
-    "mockBidRequest": {
-      "id": "some-request-id",
-      "device": {
-        "ua": "test-user-agent",
-        "ip": "123.123.123.123",
-        "language": "en",
-        "dnt": 0
-      },
-      "tmax": 1000,
-      "user": {
-        "buyeruid": "awesome-user"
-      },
-      "app": {
-        "publisher": {
-          "id": "123456789"
-        },
-        "cat": [
-          "IAB22-1"
-        ],
-        "bundle": "com.app.awesome",
-        "name": "Awesome App",
-        "domain": "awesomeapp.com",
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "device": {
+      "ua": "test-user-agent",
+      "ip": "123.123.123.123",
+      "language": "en",
+      "dnt": 0
+    },
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "app": {
+      "publisher": {
         "id": "123456789"
       },
-      "imp": [
-        {
-          "id": "some-impression-id",
-          "tagid": "ogTAGID",
-          "native": {
-            "ver":"1.1",
-            "request":"{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}"
-          },
-          "ext": {
-            "bidder": {
-              "accountId": "accountId",
-              "placementId": "placementId"
-            }
-          }
-        }
-      ]
+      "cat": [
+        "IAB22-1"
+      ],
+      "bundle": "com.app.awesome",
+      "name": "Awesome App",
+      "domain": "awesomeapp.com",
+      "id": "123456789"
     },
-    "httpCalls": [
+    "imp": [
       {
-        "expectedRequest": {
-          "headers": {
-            "Content-Type": [
-              "application/json;charset=utf-8"
-            ],
-            "Accept": [
-              "application/json"
-            ],
-            "X-Openrtb-Version": [
-              "2.5"
-            ],
-            "User-Agent": [
-              "test-user-agent"
-            ],
-            "X-Forwarded-For": [
-              "123.123.123.123"
-            ]
-          },
-          "uri": "http://us.example.com/bid?rtb_seat_id=placementId&secret_key=accountId",
-          "body": {
-            "id": "some-request-id",
-            "device": {
-              "ua": "test-user-agent",
-              "ip": "123.123.123.123",
-              "language": "en",
-              "dnt": 0
-            },
-            "imp": [
-              {
-                "id": "some-impression-id",
-                "native": {
-                  "ver":"1.1",
-                  "request":"{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}"
-                },
-                "tagid": "ogTAGID"
-              }
-            ],
-            "app": {
-              "id": "123456789",
-              "name": "Awesome App",
-              "bundle": "com.app.awesome",
-              "domain": "awesomeapp.com",
-              "cat": [
-                "IAB22-1"
-              ],
-              "publisher": {
-                "id": "123456789"
-              }
-            },
-            "user": {
-              "buyeruid": "awesome-user"
-            },
-            "tmax": 1000
-          }
+        "id": "some-impression-id",
+        "tagid": "ogTAGID",
+        "native": {
+          "ver": "1.1",
+          "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}"
         },
-        "mockResponse": {
-          "status": 200,
-          "body": {
-            "id": "awesome-resp-id",
-            "seatbid": [
-              {
-                "bid": [
-                  {
-                    "id": "a3ae1b4e2fc24a4fb45540082e98e161",
-                    "impid": "some-impression-id",
-                    "price": 3.5,
-                    "adm": "awesome-markup",
-                    "adomain": [
-                      "awesome.com"
-                    ],
-                    "crid": "20"
-                  }
-                ],
-                "type": "native",
-                "seat": "bizzclick"
-              }
-            ],
-            "cur": "USD"
+        "ext": {
+          "bidder": {
+            "accountId": "accountId",
+            "sourceId": "sourceId",
+            "host": "host"
           }
         }
       }
-    ],
-    "expectedBidResponses": [
-      {
-        "bids":[
-          {
-            "bid":  {
-              "id": "a3ae1b4e2fc24a4fb45540082e98e161",
-              "impid": "some-impression-id",
-              "price": 3.5,
-              "adm": "awesome-markup",
-              "crid": "20",
-              "adomain": [
-                "awesome.com"
-              ]
-            },
-            "type": "native"
-          }
-        ]
-      }
     ]
-  }
-  
\ No newline at end of file
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "headers": {
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Accept": [
+            "application/json"
+          ],
+          "X-Openrtb-Version": [
+            "2.5"
+          ],
+          "User-Agent": [
+            "test-user-agent"
+          ],
+          "X-Forwarded-For": [
+            "123.123.123.123"
+          ]
+        },
+        "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId",
+        "body": {
+          "id": "some-request-id",
+          "device": {
+            "ua": "test-user-agent",
+            "ip": "123.123.123.123",
+            "language": "en",
+            "dnt": 0
+          },
+          "imp": [
+            {
+              "id": "some-impression-id",
+              "native": {
+                "ver": "1.1",
+                "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}"
+              },
+              "tagid": "ogTAGID"
+            }
+          ],
+          "app": {
+            "id": "123456789",
+            "name": "Awesome App",
+            "bundle": "com.app.awesome",
+            "domain": "awesomeapp.com",
+            "cat": [
+              "IAB22-1"
+            ],
+            "publisher": {
+              "id": "123456789"
+            }
+          },
+          "user": {
+            "buyeruid": "awesome-user"
+          },
+          "tmax": 1000
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "awesome-resp-id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+                  "impid": "some-impression-id",
+                  "price": 3.5,
+                  "adm": "awesome-markup",
+                  "adomain": [
+                    "awesome.com"
+                  ],
+                  "crid": "20"
+                }
+              ],
+              "type": "native",
+              "seat": "bizzclick"
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+            "impid": "some-impression-id",
+            "price": 3.5,
+            "adm": "awesome-markup",
+            "crid": "20",
+            "adomain": [
+              "awesome.com"
+            ]
+          },
+          "type": "native"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/bizzclick/bizzclicktest/exemplary/native-web.json b/adapters/bizzclick/bizzclicktest/exemplary/native-web.json
index 04a33e6f..396e1e1e 100644
--- a/adapters/bizzclick/bizzclicktest/exemplary/native-web.json
+++ b/adapters/bizzclick/bizzclicktest/exemplary/native-web.json
@@ -22,13 +22,14 @@
         "id": "some-impression-id",
         "tagid": "ogTAGID",
         "native": {
-          "ver":"1.1",
-          "request":"{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}"
+          "ver": "1.1",
+          "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}"
         },
         "ext": {
           "bidder": {
             "accountId": "accountId",
-            "placementId": "placementId"
+            "sourceId": "sourceId",
+            "host": "host"
           }
         }
       }
@@ -54,7 +55,7 @@
             "2607:fb90:f27:4512:d800:cb23:a603:e245"
           ]
         },
-        "uri": "http://us.example.com/bid?rtb_seat_id=placementId&secret_key=accountId",
+        "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId",
         "body": {
           "id": "some-request-id",
           "device": {
@@ -68,8 +69,8 @@
               "id": "some-impression-id",
               "tagid": "ogTAGID",
               "native": {
-                "ver":"1.1",
-                "request":"{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}"
+                "ver": "1.1",
+                "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}"
               }
             }
           ],
@@ -113,9 +114,9 @@
   ],
   "expectedBidResponses": [
     {
-      "bids":[
+      "bids": [
         {
-          "bid":  {
+          "bid": {
             "id": "a3ae1b4e2fc24a4fb45540082e98e161",
             "impid": "some-impression-id",
             "price": 3.5,
@@ -130,4 +131,4 @@
       ]
     }
   ]
-}
+}
\ No newline at end of file
diff --git a/adapters/bizzclick/bizzclicktest/exemplary/video-app.json b/adapters/bizzclick/bizzclicktest/exemplary/video-app.json
index 18d38b8e..58a4a4a0 100644
--- a/adapters/bizzclick/bizzclicktest/exemplary/video-app.json
+++ b/adapters/bizzclick/bizzclicktest/exemplary/video-app.json
@@ -39,7 +39,8 @@
         "ext": {
           "bidder": {
             "accountId": "accountId",
-            "placementId": "placementId"
+            "sourceId": "sourceId",
+            "host": "host"
           }
         }
       }
@@ -65,7 +66,7 @@
             "123.123.123.123"
           ]
         },
-        "uri": "http://us.example.com/bid?rtb_seat_id=placementId&secret_key=accountId",
+        "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId",
         "body": {
           "id": "some-request-id",
           "device": {
@@ -137,9 +138,9 @@
   ],
   "expectedBidResponses": [
     {
-      "bids":[
+      "bids": [
         {
-          "bid":  {
+          "bid": {
             "id": "a3ae1b4e2fc24a4fb45540082e98e161",
             "impid": "some-impression-id",
             "price": 3.5,
@@ -156,4 +157,4 @@
       ]
     }
   ]
-}
+}
\ No newline at end of file
diff --git a/adapters/bizzclick/bizzclicktest/exemplary/video-web.json b/adapters/bizzclick/bizzclicktest/exemplary/video-web.json
index 57ec0641..69a038b3 100644
--- a/adapters/bizzclick/bizzclicktest/exemplary/video-web.json
+++ b/adapters/bizzclick/bizzclicktest/exemplary/video-web.json
@@ -33,7 +33,8 @@
         "ext": {
           "bidder": {
             "accountId": "accountId",
-            "placementId": "placementId"
+            "sourceId": "sourceId",
+            "host": "host"
           }
         }
       }
@@ -59,7 +60,7 @@
             "123.123.123.123"
           ]
         },
-        "uri": "http://us.example.com/bid?rtb_seat_id=placementId&secret_key=accountId",
+        "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId",
         "body": {
           "id": "some-request-id",
           "device": {
@@ -149,7 +150,7 @@
               }
             }
           },
-          "type":"video"
+          "type": "video"
         }
       ]
     }
diff --git a/adapters/bizzclick/bizzclicktest/supplemental/empty-seatbid-array.json b/adapters/bizzclick/bizzclicktest/supplemental/empty-seatbid-array.json
index 7b244c40..faf72aab 100644
--- a/adapters/bizzclick/bizzclicktest/supplemental/empty-seatbid-array.json
+++ b/adapters/bizzclick/bizzclicktest/supplemental/empty-seatbid-array.json
@@ -39,7 +39,8 @@
         "ext": {
           "bidder": {
             "accountId": "accountId",
-            "placementId": "placementId"
+            "sourceId": "sourceId",
+            "host": "host"
           }
         }
       }
@@ -65,7 +66,7 @@
             "123.123.123.123"
           ]
         },
-        "uri": "http://us.example.com/bid?rtb_seat_id=placementId&secret_key=accountId",
+        "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId",
         "body": {
           "id": "some-request-id",
           "device": {
@@ -111,21 +112,20 @@
         "status": 200,
         "body": {
           "id": "awesome-resp-id",
-          "seatbid": [
-          ],
+          "seatbid": [],
           "cur": "USD"
         }
       }
     }
   ],
-    "mockResponse": {
-      "status": 200,
-      "body": "invalid response"
-    },
+  "mockResponse": {
+    "status": 200,
+    "body": "invalid response"
+  },
   "expectedMakeBidsErrors": [
     {
       "value": "Empty SeatBid array",
       "comparison": "literal"
     }
   ]
-}
+}
\ No newline at end of file
diff --git a/adapters/bizzclick/bizzclicktest/supplemental/invalid-response.json b/adapters/bizzclick/bizzclicktest/supplemental/invalid-response.json
index 57f36d3a..eff1d6ca 100644
--- a/adapters/bizzclick/bizzclicktest/supplemental/invalid-response.json
+++ b/adapters/bizzclick/bizzclicktest/supplemental/invalid-response.json
@@ -1,4 +1,3 @@
-
 {
   "mockBidRequest": {
     "id": "some-request-id",
@@ -29,84 +28,86 @@
         "id": "some-impression-id",
         "tagid": "ogTAGID",
         "banner": {
-          "w":320,
-          "h":50
+          "w": 320,
+          "h": 50
         },
         "ext": {
           "bidder": {
             "accountId": "accountId",
-            "placementId": "placementId"
+            "sourceId": "sourceId",
+            "host": "host"
           }
         }
       }
     ]
   },
-
-  "httpCalls": [{
-    "expectedRequest": {
-      "headers": {
-        "Content-Type": [
-          "application/json;charset=utf-8"
-        ],
-        "Accept": [
-          "application/json"
-        ],
-        "X-Openrtb-Version": [
-          "2.5"
-        ],
-        "User-Agent": [
-          "test-user-agent"
-        ],
-        "X-Forwarded-For": [
-          "123.123.123.123"
-        ]
-      },
-      "uri": "http://us.example.com/bid?rtb_seat_id=placementId&secret_key=accountId",
-      "body": {
-        "id": "some-request-id",
-        "device": {
-          "ua": "test-user-agent",
-          "ip": "123.123.123.123",
-          "language": "en",
-          "dnt": 0
-        },
-        "imp": [
-          {
-            "id": "some-impression-id",
-            "banner": {
-                "w":320,
-                "h":50
-            },
-            "tagid": "ogTAGID"
-          }
-        ],
-        "app": {
-          "id": "123456789",
-          "name": "Awesome App",
-          "bundle": "com.app.awesome",
-          "domain": "awesomeapp.com",
-          "cat": [
-            "IAB22-1"
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "headers": {
+          "Content-Type": [
+            "application/json;charset=utf-8"
           ],
-          "publisher": {
-            "id": "123456789"
-          }
-        },
-        "user": {
-          "buyeruid": "awesome-user"
+          "Accept": [
+            "application/json"
+          ],
+          "X-Openrtb-Version": [
+            "2.5"
+          ],
+          "User-Agent": [
+            "test-user-agent"
+          ],
+          "X-Forwarded-For": [
+            "123.123.123.123"
+          ]
         },
-        "tmax": 1000
+        "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId",
+        "body": {
+          "id": "some-request-id",
+          "device": {
+            "ua": "test-user-agent",
+            "ip": "123.123.123.123",
+            "language": "en",
+            "dnt": 0
+          },
+          "imp": [
+            {
+              "id": "some-impression-id",
+              "banner": {
+                "w": 320,
+                "h": 50
+              },
+              "tagid": "ogTAGID"
+            }
+          ],
+          "app": {
+            "id": "123456789",
+            "name": "Awesome App",
+            "bundle": "com.app.awesome",
+            "domain": "awesomeapp.com",
+            "cat": [
+              "IAB22-1"
+            ],
+            "publisher": {
+              "id": "123456789"
+            }
+          },
+          "user": {
+            "buyeruid": "awesome-user"
+          },
+          "tmax": 1000
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": "invalid response"
       }
-    },
-    "mockResponse": {
-      "status": 200,
-      "body": "invalid response"
     }
-  }],
+  ],
   "expectedMakeBidsErrors": [
     {
       "value": "Bad Server Response",
       "comparison": "literal"
     }
   ]
-}
+}
\ No newline at end of file
diff --git a/adapters/bizzclick/bizzclicktest/supplemental/status-code-bad-request.json b/adapters/bizzclick/bizzclicktest/supplemental/status-code-bad-request.json
index f0a3b91a..eb29b89b 100644
--- a/adapters/bizzclick/bizzclicktest/supplemental/status-code-bad-request.json
+++ b/adapters/bizzclick/bizzclicktest/supplemental/status-code-bad-request.json
@@ -1,4 +1,3 @@
-
 {
   "mockBidRequest": {
     "id": "some-request-id",
@@ -34,55 +33,57 @@
         "ext": {
           "bidder": {
             "accountId": "accountId",
-            "placementId": "placementId"
+            "sourceId": "sourceId",
+            "host": "host"
           }
         }
       }
     ]
   },
-
-  "httpCalls": [{
-    "expectedRequest": {
-      "uri": "http://us.example.com/bid?rtb_seat_id=placementId&secret_key=accountId",
-      "body": {
-        "id": "some-request-id",
-        "imp": [
-          {
-            "id": "some-impression-id",
-            "video": {
-              "mimes": [
-                "video/mp4"
-              ],
-              "minduration": 120,
-              "maxduration": 150,
-              "w": 640,
-              "h": 480
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId",
+        "body": {
+          "id": "some-request-id",
+          "imp": [
+            {
+              "id": "some-impression-id",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 120,
+                "maxduration": 150,
+                "w": 640,
+                "h": 480
+              },
+              "tagid": "ogTAGID"
+            }
+          ],
+          "app": {
+            "publisher": {
+              "id": "123456789"
             },
-            "tagid": "ogTAGID"
-          }
-        ],
-        "app":  {
-          "publisher": {
+            "cat": [
+              "IAB22-1"
+            ],
+            "bundle": "com.app.awesome",
+            "name": "Awesome App",
+            "domain": "awesomeapp.com",
             "id": "123456789"
           },
-          "cat": [
-            "IAB22-1"
-          ],
-          "bundle": "com.app.awesome",
-          "name": "Awesome App",
-          "domain": "awesomeapp.com",
-          "id": "123456789"
-        },
-        "user": {
-          "buyeruid": "awesome-user"
-        },
-        "tmax": 1000
+          "user": {
+            "buyeruid": "awesome-user"
+          },
+          "tmax": 1000
+        }
+      },
+      "mockResponse": {
+        "status": 400
       }
-    },
-    "mockResponse": {
-      "status": 400
     }
-  }],
+  ],
   "expectedBidResponses": [],
   "expectedMakeBidsErrors": [
     {
@@ -90,4 +91,4 @@
       "comparison": "literal"
     }
   ]
-}
+}
\ No newline at end of file
diff --git a/adapters/bizzclick/bizzclicktest/supplemental/status-code-no-content.json b/adapters/bizzclick/bizzclicktest/supplemental/status-code-no-content.json
index 62aecf58..3ed865f2 100644
--- a/adapters/bizzclick/bizzclicktest/supplemental/status-code-no-content.json
+++ b/adapters/bizzclick/bizzclicktest/supplemental/status-code-no-content.json
@@ -11,59 +11,67 @@
         "id": "123456789"
       }
     },
-    "imp": [{
-      "id": "some-impression-id",
-      "tagid": "ogTAGID",
-      "video": {
-        "mimes": ["video/mp4"],
-        "w": 640,
-        "h": 480,
-        "minduration": 120,
-        "maxduration": 150
-      },
-      "ext": {
-        "bidder": {
-          "accountId": "accountId",
-          "placementId": "placementId"
+    "imp": [
+      {
+        "id": "some-impression-id",
+        "tagid": "ogTAGID",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "w": 640,
+          "h": 480,
+          "minduration": 120,
+          "maxduration": 150
+        },
+        "ext": {
+          "bidder": {
+            "accountId": "accountId",
+            "sourceId": "sourceId",
+            "host": "host"
+          }
         }
       }
-    }]
+    ]
   },
-
-  "httpCalls": [{
-    "expectedRequest": {
-      "uri": "http://us.example.com/bid?rtb_seat_id=placementId&secret_key=accountId",
-      "body": {
-        "id": "some-request-id",
-        "imp": [{
-          "id": "some-impression-id",
-          "tagid": "ogTAGID",
-          "video": {
-            "mimes": [
-              "video/mp4"
-            ],
-            "minduration": 120,
-            "maxduration": 150,
-            "w": 640,
-            "h": 480
-          }
-        }],
-        "site": {
-          "page": "test.com",
-          "publisher": {
-            "id": "123456789"
-          }
-        },
-        "user": {
-          "buyeruid": "awesome-user"
-        },
-        "tmax": 1000
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId",
+        "body": {
+          "id": "some-request-id",
+          "imp": [
+            {
+              "id": "some-impression-id",
+              "tagid": "ogTAGID",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 120,
+                "maxduration": 150,
+                "w": 640,
+                "h": 480
+              }
+            }
+          ],
+          "site": {
+            "page": "test.com",
+            "publisher": {
+              "id": "123456789"
+            }
+          },
+          "user": {
+            "buyeruid": "awesome-user"
+          },
+          "tmax": 1000
+        }
+      },
+      "mockResponse": {
+        "status": 204
       }
-    },
-    "mockResponse": {
-      "status": 204
     }
-  }],
+  ],
   "expectedBidResponses": [],
   "expectedMakeBidsErrors": []
 }
\ No newline at end of file
diff --git a/adapters/bizzclick/bizzclicktest/supplemental/status-code-other-error.json b/adapters/bizzclick/bizzclicktest/supplemental/status-code-other-error.json
index 398f0b67..81682bed 100644
--- a/adapters/bizzclick/bizzclicktest/supplemental/status-code-other-error.json
+++ b/adapters/bizzclick/bizzclicktest/supplemental/status-code-other-error.json
@@ -1,4 +1,3 @@
-
 {
   "mockBidRequest": {
     "id": "some-request-id",
@@ -17,7 +16,9 @@
         "id": "some-impression-id",
         "tagid": "ogTAGID",
         "video": {
-          "mimes": ["video/mp4"],
+          "mimes": [
+            "video/mp4"
+          ],
           "w": 640,
           "h": 480,
           "minduration": 120,
@@ -26,49 +27,51 @@
         "ext": {
           "bidder": {
             "accountId": "accountId",
-            "placementId": "placementId"
+            "sourceId": "sourceId",
+            "host": "host"
           }
         }
       }
     ]
   },
-
-  "httpCalls": [{
-    "expectedRequest": {
-      "uri": "http://us.example.com/bid?rtb_seat_id=placementId&secret_key=accountId",
-      "body": {
-        "id": "some-request-id",
-        "imp": [
-          {
-            "id": "some-impression-id",
-            "tagid": "ogTAGID",
-            "video": {
-              "mimes": [
-                "video/mp4"
-              ],
-              "minduration": 120,
-              "maxduration": 150,
-              "w": 640,
-              "h": 480
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId",
+        "body": {
+          "id": "some-request-id",
+          "imp": [
+            {
+              "id": "some-impression-id",
+              "tagid": "ogTAGID",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 120,
+                "maxduration": 150,
+                "w": 640,
+                "h": 480
+              }
             }
-          }
-        ],
-        "site": {
-          "page": "test.com",
-          "publisher": {
-            "id": "123456789"
-          }
-        },
-        "user": {
-          "buyeruid": "awesome-user"
-        },
-        "tmax": 1000
+          ],
+          "site": {
+            "page": "test.com",
+            "publisher": {
+              "id": "123456789"
+            }
+          },
+          "user": {
+            "buyeruid": "awesome-user"
+          },
+          "tmax": 1000
+        }
+      },
+      "mockResponse": {
+        "status": 306
       }
-    },
-    "mockResponse": {
-      "status": 306
     }
-  }],
+  ],
   "expectedBidResponses": [],
   "expectedMakeBidsErrors": [
     {
@@ -76,4 +79,4 @@
       "comparison": "literal"
     }
   ]
-}
+}
\ No newline at end of file
diff --git a/adapters/bizzclick/bizzclicktest/supplemental/status-code-service-unavailable.json b/adapters/bizzclick/bizzclicktest/supplemental/status-code-service-unavailable.json
index 733b5f3f..9ea01f9e 100644
--- a/adapters/bizzclick/bizzclicktest/supplemental/status-code-service-unavailable.json
+++ b/adapters/bizzclick/bizzclicktest/supplemental/status-code-service-unavailable.json
@@ -1,4 +1,3 @@
-
 {
   "mockBidRequest": {
     "id": "some-request-id",
@@ -17,7 +16,9 @@
         "id": "some-impression-id",
         "tagid": "ogTAGID",
         "video": {
-          "mimes": ["video/mp4"],
+          "mimes": [
+            "video/mp4"
+          ],
           "w": 640,
           "h": 480,
           "minduration": 120,
@@ -26,49 +27,51 @@
         "ext": {
           "bidder": {
             "accountId": "accountId",
-            "placementId": "placementId"
+            "sourceId": "sourceId",
+            "host": "host"
           }
         }
       }
     ]
   },
-
-  "httpCalls": [{
-    "expectedRequest": {
-      "uri": "http://us.example.com/bid?rtb_seat_id=placementId&secret_key=accountId",
-      "body": {
-        "id": "some-request-id",
-        "imp": [
-          {
-            "id": "some-impression-id",
-            "tagid": "ogTAGID",
-            "video": {
-              "mimes": [
-                "video/mp4"
-              ],
-              "minduration": 120,
-              "maxduration": 150,
-              "w": 640,
-              "h": 480
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId",
+        "body": {
+          "id": "some-request-id",
+          "imp": [
+            {
+              "id": "some-impression-id",
+              "tagid": "ogTAGID",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 120,
+                "maxduration": 150,
+                "w": 640,
+                "h": 480
+              }
             }
-          }
-        ],
-        "site": {
-          "page": "test.com",
-          "publisher": {
-            "id": "123456789"
-          }
-        },
-        "user": {
-          "buyeruid": "awesome-user"
-        },
-        "tmax": 1000
+          ],
+          "site": {
+            "page": "test.com",
+            "publisher": {
+              "id": "123456789"
+            }
+          },
+          "user": {
+            "buyeruid": "awesome-user"
+          },
+          "tmax": 1000
+        }
+      },
+      "mockResponse": {
+        "status": 503
       }
-    },
-    "mockResponse": {
-      "status": 503
     }
-  }],
+  ],
   "expectedBidResponses": [],
   "expectedMakeBidsErrors": [
     {
@@ -76,4 +79,4 @@
       "comparison": "literal"
     }
   ]
-}
+}
\ No newline at end of file
diff --git a/adapters/bizzclick/params_test.go b/adapters/bizzclick/params_test.go
index 496643a5..fe72e41f 100644
--- a/adapters/bizzclick/params_test.go
+++ b/adapters/bizzclick/params_test.go
@@ -8,7 +8,7 @@ import (
 )
 
 var validParams = []string{
-	`{  "accountId": "hash",  "placementId": "hash"}`,
+	`{ "host": "ep1", "sourceId": "partner", "accountId": "hash" }`,
 }
 
 func TestValidParams(t *testing.T) {
diff --git a/adapters/minutemedia/minutemedia_test.go b/adapters/minutemedia/minutemedia_test.go
new file mode 100644
index 00000000..5ab59773
--- /dev/null
+++ b/adapters/minutemedia/minutemedia_test.go
@@ -0,0 +1,24 @@
+package minutemedia
+
+import (
+	"testing"
+
+	"github.com/prebid/prebid-server/v2/adapters/adapterstest"
+	"github.com/prebid/prebid-server/v2/config"
+	"github.com/prebid/prebid-server/v2/openrtb_ext"
+)
+
+const testsDir = "minutemediatest"
+const testsBidderEndpoint = "http://localhost/prebid_server"
+
+func TestJsonSamples(t *testing.T) {
+	bidder, buildErr := Builder(
+		openrtb_ext.BidderMinuteMedia,
+		config.Adapter{Endpoint: testsBidderEndpoint},
+		config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
+	if buildErr != nil {
+		t.Fatalf("Builder returned unexpected error %v", buildErr)
+	}
+
+	adapterstest.RunJSONBidderTest(t, testsDir, bidder)
+}
diff --git a/adapters/minutemedia/minutemediatest/exemplary/banner-and-video-app.json b/adapters/minutemedia/minutemediatest/exemplary/banner-and-video-app.json
new file mode 100644
index 00000000..f1051001
--- /dev/null
+++ b/adapters/minutemedia/minutemediatest/exemplary/banner-and-video-app.json
@@ -0,0 +1,251 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            },
+            {
+              "w": 300,
+              "h": 300
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "org": "72721",
+            "path": "mvo",
+            "zone": "1r"
+          }
+        }
+      },
+      {
+        "id": "test-imp-video-id",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "minduration": 1,
+          "maxduration": 2,
+          "protocols": [
+            1,
+            2,
+            5
+          ],
+          "w": 1020,
+          "h": 780,
+          "startdelay": 1,
+          "placement": 1,
+          "playbackmethod": [
+            2
+          ],
+          "delivery": [
+            1
+          ],
+          "api": [
+            1,
+            2,
+            3,
+            4
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "org": "72721",
+            "path": "mvo",
+            "zone": "1r"
+          }
+        }
+      }
+    ],
+    "app": {
+      "id": "fake-app-id",
+      "name": "MinuteMedia Fake Test App",
+      "bundle": "12345",
+      "storeurl": "https://example.com/fake-store-url",
+      "cat": [
+        "IAB15",
+        "IAB15-10"
+      ],
+      "ver": "1.0.2",
+      "publisher": {
+        "id": "1"
+      }
+    },
+    "device": {
+      "dnt": 0,
+      "ua": "Fake Browser",
+      "ip": "123.145.167.189",
+      "carrier": "FakeTelco",
+      "language": "en",
+      "make": "Apple",
+      "model": "iPhone",
+      "os": "iOS",
+      "osv": "6.1",
+      "js": 1,
+      "ifa": "1234567890ABCDEF",
+      "connectiontype": 3,
+      "devicetype": 1
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server?publisher_id=72721",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 250
+                  },
+                  {
+                    "w": 300,
+                    "h": 300
+                  }
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "org": "72721",
+                  "zone": "1r",
+                  "path": "mvo"
+                }
+              }
+            },
+            {
+              "id": "test-imp-video-id",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 1,
+                "maxduration": 2,
+                "protocols": [
+                  1,
+                  2,
+                  5
+                ],
+                "w": 1020,
+                "h": 780,
+                "startdelay": 1,
+                "placement": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "delivery": [
+                  1
+                ],
+                "api": [
+                  1,
+                  2,
+                  3,
+                  4
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "org": "72721",
+                  "zone": "1r",
+                  "path": "mvo"
+                }
+              }
+            }
+          ],
+          "app": {
+            "id": "fake-app-id",
+            "name": "MinuteMedia Fake Test App",
+            "bundle": "12345",
+            "storeurl": "https://example.com/fake-store-url",
+            "cat": [
+              "IAB15",
+              "IAB15-10"
+            ],
+            "ver": "1.0.2",
+            "publisher": {
+              "id": "1"
+            }
+          },
+          "device": {
+            "dnt": 0,
+            "ua": "Fake Browser",
+            "ip": "123.145.167.189",
+            "carrier": "FakeTelco",
+            "language": "en",
+            "make": "Apple",
+            "model": "iPhone",
+            "os": "iOS",
+            "osv": "6.1",
+            "js": 1,
+            "ifa": "1234567890ABCDEF",
+            "connectiontype": 3,
+            "devicetype": 1
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "seat": "958",
+              "bid": [
+                {
+                  "id": "7706636740145184841",
+                  "impid": "test-imp-video-id",
+                  "price": 0.5,
+                  "adid": "29681110",
+                  "adm": "some-test-ad",
+                  "adomain": [
+                    "yahoo.com"
+                  ],
+                  "cid": "958",
+                  "crid": "29681110",
+                  "h": 576,
+                  "w": 1024,
+                  "mtype": 2
+                }
+              ]
+            }
+          ],
+          "bidid": "5778926625248726496",
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "7706636740145184841",
+            "impid": "test-imp-video-id",
+            "price": 0.5,
+            "adm": "some-test-ad",
+            "adid": "29681110",
+            "adomain": [
+              "yahoo.com"
+            ],
+            "cid": "958",
+            "crid": "29681110",
+            "w": 1024,
+            "h": 576,
+            "mtype": 2
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/minutemedia/minutemediatest/exemplary/banner-and-video-gdpr.json b/adapters/minutemedia/minutemediatest/exemplary/banner-and-video-gdpr.json
new file mode 100644
index 00000000..6816955d
--- /dev/null
+++ b/adapters/minutemedia/minutemediatest/exemplary/banner-and-video-gdpr.json
@@ -0,0 +1,215 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            },
+            {
+              "w": 300,
+              "h": 300
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "org": "72721",
+            "path": "mvo",
+            "zone": "1r"
+          }
+        }
+      },
+      {
+        "id": "test-imp-video-id",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "minduration": 1,
+          "maxduration": 2,
+          "protocols": [
+            1,
+            2,
+            5
+          ],
+          "w": 1020,
+          "h": 780,
+          "startdelay": 1,
+          "placement": 1,
+          "playbackmethod": [
+            2
+          ],
+          "delivery": [
+            1
+          ],
+          "api": [
+            1,
+            2,
+            3,
+            4
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "org": "72721",
+            "path": "mvo",
+            "zone": "1r"
+          }
+        }
+      }
+    ],
+    "user": {
+      "id": "eyJ0ZW1wVUlEcyI6eyJhZGZvcm0iOnsidWlkIjoiMzA5MTMwOTUxNjQ5NDA1MjcxIiwiZXhwaXJlcyI6IjIwMTgtMDYtMjBUMTE6NDA6MzUuODAwNTE0NzQ3KzA1OjMwIn0sImFkbnhzIjp7InVpZCI6IjM1MTUzMjg2MTAyNjMxNjQ0ODQiLCJleHBpcmVzIjoiMjAxOC0wNi0xOFQxODoxMjoxNy4wMTExMzg2MDgrMDU6MzAifX0sImJkYXkiOiIyMDE4LTA2LTA0VDE4OjEyOjE3LjAxMTEzMDg3NSswNTozMCJ9",
+      "ext": {
+        "consent": "BOPVK28OPVK28ABABAENA8-AAAADkCNQCGoQAAQ"
+      }
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 1
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server?publisher_id=72721",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 250
+                  },
+                  {
+                    "w": 300,
+                    "h": 300
+                  }
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "org": "72721",
+                  "zone": "1r",
+                  "path": "mvo"
+                }
+              }
+            },
+            {
+              "id": "test-imp-video-id",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 1,
+                "maxduration": 2,
+                "protocols": [
+                  1,
+                  2,
+                  5
+                ],
+                "w": 1020,
+                "h": 780,
+                "startdelay": 1,
+                "placement": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "delivery": [
+                  1
+                ],
+                "api": [
+                  1,
+                  2,
+                  3,
+                  4
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "org": "72721",
+                  "zone": "1r",
+                  "path": "mvo"
+                }
+              }
+            }
+          ],
+          "user": {
+            "id": "eyJ0ZW1wVUlEcyI6eyJhZGZvcm0iOnsidWlkIjoiMzA5MTMwOTUxNjQ5NDA1MjcxIiwiZXhwaXJlcyI6IjIwMTgtMDYtMjBUMTE6NDA6MzUuODAwNTE0NzQ3KzA1OjMwIn0sImFkbnhzIjp7InVpZCI6IjM1MTUzMjg2MTAyNjMxNjQ0ODQiLCJleHBpcmVzIjoiMjAxOC0wNi0xOFQxODoxMjoxNy4wMTExMzg2MDgrMDU6MzAifX0sImJkYXkiOiIyMDE4LTA2LTA0VDE4OjEyOjE3LjAxMTEzMDg3NSswNTozMCJ9",
+            "ext": {
+              "consent": "BOPVK28OPVK28ABABAENA8-AAAADkCNQCGoQAAQ"
+            }
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 1
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "seat": "958",
+              "bid": [
+                {
+                  "id": "7706636740145184841",
+                  "impid": "test-imp-video-id",
+                  "price": 0.5,
+                  "adid": "29681110",
+                  "adm": "some-test-ad",
+                  "adomain": [
+                    "yahoo.com"
+                  ],
+                  "cid": "958",
+                  "crid": "29681110",
+                  "h": 576,
+                  "w": 1024,
+                  "mtype": 2
+                }
+              ]
+            }
+          ],
+          "bidid": "5778926625248726496",
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "7706636740145184841",
+            "impid": "test-imp-video-id",
+            "price": 0.5,
+            "adm": "some-test-ad",
+            "adid": "29681110",
+            "adomain": [
+              "yahoo.com"
+            ],
+            "cid": "958",
+            "crid": "29681110",
+            "w": 1024,
+            "h": 576,
+            "mtype": 2
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/minutemedia/minutemediatest/exemplary/banner-and-video-site.json b/adapters/minutemedia/minutemediatest/exemplary/banner-and-video-site.json
new file mode 100644
index 00000000..9beae53c
--- /dev/null
+++ b/adapters/minutemedia/minutemediatest/exemplary/banner-and-video-site.json
@@ -0,0 +1,233 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            },
+            {
+              "w": 300,
+              "h": 300
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "org": "72721",
+            "path": "mvo",
+            "zone": "1r"
+          }
+        }
+      },
+      {
+        "id": "test-imp-video-id",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "minduration": 1,
+          "maxduration": 2,
+          "protocols": [
+            1,
+            2,
+            5
+          ],
+          "w": 1020,
+          "h": 780,
+          "startdelay": 1,
+          "placement": 1,
+          "playbackmethod": [
+            2
+          ],
+          "delivery": [
+            1
+          ],
+          "api": [
+            1,
+            2,
+            3,
+            4
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "org": "72721",
+            "path": "mvo",
+            "zone": "1r"
+          }
+        }
+      }
+    ],
+    "site": {
+      "id": "102855",
+      "cat": [
+        "IAB3-1"
+      ],
+      "domain": "www.foobar.com",
+      "page": "http://www.foobar.com/1234.html ",
+      "publisher": {
+        "id": "8953",
+        "name": "foobar.com",
+        "cat": [
+          "IAB3-1"
+        ],
+        "domain": "foobar.com"
+      }
+    },
+    "device": {
+      "ua": "Fake Test User Agent/6.0",
+      "ip": "123.145.167.10"
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server?publisher_id=72721",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 250
+                  },
+                  {
+                    "w": 300,
+                    "h": 300
+                  }
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "org": "72721",
+                  "zone": "1r",
+                  "path": "mvo"
+                }
+              }
+            },
+            {
+              "id": "test-imp-video-id",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 1,
+                "maxduration": 2,
+                "protocols": [
+                  1,
+                  2,
+                  5
+                ],
+                "w": 1020,
+                "h": 780,
+                "startdelay": 1,
+                "placement": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "delivery": [
+                  1
+                ],
+                "api": [
+                  1,
+                  2,
+                  3,
+                  4
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "org": "72721",
+                  "zone": "1r",
+                  "path": "mvo"
+                }
+              }
+            }
+          ],
+          "site": {
+            "id": "102855",
+            "cat": [
+              "IAB3-1"
+            ],
+            "domain": "www.foobar.com",
+            "page": "http://www.foobar.com/1234.html ",
+            "publisher": {
+              "id": "8953",
+              "name": "foobar.com",
+              "cat": [
+                "IAB3-1"
+              ],
+              "domain": "foobar.com"
+            }
+          },
+          "device": {
+            "ua": "Fake Test User Agent/6.0",
+            "ip": "123.145.167.10"
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "seat": "958",
+              "bid": [
+                {
+                  "id": "7706636740145184841",
+                  "impid": "test-imp-video-id",
+                  "price": 0.5,
+                  "adid": "29681110",
+                  "adm": "some-test-ad",
+                  "adomain": [
+                    "yahoo.com"
+                  ],
+                  "cid": "958",
+                  "crid": "29681110",
+                  "h": 576,
+                  "w": 1024,
+                  "mtype": 2
+                }
+              ]
+            }
+          ],
+          "bidid": "5778926625248726496",
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "7706636740145184841",
+            "impid": "test-imp-video-id",
+            "price": 0.5,
+            "adm": "some-test-ad",
+            "adid": "29681110",
+            "adomain": [
+              "yahoo.com"
+            ],
+            "cid": "958",
+            "crid": "29681110",
+            "w": 1024,
+            "h": 576,
+            "mtype": 2
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/minutemedia/minutemediatest/exemplary/banner-and-video.json b/adapters/minutemedia/minutemediatest/exemplary/banner-and-video.json
new file mode 100644
index 00000000..51dad5de
--- /dev/null
+++ b/adapters/minutemedia/minutemediatest/exemplary/banner-and-video.json
@@ -0,0 +1,193 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            },
+            {
+              "w": 300,
+              "h": 300
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "org": "72721",
+            "path": "mvo",
+            "zone": "1r"
+          }
+        }
+      },
+      {
+        "id": "test-imp-video-id",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "minduration": 1,
+          "maxduration": 2,
+          "protocols": [
+            1,
+            2,
+            5
+          ],
+          "w": 1020,
+          "h": 780,
+          "startdelay": 1,
+          "placement": 1,
+          "playbackmethod": [
+            2
+          ],
+          "delivery": [
+            1
+          ],
+          "api": [
+            1,
+            2,
+            3,
+            4
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "org": "72721",
+            "path": "mvo",
+            "zone": "1r"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server?publisher_id=72721",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 250
+                  },
+                  {
+                    "w": 300,
+                    "h": 300
+                  }
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "org": "72721",
+                  "zone": "1r",
+                  "path": "mvo"
+                }
+              }
+            },
+            {
+              "id": "test-imp-video-id",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 1,
+                "maxduration": 2,
+                "protocols": [
+                  1,
+                  2,
+                  5
+                ],
+                "w": 1020,
+                "h": 780,
+                "startdelay": 1,
+                "placement": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "delivery": [
+                  1
+                ],
+                "api": [
+                  1,
+                  2,
+                  3,
+                  4
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "org": "72721",
+                  "zone": "1r",
+                  "path": "mvo"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "seat": "958",
+              "bid": [
+                {
+                  "id": "7706636740145184841",
+                  "impid": "test-imp-video-id",
+                  "price": 0.500000,
+                  "adid": "29681110",
+                  "adm": "some-test-ad",
+                  "adomain": [
+                    "yahoo.com"
+                  ],
+                  "cid": "958",
+                  "crid": "29681110",
+                  "h": 576,
+                  "w": 1024,
+                  "mtype": 1
+                }
+              ]
+            }
+          ],
+          "bidid": "5778926625248726496",
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "7706636740145184841",
+            "impid": "test-imp-video-id",
+            "price": 0.5,
+            "adm": "some-test-ad",
+            "adid": "29681110",
+            "adomain": [
+              "yahoo.com"
+            ],
+            "cid": "958",
+            "crid": "29681110",
+            "w": 1024,
+            "h": 576,
+            "mtype": 1
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/minutemedia/minutemediatest/exemplary/simple-banner.json b/adapters/minutemedia/minutemediatest/exemplary/simple-banner.json
new file mode 100644
index 00000000..51a62bea
--- /dev/null
+++ b/adapters/minutemedia/minutemediatest/exemplary/simple-banner.json
@@ -0,0 +1,117 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            },
+            {
+              "w": 300,
+              "h": 300
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "org": "72721",
+            "path": "mvo",
+            "zone": "1r"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server?publisher_id=72721",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 250
+                  },
+                  {
+                    "w": 300,
+                    "h": 300
+                  }
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "org": "72721",
+                  "zone": "1r",
+                  "path": "mvo"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "seat": "958",
+              "bid": [
+                {
+                  "id": "7706636740145184841",
+                  "impid": "test-imp-id",
+                  "price": 0.500000,
+                  "adid": "29681110",
+                  "adm": "some-test-ad",
+                  "adomain": [
+                    "yahoo.com"
+                  ],
+                  "cid": "958",
+                  "crid": "29681110",
+                  "h": 250,
+                  "w": 300,
+                  "mtype": 1
+                }
+              ]
+            }
+          ],
+          "bidid": "5778926625248726496",
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "7706636740145184841",
+            "impid": "test-imp-id",
+            "price": 0.5,
+            "adm": "some-test-ad",
+            "adid": "29681110",
+            "adomain": [
+              "yahoo.com"
+            ],
+            "cid": "958",
+            "crid": "29681110",
+            "w": 300,
+            "h": 250,
+            "mtype": 1
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/minutemedia/minutemediatest/exemplary/simple-video.json b/adapters/minutemedia/minutemediatest/exemplary/simple-video.json
new file mode 100644
index 00000000..e188baf5
--- /dev/null
+++ b/adapters/minutemedia/minutemediatest/exemplary/simple-video.json
@@ -0,0 +1,138 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "minduration": 1,
+          "maxduration": 2,
+          "protocols": [
+            1,
+            3,
+            5
+          ],
+          "w": 1020,
+          "h": 780,
+          "startdelay": 1,
+          "placement": 1,
+          "playbackmethod": [
+            2
+          ],
+          "delivery": [
+            1
+          ],
+          "api": [
+            1,
+            2,
+            3,
+            4
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "org": "72721",
+            "path": "mvo",
+            "zone": "1r"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server?publisher_id=72721",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 1,
+                "maxduration": 2,
+                "protocols": [
+                  1,
+                  3,
+                  5
+                ],
+                "w": 1020,
+                "h": 780,
+                "startdelay": 1,
+                "placement": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "delivery": [
+                  1
+                ],
+                "api": [
+                  1,
+                  2,
+                  3,
+                  4
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "org": "72721",
+                  "zone": "1r",
+                  "path": "mvo"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "cur": "USD",
+          "seatbid": [
+            {
+              "seat": "958",
+              "bid": [
+                {
+                  "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
+                  "impid": "test-imp-id",
+                  "price": 0.500000,
+                  "adm": "some-test-ad",
+                  "crid": "crid_10",
+                  "w": 1024,
+                  "h": 576,
+                  "mtype": 2
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
+            "impid": "test-imp-id",
+            "price": 0.5,
+            "adm": "some-test-ad",
+            "crid": "crid_10",
+            "w": 1024,
+            "h": 576,
+            "mtype": 2
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/minutemedia/minutemediatest/supplemental/bad-request.json b/adapters/minutemedia/minutemediatest/supplemental/bad-request.json
new file mode 100644
index 00000000..ccb32559
--- /dev/null
+++ b/adapters/minutemedia/minutemediatest/supplemental/bad-request.json
@@ -0,0 +1,105 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "minduration": 1,
+          "maxduration": 2,
+          "protocols": [
+            1,
+            3,
+            5
+          ],
+          "w": 1020,
+          "h": 780,
+          "startdelay": 1,
+          "placement": 1,
+          "playbackmethod": [
+            2
+          ],
+          "delivery": [
+            1
+          ],
+          "api": [
+            1,
+            2,
+            3,
+            4
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "org": "72721",
+            "path": "mvo",
+            "zone": "1r"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server?publisher_id=72721",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 1,
+                "maxduration": 2,
+                "protocols": [
+                  1,
+                  3,
+                  5
+                ],
+                "w": 1020,
+                "h": 780,
+                "startdelay": 1,
+                "placement": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "delivery": [
+                  1
+                ],
+                "api": [
+                  1,
+                  2,
+                  3,
+                  4
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "org": "72721",
+                  "zone": "1r",
+                  "path": "mvo"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 400,
+        "body": {}
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Unexpected status code: 400. Run with request.debug = 1 for more info",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/minutemedia/minutemediatest/supplemental/missing-bidder.json b/adapters/minutemedia/minutemediatest/supplemental/missing-bidder.json
new file mode 100644
index 00000000..c5724e88
--- /dev/null
+++ b/adapters/minutemedia/minutemediatest/supplemental/missing-bidder.json
@@ -0,0 +1,48 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-missing-ext-id",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "minduration": 1,
+          "maxduration": 2,
+          "maxextended": 30,
+          "minbitrate": 300,
+          "maxbitrate": 1500,
+          "protocols": [
+            1,
+            2,
+            5
+          ],
+          "w": 1020,
+          "h": 780,
+          "startdelay": 1,
+          "placement": 1,
+          "playbackmethod": [
+            2
+          ],
+          "delivery": [
+            1
+          ],
+          "api": [
+            1,
+            2,
+            3,
+            4
+          ]
+        },
+        "ext": {}
+      }
+    ]
+  },
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "failed to extract org: failed to unmarshal ImpExtMinuteMedia: unexpected end of JSON input",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/minutemedia/minutemediatest/supplemental/missing-extension.json b/adapters/minutemedia/minutemediatest/supplemental/missing-extension.json
new file mode 100644
index 00000000..bd0f87c3
--- /dev/null
+++ b/adapters/minutemedia/minutemediatest/supplemental/missing-extension.json
@@ -0,0 +1,47 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-missing-ext-id",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "minduration": 1,
+          "maxduration": 2,
+          "maxextended": 30,
+          "minbitrate": 300,
+          "maxbitrate": 1500,
+          "protocols": [
+            1,
+            2,
+            5
+          ],
+          "w": 1020,
+          "h": 780,
+          "startdelay": 1,
+          "placement": 1,
+          "playbackmethod": [
+            2
+          ],
+          "delivery": [
+            1
+          ],
+          "api": [
+            1,
+            2,
+            3,
+            4
+          ]
+        }
+      }
+    ]
+  },
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "failed to extract org: failed to unmarshal bidderExt: unexpected end of JSON input",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/minutemedia/minutemediatest/supplemental/missing-mtype.json b/adapters/minutemedia/minutemediatest/supplemental/missing-mtype.json
new file mode 100644
index 00000000..ba1c2017
--- /dev/null
+++ b/adapters/minutemedia/minutemediatest/supplemental/missing-mtype.json
@@ -0,0 +1,149 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "minduration": 1,
+          "maxduration": 2,
+          "protocols": [
+            1,
+            3,
+            5
+          ],
+          "w": 1020,
+          "h": 780,
+          "startdelay": 1,
+          "placement": 1,
+          "playbackmethod": [
+            2
+          ],
+          "delivery": [
+            1
+          ],
+          "api": [
+            1,
+            2,
+            3,
+            4
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "org": "72721",
+            "path": "mvo",
+            "zone": "1r"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server?publisher_id=72721",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 1,
+                "maxduration": 2,
+                "protocols": [
+                  1,
+                  3,
+                  5
+                ],
+                "w": 1020,
+                "h": 780,
+                "startdelay": 1,
+                "placement": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "delivery": [
+                  1
+                ],
+                "api": [
+                  1,
+                  2,
+                  3,
+                  4
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "org": "72721",
+                  "zone": "1r",
+                  "path": "mvo"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "cur": "USD",
+          "seatbid": [
+            {
+              "seat": "958",
+              "bid": [
+                {
+                  "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
+                  "impid": "test-imp-id",
+                  "price": 0.500000,
+                  "adm": "some-test-ad",
+                  "crid": "crid_10",
+                  "w": 1024,
+                  "h": 576
+                }
+              ]
+            },
+            {
+              "seat": "958",
+              "bid": [
+                {
+                  "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
+                  "impid": "test-imp-id",
+                  "price": 0.500000,
+                  "adm": "some-test-ad",
+                  "crid": "crid_10",
+                  "w": 1024,
+                  "h": 576,
+                  "mtype": 3
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "unsupported MType 0",
+      "comparison": "literal"
+    },
+    {
+      "value": "unsupported MType 3",
+      "comparison": "literal"
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": []
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/app_banner.json b/adapters/rtbhouse/rtbhousetest/exemplary/app_banner.json
new file mode 100644
index 00000000..733d4b73
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/exemplary/app_banner.json
@@ -0,0 +1,98 @@
+{
+  "mockBidRequest": {
+      "id": "test-request-id",
+      "app": {
+        "bundle": "com.prebid"
+      },
+      "device": {
+        "ua": "test-user-agent",
+        "ip": "123.123.123.123",
+        "language": "en",
+        "dnt": 0
+      },
+      "imp": [{
+          "id": "test-imp-id",
+          "banner": {
+              "format": [{
+                  "w": 300,
+                  "h": 250
+              }]
+          },
+          "ext": {
+              "bidder": {}
+          }
+      }]
+  },
+
+  "httpCalls": [{
+      "expectedRequest": {
+          "uri": "http://localhost/prebid_server",
+          "body": {
+              "id": "test-request-id",
+              "cur": ["USD"],
+              "app": {
+                "bundle": "com.prebid"
+              },
+              "device": {
+                "ua": "test-user-agent",
+                "ip": "123.123.123.123",
+                "language": "en",
+                "dnt": 0
+              },
+              "imp": [{
+                  "id": "test-imp-id",
+                  "banner": {
+                      "format": [{
+                          "w": 300,
+                          "h": 250
+                      }]
+                  },
+                  "ext": {
+                      "bidder": {}
+                  }
+              }]
+          }
+      },
+      "mockResponse": {
+          "status": 200,
+          "body": {
+              "id": "test-request-id",
+              "seatbid": [{
+                  "seat": "rtbhouse",
+                  "bid": [{
+                      "id": "randomid",
+                      "impid": "test-imp-id",
+                      "price": 0.500000,
+                      "adid": "12345678",
+                      "adm": "some-test-ad",
+                      "cid": "987",
+                      "crid": "12345678",
+                      "h": 250,
+                      "w": 300,
+                      "mtype": 1
+                  }]
+              }],
+              "cur": "USD"
+          }
+      }
+  }],
+
+  "expectedBidResponses": [{
+      "currency": "USD",
+      "bids": [{
+          "bid": {
+              "id": "randomid",
+              "impid": "test-imp-id",
+              "price": 0.5,
+              "adm": "some-test-ad",
+              "adid": "12345678",
+              "cid": "987",
+              "crid": "12345678",
+              "w": 300,
+              "h": 250,
+              "mtype": 1
+          },
+          "type": "banner"
+      }]
+  }]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/app_native.json b/adapters/rtbhouse/rtbhousetest/exemplary/app_native.json
new file mode 100644
index 00000000..705e89d8
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/exemplary/app_native.json
@@ -0,0 +1,112 @@
+{
+  "mockBidRequest": {
+    "imp": [
+      {
+        "ext": {
+          "bidder": {}
+        },
+        "id": "test-native-imp",
+        "native": {
+          "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}",
+          "ver": "1.2"
+        }
+      }
+    ],
+    "app": {
+      "bundle": "com.prebid"
+    },
+    "device": {
+      "ua": "test-user-agent",
+      "ip": "123.123.123.123",
+      "language": "en",
+      "dnt": 0
+    },
+    "id": "test-native-request",
+    "ext": {},
+    "debug": 1
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server",
+        "body": {
+          "id": "test-native-request",
+          "cur": [
+            "USD"
+          ],
+          "imp": [
+            {
+              "id": "test-native-imp",
+              "native": {
+                "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}",
+                "ver": "1.2"
+              },
+              "ext": {
+                "bidder": {}
+              }
+            }
+          ],
+          "app": {
+            "bundle": "com.prebid"
+          },
+          "device": {
+            "ua": "test-user-agent",
+            "ip": "123.123.123.123",
+            "language": "en",
+            "dnt": 0
+          },
+          "ext": {}
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-native-request",
+          "bidid": "test-bidid",
+          "cur": "USD",
+          "seatbid": [
+            {
+              "seat": "rtbhouse",
+              "bid": [
+                {
+                  "id": "test-native-request",
+                  "impid": "test-native-imp",
+                  "price": 0.5,
+                  "adid": "test-adid",
+                  "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}",
+                  "adomain": [ "adomain.com" ],
+                  "cid": "test-cid",
+                  "crid": "test-crid",
+                  "dealid": "test-dealid",
+                  "mtype": 4
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "test-native-request",
+            "impid": "test-native-imp",
+            "price": 0.5,
+            "adid": "test-adid",
+            "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}",
+            "adomain": [ "adomain.com" ],
+            "cid": "test-cid",
+            "crid": "test-crid",
+            "dealid": "test-dealid",
+            "mtype": 4
+          },
+          "type": "native"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/yandex/params_test.go b/adapters/yandex/params_test.go
new file mode 100644
index 00000000..e65c82ff
--- /dev/null
+++ b/adapters/yandex/params_test.go
@@ -0,0 +1,87 @@
+package yandex
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/prebid/prebid-server/v2/openrtb_ext"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestValidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json schema. %v", err)
+	}
+
+	for _, p := range validParams {
+		if err := validator.Validate(openrtb_ext.BidderYandex, json.RawMessage(p)); err != nil {
+			t.Errorf("Schema rejected valid params: %s", p)
+		}
+	}
+}
+
+func TestInvalidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json schema. %v", err)
+	}
+
+	for _, p := range invalidParams {
+		if err := validator.Validate(openrtb_ext.BidderYandex, json.RawMessage(p)); err == nil {
+			t.Errorf("Schema allowed invalid params: %s", p)
+		}
+	}
+}
+
+var validParams = []string{
+	`{"page_id": 123123, "imp_id": 123}`,
+	`{"placement_id": "A-123123-123"}`,
+	`{"placement_id": "B-A-123123-123"}`,
+	`{"placement_id": "123123-123"}`,
+}
+
+var invalidParams = []string{
+	`{"pageId": 123123, "impId": 123}`,
+	`{"page_id": 0, "imp_id": 0}`,
+	`{"page_id": "123123", "imp_id": "123"}`,
+	`{"page_id": "123123", "imp_id": "123", "placement_id": "123123"}`,
+	`{"page_id": "123123"}`,
+	`{"imp_id": "123"}`,
+	`{"placement_id": 123123}`,
+	`{"placement_id": "123123"}`,
+	`{"placement_id": "A-123123"}`,
+	`{"placement_id": "B-A-123123"}`,
+	`{}`,
+}
+
+func TestValidPlacementIdMapper(t *testing.T) {
+	for ext, expectedPlacementId := range validPlacementIds {
+		val, err := mapExtToPlacementID(ext)
+
+		assert.Equal(t, &expectedPlacementId, val)
+		assert.NoError(t, err)
+	}
+}
+
+func TestInvalidPlacementIdMapper(t *testing.T) {
+	for _, ext := range invalidPlacementIds {
+		_, err := mapExtToPlacementID(ext)
+
+		assert.Error(t, err)
+	}
+}
+
+var validPlacementIds = map[openrtb_ext.ExtImpYandex]yandexPlacementID{
+	{PlacementID: "A-12345-1"}:      {PageID: "12345", ImpID: "1"},
+	{PlacementID: "B-A-123123-123"}: {PageID: "123123", ImpID: "123"},
+	{PlacementID: "111-222"}:        {PageID: "111", ImpID: "222"},
+	{PageID: 111, ImpID: 222}:       {PageID: "111", ImpID: "222"},
+}
+
+var invalidPlacementIds = []openrtb_ext.ExtImpYandex{
+	{PlacementID: "123123"},
+	{PlacementID: "A-123123"},
+	{PlacementID: "B-A-123123"},
+	{PlacementID: "C-B-A-123123"},
+}
diff --git a/adapters/yandex/yandex_test.go b/adapters/yandex/yandex_test.go
new file mode 100644
index 00000000..6978cd8b
--- /dev/null
+++ b/adapters/yandex/yandex_test.go
@@ -0,0 +1,29 @@
+package yandex
+
+import (
+	"testing"
+
+	"github.com/prebid/prebid-server/v2/adapters/adapterstest"
+	"github.com/prebid/prebid-server/v2/config"
+	"github.com/prebid/prebid-server/v2/openrtb_ext"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestJsonSamples(t *testing.T) {
+	bidder, buildErr := Builder(openrtb_ext.BidderYandex,
+		config.Adapter{Endpoint: "https://bs-metadsp.yandex.ru/prebid/{{.PageID}}?ssp-id=10500"},
+		config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
+
+	if buildErr != nil {
+		t.Fatalf("Builder returned unexpected error %v", buildErr)
+	}
+
+	adapterstest.RunJSONBidderTest(t, "yandextest", bidder)
+}
+
+func TestEndpointTemplateMalformed(t *testing.T) {
+	_, buildErr := Builder(openrtb_ext.BidderYandex, config.Adapter{
+		Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
+
+	assert.Error(t, buildErr)
+}
diff --git a/adapters/yandex/yandextest/exemplary/native.json b/adapters/yandex/yandextest/exemplary/native.json
new file mode 100644
index 00000000..f9b38885
--- /dev/null
+++ b/adapters/yandex/yandextest/exemplary/native.json
@@ -0,0 +1,134 @@
+{
+  "mockBidRequest": {
+    "id": "request_id",
+    "imp": [
+      {
+        "id": "imp_id",
+        "native": {
+          "request": "{}",
+          "ver": "1"
+        },
+        "ext": {
+          "bidder": {
+            "placement_id": "R-134001-1"
+          }
+        }
+      }
+    ],
+    "site": {
+      "domain": "www.example.com",
+      "page": "http://www.example.com"
+    },
+    "cur": [
+      "USD"
+    ],
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+      "ip": "127.0.0.1",
+      "language": "EN"
+    },
+    "tmax": 500
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bs-metadsp.yandex.ru/prebid/134001?imp-id=1&ssp-cur=USD&ssp-id=10500&target-ref=www.example.com",
+        "headers": {
+          "User-Agent": [
+            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
+          ],
+          "X-Forwarded-For": [
+            "127.0.0.1"
+          ],
+          "X-Real-Ip": [
+            "127.0.0.1"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Referer": [
+            "http://www.example.com"
+          ],
+          "Accept": [
+            "application/json"
+          ],
+          "Accept-Language": [
+            "EN"
+          ]
+        },
+        "body": {
+          "id": "request_id",
+          "imp": [
+            {
+              "id": "imp_id",
+              "native": {
+                "request": "{}",
+                "ver": "1"
+              },
+              "ext": {
+                "bidder": {
+                  "placement_id": "R-134001-1"
+                }
+              }
+            }
+          ],
+          "site": {
+            "domain": "www.example.com",
+            "page": "http://www.example.com"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+            "ip": "127.0.0.1",
+            "language": "EN"
+          },
+          "tmax": 500
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "headers": {},
+        "body": {
+          "id": "request_id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "bid_id",
+                  "impid": "imp_id",
+                  "price": 1.25,
+                  "crid": "crid",
+                  "adm": "adm_content",
+                  "h": 600,
+                  "w": 300
+                }
+              ]
+            }
+          ],
+          "bidid": "bid_id",
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "bid_id",
+            "impid": "imp_id",
+            "price": 1.25,
+            "adm": "adm_content",
+            "crid": "crid",
+            "w": 300,
+            "h": 600
+          },
+          "type": "native"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/yandex/yandextest/exemplary/simple-banner.json b/adapters/yandex/yandextest/exemplary/simple-banner.json
new file mode 100644
index 00000000..477e4ef5
--- /dev/null
+++ b/adapters/yandex/yandextest/exemplary/simple-banner.json
@@ -0,0 +1,134 @@
+{
+  "mockBidRequest": {
+    "id": "request_id",
+    "imp": [
+      {
+        "id": "imp_id",
+        "banner": {
+          "w": 300,
+          "h": 600
+        },
+        "ext": {
+          "bidder": {
+            "placement_id": "134001-1"
+          }
+        }
+      }
+    ],
+    "site": {
+      "domain": "www.example.com",
+      "page": "http://www.example.com"
+    },
+    "cur": [
+      "USD"
+    ],
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+      "ip": "127.0.0.1",
+      "language": "EN"
+    },
+    "tmax": 500
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bs-metadsp.yandex.ru/prebid/134001?imp-id=1&ssp-cur=USD&ssp-id=10500&target-ref=www.example.com",
+        "headers": {
+          "User-Agent": [
+            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
+          ],
+          "X-Forwarded-For": [
+            "127.0.0.1"
+          ],
+          "X-Real-Ip": [
+            "127.0.0.1"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Referer": [
+            "http://www.example.com"
+          ],
+          "Accept": [
+            "application/json"
+          ],
+          "Accept-Language": [
+            "EN"
+          ]
+        },
+        "body": {
+          "id": "request_id",
+          "imp": [
+            {
+              "id": "imp_id",
+              "banner": {
+                "w": 300,
+                "h": 600
+              },
+              "ext": {
+                "bidder": {
+                  "placement_id": "134001-1"
+                }
+              }
+            }
+          ],
+          "site": {
+            "domain": "www.example.com",
+            "page": "http://www.example.com"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+            "ip": "127.0.0.1",
+            "language": "EN"
+          },
+          "tmax": 500
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "headers": {},
+        "body": {
+          "id": "request_id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "bid_id",
+                  "impid": "imp_id",
+                  "price": 1.25,
+                  "crid": "crid",
+                  "adm": "<html>content</html>",
+                  "h": 600,
+                  "w": 300
+                }
+              ]
+            }
+          ],
+          "bidid": "bid_id",
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "bid_id",
+            "impid": "imp_id",
+            "price": 1.25,
+            "adm": "<html>content</html>",
+            "crid": "crid",
+            "w": 300,
+            "h": 600
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/yandex/yandextest/supplemental/multiple-imps-some-malformed.json b/adapters/yandex/yandextest/supplemental/multiple-imps-some-malformed.json
new file mode 100644
index 00000000..299f4013
--- /dev/null
+++ b/adapters/yandex/yandextest/supplemental/multiple-imps-some-malformed.json
@@ -0,0 +1,145 @@
+{
+  "mockBidRequest": {
+    "id": "request_id",
+    "imp": [
+      {
+        "id": "imp_id1",
+        "banner": {
+          "w": 300,
+          "h": 600
+        },
+        "ext": {
+          "bidder": {
+            "page_id": 111,
+            "imp_id": 1
+          }
+        }
+      },
+      {
+        "id": "imp_id2",
+        "ext": {
+          "bidder": {
+            "page_id": 222,
+            "imp_id": 2
+          }
+        }
+      }
+    ],
+    "site": {
+      "domain": "www.example.com",
+      "page": "http://www.example.com"
+    },
+    "cur": [
+      "USD"
+    ],
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+      "ip": "127.0.0.1"
+    },
+    "tmax": 500
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bs-metadsp.yandex.ru/prebid/111?imp-id=1&ssp-cur=USD&ssp-id=10500&target-ref=www.example.com",
+        "headers": {
+          "User-Agent": [
+            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
+          ],
+          "X-Forwarded-For": [
+            "127.0.0.1"
+          ],
+          "X-Real-Ip": [
+            "127.0.0.1"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Referer": [
+            "http://www.example.com"
+          ],
+          "Accept": [
+            "application/json"
+          ]
+        },
+        "body": {
+          "id": "request_id",
+          "imp": [
+            {
+              "id": "imp_id1",
+              "banner": {
+                "w": 300,
+                "h": 600
+              },
+              "ext": {
+                "bidder": {
+                  "page_id": 111,
+                  "imp_id": 1
+                }
+              }
+            }
+          ],
+          "site": {
+            "domain": "www.example.com",
+            "page": "http://www.example.com"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+            "ip": "127.0.0.1"
+          },
+          "tmax": 500
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "headers": {},
+        "body": {
+          "id": "request_id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "bid_id1",
+                  "impid": "imp_id1",
+                  "price": 1.25,
+                  "crid": "crid",
+                  "adm": "adm001",
+                  "h": 600,
+                  "w": 300
+                }
+              ]
+            }
+          ],
+          "bidid": "bid_id"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "bid_id1",
+            "impid": "imp_id1",
+            "price": 1.25,
+            "adm": "adm001",
+            "crid": "crid",
+            "w": 300,
+            "h": 600
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ],
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "Unsupported format",
+      "comparison": "regex"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/yandex/yandextest/supplemental/multiple-imps.json b/adapters/yandex/yandextest/supplemental/multiple-imps.json
new file mode 100644
index 00000000..b83f51eb
--- /dev/null
+++ b/adapters/yandex/yandextest/supplemental/multiple-imps.json
@@ -0,0 +1,235 @@
+{
+  "mockBidRequest": {
+    "id": "request_id",
+    "imp": [
+      {
+        "id": "imp_id1",
+        "banner": {
+          "w": 300,
+          "h": 600
+        },
+        "ext": {
+          "bidder": {
+            "page_id": 111,
+            "imp_id": 1
+          }
+        }
+      },
+      {
+        "id": "imp_id2",
+        "banner": {
+          "w": 400,
+          "h": 800
+        },
+        "ext": {
+          "bidder": {
+            "placement_id": "222-2"
+          }
+        }
+      }
+    ],
+    "site": {
+      "domain": "www.example.com",
+      "page": "http://www.example.com"
+    },
+    "cur": [
+      "USD"
+    ],
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+      "ip": "127.0.0.1"
+    },
+    "tmax": 500
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bs-metadsp.yandex.ru/prebid/111?imp-id=1&ssp-cur=USD&ssp-id=10500&target-ref=www.example.com",
+        "headers": {
+          "User-Agent": [
+            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
+          ],
+          "X-Forwarded-For": [
+            "127.0.0.1"
+          ],
+          "X-Real-Ip": [
+            "127.0.0.1"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Referer": [
+            "http://www.example.com"
+          ],
+          "Accept": [
+            "application/json"
+          ]
+        },
+        "body": {
+          "id": "request_id",
+          "imp": [
+            {
+              "id": "imp_id1",
+              "banner": {
+                "w": 300,
+                "h": 600
+              },
+              "ext": {
+                "bidder": {
+                  "page_id": 111,
+                  "imp_id": 1
+                }
+              }
+            }
+          ],
+          "site": {
+            "domain": "www.example.com",
+            "page": "http://www.example.com"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+            "ip": "127.0.0.1"
+          },
+          "tmax": 500
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "headers": {},
+        "body": {
+          "id": "request_id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "bid_id1",
+                  "impid": "imp_id1",
+                  "price": 1.25,
+                  "crid": "crid",
+                  "adm": "adm001",
+                  "h": 600,
+                  "w": 300
+                }
+              ]
+            }
+          ],
+          "bidid": "bid_id"
+        }
+      }
+    },
+    {
+      "expectedRequest": {
+        "uri": "https://bs-metadsp.yandex.ru/prebid/222?imp-id=2&ssp-cur=USD&ssp-id=10500&target-ref=www.example.com",
+        "headers": {
+          "User-Agent": [
+            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
+          ],
+          "X-Forwarded-For": [
+            "127.0.0.1"
+          ],
+          "X-Real-Ip": [
+            "127.0.0.1"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Referer": [
+            "http://www.example.com"
+          ],
+          "Accept": [
+            "application/json"
+          ]
+        },
+        "body": {
+          "id": "request_id",
+          "imp": [
+            {
+              "id": "imp_id2",
+              "banner": {
+                "w": 400,
+                "h": 800
+              },
+              "ext": {
+                "bidder": {
+                  "placement_id": "222-2"
+                }
+              }
+            }
+          ],
+          "site": {
+            "domain": "www.example.com",
+            "page": "http://www.example.com"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+            "ip": "127.0.0.1"
+          },
+          "tmax": 500
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "headers": {},
+        "body": {
+          "id": "request_id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "bid_id2",
+                  "impid": "imp_id2",
+                  "price": 1.25,
+                  "crid": "crid",
+                  "adm": "adm001",
+                  "h": 800,
+                  "w": 400
+                }
+              ]
+            }
+          ],
+          "bidid": "bid_id"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "bid_id1",
+            "impid": "imp_id1",
+            "price": 1.25,
+            "adm": "adm001",
+            "crid": "crid",
+            "w": 300,
+            "h": 600
+          },
+          "type": "banner"
+        }
+      ]
+    },
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "bid_id2",
+            "impid": "imp_id2",
+            "price": 1.25,
+            "adm": "adm001",
+            "crid": "crid",
+            "w": 400,
+            "h": 800
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/yandex/yandextest/supplemental/simple-banner-empty-response.json b/adapters/yandex/yandextest/supplemental/simple-banner-empty-response.json
new file mode 100644
index 00000000..ffc067eb
--- /dev/null
+++ b/adapters/yandex/yandextest/supplemental/simple-banner-empty-response.json
@@ -0,0 +1,100 @@
+{
+  "mockBidRequest": {
+    "id": "request_id",
+    "imp": [
+      {
+        "id": "imp_id",
+        "banner": {
+          "w": 300,
+          "h": 600
+        },
+        "ext": {
+          "bidder": {
+            "page_id": 134001,
+            "imp_id": 1
+          }
+        }
+      }
+    ],
+    "site": {
+      "domain": "www.example.com",
+      "page": "http://www.example.com"
+    },
+    "cur": [
+      "USD"
+    ],
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+      "ip": "127.0.0.1"
+    },
+    "tmax": 500
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bs-metadsp.yandex.ru/prebid/134001?imp-id=1&ssp-cur=USD&ssp-id=10500&target-ref=www.example.com",
+        "headers": {
+          "User-Agent": [
+            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
+          ],
+          "X-Forwarded-For": [
+            "127.0.0.1"
+          ],
+          "X-Real-Ip": [
+            "127.0.0.1"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Referer": [
+            "http://www.example.com"
+          ],
+          "Accept": [
+            "application/json"
+          ]
+        },
+        "body": {
+          "id": "request_id",
+          "imp": [
+            {
+              "id": "imp_id",
+              "banner": {
+                "w": 300,
+                "h": 600
+              },
+              "ext": {
+                "bidder": {
+                  "page_id": 134001,
+                  "imp_id": 1
+                }
+              }
+            }
+          ],
+          "site": {
+            "domain": "www.example.com",
+            "page": "http://www.example.com"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+            "ip": "127.0.0.1"
+          },
+          "tmax": 500
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "headers": {}
+      }
+    }
+  ],
+  "expectedBidResponses": [],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Bad server response",
+      "comparison": "regex"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/yandex/yandextest/supplemental/simple-banner-empty-seatbid.json b/adapters/yandex/yandextest/supplemental/simple-banner-empty-seatbid.json
new file mode 100644
index 00000000..eafb27a4
--- /dev/null
+++ b/adapters/yandex/yandextest/supplemental/simple-banner-empty-seatbid.json
@@ -0,0 +1,105 @@
+{
+  "mockBidRequest": {
+    "id": "request_id",
+    "imp": [
+      {
+        "id": "imp_id",
+        "banner": {
+          "w": 300,
+          "h": 600
+        },
+        "ext": {
+          "bidder": {
+            "page_id": 134001,
+            "imp_id": 1
+          }
+        }
+      }
+    ],
+    "site": {
+      "domain": "www.example.com",
+      "page": "http://www.example.com"
+    },
+    "cur": [
+      "USD"
+    ],
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+      "ip": "127.0.0.1"
+    },
+    "tmax": 500
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bs-metadsp.yandex.ru/prebid/134001?imp-id=1&ssp-cur=USD&ssp-id=10500&target-ref=www.example.com",
+        "headers": {
+          "User-Agent": [
+            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
+          ],
+          "X-Forwarded-For": [
+            "127.0.0.1"
+          ],
+          "X-Real-Ip": [
+            "127.0.0.1"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Referer": [
+            "http://www.example.com"
+          ],
+          "Accept": [
+            "application/json"
+          ]
+        },
+        "body": {
+          "id": "request_id",
+          "imp": [
+            {
+              "id": "imp_id",
+              "banner": {
+                "w": 300,
+                "h": 600
+              },
+              "ext": {
+                "bidder": {
+                  "page_id": 134001,
+                  "imp_id": 1
+                }
+              }
+            }
+          ],
+          "site": {
+            "domain": "www.example.com",
+            "page": "http://www.example.com"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+            "ip": "127.0.0.1"
+          },
+          "tmax": 500
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "headers": {},
+        "body": {
+          "id": "request_id",
+          "seatbid": null,
+          "bidid": "bid_id",
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": []
+    }
+  ],
+  "expectedMakeBidsErrors": []
+}
\ No newline at end of file
diff --git a/adapters/yandex/yandextest/supplemental/simple-banner-sizes.json b/adapters/yandex/yandextest/supplemental/simple-banner-sizes.json
new file mode 100644
index 00000000..23a14288
--- /dev/null
+++ b/adapters/yandex/yandextest/supplemental/simple-banner-sizes.json
@@ -0,0 +1,232 @@
+{
+  "mockBidRequest": {
+    "id": "request_id",
+    "imp": [
+      {
+        "id": "invalid_width",
+        "banner": {
+          "w": 0,
+          "h": 600
+        },
+        "ext": {
+          "bidder": {
+            "page_id": 111,
+            "imp_id": 1
+          }
+        }
+      },
+      {
+        "id": "invalid_height",
+        "banner": {
+          "w": 400,
+          "h": 0
+        },
+        "ext": {
+          "bidder": {
+            "page_id": 222,
+            "imp_id": 2
+          }
+        }
+      },
+      {
+        "id": "invalid_size",
+        "banner": {
+          "w": 0,
+          "h": 0
+        },
+        "ext": {
+          "bidder": {
+            "page_id": 222,
+            "imp_id": 3
+          }
+        }
+      },
+      {
+        "id": "invalid_no_size_no_formats",
+        "banner": {},
+        "ext": {
+          "bidder": {
+            "page_id": 222,
+            "imp_id": 5
+          }
+        }
+      },
+      {
+        "id": "invalid_size",
+        "banner": {
+          "w": 0,
+          "h": 0
+        },
+        "ext": {
+          "bidder": {
+            "page_id": 222,
+            "imp_id": 3
+          }
+        }
+      },
+      {
+        "id": "no_size_but_valid_formats",
+        "banner": {
+          "format": [
+            {
+              "w": 600,
+              "h": 500
+            },
+            {
+              "w": 300,
+              "h": 600
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "page_id": 222,
+            "imp_id": 4
+          }
+        }
+      }
+    ],
+    "site": {
+      "domain": "www.example.com",
+      "page": "http://www.example.com"
+    },
+    "cur": [
+      "USD"
+    ],
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+      "ip": "127.0.0.1"
+    },
+    "tmax": 500
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bs-metadsp.yandex.ru/prebid/222?imp-id=4&ssp-cur=USD&ssp-id=10500&target-ref=www.example.com",
+        "headers": {
+          "User-Agent": [
+            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
+          ],
+          "X-Forwarded-For": [
+            "127.0.0.1"
+          ],
+          "X-Real-Ip": [
+            "127.0.0.1"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Referer": [
+            "http://www.example.com"
+          ],
+          "Accept": [
+            "application/json"
+          ]
+        },
+        "body": {
+          "id": "request_id",
+          "imp": [
+            {
+              "id": "no_size_but_valid_formats",
+              "banner": {
+                "w": 600,
+                "h": 500,
+                "format": [
+                  {
+                    "w": 600,
+                    "h": 500
+                  },
+                  {
+                    "w": 300,
+                    "h": 600
+                  }
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "page_id": 222,
+                  "imp_id": 4
+                }
+              }
+            }
+          ],
+          "site": {
+            "domain": "www.example.com",
+            "page": "http://www.example.com"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+            "ip": "127.0.0.1"
+          },
+          "tmax": 500
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "headers": {},
+        "body": {
+          "id": "request_id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "bid_id4",
+                  "impid": "no_size_but_valid_formats",
+                  "price": 1.25,
+                  "crid": "crid",
+                  "adm": "adm001",
+                  "h": 800,
+                  "w": 400
+                }
+              ]
+            }
+          ],
+          "bidid": "bid_id"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "bid_id4",
+            "impid": "no_size_but_valid_formats",
+            "price": 1.25,
+            "adm": "adm001",
+            "crid": "crid",
+            "w": 400,
+            "h": 800
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ],
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "Invalid size",
+      "comparison": "regex"
+    },
+    {
+      "value": "Invalid size",
+      "comparison": "regex"
+    },
+    {
+      "value": "Invalid size",
+      "comparison": "regex"
+    },
+    {
+      "value": "Invalid size",
+      "comparison": "regex"
+    },
+    {
+      "value": "Invalid size",
+      "comparison": "regex"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/yandex/yandextest/supplemental/simple-banner-status-400.json b/adapters/yandex/yandextest/supplemental/simple-banner-status-400.json
new file mode 100644
index 00000000..78d2813b
--- /dev/null
+++ b/adapters/yandex/yandextest/supplemental/simple-banner-status-400.json
@@ -0,0 +1,101 @@
+{
+  "mockBidRequest": {
+    "id": "request_id",
+    "imp": [
+      {
+        "id": "imp_id",
+        "banner": {
+          "w": 300,
+          "h": 600
+        },
+        "ext": {
+          "bidder": {
+            "page_id": 134001,
+            "imp_id": 1
+          }
+        }
+      }
+    ],
+    "site": {
+      "domain": "www.example.com",
+      "page": "http://www.example.com"
+    },
+    "cur": [
+      "USD"
+    ],
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+      "ip": "127.0.0.1"
+    },
+    "tmax": 500
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bs-metadsp.yandex.ru/prebid/134001?imp-id=1&ssp-cur=USD&ssp-id=10500&target-ref=www.example.com",
+        "headers": {
+          "User-Agent": [
+            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
+          ],
+          "X-Forwarded-For": [
+            "127.0.0.1"
+          ],
+          "X-Real-Ip": [
+            "127.0.0.1"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Referer": [
+            "http://www.example.com"
+          ],
+          "Accept": [
+            "application/json"
+          ]
+        },
+        "body": {
+          "id": "request_id",
+          "imp": [
+            {
+              "id": "imp_id",
+              "banner": {
+                "w": 300,
+                "h": 600
+              },
+              "ext": {
+                "bidder": {
+                  "page_id": 134001,
+                  "imp_id": 1
+                }
+              }
+            }
+          ],
+          "site": {
+            "domain": "www.example.com",
+            "page": "http://www.example.com"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+            "ip": "127.0.0.1"
+          },
+          "tmax": 500
+        }
+      },
+      "mockResponse": {
+        "status": 400,
+        "headers": {},
+        "body": {}
+      }
+    }
+  ],
+  "expectedBidResponses": [],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Unexpected status code",
+      "comparison": "regex"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/yandex/yandextest/supplemental/simple-banner-unknown-imp.json b/adapters/yandex/yandextest/supplemental/simple-banner-unknown-imp.json
new file mode 100644
index 00000000..5c94be30
--- /dev/null
+++ b/adapters/yandex/yandextest/supplemental/simple-banner-unknown-imp.json
@@ -0,0 +1,124 @@
+{
+  "mockBidRequest": {
+    "id": "request_id",
+    "imp": [
+      {
+        "id": "imp_id",
+        "banner": {
+          "w": 300,
+          "h": 600
+        },
+        "ext": {
+          "bidder": {
+            "page_id": 134001,
+            "imp_id": 1
+          }
+        }
+      }
+    ],
+    "site": {
+      "domain": "www.example.com",
+      "page": "http://www.example.com"
+    },
+    "cur": [
+      "USD"
+    ],
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+      "ip": "127.0.0.1"
+    },
+    "tmax": 500
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bs-metadsp.yandex.ru/prebid/134001?imp-id=1&ssp-cur=USD&ssp-id=10500&target-ref=www.example.com",
+        "headers": {
+          "User-Agent": [
+            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
+          ],
+          "X-Forwarded-For": [
+            "127.0.0.1"
+          ],
+          "X-Real-Ip": [
+            "127.0.0.1"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Referer": [
+            "http://www.example.com"
+          ],
+          "Accept": [
+            "application/json"
+          ]
+        },
+        "body": {
+          "id": "request_id",
+          "imp": [
+            {
+              "id": "imp_id",
+              "banner": {
+                "w": 300,
+                "h": 600
+              },
+              "ext": {
+                "bidder": {
+                  "page_id": 134001,
+                  "imp_id": 1
+                }
+              }
+            }
+          ],
+          "site": {
+            "domain": "www.example.com",
+            "page": "http://www.example.com"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+            "ip": "127.0.0.1"
+          },
+          "tmax": 500
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "headers": {},
+        "body": {
+          "id": "request_id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "bid_id",
+                  "impid": "imp_id_unknown",
+                  "price": 1.25,
+                  "crid": "crid",
+                  "adm": "<html>content</html>",
+                  "h": 600,
+                  "w": 300
+                }
+              ]
+            }
+          ],
+          "bidid": "bid_id",
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": []
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Invalid bid imp",
+      "comparison": "regex"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/yandex/yandextest/supplemental/simple-banner-unparsable-body.json b/adapters/yandex/yandextest/supplemental/simple-banner-unparsable-body.json
new file mode 100644
index 00000000..0adfdb40
--- /dev/null
+++ b/adapters/yandex/yandextest/supplemental/simple-banner-unparsable-body.json
@@ -0,0 +1,101 @@
+{
+  "mockBidRequest": {
+    "id": "request_id",
+    "imp": [
+      {
+        "id": "imp_id",
+        "banner": {
+          "w": 300,
+          "h": 600
+        },
+        "ext": {
+          "bidder": {
+            "page_id": 134001,
+            "imp_id": 1
+          }
+        }
+      }
+    ],
+    "site": {
+      "domain": "www.example.com",
+      "page": "http://www.example.com"
+    },
+    "cur": [
+      "USD"
+    ],
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+      "ip": "127.0.0.1"
+    },
+    "tmax": 500
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bs-metadsp.yandex.ru/prebid/134001?imp-id=1&ssp-cur=USD&ssp-id=10500&target-ref=www.example.com",
+        "headers": {
+          "User-Agent": [
+            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
+          ],
+          "X-Forwarded-For": [
+            "127.0.0.1"
+          ],
+          "X-Real-Ip": [
+            "127.0.0.1"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Referer": [
+            "http://www.example.com"
+          ],
+          "Accept": [
+            "application/json"
+          ]
+        },
+        "body": {
+          "id": "request_id",
+          "imp": [
+            {
+              "id": "imp_id",
+              "banner": {
+                "w": 300,
+                "h": 600
+              },
+              "ext": {
+                "bidder": {
+                  "page_id": 134001,
+                  "imp_id": 1
+                }
+              }
+            }
+          ],
+          "site": {
+            "domain": "www.example.com",
+            "page": "http://www.example.com"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+            "ip": "127.0.0.1"
+          },
+          "tmax": 500
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "headers": {},
+        "body": "invalid"
+      }
+    }
+  ],
+  "expectedBidResponses": [],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Bad server response",
+      "comparison": "regex"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/yandex/yandextest/supplemental/unknown-banner.json b/adapters/yandex/yandextest/supplemental/unknown-banner.json
new file mode 100644
index 00000000..a01b9037
--- /dev/null
+++ b/adapters/yandex/yandextest/supplemental/unknown-banner.json
@@ -0,0 +1,32 @@
+{
+  "mockBidRequest": {
+    "id": "request_id",
+    "imp": [
+      {
+        "id": "imp_id",
+        "video": {
+          "w": 100,
+          "h": 200
+        },
+        "ext": {
+          "bidder": {
+            "page_id": 134001,
+            "imp_id": 1
+          }
+        }
+      }
+    ],
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
+      "ip": "127.0.0.1"
+    },
+    "tmax": 500
+  },
+  "httpCalls": [],
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "Unsupported format",
+      "comparison": "regex"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/zmaticoo/params_test.go b/adapters/zmaticoo/params_test.go
new file mode 100644
index 00000000..23c599e8
--- /dev/null
+++ b/adapters/zmaticoo/params_test.go
@@ -0,0 +1,48 @@
+package zmaticoo
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/prebid/prebid-server/v2/openrtb_ext"
+)
+
+func TestValidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json-schemas. %v", err)
+	}
+
+	for _, validParam := range validParams {
+		if err := validator.Validate(openrtb_ext.BidderZmaticoo, json.RawMessage(validParam)); err != nil {
+			t.Errorf("Schema rejected zmaticoo params: %s", validParam)
+		}
+	}
+}
+
+// TestInvalidParams makes sure that the zmaticoo schema rejects all the imp.ext fields we don't support.
+func TestInvalidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json-schemas. %v", err)
+	}
+
+	for _, invalidParam := range invalidParams {
+		if err := validator.Validate(openrtb_ext.BidderZmaticoo, json.RawMessage(invalidParam)); err == nil {
+			t.Errorf("Schema allowed unexpected params: %s", invalidParam)
+		}
+	}
+}
+
+var validParams = []string{
+	`{"pubId": "11233", "zoneId": "sin"}`,
+	`{"pubId": "11244", "zoneId": "iad"}`,
+}
+
+var invalidParams = []string{
+	`{"pubId": "11233"}`,
+	`{"zoneId": "aaa"}`,
+	`{"pubId": 123, "zoneId": "sin"}`,
+	`{"pubId": "", "zoneId": "iad"}`,
+	`{"pubId": "11233", "zoneId": ""}`,
+}
diff --git a/adapters/zmaticoo/zmaticoo_test.go b/adapters/zmaticoo/zmaticoo_test.go
new file mode 100644
index 00000000..1effdd2a
--- /dev/null
+++ b/adapters/zmaticoo/zmaticoo_test.go
@@ -0,0 +1,20 @@
+package zmaticoo
+
+import (
+	"testing"
+
+	"github.com/prebid/prebid-server/v2/adapters/adapterstest"
+	"github.com/prebid/prebid-server/v2/config"
+	"github.com/prebid/prebid-server/v2/openrtb_ext"
+)
+
+func TestJsonSamples(t *testing.T) {
+	bidder, buildErr := Builder(openrtb_ext.BidderZmaticoo, config.Adapter{
+		Endpoint: "https://bid.zmaticoo.com/prebid/bid"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
+
+	if buildErr != nil {
+		t.Fatalf("Builder returned unexpected error %v", buildErr)
+	}
+
+	adapterstest.RunJSONBidderTest(t, "zmaticootest", bidder)
+}
diff --git a/adapters/zmaticoo/zmaticootest/exemplary/no-bid.json b/adapters/zmaticoo/zmaticootest/exemplary/no-bid.json
new file mode 100644
index 00000000..d0e5d17e
--- /dev/null
+++ b/adapters/zmaticoo/zmaticootest/exemplary/no-bid.json
@@ -0,0 +1,58 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 50
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "pubId": "fake-pub-id",
+            "zoneId": "sin"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bid.zmaticoo.com/prebid/bid",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 50
+                  }
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "pubId": "fake-pub-id",
+                  "zoneId": "sin"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 204,
+        "body": {}
+      }
+    }
+  ],
+  "expectedBidResponses": []
+}
diff --git a/adapters/zmaticoo/zmaticootest/exemplary/simple-banner.json b/adapters/zmaticoo/zmaticootest/exemplary/simple-banner.json
new file mode 100644
index 00000000..22d104ed
--- /dev/null
+++ b/adapters/zmaticoo/zmaticootest/exemplary/simple-banner.json
@@ -0,0 +1,93 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 50
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "pubId": "fake-pub-id",
+            "zoneId": "sin"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bid.zmaticoo.com/prebid/bid",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 50
+                  }
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "pubId": "fake-pub-id",
+                  "zoneId": "sin"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "seat": "ttx",
+              "bid": [
+                {
+                  "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
+                  "impid": "test-imp-id",
+                  "price": 1.2,
+                  "adm": "some-ads",
+                  "crid": "crid_testid",
+                  "mtype": 1
+                }
+              ]
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
+            "impid": "test-imp-id",
+            "price": 1.2,
+            "adm": "some-ads",
+            "crid": "crid_testid",
+            "mtype": 1
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/zmaticoo/zmaticootest/exemplary/simple-native-1.1.json b/adapters/zmaticoo/zmaticootest/exemplary/simple-native-1.1.json
new file mode 100644
index 00000000..307e3d87
--- /dev/null
+++ b/adapters/zmaticoo/zmaticootest/exemplary/simple-native-1.1.json
@@ -0,0 +1,83 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "native": {
+          "request": "{\"native\":{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}}",
+          "ver": "1.2"
+        },
+        "ext": {
+          "bidder": {
+            "pubId": "fake-pub-id",
+            "zoneId": "sin"
+          }
+        }
+      }
+    ]
+  },
+  "httpcalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bid.zmaticoo.com/prebid/bid",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "native": {
+                "request": "{\"native\":{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}}",
+                "ver": "1.2"
+              },
+              "ext": {
+                "bidder": {
+                  "pubId": "fake-pub-id",
+                  "zoneId": "sin"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "8400d766-58b3-47d4-80d7-6658b337d403",
+                  "impid": "test-imp-id",
+                  "price": 1.2,
+                  "adm": "some ads",
+                  "crid": "crid_testid",
+                  "mtype": 4
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "8400d766-58b3-47d4-80d7-6658b337d403",
+            "impid": "test-imp-id",
+            "price": 1.2,
+            "adm": "some ads",
+            "crid": "crid_testid",
+            "mtype": 4
+          },
+          "type": "native"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/zmaticoo/zmaticootest/exemplary/simple-native.json b/adapters/zmaticoo/zmaticootest/exemplary/simple-native.json
new file mode 100644
index 00000000..6cff9b86
--- /dev/null
+++ b/adapters/zmaticoo/zmaticootest/exemplary/simple-native.json
@@ -0,0 +1,83 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "native": {
+          "request": "{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}",
+          "ver": "1.2"
+        },
+        "ext": {
+          "bidder": {
+            "pubId": "fake-pub-id",
+            "zoneId": "sin"
+          }
+        }
+      }
+    ]
+  },
+  "httpcalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bid.zmaticoo.com/prebid/bid",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "native": {
+                "request": "{\"native\":{\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"img\":{\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"],\"type\":3,\"wmin\":128},\"required\":1},{\"data\":{\"len\":120,\"type\":2},\"id\":7,\"required\":1}],\"context\":1,\"plcmtcnt\":1,\"plcmttype\":4,\"ver\":\"1.2\"}}",
+                "ver": "1.2"
+              },
+              "ext": {
+                "bidder": {
+                  "pubId": "fake-pub-id",
+                  "zoneId": "sin"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "8400d766-58b3-47d4-80d7-6658b337d403",
+                  "impid": "test-imp-id",
+                  "price": 1.2,
+                  "adm": "some ads",
+                  "crid": "crid_testid",
+                  "mtype": 4
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "8400d766-58b3-47d4-80d7-6658b337d403",
+            "impid": "test-imp-id",
+            "price": 1.2,
+            "adm": "some ads",
+            "crid": "crid_testid",
+            "mtype": 4
+          },
+          "type": "native"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/zmaticoo/zmaticootest/exemplary/simple-video.json b/adapters/zmaticoo/zmaticootest/exemplary/simple-video.json
new file mode 100644
index 00000000..5ff93efa
--- /dev/null
+++ b/adapters/zmaticoo/zmaticootest/exemplary/simple-video.json
@@ -0,0 +1,91 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "video": {
+          "w": 300,
+          "h": 250,
+          "mimes": [
+            "video/mp4"
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "pubId": "fake-pub-id",
+            "zoneId": "sin"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bid.zmaticoo.com/prebid/bid",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "video": {
+                "w": 300,
+                "h": 250,
+                "mimes": [
+                  "video/mp4"
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "pubId": "fake-pub-id",
+                  "zoneId": "sin"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "seat": "ttx",
+              "bid": [
+                {
+                  "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
+                  "impid": "test-imp-id",
+                  "price": 1.2,
+                  "adm": "some-ads",
+                  "crid": "crid_testid",
+                  "mtype": 2
+                }
+              ]
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
+            "impid": "test-imp-id",
+            "price": 1.2,
+            "adm": "some-ads",
+            "crid": "crid_testid",
+            "mtype": 2
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext.json b/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext.json
new file mode 100644
index 00000000..444e1e7a
--- /dev/null
+++ b/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext.json
@@ -0,0 +1,21 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [{"w": 300, "h": 50}]
+        },
+        "ext": "aaa"
+      }
+    ]
+  },
+
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext_bidder.json b/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext_bidder.json
new file mode 100644
index 00000000..433bac5e
--- /dev/null
+++ b/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext_bidder.json
@@ -0,0 +1,27 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 50
+            }
+          ]
+        },
+        "ext": {
+          "bidder": "aa"
+        }
+      }
+    ]
+  },
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpZmaticoo",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/zmaticoo/zmaticootest/supplemental/bad_response.json b/adapters/zmaticoo/zmaticootest/supplemental/bad_response.json
new file mode 100644
index 00000000..9827081e
--- /dev/null
+++ b/adapters/zmaticoo/zmaticootest/supplemental/bad_response.json
@@ -0,0 +1,63 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 50
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "pubId": "fake-pub-id",
+            "zoneId": "sin"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bid.zmaticoo.com/prebid/bid",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 50
+                  }
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "pubId": "fake-pub-id",
+                  "zoneId": "sin"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": "{\"id\":test-request-id"
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "comparison": "literal",
+      "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse"
+    }
+  ]
+}
diff --git a/adapters/zmaticoo/zmaticootest/supplemental/empty_imp_ext_bidder.json b/adapters/zmaticoo/zmaticootest/supplemental/empty_imp_ext_bidder.json
new file mode 100644
index 00000000..43ee7a72
--- /dev/null
+++ b/adapters/zmaticoo/zmaticootest/supplemental/empty_imp_ext_bidder.json
@@ -0,0 +1,30 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 50
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "pubId": "",
+            "zoneId": ""
+          }
+        }
+      }
+    ]
+  },
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "imp.ext.pubId or imp.ext.zoneId required",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/zmaticoo/zmaticootest/supplemental/status_400.json b/adapters/zmaticoo/zmaticootest/supplemental/status_400.json
new file mode 100644
index 00000000..a03b5e36
--- /dev/null
+++ b/adapters/zmaticoo/zmaticootest/supplemental/status_400.json
@@ -0,0 +1,63 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 50
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "pubId": "fake-pub-id",
+            "zoneId": "sin"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bid.zmaticoo.com/prebid/bid",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 50
+                  }
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "pubId": "fake-pub-id",
+                  "zoneId": "sin"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 400,
+        "body": {}
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "comparison": "literal",
+      "value": "Unexpected status code: 400."
+    }
+  ]
+}
diff --git a/adapters/zmaticoo/zmaticootest/supplemental/status_500.json b/adapters/zmaticoo/zmaticootest/supplemental/status_500.json
new file mode 100644
index 00000000..732b2cb6
--- /dev/null
+++ b/adapters/zmaticoo/zmaticootest/supplemental/status_500.json
@@ -0,0 +1,63 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 50
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "pubId": "fake-pub-id",
+            "zoneId": "sin"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://bid.zmaticoo.com/prebid/bid",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 50
+                  }
+                ]
+              },
+              "ext": {
+                "bidder": {
+                  "pubId": "fake-pub-id",
+                  "zoneId": "sin"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 500,
+        "body": {}
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "comparison": "literal",
+      "value": "Unexpected status code: 500."
+    }
+  ]
+}
diff --git a/analytics/build/build_test.go b/analytics/build/build_test.go
index efc0c862..d6fea975 100644
--- a/analytics/build/build_test.go
+++ b/analytics/build/build_test.go
@@ -1,6 +1,9 @@
 package build
 
 import (
+	"github.com/prebid/prebid-server/v2/openrtb_ext"
+	"github.com/prebid/prebid-server/v2/util/iputil"
+
 	"net/http"
 	"os"
 	"testing"
@@ -143,7 +146,7 @@ func TestSampleModuleActivitiesAllowed(t *testing.T) {
 	var count int
 	am := initAnalytics(&count)
 
-	acAllowed := privacy.NewActivityControl(getDefaultActivityConfig("sampleModule", true))
+	acAllowed := privacy.NewActivityControl(getActivityConfig("sampleModule", true, true, true))
 
 	ao := &analytics.AuctionObject{
 		Status:   http.StatusOK,
@@ -172,11 +175,46 @@ func TestSampleModuleActivitiesAllowed(t *testing.T) {
 	}
 }
 
+func TestSampleModuleActivitiesAllowedAndDenied(t *testing.T) {
+	var count int
+	am := initAnalytics(&count)
+
+	acAllowed := privacy.NewActivityControl(getActivityConfig("sampleModule", true, false, true))
+
+	rw := &openrtb_ext.RequestWrapper{BidRequest: getDefaultBidRequest()}
+	ao := &analytics.AuctionObject{
+		RequestWrapper: rw,
+		Status:         http.StatusOK,
+		Errors:         nil,
+		Response:       &openrtb2.BidResponse{},
+	}
+
+	am.LogAuctionObject(ao, acAllowed)
+	if count != 1 {
+		t.Errorf("PBSAnalyticsModule failed at LogAuctionObject")
+	}
+
+	am.LogAmpObject(&analytics.AmpObject{RequestWrapper: rw}, acAllowed)
+	if count != 2 {
+		t.Errorf("PBSAnalyticsModule failed at LogAmpObject")
+	}
+
+	am.LogVideoObject(&analytics.VideoObject{RequestWrapper: rw}, acAllowed)
+	if count != 3 {
+		t.Errorf("PBSAnalyticsModule failed at LogVideoObject")
+	}
+
+	am.LogNotificationEventObject(&analytics.NotificationEvent{}, acAllowed)
+	if count != 4 {
+		t.Errorf("PBSAnalyticsModule failed at LogNotificationEventObject")
+	}
+}
+
 func TestSampleModuleActivitiesDenied(t *testing.T) {
 	var count int
 	am := initAnalytics(&count)
 
-	acDenied := privacy.NewActivityControl(getDefaultActivityConfig("sampleModule", false))
+	acDenied := privacy.NewActivityControl(getActivityConfig("sampleModule", false, true, true))
 
 	ao := &analytics.AuctionObject{
 		Status:   http.StatusOK,
@@ -205,14 +243,102 @@ func TestSampleModuleActivitiesDenied(t *testing.T) {
 	}
 }
 
-func getDefaultActivityConfig(componentName string, allow bool) *config.AccountPrivacy {
+func TestEvaluateActivities(t *testing.T) {
+	testCases := []struct {
+		description             string
+		givenActivityControl    privacy.ActivityControl
+		expectedRequest         *openrtb_ext.RequestWrapper
+		expectedAllowActivities bool
+	}{
+		{
+			description:             "all blocked",
+			givenActivityControl:    privacy.NewActivityControl(getActivityConfig("sampleModule", false, false, false)),
+			expectedRequest:         nil,
+			expectedAllowActivities: false,
+		},
+		{
+			description:             "all allowed",
+			givenActivityControl:    privacy.NewActivityControl(getActivityConfig("sampleModule", true, true, true)),
+			expectedRequest:         nil,
+			expectedAllowActivities: true,
+		},
+
+		{
+			description:          "ActivityTransmitUserFPD and ActivityTransmitPreciseGeo disabled",
+			givenActivityControl: privacy.NewActivityControl(getActivityConfig("sampleModule", true, false, false)),
+			expectedRequest: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{ID: "test_request", User: &openrtb2.User{ID: ""}, Device: &openrtb2.Device{IFA: "", IP: "127.0.0.0"}},
+			},
+			expectedAllowActivities: true,
+		},
+		{
+			description:          "ActivityTransmitUserFPD enabled, ActivityTransmitPreciseGeo disabled",
+			givenActivityControl: privacy.NewActivityControl(getActivityConfig("sampleModule", true, true, false)),
+			expectedRequest: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{ID: "test_request", User: &openrtb2.User{ID: "user-id"}, Device: &openrtb2.Device{IFA: "device-ifa", IP: "127.0.0.0"}},
+			},
+			expectedAllowActivities: true,
+		},
+	}
+
+	for _, test := range testCases {
+		t.Run(test.description, func(t *testing.T) {
+			rw := &openrtb_ext.RequestWrapper{BidRequest: getDefaultBidRequest()}
+			resActivityAllowed, resRequest := evaluateActivities(rw, test.givenActivityControl, "sampleModule")
+			assert.Equal(t, test.expectedAllowActivities, resActivityAllowed)
+			if test.expectedRequest != nil {
+				assert.Equal(t, test.expectedRequest.User.ID, resRequest.User.ID)
+				assert.Equal(t, test.expectedRequest.Device.IFA, resRequest.Device.IFA)
+				assert.Equal(t, test.expectedRequest.Device.IP, resRequest.Device.IP)
+			} else {
+				assert.Nil(t, resRequest)
+			}
+
+		})
+	}
+
+}
+
+func getDefaultBidRequest() *openrtb2.BidRequest {
+	return &openrtb2.BidRequest{
+		ID:     "test_request",
+		User:   &openrtb2.User{ID: "user-id"},
+		Device: &openrtb2.Device{IFA: "device-ifa", IP: "127.0.0.1"}}
+
+}
+
+func getActivityConfig(componentName string, allowReportAnalytics, allowTransmitUserFPD, allowTransmitPreciseGeo bool) *config.AccountPrivacy {
 	return &config.AccountPrivacy{
 		AllowActivities: &config.AllowActivities{
 			ReportAnalytics: config.Activity{
 				Default: ptrutil.ToPtr(true),
 				Rules: []config.ActivityRule{
 					{
-						Allow: allow,
+						Allow: allowReportAnalytics,
+						Condition: config.ActivityCondition{
+							ComponentName: []string{componentName},
+							ComponentType: []string{"analytics"},
+						},
+					},
+				},
+			},
+			TransmitUserFPD: config.Activity{
+				Default: ptrutil.ToPtr(true),
+				Rules: []config.ActivityRule{
+					{
+						Allow: allowTransmitUserFPD,
+						Condition: config.ActivityCondition{
+							ComponentName: []string{componentName},
+							ComponentType: []string{"analytics"},
+						},
+					},
+				},
+			},
+			TransmitPreciseGeo: config.Activity{
+				Default: ptrutil.ToPtr(true),
+				Rules: []config.ActivityRule{
+					{
+						Allow: allowTransmitPreciseGeo,
 						Condition: config.ActivityCondition{
 							ComponentName: []string{componentName},
 							ComponentType: []string{"analytics"},
@@ -221,5 +347,11 @@ func getDefaultActivityConfig(componentName string, allow bool) *config.AccountP
 				},
 			},
 		},
+		IPv4Config: config.IPv4{
+			AnonKeepBits: iputil.IPv4DefaultMaskingBitSize,
+		},
+		IPv6Config: config.IPv6{
+			AnonKeepBits: iputil.IPv6DefaultMaskingBitSize,
+		},
 	}
 }
diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go
index 70a37aab..34606c1d 100644
--- a/endpoints/openrtb2/video_auction_test.go
+++ b/endpoints/openrtb2/video_auction_test.go
@@ -1250,7 +1250,8 @@ func (m *mockAnalyticsModule) LogCookieSyncObject(cso *analytics.CookieSyncObjec
 
 func (m *mockAnalyticsModule) LogSetUIDObject(so *analytics.SetUIDObject) {}
 
-func (m *mockAnalyticsModule) LogAmpObject(ao *analytics.AmpObject, _ privacy.ActivityControl) {}
+func (m *mockAnalyticsModule) LogAmpObject(ao *analytics.AmpObject, _ privacy.ActivityControl) {
+}
 
 func (m *mockAnalyticsModule) LogNotificationEventObject(ne *analytics.NotificationEvent, _ privacy.ActivityControl) {
 }
diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go
index b2314c8c..d3af2a46 100644
--- a/exchange/bidder_test.go
+++ b/exchange/bidder_test.go
@@ -2,6 +2,7 @@ package exchange
 
 import (
 	"bytes"
+	"compress/gzip"
 	"context"
 	"crypto/tls"
 	"encoding/json"
@@ -3347,3 +3348,77 @@ func TestDoRequestImplWithTmaxTimeout(t *testing.T) {
 		test.assertFn(httpCallInfo.err)
 	}
 }
+
+func TestGetRequestBody(t *testing.T) {
+	tests := []struct {
+		name                string
+		endpointCompression string
+		givenReqBody        []byte
+	}{
+		{
+			name:                "No-Compression",
+			endpointCompression: "",
+			givenReqBody:        []byte("test body"),
+		},
+		{
+			name:                "GZIP-Compression",
+			endpointCompression: "GZIP",
+			givenReqBody:        []byte("test body"),
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			req := &adapters.RequestData{Body: test.givenReqBody, Headers: http.Header{}}
+			requestBody, err := getRequestBody(req, test.endpointCompression)
+			assert.NoError(t, err)
+
+			if test.endpointCompression == "GZIP" {
+				assert.Equal(t, "gzip", req.Headers.Get("Content-Encoding"))
+
+				decompressedReqBody, err := decompressGzip(requestBody)
+				assert.NoError(t, err)
+				assert.Equal(t, test.givenReqBody, decompressedReqBody)
+			} else {
+				assert.Equal(t, test.givenReqBody, requestBody)
+			}
+		})
+	}
+}
+
+func decompressGzip(input []byte) ([]byte, error) {
+	r, err := gzip.NewReader(bytes.NewReader(input))
+	if err != nil {
+		return nil, err
+	}
+	defer r.Close()
+
+	decompressed, err := io.ReadAll(r)
+	if err != nil {
+		return nil, err
+	}
+
+	return decompressed, nil
+}
+
+func BenchmarkCompressToGZIPOptimized(b *testing.B) {
+	// Setup the mock server
+	respBody := "{\"bid\":false}"
+	respStatus := 200
+	server := httptest.NewServer(mockHandler(respStatus, "getBody", respBody))
+	defer server.Close()
+
+	// Prepare the request data
+	req := &adapters.RequestData{
+		Method:  "POST",
+		Uri:     server.URL,
+		Body:    []byte("{\"key\":\"val\"}"),
+		Headers: http.Header{},
+	}
+
+	// Run the benchmark
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		getRequestBody(req, "GZIP")
+	}
+}
diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go
index aa354ea2..65ad7eeb 100644
--- a/exchange/exchange_test.go
+++ b/exchange/exchange_test.go
@@ -5699,13 +5699,22 @@ func TestModulesCanBeExecutedForMultipleBiddersSimultaneously(t *testing.T) {
 	server := httptest.NewServer(http.HandlerFunc(noBidServer))
 	defer server.Close()
 
-	bidderImpl := &goodSingleBidder{
-		httpRequest: &adapters.RequestData{
-			Method:  "POST",
-			Uri:     server.URL,
-			Body:    []byte(`{"key":"val"}`),
-			Headers: http.Header{},
-		},
+	reqBdy := []byte(`{"key":"val"}`)
+
+	bidderImplAppnexus := &goodSingleBidder{
+		httpRequest: &adapters.RequestData{Method: http.MethodPost, Uri: server.URL, Body: reqBdy, Headers: http.Header{}},
+		bidResponse: &adapters.BidderResponse{},
+	}
+	bidderImplTelaria := &goodSingleBidder{
+		httpRequest: &adapters.RequestData{Method: http.MethodPost, Uri: server.URL, Body: reqBdy, Headers: http.Header{}},
+		bidResponse: &adapters.BidderResponse{},
+	}
+	bidderImpl33Across := &goodSingleBidder{
+		httpRequest: &adapters.RequestData{Method: http.MethodPost, Uri: server.URL, Body: reqBdy, Headers: http.Header{}},
+		bidResponse: &adapters.BidderResponse{},
+	}
+	bidderImplAax := &goodSingleBidder{
+		httpRequest: &adapters.RequestData{Method: http.MethodPost, Uri: server.URL, Body: reqBdy, Headers: http.Header{}},
 		bidResponse: &adapters.BidderResponse{},
 	}
 
@@ -5744,10 +5753,10 @@ func TestModulesCanBeExecutedForMultipleBiddersSimultaneously(t *testing.T) {
 	}
 
 	e.adapterMap = map[openrtb_ext.BidderName]AdaptedBidder{
-		openrtb_ext.BidderAppnexus: AdaptBidder(bidderImpl, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderAppnexus, &config.DebugInfo{}, ""),
-		openrtb_ext.BidderTelaria:  AdaptBidder(bidderImpl, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderAppnexus, &config.DebugInfo{}, ""),
-		openrtb_ext.Bidder33Across: AdaptBidder(bidderImpl, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.Bidder33Across, &config.DebugInfo{}, ""),
-		openrtb_ext.BidderAax:      AdaptBidder(bidderImpl, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderAax, &config.DebugInfo{}, ""),
+		openrtb_ext.BidderAppnexus: AdaptBidder(bidderImplAppnexus, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderAppnexus, &config.DebugInfo{}, ""),
+		openrtb_ext.BidderTelaria:  AdaptBidder(bidderImplTelaria, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderTelaria, &config.DebugInfo{}, ""),
+		openrtb_ext.Bidder33Across: AdaptBidder(bidderImpl33Across, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.Bidder33Across, &config.DebugInfo{}, ""),
+		openrtb_ext.BidderAax:      AdaptBidder(bidderImplAax, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderAax, &config.DebugInfo{}, ""),
 	}
 	// Run test
 	_, err := e.HoldAuction(context.Background(), auctionRequest, &DebugLog{})
@@ -5805,12 +5814,16 @@ func (e mockUpdateBidRequestHook) HandleBidderRequestHook(_ context.Context, mct
 	c := hookstage.ChangeSet[hookstage.BidderRequestPayload]{}
 	c.AddMutation(
 		func(payload hookstage.BidderRequestPayload) (hookstage.BidderRequestPayload, error) {
-			payload.Request.Site.Name = "test"
+			site := ptrutil.Clone(payload.Request.Site)
+			site.Name = "test"
+			payload.Request.Site = site
 			return payload, nil
 		}, hookstage.MutationUpdate, "bidRequest", "site.name",
 	).AddMutation(
 		func(payload hookstage.BidderRequestPayload) (hookstage.BidderRequestPayload, error) {
-			payload.Request.Site.Domain = "test.com"
+			site := ptrutil.Clone(payload.Request.Site)
+			site.Domain = "test.com"
+			payload.Request.Site = site
 			return payload, nil
 		}, hookstage.MutationUpdate, "bidRequest", "site.domain",
 	)
diff --git a/hooks/hookexecution/mocks_test.go b/hooks/hookexecution/mocks_test.go
index c47e2892..a0d9e25c 100644
--- a/hooks/hookexecution/mocks_test.go
+++ b/hooks/hookexecution/mocks_test.go
@@ -7,6 +7,7 @@ import (
 
 	"github.com/prebid/prebid-server/v2/hooks/hookstage"
 	"github.com/prebid/prebid-server/v2/openrtb_ext"
+	"github.com/prebid/prebid-server/v2/util/ptrutil"
 )
 
 type mockUpdateHeaderEntrypointHook struct{}
@@ -330,12 +331,16 @@ func (e mockUpdateBidRequestHook) HandleBidderRequestHook(_ context.Context, _ h
 	c := hookstage.ChangeSet[hookstage.BidderRequestPayload]{}
 	c.AddMutation(
 		func(payload hookstage.BidderRequestPayload) (hookstage.BidderRequestPayload, error) {
-			payload.Request.User.Yob = 2000
+			user := ptrutil.Clone(payload.Request.User)
+			user.Yob = 2000
+			payload.Request.User = user
 			return payload, nil
 		}, hookstage.MutationUpdate, "bidRequest", "user.yob",
 	).AddMutation(
 		func(payload hookstage.BidderRequestPayload) (hookstage.BidderRequestPayload, error) {
-			payload.Request.User.Consent = "true"
+			user := ptrutil.Clone(payload.Request.User)
+			user.Consent = "true"
+			payload.Request.User = user
 			return payload, nil
 		}, hookstage.MutationUpdate, "bidRequest", "user.consent",
 	)
diff --git a/openrtb_ext/deal_tier_test.go b/openrtb_ext/deal_tier_test.go
index 6b74f7a1..4a9ed2c8 100644
--- a/openrtb_ext/deal_tier_test.go
+++ b/openrtb_ext/deal_tier_test.go
@@ -59,7 +59,12 @@ func TestReadDealTiersFromImp(t *testing.T) {
 		{
 			description:    "imp.ext.prebid.bidder_one_but_not_found_in_the_adapter_bidder_list",
 			impExt:         json.RawMessage(`{"prebid": {"bidder": {"unknown": {"dealTier": {"minDealTier": 5, "prefix": "anyPrefix"}, "placementId": 12345}}}}`),
-			expectedResult: DealTierBidderMap{},
+			expectedResult: DealTierBidderMap{"unknown": {Prefix: "anyPrefix", MinDealTier: 5}},
+		},
+		{
+			description:    "imp.ext.prebid.bidder_one_but_not_found_in_the_adapter_bidder_list_with_case_insensitive",
+			impExt:         json.RawMessage(`{"prebid": {"bidder": {"UnKnOwn": {"dealTier": {"minDealTier": 5, "prefix": "anyPrefix"}, "placementId": 12345}}}}`),
+			expectedResult: DealTierBidderMap{"UnKnOwn": {Prefix: "anyPrefix", MinDealTier: 5}},
 		},
 		{
 			description:    "imp.ext.prebid.bidder_one_but_case_is_different_from_the_adapter_bidder_list",
diff --git a/privacy/activitycontrol_test.go b/privacy/activitycontrol_test.go
index b8b06ee8..5cd9f38b 100644
--- a/privacy/activitycontrol_test.go
+++ b/privacy/activitycontrol_test.go
@@ -33,17 +33,23 @@ func TestNewActivityControl(t *testing.T) {
 					TransmitUniqueRequestIds: getTestActivityConfig(true),
 					TransmitTids:             getTestActivityConfig(true),
 				},
+				IPv6Config: config.IPv6{AnonKeepBits: 32},
+				IPv4Config: config.IPv4{AnonKeepBits: 16},
+			},
+			activityControl: ActivityControl{
+				plans: map[Activity]ActivityPlan{
+					ActivitySyncUser:                 getTestActivityPlan(ActivityAllow),
+					ActivityFetchBids:                getTestActivityPlan(ActivityAllow),
+					ActivityEnrichUserFPD:            getTestActivityPlan(ActivityAllow),
+					ActivityReportAnalytics:          getTestActivityPlan(ActivityAllow),
+					ActivityTransmitUserFPD:          getTestActivityPlan(ActivityAllow),
+					ActivityTransmitPreciseGeo:       getTestActivityPlan(ActivityDeny),
+					ActivityTransmitUniqueRequestIDs: getTestActivityPlan(ActivityAllow),
+					ActivityTransmitTIDs:             getTestActivityPlan(ActivityAllow),
+				},
+				IPv6Config: config.IPv6{AnonKeepBits: 32},
+				IPv4Config: config.IPv4{AnonKeepBits: 16},
 			},
-			activityControl: ActivityControl{plans: map[Activity]ActivityPlan{
-				ActivitySyncUser:                 getTestActivityPlan(ActivityAllow),
-				ActivityFetchBids:                getTestActivityPlan(ActivityAllow),
-				ActivityEnrichUserFPD:            getTestActivityPlan(ActivityAllow),
-				ActivityReportAnalytics:          getTestActivityPlan(ActivityAllow),
-				ActivityTransmitUserFPD:          getTestActivityPlan(ActivityAllow),
-				ActivityTransmitPreciseGeo:       getTestActivityPlan(ActivityDeny),
-				ActivityTransmitUniqueRequestIDs: getTestActivityPlan(ActivityAllow),
-				ActivityTransmitTIDs:             getTestActivityPlan(ActivityAllow),
-			}},
 		},
 	}