Repository: prebid/prebid-server
Pull request #2093 (2021-11-24 13:53:32)

Orbidder: bidfloor currency handling
The Orbidder Backend only supports EUR. This PR deals with Bid Floor Currency conversion into EUR as requested by mail from the Prebid Server committee.


Patch:
diff --git a/adapters/adf/adf.go b/adapters/adf/adf.go
index 8014bd5b..bc54f78f 100644
--- a/adapters/adf/adf.go
+++ b/adapters/adf/adf.go
@@ -16,6 +16,11 @@ type adapter struct {
 	endpoint string
 }
 
+type adfRequestExt struct {
+	openrtb_ext.ExtRequest
+	PriceType string `json:"pt"`
+}
+
 // Builder builds a new instance of the Adf adapter for the given bidder with the given config.
 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
 	bidder := &adapter{
@@ -27,6 +32,7 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters
 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
 	var errors []error
 	var validImps = make([]openrtb2.Imp, 0, len(request.Imp))
+	priceType := ""
 
 	for _, imp := range request.Imp {
 		var bidderExt adapters.ExtImpBidder
@@ -47,6 +53,30 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte
 
 		imp.TagID = adfImpExt.MasterTagID.String()
 		validImps = append(validImps, imp)
+
+		// If imps specify priceType they should all be the same. If they differ, only the first one will be used
+		if adfImpExt.PriceType != "" && priceType == "" {
+			priceType = adfImpExt.PriceType
+		}
+	}
+
+	if priceType != "" {
+		requestExt := adfRequestExt{}
+		var err error
+
+		if len(request.Ext) > 0 {
+			if err = json.Unmarshal(request.Ext, &requestExt); err != nil {
+				errors = append(errors, err)
+			}
+		}
+
+		if err == nil {
+			requestExt.PriceType = priceType
+
+			if request.Ext, err = json.Marshal(&requestExt); err != nil {
+				errors = append(errors, err)
+			}
+		}
 	}
 
 	request.Imp = validImps
diff --git a/adapters/algorix/algorix.go b/adapters/algorix/algorix.go
index 31d01349..628207d6 100644
--- a/adapters/algorix/algorix.go
+++ b/adapters/algorix/algorix.go
@@ -90,10 +90,22 @@ func getImpAlgoriXExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpAlgorix, error) {
 	return &extImpAlgoriX, nil
 }
 
+func getRegionInfo(region string) string {
+	switch region {
+	case "APAC":
+		return "apac.xyz"
+	case "USE":
+		return "use.xyz"
+	default:
+		return "xyz"
+	}
+}
+
 func (a *adapter) getEndPoint(ext *openrtb_ext.ExtImpAlgorix) (string, error) {
 	endPointParams := macros.EndpointTemplateParams{
 		SourceId:  url.PathEscape(ext.Sid),
 		AccountID: url.PathEscape(ext.Token),
+		Host:      url.PathEscape(getRegionInfo(ext.Region)),
 	}
 	return macros.ResolveMacros(a.EndpointTemplate, endPointParams)
 }
diff --git a/adapters/beachfront/beachfront.go b/adapters/beachfront/beachfront.go
index 3e3ff62b..6eaf5ad9 100644
--- a/adapters/beachfront/beachfront.go
+++ b/adapters/beachfront/beachfront.go
@@ -23,7 +23,7 @@ const defaultVideoEndpoint = "https://reachms.bfmio.com/bid.json?exchange_id"
 const nurlVideoEndpointSuffix = "&prebidserver"
 
 const beachfrontAdapterName = "BF_PREBID_S2S"
-const beachfrontAdapterVersion = "0.9.2"
+const beachfrontAdapterVersion = "1.0.0"
 
 const minBidFloor = 0.01
 
@@ -110,7 +110,7 @@ type beachfrontVideoBidExtension struct {
 }
 
 func (a *BeachfrontAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
-	beachfrontRequests, errs := preprocess(request)
+	beachfrontRequests, errs := preprocess(request, reqInfo)
 
 	headers := http.Header{}
 	headers.Add("Content-Type", "application/json;charset=utf-8")
@@ -140,7 +140,6 @@ func (a *BeachfrontAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *
 	var nurlBump = 0
 	var admBump = 0
 
-	// At most, I only ever have one banner request, and it does not need the cookie, so doing it first.
 	if len(beachfrontRequests.Banner.Slots) > 0 {
 		bytes, err := json.Marshal(beachfrontRequests.Banner)
 
@@ -199,7 +198,7 @@ func (a *BeachfrontAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *
 	return reqs, errs
 }
 
-func preprocess(request *openrtb2.BidRequest) (beachfrontReqs beachfrontRequests, errs []error) {
+func preprocess(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) (beachfrontReqs beachfrontRequests, errs []error) {
 	var videoImps = make([]openrtb2.Imp, 0)
 	var bannerImps = make([]openrtb2.Imp, 0)
 
@@ -221,7 +220,7 @@ func preprocess(request *openrtb2.BidRequest) (beachfrontReqs beachfrontRequests
 
 	if len(bannerImps) > 0 {
 		request.Imp = bannerImps
-		beachfrontReqs.Banner, errs = getBannerRequest(request)
+		beachfrontReqs.Banner, errs = getBannerRequest(request, reqInfo)
 	}
 
 	if len(videoImps) > 0 {
@@ -229,8 +228,9 @@ func preprocess(request *openrtb2.BidRequest) (beachfrontReqs beachfrontRequests
 		var videoList []beachfrontVideoRequest
 
 		request.Imp = videoImps
+		request.Ext = nil
 
-		videoList, videoErrs = getVideoRequests(request)
+		videoList, videoErrs = getVideoRequests(request, reqInfo)
 		errs = append(errs, videoErrs...)
 
 		for i := 0; i < len(videoList); i++ {
@@ -269,7 +269,7 @@ func getSchain(request *openrtb2.BidRequest) (openrtb_ext.ExtRequestPrebidSChain
 	return schain, json.Unmarshal(request.Source.Ext, &schain)
 }
 
-func getBannerRequest(request *openrtb2.BidRequest) (beachfrontBannerRequest, []error) {
+func getBannerRequest(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) (beachfrontBannerRequest, []error) {
 	var bfr beachfrontBannerRequest
 	var errs = make([]error, 0, len(request.Imp))
 
@@ -285,16 +285,15 @@ func getBannerRequest(request *openrtb2.BidRequest) (beachfrontBannerRequest, []
 		appid, err := getAppId(beachfrontExt, openrtb_ext.BidTypeBanner)
 
 		if err != nil {
-			// Failed to get an appid, so this request is junk.
 			errs = append(errs, err)
 			continue
 		}
 
-		err = setBidFloor(&beachfrontExt, &request.Imp[i])
-
-		if err != nil {
+		if fatal, err := setBidFloor(&beachfrontExt, &request.Imp[i], reqInfo); err != nil {
 			errs = append(errs, err)
-			continue
+			if fatal {
+				continue
+			}
 		}
 
 		slot := beachfrontSlot{
@@ -393,7 +392,7 @@ func fallBackDeviceType(request *openrtb2.BidRequest) openrtb2.DeviceType {
 	return openrtb2.DeviceTypeMobileTablet
 }
 
-func getVideoRequests(request *openrtb2.BidRequest) ([]beachfrontVideoRequest, []error) {
+func getVideoRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]beachfrontVideoRequest, []error) {
 	var bfReqs = make([]beachfrontVideoRequest, len(request.Imp))
 	var errs = make([]error, 0, len(request.Imp))
 	var failedRequestIndicies = make([]int, 0)
@@ -402,7 +401,6 @@ func getVideoRequests(request *openrtb2.BidRequest) ([]beachfrontVideoRequest, [
 		beachfrontExt, err := getBeachfrontExtension(request.Imp[i])
 
 		if err != nil {
-			// Failed to extract the beachfrontExt, so this request is junk.
 			failedRequestIndicies = append(failedRequestIndicies, i)
 			errs = append(errs, err)
 			continue
@@ -412,7 +410,6 @@ func getVideoRequests(request *openrtb2.BidRequest) ([]beachfrontVideoRequest, [
 		bfReqs[i].AppId = appid
 
 		if err != nil {
-			// Failed to get an appid, so this request is junk.
 			failedRequestIndicies = append(failedRequestIndicies, i)
 			errs = append(errs, err)
 			continue
@@ -458,7 +455,6 @@ func getVideoRequests(request *openrtb2.BidRequest) ([]beachfrontVideoRequest, [
 		}
 
 		if deviceCopy.DeviceType == 0 {
-			// More fine graned deviceType methods will be added in the future
 			deviceCopy.DeviceType = fallBackDeviceType(request)
 		}
 		bfReqs[i].Request.Device = &deviceCopy
@@ -468,10 +464,12 @@ func getVideoRequests(request *openrtb2.BidRequest) ([]beachfrontVideoRequest, [
 		imp.Banner = nil
 		imp.Ext = nil
 		imp.Secure = &secure
-		if err := setBidFloor(&beachfrontExt, &imp); err != nil {
+		if fatal, err := setBidFloor(&beachfrontExt, &imp, reqInfo); err != nil {
 			errs = append(errs, err)
-			failedRequestIndicies = append(failedRequestIndicies, i)
-			continue
+			if fatal {
+				failedRequestIndicies = append(failedRequestIndicies, i)
+				continue
+			}
 		}
 
 		if imp.Video.H == 0 && imp.Video.W == 0 {
@@ -490,7 +488,6 @@ func getVideoRequests(request *openrtb2.BidRequest) ([]beachfrontVideoRequest, [
 
 	}
 
-	// Strip out any failed requests
 	if len(failedRequestIndicies) > 0 {
 		for i := 0; i < len(failedRequestIndicies); i++ {
 			bfReqs = removeVideoElement(bfReqs, failedRequestIndicies[i])
@@ -525,8 +522,6 @@ func (a *BeachfrontAdapter) MakeBids(internalRequest *openrtb2.BidRequest, exter
 	var errs = make([]error, 0)
 	var xtrnal openrtb2.BidRequest
 
-	// For video, which uses RTB for the external request, this will unmarshal as expected. For banner, it will
-	// only get the User struct and everything else will be nil
 	if err := json.Unmarshal(externalRequest.Body, &xtrnal); err != nil {
 		errs = append(errs, err)
 	} else {
@@ -568,29 +563,51 @@ func (a *BeachfrontAdapter) MakeBids(internalRequest *openrtb2.BidRequest, exter
 	return bidResponse, errs
 }
 
-func setBidFloor(ext *openrtb_ext.ExtImpBeachfront, imp *openrtb2.Imp) error {
-	var floor float64
+func setBidFloor(ext *openrtb_ext.ExtImpBeachfront, imp *openrtb2.Imp, reqInfo *adapters.ExtraRequestInfo) (bool, error) {
+	var initialImpBidfloor float64 = imp.BidFloor
+	var err error
 
-	if imp.BidFloor > 0 {
-		floor = imp.BidFloor
-	} else if ext.BidFloor > 0 {
-		floor = ext.BidFloor
-	} else {
-		floor = minBidFloor
-	}
+	if imp.BidFloorCur != "" && strings.ToUpper(imp.BidFloorCur) != "USD" && imp.BidFloor > 0 {
+		imp.BidFloor, err = reqInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "USD")
+
+		var convertedFromCurrency = imp.BidFloorCur
+		imp.BidFloorCur = "USD"
 
-	if floor >= 0 && imp.BidFloorCur != "" && strings.ToUpper(imp.BidFloorCur) != "USD" {
-		return &errortypes.BadInput{
-			Message: fmt.Sprintf("unsupported bid currency, %s. bids are currently accepted in USD only.", imp.BidFloorCur),
+		if err != nil {
+			if ext.BidFloor > minBidFloor {
+				imp.BidFloor = ext.BidFloor
+				return false, &errortypes.Warning{
+					Message: fmt.Sprintf("The following error was recieved from the currency converter while attempting to convert the imp.bidfloor value of %.2f from %s to USD:\n%s\nThe provided value of imp.ext.beachfront.bidfloor, %.2f USD is being used as a fallback.",
+						initialImpBidfloor,
+						convertedFromCurrency,
+						err,
+						ext.BidFloor,
+					),
+				}
+			} else {
+				return true, &errortypes.BadInput{
+					Message: fmt.Sprintf("The following error was recieved from the currency converter while attempting to convert the imp.bidfloor value of %.2f from %s to USD:\n%s\nA value of imp.ext.beachfront.bidfloor was not provided. The bid is being skipped.",
+						initialImpBidfloor,
+						convertedFromCurrency,
+						err,
+					),
+				}
+			}
 		}
 	}
 
-	if floor <= minBidFloor {
-		floor = 0
+	if imp.BidFloor < ext.BidFloor {
+		imp.BidFloor = ext.BidFloor
+	}
+
+	if imp.BidFloor > minBidFloor {
+		imp.BidFloorCur = "USD"
+	} else {
+		imp.BidFloor = 0
+		imp.BidFloorCur = ""
 	}
 
-	imp.BidFloor = floor
-	return nil
+	return false, nil
 }
 
 func (a *BeachfrontAdapter) getBidType(externalRequest *adapters.RequestData) openrtb_ext.BidType {
diff --git a/adapters/bizzclick/bizzclick.go b/adapters/bizzclick/bizzclick.go
new file mode 100644
index 00000000..70c2bb0c
--- /dev/null
+++ b/adapters/bizzclick/bizzclick.go
@@ -0,0 +1,192 @@
+package bizzclick
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"text/template"
+
+	"github.com/mxmCherry/openrtb/v15/openrtb2"
+	"github.com/prebid/prebid-server/adapters"
+	"github.com/prebid/prebid-server/config"
+	"github.com/prebid/prebid-server/errortypes"
+	"github.com/prebid/prebid-server/macros"
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+type adapter struct {
+	endpoint *template.Template
+}
+
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (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 getHeaders(request *openrtb2.BidRequest) http.Header {
+	headers := http.Header{}
+	headers.Add("Content-Type", "application/json;charset=utf-8")
+	headers.Add("Accept", "application/json")
+	headers.Add("X-Openrtb-Version", "2.5")
+
+	if request.Device != nil {
+		if len(request.Device.UA) > 0 {
+			headers.Add("User-Agent", request.Device.UA)
+		}
+
+		if len(request.Device.IPv6) > 0 {
+			headers.Add("X-Forwarded-For", request.Device.IPv6)
+		}
+
+		if len(request.Device.IP) > 0 {
+			headers.Add("X-Forwarded-For", request.Device.IP)
+		}
+	}
+
+	return headers
+}
+
+func (a *adapter) MakeRequests(
+	openRTBRequest *openrtb2.BidRequest,
+	reqInfo *adapters.ExtraRequestInfo,
+) (
+	requestsToBidder []*adapters.RequestData,
+	errs []error,
+) {
+	bizzclickExt, err := a.getImpressionExt(&openRTBRequest.Imp[0])
+	if err != nil {
+		return nil, []error{err}
+	}
+
+	for idx := range openRTBRequest.Imp {
+		openRTBRequest.Imp[idx].Ext = nil
+	}
+	url, err := a.buildEndpointURL(bizzclickExt)
+	if err != nil {
+		return nil, []error{err}
+	}
+
+	reqJSON, err := json.Marshal(openRTBRequest)
+	if err != nil {
+		return nil, []error{err}
+	}
+
+	return []*adapters.RequestData{{
+		Method:  http.MethodPost,
+		Body:    reqJSON,
+		Uri:     url,
+		Headers: getHeaders(openRTBRequest),
+	}}, nil
+}
+
+func (a *adapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtBizzclick, error) {
+	var bidderExt adapters.ExtImpBidder
+	if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
+		return nil, &errortypes.BadInput{
+			Message: "ext.bidder not provided",
+		}
+	}
+	var bizzclickExt openrtb_ext.ExtBizzclick
+	if err := json.Unmarshal(bidderExt.Bidder, &bizzclickExt); err != nil {
+		return nil, &errortypes.BadInput{
+			Message: "ext.bidder not provided",
+		}
+	}
+
+	return &bizzclickExt, nil
+}
+
+func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtBizzclick) (string, error) {
+	endpointParams := macros.EndpointTemplateParams{AccountID: params.AccountID, SourceId: params.PlacementID}
+	return macros.ResolveMacros(a.endpoint, endpointParams)
+}
+
+func (a *adapter) checkResponseStatusCodes(response *adapters.ResponseData) error {
+	if response.StatusCode == http.StatusBadRequest {
+		return &errortypes.BadInput{
+			Message: fmt.Sprintf("Unexpected status code: [ %d ]", response.StatusCode),
+		}
+	}
+
+	if response.StatusCode == http.StatusServiceUnavailable {
+		return &errortypes.BadServerResponse{
+			Message: fmt.Sprintf("Something went wrong, please contact your Account Manager. Status Code: [ %d ] ", response.StatusCode),
+		}
+	}
+
+	if response.StatusCode != http.StatusOK {
+		return &errortypes.BadServerResponse{
+			Message: fmt.Sprintf("Unexpected status code: [ %d ]. Run with request.debug = 1 for more info", response.StatusCode),
+		}
+	}
+
+	return nil
+}
+
+func (a *adapter) MakeBids(
+	openRTBRequest *openrtb2.BidRequest,
+	requestToBidder *adapters.RequestData,
+	bidderRawResponse *adapters.ResponseData,
+) (
+	bidderResponse *adapters.BidderResponse,
+	errs []error,
+) {
+	if bidderRawResponse.StatusCode == http.StatusNoContent {
+		return nil, nil
+	}
+
+	httpStatusError := a.checkResponseStatusCodes(bidderRawResponse)
+	if httpStatusError != nil {
+		return nil, []error{httpStatusError}
+	}
+
+	responseBody := bidderRawResponse.Body
+	var bidResp openrtb2.BidResponse
+	if err := json.Unmarshal(responseBody, &bidResp); err != nil {
+		return nil, []error{&errortypes.BadServerResponse{
+			Message: "Bad Server Response",
+		}}
+	}
+
+	if len(bidResp.SeatBid) == 0 {
+		return nil, []error{&errortypes.BadServerResponse{
+			Message: "Empty SeatBid array",
+		}}
+	}
+
+	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid))
+	sb := bidResp.SeatBid[0]
+	var bidsArray []*adapters.TypedBid
+
+	for idx, bid := range sb.Bid {
+		bidsArray = append(bidsArray, &adapters.TypedBid{
+			Bid:     &sb.Bid[idx],
+			BidType: getMediaTypeForImp(bid.ImpID, openRTBRequest.Imp),
+		})
+	}
+
+	bidResponse.Bids = bidsArray
+	return bidResponse, nil
+}
+
+func getMediaTypeForImp(impId string, imps []openrtb2.Imp) openrtb_ext.BidType {
+	mediaType := openrtb_ext.BidTypeBanner
+	for _, imp := range imps {
+		if imp.ID == impId {
+			if imp.Video != nil {
+				mediaType = openrtb_ext.BidTypeVideo
+			} else if imp.Native != nil {
+				mediaType = openrtb_ext.BidTypeNative
+			}
+			return mediaType
+		}
+	}
+	return mediaType
+}
diff --git a/adapters/marsmedia/marsmedia.go b/adapters/marsmedia/marsmedia.go
index 0f4fad5a..65ffff25 100644
--- a/adapters/marsmedia/marsmedia.go
+++ b/adapters/marsmedia/marsmedia.go
@@ -83,7 +83,7 @@ func (a *MarsmediaAdapter) MakeRequests(requestIn *openrtb2.BidRequest, reqInfo
 		}}
 	}
 
-	uri := a.URI + "&zone=" + marsmediaExt.ZoneID
+	uri := a.URI + "&zone=" + marsmediaExt.ZoneID.String()
 	headers := http.Header{}
 	headers.Add("Content-Type", "application/json;charset=utf-8")
 	headers.Add("Accept", "application/json")
diff --git a/adapters/openrtb_util.go b/adapters/openrtb_util.go
index 5587cac7..2816e730 100644
--- a/adapters/openrtb_util.go
+++ b/adapters/openrtb_util.go
@@ -4,11 +4,12 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+
 	"github.com/mxmCherry/openrtb/v15/openrtb2"
 	"github.com/prebid/prebid-server/openrtb_ext"
 )
 
-func ExtractAdapterReqBidderParams(bidRequest *openrtb2.BidRequest) (map[string]json.RawMessage, error) {
+func ExtractReqExtBidderParamsMap(bidRequest *openrtb2.BidRequest) (map[string]json.RawMessage, error) {
 	if bidRequest == nil {
 		return nil, errors.New("error bidRequest should not be nil")
 	}
@@ -34,15 +35,14 @@ func ExtractAdapterReqBidderParams(bidRequest *openrtb2.BidRequest) (map[string]
 	return bidderParams, nil
 }
 
-func ExtractReqExtBidderParams(bidReq *openrtb2.BidRequest) (map[string]map[string]json.RawMessage, error) {
-	if bidReq == nil {
+func ExtractReqExtBidderParamsEmbeddedMap(bidRequest *openrtb2.BidRequest) (map[string]map[string]json.RawMessage, error) {
+	if bidRequest == nil {
 		return nil, errors.New("error bidRequest should not be nil")
 	}
 
 	reqExt := &openrtb_ext.ExtRequest{}
-	if len(bidReq.Ext) > 0 {
-		err := json.Unmarshal(bidReq.Ext, &reqExt)
-		if err != nil {
+	if len(bidRequest.Ext) > 0 {
+		if err := json.Unmarshal(bidRequest.Ext, &reqExt); err != nil {
 			return nil, fmt.Errorf("error decoding Request.ext : %s", err.Error())
 		}
 	}
@@ -52,8 +52,7 @@ func ExtractReqExtBidderParams(bidReq *openrtb2.BidRequest) (map[string]map[stri
 	}
 
 	var bidderParams map[string]map[string]json.RawMessage
-	err := json.Unmarshal(reqExt.Prebid.BidderParams, &bidderParams)
-	if err != nil {
+	if err := json.Unmarshal(reqExt.Prebid.BidderParams, &bidderParams); err != nil {
 		return nil, err
 	}
 
diff --git a/adapters/orbidder/orbidder.go b/adapters/orbidder/orbidder.go
index 77985c8d..f2dda85e 100644
--- a/adapters/orbidder/orbidder.go
+++ b/adapters/orbidder/orbidder.go
@@ -3,13 +3,13 @@ package orbidder
 import (
 	"encoding/json"
 	"fmt"
-	"net/http"
-
 	"github.com/mxmCherry/openrtb/v15/openrtb2"
 	"github.com/prebid/prebid-server/adapters"
 	"github.com/prebid/prebid-server/config"
 	"github.com/prebid/prebid-server/errortypes"
 	"github.com/prebid/prebid-server/openrtb_ext"
+	"net/http"
+	"strings"
 )
 
 type OrbidderAdapter struct {
@@ -18,30 +18,11 @@ type OrbidderAdapter struct {
 
 // MakeRequests makes the HTTP requests which should be made to fetch bids from orbidder.
 func (rcv *OrbidderAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
-	var errs []error
-	var validImps []openrtb2.Imp
-
-	// check if imps exists, if not return error and do send request to orbidder.
-	if len(request.Imp) == 0 {
-		return nil, []error{&errortypes.BadInput{
-			Message: "No impressions in request",
-		}}
-	}
-
-	// validate imps
-	for _, imp := range request.Imp {
-		if err := preprocess(&imp); err != nil {
-			errs = append(errs, err)
-			continue
-		}
-		validImps = append(validImps, imp)
-	}
-
+	validImps, errs := getValidImpressions(request, reqInfo)
 	if len(validImps) == 0 {
 		return nil, errs
 	}
 
-	//set imp array to only valid imps
 	request.Imp = validImps
 
 	requestBodyJSON, err := json.Marshal(request)
@@ -55,14 +36,34 @@ func (rcv *OrbidderAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *
 	headers.Add("Accept", "application/json")
 
 	return []*adapters.RequestData{{
-		Method:  "POST",
+		Method:  http.MethodPost,
 		Uri:     rcv.endpoint,
 		Body:    requestBodyJSON,
 		Headers: headers,
 	}}, errs
 }
 
-func preprocess(imp *openrtb2.Imp) error {
+// getValidImpressions validate imps and check for bid floor currency. Convert to EUR if necessary
+func getValidImpressions(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]openrtb2.Imp, []error) {
+	var errs []error
+	var validImps []openrtb2.Imp
+
+	for _, imp := range request.Imp {
+		if err := preprocessBidFloorCurrency(&imp, reqInfo); err != nil {
+			errs = append(errs, err)
+			continue
+		}
+
+		if err := preprocessExtensions(&imp); err != nil {
+			errs = append(errs, err)
+			continue
+		}
+		validImps = append(validImps, imp)
+	}
+	return validImps, errs
+}
+
+func preprocessExtensions(imp *openrtb2.Imp) error {
 	var bidderExt adapters.ExtImpBidder
 	if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
 		return &errortypes.BadInput{
@@ -80,8 +81,21 @@ func preprocess(imp *openrtb2.Imp) error {
 	return nil
 }
 
+func preprocessBidFloorCurrency(imp *openrtb2.Imp, reqInfo *adapters.ExtraRequestInfo) error {
+	// we expect every currency related data to be EUR
+	if imp.BidFloor > 0 && strings.ToUpper(imp.BidFloorCur) != "EUR" && imp.BidFloorCur != "" {
+		if convertedValue, err := reqInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "EUR"); err != nil {
+			return err
+		} else {
+			imp.BidFloor = convertedValue
+		}
+	}
+	imp.BidFloorCur = "EUR"
+	return nil
+}
+
 // MakeBids unpacks server response into Bids.
-func (rcv OrbidderAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+func (rcv OrbidderAdapter) MakeBids(_ *openrtb2.BidRequest, _ *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
 	if response.StatusCode == http.StatusNoContent {
 		return nil, nil
 	}
@@ -125,7 +139,7 @@ func (rcv OrbidderAdapter) MakeBids(internalRequest *openrtb2.BidRequest, extern
 }
 
 // Builder builds a new instance of the Orbidder adapter for the given bidder with the given config.
-func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
+func Builder(_ openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
 	bidder := &OrbidderAdapter{
 		endpoint: config.Endpoint,
 	}
diff --git a/adapters/pubmatic/pubmatic.go b/adapters/pubmatic/pubmatic.go
index 799d3364..f855f917 100644
--- a/adapters/pubmatic/pubmatic.go
+++ b/adapters/pubmatic/pubmatic.go
@@ -305,7 +305,7 @@ func parseImpressionObject(imp *openrtb2.Imp, extractWrapperExtFromImp, extractP
 // extractPubmaticWrapperExtFromRequest parse the imp to get it ready to send to pubmatic
 func extractPubmaticWrapperExtFromRequest(request *openrtb2.BidRequest) (*pubmaticWrapperExt, error) {
 	var wrpExt pubmaticWrapperExt
-	reqExtBidderParams, err := adapters.ExtractAdapterReqBidderParams(request)
+	reqExtBidderParams, err := adapters.ExtractReqExtBidderParamsMap(request)
 	if err != nil {
 		return nil, err
 	}
diff --git a/adapters/rubicon/rubicon.go b/adapters/rubicon/rubicon.go
index ace1bfaa..72b61628 100644
--- a/adapters/rubicon/rubicon.go
+++ b/adapters/rubicon/rubicon.go
@@ -25,6 +25,28 @@ type RubiconAdapter struct {
 	XAPIPassword string
 }
 
+type rubiconContext struct {
+	Data json.RawMessage `json:"data"`
+}
+
+type rubiconData struct {
+	AdServer rubiconAdServer `json:"adserver"`
+	PbAdSlot string          `json:"pbadslot"`
+}
+
+type rubiconAdServer struct {
+	Name   string `json:"name"`
+	AdSlot string `json:"adslot"`
+}
+
+type rubiconExtImpBidder struct {
+	Prebid  *openrtb_ext.ExtImpPrebid `json:"prebid"`
+	Bidder  json.RawMessage           `json:"bidder"`
+	Gpid    string                    `json:"gpid"`
+	Data    json.RawMessage           `json:"data"`
+	Context rubiconContext            `json:"context"`
+}
+
 type bidRequestExt struct {
 	Prebid bidRequestExtPrebid `json:"prebid"`
 }
@@ -254,7 +276,7 @@ type mappedRubiconUidsParam struct {
 	liverampIdl string
 }
 
-//MAS algorithm
+// MAS algorithm
 func findPrimary(alt []int) (int, []int) {
 	min, pos, primary := 0, 0, 0
 	for i, size := range alt {
@@ -364,7 +386,7 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada
 	rubiconRequest := *request
 	for _, imp := range requestImpCopy {
 
-		var bidderExt adapters.ExtImpBidder
+		var bidderExt rubiconExtImpBidder
 		if err = json.Unmarshal(imp.Ext, &bidderExt); err != nil {
 			errs = append(errs, &errortypes.BadInput{
 				Message: err.Error(),
@@ -380,12 +402,7 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada
 			continue
 		}
 
-		target, err := updateImpRpTargetWithFpdAttributes(rubiconExt, imp, request.Site, request.App)
-		if err != nil {
-			errs = append(errs, err)
-			continue
-		}
-		adSlot, err := getAdSlot(imp)
+		target, err := updateImpRpTargetWithFpdAttributes(bidderExt, rubiconExt, imp, request.Site, request.App)
 		if err != nil {
 			errs = append(errs, err)
 			continue
@@ -397,8 +414,9 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada
 				Target: target,
 				Track:  rubiconImpExtRPTrack{Mint: "", MintVersion: ""},
 			},
-			GPID: adSlot,
+			GPID: bidderExt.Gpid,
 		}
+
 		imp.Ext, err = json.Marshal(&impExt)
 		if err != nil {
 			errs = append(errs, err)
@@ -589,8 +607,9 @@ func resolveBidFloor(bidFloor float64, bidFloorCur string, reqInfo *adapters.Ext
 	return bidFloor, nil
 }
 
-func updateImpRpTargetWithFpdAttributes(extImp openrtb_ext.ExtImpRubicon, imp openrtb2.Imp,
-	site *openrtb2.Site, app *openrtb2.App) (json.RawMessage, error) {
+func updateImpRpTargetWithFpdAttributes(extImp rubiconExtImpBidder, extImpRubicon openrtb_ext.ExtImpRubicon,
+	imp openrtb2.Imp, site *openrtb2.Site, app *openrtb2.App) (json.RawMessage, error) {
+
 	existingTarget, _, _, err := jsonparser.Get(imp.Ext, "rp", "target")
 	if isNotKeyPathError(err) {
 		return nil, err
@@ -599,7 +618,7 @@ func updateImpRpTargetWithFpdAttributes(extImp openrtb_ext.ExtImpRubicon, imp op
 	if err != nil {
 		return nil, err
 	}
-	err = populateFirstPartyDataAttributes(extImp.Inventory, target)
+	err = populateFirstPartyDataAttributes(extImpRubicon.Inventory, target)
 	if err != nil {
 		return nil, err
 	}
@@ -645,28 +664,41 @@ func updateImpRpTargetWithFpdAttributes(extImp openrtb_ext.ExtImpRubicon, imp op
 		}
 	}
 
-	impExtContextAttributes, _, _, err := jsonparser.Get(imp.Ext, "context", "data")
+	if len(extImp.Context.Data) > 0 {
+		err = populateFirstPartyDataAttributes(extImp.Context.Data, target)
+	} else if len(extImp.Data) > 0 {
+		err = populateFirstPartyDataAttributes(extImp.Data, target)
+	}
 	if isNotKeyPathError(err) {
 		return nil, err
 	}
 
-	if len(impExtContextAttributes) > 0 {
-		err = populateFirstPartyDataAttributes(impExtContextAttributes, target)
+	var data rubiconData
+	if len(extImp.Data) > 0 {
+		err := json.Unmarshal(extImp.Data, &data)
 		if err != nil {
 			return nil, err
 		}
-	} else if impExtDataAttributes, _, _, err := jsonparser.Get(imp.Ext, "data"); err == nil && len(impExtDataAttributes) > 0 {
-		err = populateFirstPartyDataAttributes(impExtDataAttributes, target)
+	}
+	var contextData rubiconData
+	if len(extImp.Context.Data) > 0 {
+		err := json.Unmarshal(extImp.Context.Data, &contextData)
 		if err != nil {
 			return nil, err
 		}
 	}
-	if isNotKeyPathError(err) {
-		return nil, err
+
+	if data.PbAdSlot != "" {
+		target["pbadslot"] = data.PbAdSlot
+	} else {
+		dfpAdUnitCode := extractDfpAdUnitCode(data, contextData)
+		if dfpAdUnitCode != "" {
+			target["dfp_ad_unit_code"] = dfpAdUnitCode
+		}
 	}
 
-	if len(extImp.Keywords) > 0 {
-		addStringArrayAttribute(extImp.Keywords, target, "keywords")
+	if len(extImpRubicon.Keywords) > 0 {
+		addStringArrayAttribute(extImpRubicon.Keywords, target, "keywords")
 	}
 	updatedTarget, err := json.Marshal(target)
 	if err != nil {
@@ -675,6 +707,16 @@ func updateImpRpTargetWithFpdAttributes(extImp openrtb_ext.ExtImpRubicon, imp op
 	return updatedTarget, nil
 }
 
+func extractDfpAdUnitCode(data rubiconData, contextData rubiconData) string {
+	if contextData.AdServer.Name == "gam" && contextData.AdServer.AdSlot != "" {
+		return contextData.AdServer.AdSlot
+	} else if data.AdServer.Name == "gam" && data.AdServer.AdSlot != "" {
+		return data.AdServer.AdSlot
+	}
+
+	return ""
+}
+
 func isNotKeyPathError(err error) bool {
 	return err != nil && err != jsonparser.KeyPathNotFoundError
 }
@@ -687,62 +729,6 @@ func addStringArrayAttribute(attribute []string, target map[string]interface{},
 	target[attributeName] = attribute
 }
 
-func getAdSlot(imp openrtb2.Imp) (string, error) {
-	var adSlot string
-	var parsingError error
-	jsonparser.EachKey(imp.Ext, func(idx int, value []byte, vt jsonparser.ValueType, err error) {
-		switch idx {
-		case 0:
-			adServerContextName, err := jsonparser.GetString(value, "name")
-			if isNotKeyPathError(err) {
-				parsingError = err
-				return
-			}
-			if adServerContextName == "gam" {
-				contextAdSlot, err := jsonparser.GetString(value, "adslot")
-				if isNotKeyPathError(err) {
-					parsingError = err
-					return
-				}
-				adSlot = contextAdSlot
-			}
-		}
-	}, []string{"context", "data", "adserver"})
-
-	if parsingError != nil {
-		return "", parsingError
-	}
-
-	if adSlot != "" {
-		return adSlot, nil
-	}
-
-	jsonparser.EachKey(imp.Ext, func(idx int, value []byte, vt jsonparser.ValueType, err error) {
-		switch idx {
-		case 0:
-			adServerDataName, err := jsonparser.GetString(value, "name")
-			if isNotKeyPathError(err) {
-				parsingError = err
-				return
-			}
-			if adServerDataName == "gam" {
-				dataAdSlot, err := jsonparser.GetString(value, "adslot")
-				if isNotKeyPathError(err) {
-					parsingError = err
-					return
-				}
-				adSlot = dataAdSlot
-			}
-		}
-	}, []string{"data", "adserver"})
-
-	if parsingError != nil {
-		return "", parsingError
-	}
-
-	return adSlot, nil
-}
-
 func updateUserRpTargetWithFpdAttributes(visitor json.RawMessage, user openrtb2.User) (json.RawMessage, error) {
 	existingTarget, _, _, err := jsonparser.Get(user.Ext, "rp", "target")
 	if isNotKeyPathError(err) {
@@ -848,6 +834,7 @@ func rawJSONToMap(message json.RawMessage) (map[string]interface{}, error) {
 
 	return mapFromRawJSON(message)
 }
+
 func mapFromRawJSON(message json.RawMessage) (map[string]interface{}, error) {
 	targetAsMap := make(map[string]interface{})
 	err := json.Unmarshal(message, &targetAsMap)
diff --git a/config/config.go b/config/config.go
index 84ed6109..f9dbc274 100644
--- a/config/config.go
+++ b/config/config.go
@@ -788,7 +788,7 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("adapters.adxcg.disabled", true)
 	v.SetDefault("adapters.adyoulike.endpoint", "https://broker.omnitagjs.com/broker/bid?partnerId=19340f4f097d16f41f34fc0274981ca4")
 	v.SetDefault("adapters.aja.endpoint", "https://ad.as.amanad.adtdp.com/v1/bid/4")
-	v.SetDefault("adapters.algorix.endpoint", "https://xyz.svr-algorix.com/rtb/sa?sid={{.SourceId}}&token={{.AccountID}}")
+	v.SetDefault("adapters.algorix.endpoint", "https://{{.Host}}.svr-algorix.com/rtb/sa?sid={{.SourceId}}&token={{.AccountID}}")
 	v.SetDefault("adapters.amx.endpoint", "http://pbs.amxrtb.com/auction/openrtb")
 	v.SetDefault("adapters.applogy.endpoint", "http://rtb.applogy.com/v1/prebid")
 	v.SetDefault("adapters.appnexus.endpoint", "http://ib.adnxs.com/openrtb2") // Docs: https://wiki.appnexus.com/display/supply/Incoming+Bid+Request+from+SSPs
@@ -804,6 +804,7 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("adapters.bidmachine.endpoint", "https://{{.Host}}.bidmachine.io")
 	v.SetDefault("adapters.bidmyadz.endpoint", "http://endpoint.bidmyadz.com/c0f68227d14ed938c6c49f3967cbe9bc")
 	v.SetDefault("adapters.bidscube.endpoint", "http://supply.bidscube.com/?c=o&m=rtb")
+	v.SetDefault("adapters.bizzclick.endpoint", "http://us-e-node1.bizzclick.com/bid?rtb_seat_id={{.SourceId}}&secret_key={{.AccountID}}")
 	v.SetDefault("adapters.bmtm.endpoint", "https://one.elitebidder.com/api/pbs")
 	v.SetDefault("adapters.brightroll.endpoint", "http://east-bid.ybp.yahoo.com/bid/appnexuspbs")
 	v.SetDefault("adapters.coinzilla.endpoint", "http://request-global.czilladx.com/serve/prebid-server.php")
@@ -826,6 +827,7 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("adapters.gamma.endpoint", "https://hb.gammaplatform.com/adx/request/")
 	v.SetDefault("adapters.gamoshi.endpoint", "https://rtb.gamoshi.io")
 	v.SetDefault("adapters.grid.endpoint", "https://grid.bidswitch.net/sp_bid?sp=prebid")
+	v.SetDefault("adapters.groupm.endpoint", "https://hbopenbid.pubmatic.com/translator?source=prebid-server")
 	v.SetDefault("adapters.gumgum.endpoint", "https://g2.gumgum.com/providers/prbds2s/bid")
 	v.SetDefault("adapters.huaweiads.endpoint", "https://acd.op.hicloud.com/ppsadx/getResult")
 	v.SetDefault("adapters.huaweiads.disabled", true)
diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go
index 123b576a..ff71770d 100644
--- a/endpoints/openrtb2/amp_auction.go
+++ b/endpoints/openrtb2/amp_auction.go
@@ -313,8 +313,7 @@ func (deps *endpointDeps) parseAmpRequest(httpRequest *http.Request) (req *openr
 	}
 
 	// At this point, we should have a valid request that definitely has Targeting and Cache turned on
-
-	e = deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: req})
+	e = deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: req}, true)
 	errs = append(errs, e...)
 	return
 }
diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go
index 2b05e9aa..07d869dc 100644
--- a/endpoints/openrtb2/auction.go
+++ b/endpoints/openrtb2/auction.go
@@ -5,7 +5,6 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"github.com/prebid/prebid-server/firstpartydata"
 	"io"
 	"io/ioutil"
 	"net/http"
@@ -14,8 +13,10 @@ import (
 	"strconv"
 	"time"
 
+	"github.com/prebid/prebid-server/firstpartydata"
+
 	"github.com/buger/jsonparser"
-	"github.com/evanphx/json-patch"
+	jsonpatch "github.com/evanphx/json-patch"
 	"github.com/gofrs/uuid"
 	"github.com/golang/glog"
 	"github.com/julienschmidt/httprouter"
@@ -44,6 +45,8 @@ import (
 )
 
 const storedRequestTimeoutMillis = 50
+const ampChannel = "amp"
+const appChannel = "app"
 
 var (
 	dntKey      string = http.CanonicalHeaderKey("DNT")
@@ -306,7 +309,7 @@ func (deps *endpointDeps) parseRequest(httpRequest *http.Request) (req *openrtb_
 
 	lmt.ModifyForIOS(req.BidRequest)
 
-	errL := deps.validateRequest(req)
+	errL := deps.validateRequest(req, false)
 	if len(errL) > 0 {
 		errs = append(errs, errL...)
 	}
@@ -329,118 +332,141 @@ func parseTimeout(requestJson []byte, defaultTimeout time.Duration) time.Duratio
 	return defaultTimeout
 }
 
-// mergeBidderParams merges bidder parameters passed at req.ext level with imp[].ext level.
-// Preference is given to parameters at imp[].ext level over req.ext level.
-// Parameters at req.ext level are propagated to adapters as is without any validation.
+// mergeBidderParams merges bidder parameters in req.ext down to the imp[].ext level, with
+// priority given to imp[].ext in case of a conflict. No validation of bidder parameters or
+// of the ext json is performed. Unmarshal errors are not expected since the ext json was
+// validated during the bid request unmarshal. If there is an unmarshal error for some reason,
+// we rely on downstream validation to return the error.
 func mergeBidderParams(req *openrtb_ext.RequestWrapper) error {
-	reqBidderParams, err := adapters.ExtractReqExtBidderParams(req.BidRequest)
-	if err != nil {
-		return err
+	reqBidderParams, err := adapters.ExtractReqExtBidderParamsEmbeddedMap(req.BidRequest)
+	if err != nil || len(reqBidderParams) == 0 {
+		return nil
 	}
 
-	impCpy := make([]openrtb2.Imp, 0, len(req.BidRequest.Imp))
-	for _, imp := range req.BidRequest.Imp {
+	imps := make([]openrtb2.Imp, 0, len(req.BidRequest.Imp))
+	for impIndex, imp := range req.BidRequest.Imp {
 		updatedImp := imp
 
 		if len(imp.Ext) == 0 {
-			impCpy = append(impCpy, updatedImp)
+			imps = append(imps, updatedImp)
 			continue
 		}
 
-		var impExt map[string]map[string]json.RawMessage
-		err := json.Unmarshal(imp.Ext, &impExt)
-		if err != nil {
-			return err
+		var impExt map[string]json.RawMessage
+		if err := json.Unmarshal(imp.Ext, &impExt); err != nil {
+			// imp.ext should be parsable, but we haven't validated yet so there may be another issue. ignore it here
+			// and let the validation catch it later on.
+			imps = append(imps, updatedImp)
+			continue
 		}
 
 		//merges bidder parameters passed at req.ext level with imp[].ext level.
-		err = addMissingReqExtParamsInImpExt(impExt, reqBidderParams)
+		impExtModified, err := addMissingReqExtParamsInImpExt(impExt, reqBidderParams)
 		if err != nil {
-			return err
+			return fmt.Errorf("error processing bidder parameters for imp[%d]: %s", impIndex, err.Error())
 		}
 
 		//merges bidder parameters passed at req.ext level with imp[].ext.prebid.bidder level.
-		err = addMissingReqExtParamsInImpExtPrebid(impExt, reqBidderParams)
+		impExtPrebidModified, err := addMissingReqExtParamsInImpExtPrebid(impExt, reqBidderParams)
 		if err != nil {
-			return err
+			return fmt.Errorf("error processing bidder parameters for imp[%d]: %s", impIndex, err.Error())
 		}
 
-		iExt, err := json.Marshal(impExt)
-		if err != nil {
-			return fmt.Errorf("error marshalling imp[].ext : %s", err.Error())
+		if impExtModified || impExtPrebidModified {
+			updatedImpExt, err := json.Marshal(impExt)
+			if err != nil {
+				return fmt.Errorf("error processing bidder parameters for imp[%d]: error marshalling ext:%s", impIndex, err.Error())
+			}
+			updatedImp.Ext = updatedImpExt
 		}
-		updatedImp.Ext = iExt
-		impCpy = append(impCpy, updatedImp)
+
+		imps = append(imps, updatedImp)
 	}
 
-	req.BidRequest.Imp = impCpy
+	req.BidRequest.Imp = imps
 	return nil
 }
 
 // addMissingReqExtParamsInImpExtPrebid merges bidder parameters passed at req.ext level with imp[].ext.prebid.bidder level.
-func addMissingReqExtParamsInImpExtPrebid(impExtBidder map[string]map[string]json.RawMessage, reqExtParams map[string]map[string]json.RawMessage) error {
-	var bidderParams map[string]json.RawMessage
-	if impExtBidder["prebid"] != nil && impExtBidder["prebid"]["bidder"] != nil {
-		err := json.Unmarshal(impExtBidder["prebid"]["bidder"], &bidderParams)
-		if err != nil {
-			return err
-		}
+func addMissingReqExtParamsInImpExtPrebid(impExtByKey map[string]json.RawMessage, reqExtParams map[string]map[string]json.RawMessage) (bool, error) {
+	if _, prebidSectionExists := impExtByKey["prebid"]; !prebidSectionExists {
+		return false, nil
 	}
 
-	if len(bidderParams) != 0 {
-		for bidder, bidderExt := range bidderParams {
-			if !isBidderToValidate(bidder) {
-				continue
-			}
+	var prebidByKey map[string]json.RawMessage
+	if err := json.Unmarshal(impExtByKey["prebid"], &prebidByKey); err != nil {
+		// prebid should be parsable, but we haven't validated yet so there may be another issue. ignore it here
+		// and let the validation catch it later on.
+		return false, nil
+	}
 
-			var params map[string]json.RawMessage
-			err := json.Unmarshal(bidderExt, &params)
+	if _, prebidBidderSectionExists := prebidByKey["bidder"]; !prebidBidderSectionExists {
+		return false, nil
+	}
 
-			for key, value := range reqExtParams[bidder] {
-				if _, present := params[key]; !present {
-					params[key] = value
-				}
-			}
+	var prebidBidderByBidder map[string]json.RawMessage
+	if err := json.Unmarshal(prebidByKey["bidder"], &prebidBidderByBidder); err != nil {
+		// added for completeness, but not possible. would be caught by the earlier unmarshal call.
+		return false, nil
+	}
 
-			paramsJson, err := json.Marshal(params)
-			if err != nil {
-				return err
-			}
-			bidderParams[bidder] = paramsJson
+	anyModified, err := addMissingReqExtParamsInImpExt(prebidBidderByBidder, reqExtParams)
+
+	if anyModified && err == nil {
+		// marshal imp.ext.prebid.bidder
+		prebidBidderJSON, err := json.Marshal(prebidBidderByBidder)
+		if err != nil {
+			return anyModified, err
 		}
+		prebidByKey["bidder"] = prebidBidderJSON
 
-		bidderParamsJson, err := json.Marshal(bidderParams)
+		// marshal imp.ext.prebid
+		prebidJSON, err := json.Marshal(prebidByKey)
 		if err != nil {
-			return err
+			return anyModified, err
 		}
-		impExtBidder["prebid"]["bidder"] = bidderParamsJson
+		impExtByKey["prebid"] = prebidJSON
 	}
 
-	return nil
+	return anyModified, err
 }
 
 // addMissingReqExtParamsInImpExt merges bidder parameters passed at req.ext level with imp[].ext level.
-func addMissingReqExtParamsInImpExt(impExtBidder map[string]map[string]json.RawMessage, reqExtParams map[string]map[string]json.RawMessage) error {
-	for bidder, bidderExt := range impExtBidder {
+func addMissingReqExtParamsInImpExt(impExtByBidder map[string]json.RawMessage, reqExtParams map[string]map[string]json.RawMessage) (bool, error) {
+	anyModified := false
+	for bidder, bidderExt := range impExtByBidder {
 		if !isBidderToValidate(bidder) {
 			continue
 		}
 
-		wasModified := false
+		var params map[string]json.RawMessage
+		if err := json.Unmarshal(bidderExt, &params); err != nil {
+			// bidder should be parsable, but we haven't validated yet so there may be another issue. ignore it here
+			// and let the validation later on catch it.
+			continue
+		}
+
+		modified := false
 		for key, value := range reqExtParams[bidder] {
-			if _, present := bidderExt[key]; !present {
-				bidderExt[key] = value
-				wasModified = true
+			if _, present := params[key]; !present {
+				params[key] = value
+				modified = true
 			}
 		}
-		if wasModified {
-			impExtBidder[bidder] = bidderExt
+
+		if modified {
+			paramsJson, err := json.Marshal(params)
+			if err != nil {
+				return anyModified, fmt.Errorf("error marshalling ext.prebid.bidder: %s", err.Error())
+			}
+			impExtByBidder[bidder] = paramsJson
+			anyModified = true
 		}
 	}
-	return nil
+	return anyModified, nil
 }
 
-func (deps *endpointDeps) validateRequest(req *openrtb_ext.RequestWrapper) []error {
+func (deps *endpointDeps) validateRequest(req *openrtb_ext.RequestWrapper, isAmp bool) []error {
 	errL := []error{}
 	if req.ID == "" {
 		return []error{errors.New("request missing required field: \"id\"")}
@@ -499,6 +525,10 @@ func (deps *endpointDeps) validateRequest(req *openrtb_ext.RequestWrapper) []err
 		}
 	}
 
+	if err := validateOrFillChannel(req, isAmp); err != nil {
+		return []error{err}
+	}
+
 	if (req.Site == nil && req.App == nil) || (req.Site != nil && req.App != nil) {
 		return append(errL, errors.New("request.site or request.app must be defined, but not both."))
 	}
@@ -1166,12 +1196,12 @@ func isBidderToValidate(bidder string) bool {
 		return false
 	case openrtb_ext.BidderReservedData:
 		return false
+	case openrtb_ext.BidderReservedGPID:
+		return false
 	case openrtb_ext.BidderReservedPrebid:
 		return false
 	case openrtb_ext.BidderReservedSKAdN:
 		return false
-	case openrtb_ext.BidderReservedBidder:
-		return false
 	default:
 		return true
 	}
@@ -1334,6 +1364,46 @@ func validateDevice(device *openrtb2.Device) error {
 	return nil
 }
 
+func validateOrFillChannel(reqWrapper *openrtb_ext.RequestWrapper, isAmp bool) error {
+	requestExt, err := reqWrapper.GetRequestExt()
+	if err != nil {
+		return err
+	}
+	requestPrebid := requestExt.GetPrebid()
+
+	if requestPrebid == nil || requestPrebid.Channel == nil {
+		fillChannel(reqWrapper, isAmp)
+	} else if requestPrebid.Channel.Name == "" {
+		return errors.New("ext.prebid.channel.name can't be empty")
+	}
+	return nil
+}
+
+func fillChannel(reqWrapper *openrtb_ext.RequestWrapper, isAmp bool) error {
+	var channelName string
+	requestExt, err := reqWrapper.GetRequestExt()
+	if err != nil {
+		return err
+	}
+	requestPrebid := requestExt.GetPrebid()
+	if isAmp {
+		channelName = ampChannel
+	}
+	if reqWrapper.App != nil {
+		channelName = appChannel
+	}
+	if channelName != "" {
+		if requestPrebid == nil {
+			requestPrebid = &openrtb_ext.ExtRequestPrebid{}
+		}
+		requestPrebid.Channel = &openrtb_ext.ExtRequestPrebidChannel{Name: channelName}
+		requestExt.SetPrebid(requestPrebid)
+		reqWrapper.RebuildRequest()
+	}
+	return nil
+
+}
+
 func sanitizeRequest(r *openrtb2.BidRequest, ipValidator iputil.IPValidator) {
 	if r.Device != nil {
 		if ip, ver := iputil.ParseIP(r.Device.IP); ip == nil || ver != iputil.IPv4 || !ipValidator.IsValid(ip, ver) {
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json b/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json
index 5baaa09d..76dc1c2b 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json
@@ -27,5 +27,5 @@
     }
   },
   "expectedReturnCode": 400,
-  "expectedErrorMessage": "Invalid request: error decoding Request.ext : request.ext.prebid.cache requires one of the \"bids\" or \"vastxml\" properties\n"
+  "expectedErrorMessage": "Invalid request: request.ext is invalid: request.ext.prebid.cache requires one of the \"bids\" or \"vastxml\" properties\n"
 }
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/imp-ext-invalid-params.json b/endpoints/openrtb2/sample-requests/invalid-whole/imp-ext-invalid-params.json
index b1e9b784..d9ed59c8 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/imp-ext-invalid-params.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/imp-ext-invalid-params.json
@@ -20,5 +20,5 @@
     }
   },
   "expectedReturnCode": 400,
-  "expectedErrorMessage": "Invalid request: json: cannot unmarshal string into Go value of type map[string]json.RawMessage"
+  "expectedErrorMessage": "Invalid request: request.imp[0].ext.appnexus failed validation.\n(root): Invalid type. Expected: object, given: string\n"
 }
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext.json
index 46af5163..fb29efee 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext.json
@@ -65,6 +65,10 @@
         "cache": {
           "bids": {}
         },
+        "channel": {
+          "name": "video",
+          "version": "1.0"
+        },
         "targeting": {
           "includewinners": false,
           "pricegranularity": {
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-ext-bidder-params-merge-reserved-keyword.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-ext-bidder-params-merge-reserved-keyword.json
deleted file mode 100644
index 982f86cb..00000000
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-ext-bidder-params-merge-reserved-keyword.json
+++ /dev/null
@@ -1,116 +0,0 @@
-{
-  "description": "add missing bidder-params from req.ext.prebid.bidderparams to imp[].ext.prebid.bidder for reserved keyword",
-  "mockBidRequest": {
-    "id": "some-request-id",
-    "site": {
-      "page": "test.somepage.com"
-    },
-    "imp": [
-      {
-        "id": "my-imp-id",
-        "banner": {
-          "format": [
-            {
-              "w": 300,
-              "h": 600
-            }
-          ]
-        },
-        "pmp": {
-          "deals": [
-            {
-              "id": "some-deal-id"
-            }
-          ]
-        },
-        "ext": {
-          "prebid": {
-            "bidder": {
-              "bidder": {
-                "param1": 111111
-              },
-              "appnexus": {
-                "placementId": 111111
-              },
-              "pubmatic": {
-                "publisherId": "1234",
-                "wrapper": {
-                  "profile": 1234
-                }
-              }
-            }
-          }
-        }
-      }
-    ],
-    "ext": {
-      "prebid": {
-        "targeting": {
-          "pricegranularity": "low"
-        },
-        "cache": {
-          "bids": {}
-        },
-        "bidderparams": {
-          "bidder": {
-            "param2": 111111
-          },
-          "appnexus": {
-            "placementId": 222222
-          },
-          "pubmatic": {
-            "publisherId": "5678",
-            "wrapper": {
-              "profile": 5678,
-              "version": 2
-            }
-          }
-        }
-      }
-    }
-  },
-  "expectedReqExt": {
-    "prebid": {
-      "targeting": {
-        "pricegranularity": "low"
-      },
-      "cache": {
-        "bids": {}
-      },
-      "bidderparams": {
-        "bidder": {
-          "param2": 111111
-        },
-        "appnexus": {
-          "placementId": 222222
-        },
-        "pubmatic": {
-          "publisherId": "5678",
-          "wrapper": {
-            "profile": 5678,
-            "version": 2
-          }
-        }
-      }
-    }
-  },
-  "expectedImpExt": {
-    "prebid": {
-      "bidder": {
-        "bidder": {
-          "param1": 111111
-        },
-        "appnexus": {
-          "placementId": 111111
-        },
-        "pubmatic": {
-          "publisherId": "1234",
-          "wrapper": {
-            "profile": 1234
-          }
-        }
-      }
-    }
-  },
-  "expectedReturnCode": 200
-}
\ No newline at end of file
diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go
index 56c67c4d..60372c38 100644
--- a/endpoints/openrtb2/video_auction.go
+++ b/endpoints/openrtb2/video_auction.go
@@ -244,7 +244,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
 	// Populate any "missing" OpenRTB fields with info from other sources, (e.g. HTTP request headers).
 	deps.setFieldsImplicitly(r, bidReq) // move after merge
 
-	errL = deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: bidReq})
+	errL = deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: bidReq}, false)
 	if errortypes.ContainsFatalError(errL) {
 		handleError(&labels, w, errL, &vo, &debugLog)
 		return
diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go
index 29faaca8..0f14b75c 100755
--- a/exchange/adapter_builders.go
+++ b/exchange/adapter_builders.go
@@ -39,6 +39,7 @@ import (
 	"github.com/prebid/prebid-server/adapters/bidmachine"
 	"github.com/prebid/prebid-server/adapters/bidmyadz"
 	"github.com/prebid/prebid-server/adapters/bidscube"
+	"github.com/prebid/prebid-server/adapters/bizzclick"
 	"github.com/prebid/prebid-server/adapters/bmtm"
 	"github.com/prebid/prebid-server/adapters/brightroll"
 	"github.com/prebid/prebid-server/adapters/coinzilla"
@@ -177,6 +178,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderBidmachine:        bidmachine.Builder,
 		openrtb_ext.BidderBidmyadz:          bidmyadz.Builder,
 		openrtb_ext.BidderBidsCube:          bidscube.Builder,
+		openrtb_ext.BidderBizzclick:         bizzclick.Builder,
 		openrtb_ext.BidderBmtm:              bmtm.Builder,
 		openrtb_ext.BidderBrightroll:        brightroll.Builder,
 		openrtb_ext.BidderCoinzilla:         coinzilla.Builder,
@@ -198,6 +200,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderGamma:             gamma.Builder,
 		openrtb_ext.BidderGamoshi:           gamoshi.Builder,
 		openrtb_ext.BidderGrid:              grid.Builder,
+		openrtb_ext.BidderGroupm:            pubmatic.Builder,
 		openrtb_ext.BidderGumGum:            gumgum.Builder,
 		openrtb_ext.BidderHuaweiAds:         huaweiads.Builder,
 		openrtb_ext.BidderImpactify:         impactify.Builder,
diff --git a/exchange/utils.go b/exchange/utils.go
index 23ffe5e5..48f76b2a 100644
--- a/exchange/utils.go
+++ b/exchange/utils.go
@@ -223,7 +223,7 @@ func getAuctionBidderRequests(req AuctionRequest,
 		return nil, []error{err}
 	}
 
-	bidderParamsInReqExt, err := adapters.ExtractReqExtBidderParams(req.BidRequest)
+	bidderParamsInReqExt, err := adapters.ExtractReqExtBidderParamsEmbeddedMap(req.BidRequest)
 	if err != nil {
 		return nil, []error{err}
 	}
@@ -464,6 +464,10 @@ func createSanitizedImpExt(impExt, impExtPrebid map[string]json.RawMessage) (map
 		sanitizedImpExt[openrtb_ext.SKAdNExtKey] = v
 	}
 
+	if v, exists := impExt[string(openrtb_ext.GPIDKey)]; exists {
+		sanitizedImpExt[openrtb_ext.GPIDKey] = v
+	}
+
 	return sanitizedImpExt, nil
 }
 
@@ -493,6 +497,7 @@ func isSpecialField(bidder string) bool {
 	return bidder == openrtb_ext.FirstPartyDataContextExtKey ||
 		bidder == openrtb_ext.FirstPartyDataExtKey ||
 		bidder == openrtb_ext.SKAdNExtKey ||
+		bidder == openrtb_ext.GPIDKey ||
 		bidder == openrtb_ext.PrebidExtKey
 }
 
diff --git a/metrics/prometheus/prometheus.go b/metrics/prometheus/prometheus.go
index 53a5afab..368424c5 100644
--- a/metrics/prometheus/prometheus.go
+++ b/metrics/prometheus/prometheus.go
@@ -1,6 +1,7 @@
 package prometheusmetrics
 
 import (
+	"fmt"
 	"strconv"
 	"time"
 
@@ -8,11 +9,13 @@ import (
 	"github.com/prebid/prebid-server/metrics"
 	"github.com/prebid/prebid-server/openrtb_ext"
 	"github.com/prometheus/client_golang/prometheus"
+	promCollector "github.com/prometheus/client_golang/prometheus/collectors"
 )
 
 // Metrics defines the Prometheus metrics backing the MetricsEngine implementation.
 type Metrics struct {
-	Registry *prometheus.Registry
+	Registerer prometheus.Registerer
+	Gatherer   *prometheus.Registry
 
 	// General Metrics
 	connectionsClosed            prometheus.Counter
@@ -133,246 +136,253 @@ func NewMetrics(cfg config.PrometheusMetrics, disabledMetrics config.DisabledMet
 	queuedRequestTimeBuckets := []float64{0, 1, 5, 30, 60, 120, 180, 240, 300}
 
 	metrics := Metrics{}
-	metrics.Registry = prometheus.NewRegistry()
+	reg := prometheus.NewRegistry()
 	metrics.metricsDisabled = disabledMetrics
 
-	metrics.connectionsClosed = newCounterWithoutLabels(cfg, metrics.Registry,
+	metrics.connectionsClosed = newCounterWithoutLabels(cfg, reg,
 		"connections_closed",
 		"Count of successful connections closed to Prebid Server.")
 
-	metrics.connectionsError = newCounter(cfg, metrics.Registry,
+	metrics.connectionsError = newCounter(cfg, reg,
 		"connections_error",
 		"Count of errors for connection open and close attempts to Prebid Server labeled by type.",
 		[]string{connectionErrorLabel})
 
-	metrics.connectionsOpened = newCounterWithoutLabels(cfg, metrics.Registry,
+	metrics.connectionsOpened = newCounterWithoutLabels(cfg, reg,
 		"connections_opened",
 		"Count of successful connections opened to Prebid Server.")
 
-	metrics.cookieSync = newCounter(cfg, metrics.Registry,
+	metrics.cookieSync = newCounter(cfg, reg,
 		"cookie_sync_requests",
 		"Count of cookie sync requests to Prebid Server.",
 		[]string{statusLabel})
 
-	metrics.setUid = newCounter(cfg, metrics.Registry,
+	metrics.setUid = newCounter(cfg, reg,
 		"setuid_requests",
 		"Count of set uid requests to Prebid Server.",
 		[]string{statusLabel})
 
-	metrics.impressions = newCounter(cfg, metrics.Registry,
+	metrics.impressions = newCounter(cfg, reg,
 		"impressions_requests",
 		"Count of requested impressions to Prebid Server labeled by type.",
 		[]string{isBannerLabel, isVideoLabel, isAudioLabel, isNativeLabel})
 
-	metrics.impressionsLegacy = newCounterWithoutLabels(cfg, metrics.Registry,
+	metrics.impressionsLegacy = newCounterWithoutLabels(cfg, reg,
 		"impressions_requests_legacy",
 		"Count of requested impressions to Prebid Server using the legacy endpoint.")
 
-	metrics.prebidCacheWriteTimer = newHistogramVec(cfg, metrics.Registry,
+	metrics.prebidCacheWriteTimer = newHistogramVec(cfg, reg,
 		"prebidcache_write_time_seconds",
 		"Seconds to write to Prebid Cache labeled by success or failure. Failure timing is limited by Prebid Server enforced timeouts.",
 		[]string{successLabel},
 		cacheWriteTimeBuckets)
 
-	metrics.requests = newCounter(cfg, metrics.Registry,
+	metrics.requests = newCounter(cfg, reg,
 		"requests",
 		"Count of total requests to Prebid Server labeled by type and status.",
 		[]string{requestTypeLabel, requestStatusLabel})
 
-	metrics.requestsTimer = newHistogramVec(cfg, metrics.Registry,
+	metrics.requestsTimer = newHistogramVec(cfg, reg,
 		"request_time_seconds",
 		"Seconds to resolve successful Prebid Server requests labeled by type.",
 		[]string{requestTypeLabel},
 		standardTimeBuckets)
 
-	metrics.requestsWithoutCookie = newCounter(cfg, metrics.Registry,
+	metrics.requestsWithoutCookie = newCounter(cfg, reg,
 		"requests_without_cookie",
 		"Count of total requests to Prebid Server without a cookie labeled by type.",
 		[]string{requestTypeLabel})
 
-	metrics.storedImpressionsCacheResult = newCounter(cfg, metrics.Registry,
+	metrics.storedImpressionsCacheResult = newCounter(cfg, reg,
 		"stored_impressions_cache_performance",
 		"Count of stored impression cache requests attempts by hits or miss.",
 		[]string{cacheResultLabel})
 
-	metrics.storedRequestCacheResult = newCounter(cfg, metrics.Registry,
+	metrics.storedRequestCacheResult = newCounter(cfg, reg,
 		"stored_request_cache_performance",
 		"Count of stored request cache requests attempts by hits or miss.",
 		[]string{cacheResultLabel})
 
-	metrics.accountCacheResult = newCounter(cfg, metrics.Registry,
+	metrics.accountCacheResult = newCounter(cfg, reg,
 		"account_cache_performance",
 		"Count of account cache lookups by hits or miss.",
 		[]string{cacheResultLabel})
 
-	metrics.storedAccountFetchTimer = newHistogramVec(cfg, metrics.Registry,
+	metrics.storedAccountFetchTimer = newHistogramVec(cfg, reg,
 		"stored_account_fetch_time_seconds",
 		"Seconds to fetch stored accounts labeled by fetch type",
 		[]string{storedDataFetchTypeLabel},
 		standardTimeBuckets)
 
-	metrics.storedAccountErrors = newCounter(cfg, metrics.Registry,
+	metrics.storedAccountErrors = newCounter(cfg, reg,
 		"stored_account_errors",
 		"Count of stored account errors by error type",
 		[]string{storedDataErrorLabel})
 
-	metrics.storedAMPFetchTimer = newHistogramVec(cfg, metrics.Registry,
+	metrics.storedAMPFetchTimer = newHistogramVec(cfg, reg,
 		"stored_amp_fetch_time_seconds",
 		"Seconds to fetch stored AMP requests labeled by fetch type",
 		[]string{storedDataFetchTypeLabel},
 		standardTimeBuckets)
 
-	metrics.storedAMPErrors = newCounter(cfg, metrics.Registry,
+	metrics.storedAMPErrors = newCounter(cfg, reg,
 		"stored_amp_errors",
 		"Count of stored AMP errors by error type",
 		[]string{storedDataErrorLabel})
 
-	metrics.storedCategoryFetchTimer = newHistogramVec(cfg, metrics.Registry,
+	metrics.storedCategoryFetchTimer = newHistogramVec(cfg, reg,
 		"stored_category_fetch_time_seconds",
 		"Seconds to fetch stored categories labeled by fetch type",
 		[]string{storedDataFetchTypeLabel},
 		standardTimeBuckets)
 
-	metrics.storedCategoryErrors = newCounter(cfg, metrics.Registry,
+	metrics.storedCategoryErrors = newCounter(cfg, reg,
 		"stored_category_errors",
 		"Count of stored category errors by error type",
 		[]string{storedDataErrorLabel})
 
-	metrics.storedRequestFetchTimer = newHistogramVec(cfg, metrics.Registry,
+	metrics.storedRequestFetchTimer = newHistogramVec(cfg, reg,
 		"stored_request_fetch_time_seconds",
 		"Seconds to fetch stored requests labeled by fetch type",
 		[]string{storedDataFetchTypeLabel},
 		standardTimeBuckets)
 
-	metrics.storedRequestErrors = newCounter(cfg, metrics.Registry,
+	metrics.storedRequestErrors = newCounter(cfg, reg,
 		"stored_request_errors",
 		"Count of stored request errors by error type",
 		[]string{storedDataErrorLabel})
 
-	metrics.storedVideoFetchTimer = newHistogramVec(cfg, metrics.Registry,
+	metrics.storedVideoFetchTimer = newHistogramVec(cfg, reg,
 		"stored_video_fetch_time_seconds",
 		"Seconds to fetch stored video labeled by fetch type",
 		[]string{storedDataFetchTypeLabel},
 		standardTimeBuckets)
 
-	metrics.storedVideoErrors = newCounter(cfg, metrics.Registry,
+	metrics.storedVideoErrors = newCounter(cfg, reg,
 		"stored_video_errors",
 		"Count of stored video errors by error type",
 		[]string{storedDataErrorLabel})
 
-	metrics.timeoutNotifications = newCounter(cfg, metrics.Registry,
+	metrics.timeoutNotifications = newCounter(cfg, reg,
 		"timeout_notification",
 		"Count of timeout notifications triggered, and if they were successfully sent.",
 		[]string{successLabel})
 
-	metrics.dnsLookupTimer = newHistogram(cfg, metrics.Registry,
+	metrics.dnsLookupTimer = newHistogram(cfg, reg,
 		"dns_lookup_time",
 		"Seconds to resolve DNS",
 		standardTimeBuckets)
 
-	metrics.tlsHandhakeTimer = newHistogram(cfg, metrics.Registry,
+	metrics.tlsHandhakeTimer = newHistogram(cfg, reg,
 		"tls_handshake_time",
 		"Seconds to perform TLS Handshake",
 		standardTimeBuckets)
 
-	metrics.privacyCCPA = newCounter(cfg, metrics.Registry,
+	metrics.privacyCCPA = newCounter(cfg, reg,
 		"privacy_ccpa",
 		"Count of total requests to Prebid Server where CCPA was provided by source and opt-out .",
 		[]string{sourceLabel, optOutLabel})
 
-	metrics.privacyCOPPA = newCounter(cfg, metrics.Registry,
+	metrics.privacyCOPPA = newCounter(cfg, reg,
 		"privacy_coppa",
 		"Count of total requests to Prebid Server where the COPPA flag was set by source",
 		[]string{sourceLabel})
 
-	metrics.privacyTCF = newCounter(cfg, metrics.Registry,
+	metrics.privacyTCF = newCounter(cfg, reg,
 		"privacy_tcf",
 		"Count of TCF versions for requests where GDPR was enforced by source and version.",
 		[]string{versionLabel, sourceLabel})
 
-	metrics.privacyLMT = newCounter(cfg, metrics.Registry,
+	metrics.privacyLMT = newCounter(cfg, reg,
 		"privacy_lmt",
 		"Count of total requests to Prebid Server where the LMT flag was set by source",
 		[]string{sourceLabel})
 
 	if !metrics.metricsDisabled.AdapterGDPRRequestBlocked {
-		metrics.adapterGDPRBlockedRequests = newCounter(cfg, metrics.Registry,
+		metrics.adapterGDPRBlockedRequests = newCounter(cfg, reg,
 			"adapter_gdpr_requests_blocked",
 			"Count of total bidder requests blocked due to unsatisfied GDPR purpose 2 legal basis",
 			[]string{adapterLabel})
 	}
 
-	metrics.adapterBids = newCounter(cfg, metrics.Registry,
+	metrics.adapterBids = newCounter(cfg, reg,
 		"adapter_bids",
 		"Count of bids labeled by adapter and markup delivery type (adm or nurl).",
 		[]string{adapterLabel, markupDeliveryLabel})
 
-	metrics.adapterErrors = newCounter(cfg, metrics.Registry,
+	metrics.adapterErrors = newCounter(cfg, reg,
 		"adapter_errors",
 		"Count of errors labeled by adapter and error type.",
 		[]string{adapterLabel, adapterErrorLabel})
 
-	metrics.adapterPanics = newCounter(cfg, metrics.Registry,
+	metrics.adapterPanics = newCounter(cfg, reg,
 		"adapter_panics",
 		"Count of panics labeled by adapter.",
 		[]string{adapterLabel})
 
-	metrics.adapterPrices = newHistogramVec(cfg, metrics.Registry,
+	metrics.adapterPrices = newHistogramVec(cfg, reg,
 		"adapter_prices",
 		"Monetary value of the bids labeled by adapter.",
 		[]string{adapterLabel},
 		priceBuckets)
 
-	metrics.adapterRequests = newCounter(cfg, metrics.Registry,
+	metrics.adapterRequests = newCounter(cfg, reg,
 		"adapter_requests",
 		"Count of requests labeled by adapter, if has a cookie, and if it resulted in bids.",
 		[]string{adapterLabel, cookieLabel, hasBidsLabel})
 
 	if !metrics.metricsDisabled.AdapterConnectionMetrics {
-		metrics.adapterCreatedConnections = newCounter(cfg, metrics.Registry,
+		metrics.adapterCreatedConnections = newCounter(cfg, reg,
 			"adapter_connection_created",
 			"Count that keeps track of new connections when contacting adapter bidder endpoints.",
 			[]string{adapterLabel})
 
-		metrics.adapterReusedConnections = newCounter(cfg, metrics.Registry,
+		metrics.adapterReusedConnections = newCounter(cfg, reg,
 			"adapter_connection_reused",
 			"Count that keeps track of reused connections when contacting adapter bidder endpoints.",
 			[]string{adapterLabel})
 
-		metrics.adapterConnectionWaitTime = newHistogramVec(cfg, metrics.Registry,
+		metrics.adapterConnectionWaitTime = newHistogramVec(cfg, reg,
 			"adapter_connection_wait",
 			"Seconds from when the connection was requested until it is either created or reused",
 			[]string{adapterLabel},
 			standardTimeBuckets)
 	}
 
-	metrics.adapterRequestsTimer = newHistogramVec(cfg, metrics.Registry,
+	metrics.adapterRequestsTimer = newHistogramVec(cfg, reg,
 		"adapter_request_time_seconds",
 		"Seconds to resolve each successful request labeled by adapter.",
 		[]string{adapterLabel},
 		standardTimeBuckets)
 
-	metrics.syncerRequests = newCounter(cfg, metrics.Registry,
+	metrics.syncerRequests = newCounter(cfg, reg,
 		"syncer_requests",
 		"Count of cookie sync requests where a syncer is a candidate to be synced labeled by syncer key and status.",
 		[]string{syncerLabel, statusLabel})
 
-	metrics.syncerSets = newCounter(cfg, metrics.Registry,
+	metrics.syncerSets = newCounter(cfg, reg,
 		"syncer_sets",
 		"Count of setuid set requests for a syncer labeled by syncer key and status.",
 		[]string{syncerLabel, statusLabel})
 
-	metrics.accountRequests = newCounter(cfg, metrics.Registry,
+	metrics.accountRequests = newCounter(cfg, reg,
 		"account_requests",
 		"Count of total requests to Prebid Server labeled by account.",
 		[]string{accountLabel})
 
-	metrics.requestsQueueTimer = newHistogramVec(cfg, metrics.Registry,
+	metrics.requestsQueueTimer = newHistogramVec(cfg, reg,
 		"request_queue_time",
 		"Seconds request was waiting in queue",
 		[]string{requestTypeLabel, requestStatusLabel},
 		queuedRequestTimeBuckets)
 
+	metrics.Gatherer = reg
+
+	metricsPrefix := fmt.Sprintf("%s_%s_", cfg.Namespace, cfg.Subsystem)
+
+	metrics.Registerer = prometheus.WrapRegistererWithPrefix(metricsPrefix, reg)
+	metrics.Registerer.MustRegister(promCollector.NewGoCollector())
+
 	preloadLabelValues(&metrics, syncerKeys)
 
 	return &metrics
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index 770811a9..7ebfe631 100644
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -32,9 +32,9 @@ const (
 	BidderReservedContext BidderName = "context" // Reserved for first party data.
 	BidderReservedData    BidderName = "data"    // Reserved for first party data.
 	BidderReservedGeneral BidderName = "general" // Reserved for non-bidder specific messages when using a map keyed on the bidder name.
+	BidderReservedGPID    BidderName = "gpid"    // Reserved for Global Placement ID (GPID).
 	BidderReservedPrebid  BidderName = "prebid"  // Reserved for Prebid Server configuration.
 	BidderReservedSKAdN   BidderName = "skadn"   // Reserved for Apple's SKAdNetwork OpenRTB extension.
-	BidderReservedBidder  BidderName = "bidder"  // Reserved for passing bidder parameters.
 )
 
 // IsBidderNameReserved returns true if the specified name is a case insensitive match for a reserved bidder name.
@@ -55,15 +55,15 @@ func IsBidderNameReserved(name string) bool {
 		return true
 	}
 
-	if strings.EqualFold(name, string(BidderReservedSKAdN)) {
+	if strings.EqualFold(name, string(BidderReservedGPID)) {
 		return true
 	}
 
-	if strings.EqualFold(name, string(BidderReservedPrebid)) {
+	if strings.EqualFold(name, string(BidderReservedSKAdN)) {
 		return true
 	}
 
-	if strings.EqualFold(name, string(BidderReservedBidder)) {
+	if strings.EqualFold(name, string(BidderReservedPrebid)) {
 		return true
 	}
 
@@ -114,6 +114,7 @@ const (
 	BidderBidmachine        BidderName = "bidmachine"
 	BidderBidmyadz          BidderName = "bidmyadz"
 	BidderBidsCube          BidderName = "bidscube"
+	BidderBizzclick         BidderName = "bizzclick"
 	BidderBmtm              BidderName = "bmtm"
 	BidderBrightroll        BidderName = "brightroll"
 	BidderCoinzilla         BidderName = "coinzilla"
@@ -135,6 +136,7 @@ const (
 	BidderGamma             BidderName = "gamma"
 	BidderGamoshi           BidderName = "gamoshi"
 	BidderGrid              BidderName = "grid"
+	BidderGroupm            BidderName = "groupm"
 	BidderGumGum            BidderName = "gumgum"
 	BidderHuaweiAds         BidderName = "huaweiads"
 	BidderImpactify         BidderName = "impactify"
@@ -255,6 +257,7 @@ func CoreBidderNames() []BidderName {
 		BidderBidmachine,
 		BidderBidmyadz,
 		BidderBidsCube,
+		BidderBizzclick,
 		BidderBmtm,
 		BidderBrightroll,
 		BidderCoinzilla,
@@ -276,6 +279,7 @@ func CoreBidderNames() []BidderName {
 		BidderGamma,
 		BidderGamoshi,
 		BidderGrid,
+		BidderGroupm,
 		BidderGumGum,
 		BidderHuaweiAds,
 		BidderImpactify,
diff --git a/openrtb_ext/imp_adf.go b/openrtb_ext/imp_adf.go
index 6a8f9afa..e4f5283b 100644
--- a/openrtb_ext/imp_adf.go
+++ b/openrtb_ext/imp_adf.go
@@ -8,4 +8,5 @@ type ExtImpAdf struct {
 	MasterTagID       json.Number `json:"mid,omitempty"`
 	InventorySourceID int         `json:"inv,omitempty"`
 	PlacementName     string      `json:"mname,omitempty"`
+	PriceType         string      `json:"priceType,omitempty"`
 }
diff --git a/openrtb_ext/imp_algorix.go b/openrtb_ext/imp_algorix.go
index 3661018d..d395600c 100644
--- a/openrtb_ext/imp_algorix.go
+++ b/openrtb_ext/imp_algorix.go
@@ -6,4 +6,5 @@ type ExtImpAlgorix struct {
 	Token       string `json:"token"`
 	PlacementId string `json:"placementId"`
 	AppId       string `json:"appId"`
+	Region      string `json:"region"`
 }
diff --git a/openrtb_ext/imp_bizzclick.go b/openrtb_ext/imp_bizzclick.go
new file mode 100644
index 00000000..5090a822
--- /dev/null
+++ b/openrtb_ext/imp_bizzclick.go
@@ -0,0 +1,6 @@
+package openrtb_ext
+
+type ExtBizzclick struct {
+	AccountID   string `json:"accountId"`
+	PlacementID string `json:"placementId"`
+}
diff --git a/openrtb_ext/imp_marsmedia.go b/openrtb_ext/imp_marsmedia.go
index c27fe2db..e07b6d7c 100644
--- a/openrtb_ext/imp_marsmedia.go
+++ b/openrtb_ext/imp_marsmedia.go
@@ -1,6 +1,8 @@
 package openrtb_ext
 
+import "encoding/json"
+
 // ExtImpMarsmedia defines the contract for bidrequest.imp[i].ext.marsmedia
 type ExtImpMarsmedia struct {
-	ZoneID string `json:"zoneId"`
+	ZoneID json.Number `json:"zoneId"`
 }
diff --git a/openrtb_ext/request.go b/openrtb_ext/request.go
index a65e8d3c..dba30863 100644
--- a/openrtb_ext/request.go
+++ b/openrtb_ext/request.go
@@ -14,6 +14,9 @@ const FirstPartyDataContextExtKey = "context"
 // SKAdNExtKey defines the field name within request.ext reserved for Apple's SKAdNetwork.
 const SKAdNExtKey = "skadn"
 
+// GPIDKey defines the field name within request.ext reserved for the Global Placement ID (GPID),
+const GPIDKey = "gpid"
+
 // NativeExchangeSpecificLowerBound defines the lower threshold of exchange specific types for native ads. There is no upper bound.
 const NativeExchangeSpecificLowerBound = 500
 
diff --git a/server/prometheus.go b/server/prometheus.go
index 6f0a0b2d..33114c86 100644
--- a/server/prometheus.go
+++ b/server/prometheus.go
@@ -19,7 +19,7 @@ func newPrometheusServer(cfg *config.Configuration, metrics *metricsconfig.Detai
 	}
 	return &http.Server{
 		Addr: cfg.Host + ":" + strconv.Itoa(cfg.Metrics.Prometheus.Port),
-		Handler: promhttp.HandlerFor(proMetrics.Registry, promhttp.HandlerOpts{
+		Handler: promhttp.HandlerFor(proMetrics.Gatherer, promhttp.HandlerOpts{
 			ErrorLog:            loggerForPrometheus{},
 			MaxRequestsInFlight: 5,
 			Timeout:             cfg.Metrics.Prometheus.Timeout(),
diff --git a/static/bidder-info/bizzclick.yaml b/static/bidder-info/bizzclick.yaml
new file mode 100644
index 00000000..48921c39
--- /dev/null
+++ b/static/bidder-info/bizzclick.yaml
@@ -0,0 +1,13 @@
+maintainer:
+  email: "support@bizzclick.com"
+capabilities:
+  app:
+    mediaTypes:
+      - banner
+      - video
+      - native
+  site:
+    mediaTypes:
+      - banner
+      - video
+      - native
diff --git a/static/bidder-info/groupm.yaml b/static/bidder-info/groupm.yaml
new file mode 100644
index 00000000..9e487ad5
--- /dev/null
+++ b/static/bidder-info/groupm.yaml
@@ -0,0 +1,18 @@
+maintainer:
+  email: "header-bidding@pubmatic.com"
+gvlVendorID: 98
+capabilities:
+  app:
+    mediaTypes:
+      - banner
+      - video
+  site:
+    mediaTypes:
+      - banner
+      - video
+userSync:
+  iframe:
+    url: "https://ads.pubmatic.com/AdServer/js/user_sync.html?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&predirect={{.RedirectURL}}"
+    userMacro: ""
+    # groupm appends the user id to end of the redirect url and does not utilize a macro
+
diff --git a/static/bidder-info/openx.yaml b/static/bidder-info/openx.yaml
index c48d7de2..4b456014 100644
--- a/static/bidder-info/openx.yaml
+++ b/static/bidder-info/openx.yaml
@@ -12,6 +12,10 @@ capabilities:
       - video
 modifyingVastXmlAllowed: true
 userSync:
+  default: "iframe"
+  iframe:
+    url: "https://u.openx.net/w/1.0/cm?id=891039ac-a916-42bb-a651-4be9e3b201da&ph=a3aece0c-9e80-4316-8deb-faf804779bd1&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r={{.RedirectURL}}"
+    userMacro: "{OPENX_ID}"
   redirect:
     url: "https://rtb.openx.net/sync/prebid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r={{.RedirectURL}}"
     userMacro: "${UID}"
diff --git a/static/bidder-info/unruly.yaml b/static/bidder-info/unruly.yaml
index 7e018a0a..9b1ba9c6 100644
--- a/static/bidder-info/unruly.yaml
+++ b/static/bidder-info/unruly.yaml
@@ -11,6 +11,6 @@ capabilities:
       - banner
       - video
 userSync:
-  iframe:
-    url: "https://usermatch.targeting.unrulymedia.com/pbsync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&rurl={{.RedirectURL}}"
-    userMacro: "$UID"
+  redirect:
+    url: "https://sync.1rx.io/usersync2/rmphb?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir={{.RedirectURL}}"
+    userMacro: "[RX_UUID]"
diff --git a/static/bidder-params/adf.json b/static/bidder-params/adf.json
index 4a1a1182..e165fa85 100644
--- a/static/bidder-params/adf.json
+++ b/static/bidder-params/adf.json
@@ -16,6 +16,11 @@
     "mname": {
       "type": ["string"],
       "description": "A Name which identifies the placement selling the impression"
+    },
+    "priceType": {
+      "type": ["string"],
+      "description": "gross or net. Default is net.",
+      "pattern": "gross|net"
     }
   },
   "anyOf":[
diff --git a/static/bidder-params/adform.json b/static/bidder-params/adform.json
index 906241ff..e112f122 100644
--- a/static/bidder-params/adform.json
+++ b/static/bidder-params/adform.json
@@ -16,6 +16,11 @@
     "mname": {
       "type": ["string"],
       "description": "A Name which identifies the placement selling the impression"
+    },
+    "priceType": {
+      "type": ["string"],
+      "description": "gross or net. Default is net.",
+      "pattern": "gross|net"
     }
   },
   "anyOf":[
diff --git a/static/bidder-params/algorix.json b/static/bidder-params/algorix.json
index 675d9793..2fcbd6ec 100644
--- a/static/bidder-params/algorix.json
+++ b/static/bidder-params/algorix.json
@@ -21,6 +21,11 @@
     "appId": {
       "type": "string",
       "description": "An ID which identifies this app of the impression"
+    },
+    "region": {
+      "type": "string",
+      "enum": ["APAC", "USE"],
+      "description": "Server region for PBS request, null for global, APAC for SG Region, USE for US Region"
     }
   },
   "required": ["sid", "token"]
diff --git a/static/bidder-params/beachfront.json b/static/bidder-params/beachfront.json
index 5b1e71a9..fd3a4b67 100644
--- a/static/bidder-params/beachfront.json
+++ b/static/bidder-params/beachfront.json
@@ -30,7 +30,7 @@
     },
     "bidfloor": {
       "type": "number",
-      "description": "The price floor for the bid. Will override the bidfloor set for the impression."
+      "description": "The price floor for the bid. Will override the bidfloor set for the impression. Always in USD, regardless of the value of the currency set for the impression."
     },
     "videoResponseType": {
       "type": "string",
diff --git a/static/bidder-params/bizzclick.json b/static/bidder-params/bizzclick.json
new file mode 100644
index 00000000..429e2948
--- /dev/null
+++ b/static/bidder-params/bizzclick.json
@@ -0,0 +1,19 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "title": "Bizzclick Adapter Params",
+  "description": "A schema which validates params accepted by the Bizzclick adapter",
+  "type": "object",
+  "properties": {
+    "accountId": {
+      "type": "string",
+      "description": "Account id",
+      "minLength": 1
+    },
+    "placementId": {
+      "type": "string",
+      "description": "PlacementId id",
+      "minLength": 1
+    }
+  },
+  "required": ["accountId", "placementId"]
+}
\ No newline at end of file
diff --git a/static/bidder-params/groupm.json b/static/bidder-params/groupm.json
new file mode 100644
index 00000000..cfebd2ad
--- /dev/null
+++ b/static/bidder-params/groupm.json
@@ -0,0 +1,61 @@
+{
+	"$schema": "http://json-schema.org/draft-04/schema#",
+	"title": "Groupm Adapter Params",
+	"description": "A schema which validates params accepted by the Groupm adapter",
+	"type": "object",
+	"properties": {
+		"publisherId": {
+			"type": "string",
+			"description": "An ID which identifies the publisher"
+		},
+		"adSlot": {
+			"type": "string",
+			"description": "An ID which identifies the ad slot"
+		},
+		"pmzoneid": {
+			"type": "string",
+			"description": "Comma separated zone id. Used im deal targeting & site section targeting. e.g drama,sport"
+		},
+		"dctr": {
+			"type": "string",
+			"description": "Deals Custom Targeting, pipe separated key-value pairs e.g key1=V1,V2,V3|key2=v1|key3=v3,v5"
+		},
+		"wrapper": {
+			"type": "object",
+			"description": "Specifies Groupm openwrap configuration for a publisher",
+			"properties": {
+				"profile": {
+					"type": "integer",
+					"description": "An ID which identifies the openwrap profile of publisher"
+				},
+				"version": {
+					"type": "integer",
+					"description": "An ID which identifies version of the openwrap profile"
+				}
+			},
+			"required": ["profile"]
+		},
+		"keywords": {
+			"type": "array",
+			"minItems": 1,
+			"items": {
+			  "type": "object",
+			  "description": "A key with one or more values associated with it. These are used in buy-side segment targeting.",
+			  "properties": {
+				"key": {
+				  "type": "string"
+				},
+				"value": {
+				  "type": "array",
+				  "minItems": 1,
+				  "items": {
+					"type": "string"
+				  }
+				}
+			  },
+			  "required": ["key", "value"]
+			}
+		  }
+	},
+	"required": ["publisherId"]
+}
diff --git a/static/bidder-params/marsmedia.json b/static/bidder-params/marsmedia.json
index b812eb89..7555261a 100644
--- a/static/bidder-params/marsmedia.json
+++ b/static/bidder-params/marsmedia.json
@@ -5,8 +5,8 @@
   "type": "object",
   "properties": {
     "zoneId": {
-      "type": "string",
-      "description": "Zone ID to use."
+      "type": ["integer", "string"],
+      "description": "The zone ID from Mars Media Group."
     }
   }
 }


Test patch:
diff --git a/adapters/adf/adftest/exemplary/single-banner-pricetype-gross-extend-ext.json b/adapters/adf/adftest/exemplary/single-banner-pricetype-gross-extend-ext.json
new file mode 100644
index 00000000..0cd03c75
--- /dev/null
+++ b/adapters/adf/adftest/exemplary/single-banner-pricetype-gross-extend-ext.json
@@ -0,0 +1,122 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "ext":{
+      "prebid":{
+        "aliases":{
+          "adfalias": "adf"
+        }
+      }
+    },
+    "imp": [{
+      "id": "test-imp-id",
+      "ext": {
+        "bidder": {
+          "mid": "828782",
+          "priceType": "gross"
+        }
+      },
+      "banner": {
+        "format": [{
+          "w": 300,
+          "h": 250
+        }]
+      }
+    }],
+    "site": {
+      "publisher": {
+        "id": "1"
+      },
+      "page": "some-page-url"
+    },
+    "device": {
+      "w": 1920,
+      "h": 800
+    }
+  },
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "https://adx.adform.net/adx/openrtb",
+      "body": {
+        "id": "test-request-id",
+        "ext": {
+          "prebid":{
+            "aliases":{
+              "adfalias": "adf"
+            }
+          },
+          "pt": "gross"
+        },
+        "imp": [{
+          "id": "test-imp-id",
+          "ext": {
+            "bidder": {
+              "mid": "828782",
+              "priceType": "gross"
+            }
+          },
+          "banner": {
+            "format": [{
+              "w": 300,
+              "h": 250
+            }]
+          },
+          "tagid": "828782"
+        }],
+        "site": {
+          "publisher": {
+            "id": "1"
+          },
+          "page": "some-page-url"
+        },
+        "device": {
+          "w": 1920,
+          "h": 800
+        }
+      }
+    },
+    "mockResponse": {
+      "status": 200,
+      "body": {
+        "id": "test-request-id",
+        "seatbid": [{
+          "bid": [{
+            "id": "test-bid-id",
+            "impid": "test-imp-id",
+            "price": 10,
+            "adm": "{banner html}",
+            "adomain": [ "test.com" ],
+            "crid": "test-creative-id",
+            "ext": {
+              "prebid": {
+                "type": "banner"
+              }
+            }
+          }]
+        }],
+        "cur": "USD"
+      }
+    }
+  }],
+  "expectedBidResponses": [{
+    "currency": "USD",
+    "bids": [
+      {
+        "bid": {
+          "id": "test-bid-id",
+          "impid": "test-imp-id",
+          "price": 10,
+          "adm": "{banner html}",
+          "crid": "test-creative-id",
+          "adomain": [ "test.com" ],
+          "ext": {
+            "prebid": {
+              "type": "banner"
+            }
+          }
+        },
+        "type": "banner"
+      }
+    ]
+  }]
+}
diff --git a/adapters/adf/adftest/exemplary/single-banner-pricetype-gross.json b/adapters/adf/adftest/exemplary/single-banner-pricetype-gross.json
new file mode 100644
index 00000000..2fb7cf24
--- /dev/null
+++ b/adapters/adf/adftest/exemplary/single-banner-pricetype-gross.json
@@ -0,0 +1,112 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [{
+      "id": "test-imp-id",
+      "ext": {
+        "bidder": {
+          "mid": "828782",
+          "priceType": "gross"
+        }
+      },
+      "banner": {
+        "format": [{
+          "w": 300,
+          "h": 250
+        }]
+      }
+    }],
+    "site": {
+      "publisher": {
+        "id": "1"
+      },
+      "page": "some-page-url"
+    },
+    "device": {
+      "w": 1920,
+      "h": 800
+    }
+  },
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "https://adx.adform.net/adx/openrtb",
+      "body": {
+        "id": "test-request-id",
+        "ext": {
+          "prebid": {
+          },
+          "pt": "gross"
+        },
+        "imp": [{
+          "id": "test-imp-id",
+          "ext": {
+            "bidder": {
+              "mid": "828782",
+              "priceType": "gross"
+            }
+          },
+          "banner": {
+            "format": [{
+              "w": 300,
+              "h": 250
+            }]
+          },
+          "tagid": "828782"
+        }],
+        "site": {
+          "publisher": {
+            "id": "1"
+          },
+          "page": "some-page-url"
+        },
+        "device": {
+          "w": 1920,
+          "h": 800
+        }
+      }
+    },
+    "mockResponse": {
+      "status": 200,
+      "body": {
+        "id": "test-request-id",
+        "seatbid": [{
+          "bid": [{
+            "id": "test-bid-id",
+            "impid": "test-imp-id",
+            "price": 10,
+            "adm": "{banner html}",
+            "adomain": [ "test.com" ],
+            "crid": "test-creative-id",
+            "ext": {
+              "prebid": {
+                "type": "banner"
+              }
+            }
+          }]
+        }],
+        "cur": "USD"
+      }
+    }
+  }],
+  "expectedBidResponses": [{
+    "currency": "USD",
+    "bids": [
+      {
+        "bid": {
+          "id": "test-bid-id",
+          "impid": "test-imp-id",
+          "price": 10,
+          "adm": "{banner html}",
+          "crid": "test-creative-id",
+          "adomain": [ "test.com" ],
+          "ext": {
+            "prebid": {
+              "type": "banner"
+            }
+          }
+        },
+        "type": "banner"
+      }
+    ]
+  }]
+}
diff --git a/adapters/adf/adftest/exemplary/single-banner-pricetype-net.json b/adapters/adf/adftest/exemplary/single-banner-pricetype-net.json
new file mode 100644
index 00000000..cb4b5f8a
--- /dev/null
+++ b/adapters/adf/adftest/exemplary/single-banner-pricetype-net.json
@@ -0,0 +1,112 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [{
+      "id": "test-imp-id",
+      "ext": {
+        "bidder": {
+          "mid": "828782",
+          "priceType": "net"
+        }
+      },
+      "banner": {
+        "format": [{
+          "w": 300,
+          "h": 250
+        }]
+      }
+    }],
+    "site": {
+      "publisher": {
+        "id": "1"
+      },
+      "page": "some-page-url"
+    },
+    "device": {
+      "w": 1920,
+      "h": 800
+    }
+  },
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "https://adx.adform.net/adx/openrtb",
+      "body": {
+        "id": "test-request-id",
+        "ext": {
+          "prebid": {
+          },
+          "pt": "net"
+        },
+        "imp": [{
+          "id": "test-imp-id",
+          "ext": {
+            "bidder": {
+              "mid": "828782",
+              "priceType": "net"
+            }
+          },
+          "banner": {
+            "format": [{
+              "w": 300,
+              "h": 250
+            }]
+          },
+          "tagid": "828782"
+        }],
+        "site": {
+          "publisher": {
+            "id": "1"
+          },
+          "page": "some-page-url"
+        },
+        "device": {
+          "w": 1920,
+          "h": 800
+        }
+      }
+    },
+    "mockResponse": {
+      "status": 200,
+      "body": {
+        "id": "test-request-id",
+        "seatbid": [{
+          "bid": [{
+            "id": "test-bid-id",
+            "impid": "test-imp-id",
+            "price": 10,
+            "adm": "{banner html}",
+            "adomain": [ "test.com" ],
+            "crid": "test-creative-id",
+            "ext": {
+              "prebid": {
+                "type": "banner"
+              }
+            }
+          }]
+        }],
+        "cur": "USD"
+      }
+    }
+  }],
+  "expectedBidResponses": [{
+    "currency": "USD",
+    "bids": [
+      {
+        "bid": {
+          "id": "test-bid-id",
+          "impid": "test-imp-id",
+          "price": 10,
+          "adm": "{banner html}",
+          "crid": "test-creative-id",
+          "adomain": [ "test.com" ],
+          "ext": {
+            "prebid": {
+              "type": "banner"
+            }
+          }
+        },
+        "type": "banner"
+      }
+    ]
+  }]
+}
diff --git a/adapters/adf/adftest/exemplary/two-banners-different-pricetypes-extend-ext.json b/adapters/adf/adftest/exemplary/two-banners-different-pricetypes-extend-ext.json
new file mode 100644
index 00000000..59e380d5
--- /dev/null
+++ b/adapters/adf/adftest/exemplary/two-banners-different-pricetypes-extend-ext.json
@@ -0,0 +1,151 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "ext":{
+      "prebid":{
+        "aliases":{
+          "adfalias": "adf"
+        }
+      }
+    },
+    "imp": [{
+      "id": "test-imp-id",
+      "ext": {
+        "bidder": {
+          "mid": "828782",
+          "priceType": "gross"
+        }
+      },
+      "banner": {
+        "format": [{
+          "w": 300,
+          "h": 250
+        }]
+      }
+    },{
+      "id": "test-imp-id2",
+      "ext": {
+        "bidder": {
+          "mid": "828783",
+          "priceType": "net"
+        }
+      },
+      "banner": {
+        "format": [{
+          "w": 300,
+          "h": 250
+        }]
+      }
+    }],
+    "site": {
+      "publisher": {
+        "id": "1"
+      },
+      "page": "some-page-url"
+    },
+    "device": {
+      "w": 1920,
+      "h": 800
+    }
+  },
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "https://adx.adform.net/adx/openrtb",
+      "body": {
+        "id": "test-request-id",
+        "ext": {
+          "prebid":{
+            "aliases":{
+              "adfalias": "adf"
+            }
+          },
+          "pt": "gross"
+        },
+        "imp": [{
+          "id": "test-imp-id",
+          "ext": {
+            "bidder": {
+              "mid": "828782",
+              "priceType": "gross"
+            }
+          },
+          "banner": {
+            "format": [{
+              "w": 300,
+              "h": 250
+            }]
+          },
+          "tagid": "828782"
+        },{
+          "id": "test-imp-id2",
+          "ext": {
+            "bidder": {
+              "mid": "828783",
+              "priceType": "net"
+            }
+          },
+          "banner": {
+            "format": [{
+              "w": 300,
+              "h": 250
+            }]
+          },
+          "tagid": "828783"
+        }],
+        "site": {
+          "publisher": {
+            "id": "1"
+          },
+          "page": "some-page-url"
+        },
+        "device": {
+          "w": 1920,
+          "h": 800
+        }
+      }
+    },
+    "mockResponse": {
+      "status": 200,
+      "body": {
+        "id": "test-request-id",
+        "seatbid": [{
+          "bid": [{
+            "id": "test-bid-id",
+            "impid": "test-imp-id",
+            "price": 10,
+            "adm": "{banner html}",
+            "adomain": [ "test.com" ],
+            "crid": "test-creative-id",
+            "ext": {
+              "prebid": {
+                "type": "banner"
+              }
+            }
+          }]
+        }],
+        "cur": "USD"
+      }
+    }
+  }],
+  "expectedBidResponses": [{
+    "currency": "USD",
+    "bids": [
+      {
+        "bid": {
+          "id": "test-bid-id",
+          "impid": "test-imp-id",
+          "price": 10,
+          "adm": "{banner html}",
+          "crid": "test-creative-id",
+          "adomain": [ "test.com" ],
+          "ext": {
+            "prebid": {
+              "type": "banner"
+            }
+          }
+        },
+        "type": "banner"
+      }
+    ]
+  }]
+}
diff --git a/adapters/adf/adftest/exemplary/two-banners-different-pricetypes.json b/adapters/adf/adftest/exemplary/two-banners-different-pricetypes.json
new file mode 100644
index 00000000..918ef3ca
--- /dev/null
+++ b/adapters/adf/adftest/exemplary/two-banners-different-pricetypes.json
@@ -0,0 +1,141 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [{
+      "id": "test-imp-id",
+      "ext": {
+        "bidder": {
+          "mid": "828782",
+          "priceType": "gross"
+        }
+      },
+      "banner": {
+        "format": [{
+          "w": 300,
+          "h": 250
+        }]
+      }
+    },{
+      "id": "test-imp-id2",
+      "ext": {
+        "bidder": {
+          "mid": "828783",
+          "priceType": "net"
+        }
+      },
+      "banner": {
+        "format": [{
+          "w": 300,
+          "h": 250
+        }]
+      }
+    }],
+    "site": {
+      "publisher": {
+        "id": "1"
+      },
+      "page": "some-page-url"
+    },
+    "device": {
+      "w": 1920,
+      "h": 800
+    }
+  },
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "https://adx.adform.net/adx/openrtb",
+      "body": {
+        "id": "test-request-id",
+        "ext": {
+          "prebid": {
+          },
+          "pt": "gross"
+        },
+        "imp": [{
+          "id": "test-imp-id",
+          "ext": {
+            "bidder": {
+              "mid": "828782",
+              "priceType": "gross"
+            }
+          },
+          "banner": {
+            "format": [{
+              "w": 300,
+              "h": 250
+            }]
+          },
+          "tagid": "828782"
+        },{
+          "id": "test-imp-id2",
+          "ext": {
+            "bidder": {
+              "mid": "828783",
+              "priceType": "net"
+            }
+          },
+          "banner": {
+            "format": [{
+              "w": 300,
+              "h": 250
+            }]
+          },
+          "tagid": "828783"
+        }],
+        "site": {
+          "publisher": {
+            "id": "1"
+          },
+          "page": "some-page-url"
+        },
+        "device": {
+          "w": 1920,
+          "h": 800
+        }
+      }
+    },
+    "mockResponse": {
+      "status": 200,
+      "body": {
+        "id": "test-request-id",
+        "seatbid": [{
+          "bid": [{
+            "id": "test-bid-id",
+            "impid": "test-imp-id",
+            "price": 10,
+            "adm": "{banner html}",
+            "adomain": [ "test.com" ],
+            "crid": "test-creative-id",
+            "ext": {
+              "prebid": {
+                "type": "banner"
+              }
+            }
+          }]
+        }],
+        "cur": "USD"
+      }
+    }
+  }],
+  "expectedBidResponses": [{
+    "currency": "USD",
+    "bids": [
+      {
+        "bid": {
+          "id": "test-bid-id",
+          "impid": "test-imp-id",
+          "price": 10,
+          "adm": "{banner html}",
+          "crid": "test-creative-id",
+          "adomain": [ "test.com" ],
+          "ext": {
+            "prebid": {
+              "type": "banner"
+            }
+          }
+        },
+        "type": "banner"
+      }
+    ]
+  }]
+}
diff --git a/adapters/adf/params_test.go b/adapters/adf/params_test.go
index d075f914..d46c6528 100644
--- a/adapters/adf/params_test.go
+++ b/adapters/adf/params_test.go
@@ -46,6 +46,8 @@ var validParams = []string{
 	`{"inv":321,"mname":"12345"}`,
 	`{"mid":123,"inv":321,"mname":"pcl1"}`,
 	`{"mid":"123","inv":321,"mname":"pcl1"}`,
+	`{"mid":"123","priceType":"gross"}`,
+	`{"mid":"123","priceType":"net"}`,
 }
 
 var invalidParams = []string{
@@ -62,4 +64,5 @@ var invalidParams = []string{
 	`{"inv":321}`,
 	`{"inv":"321"}`,
 	`{"mname":"12345"}`,
+	`{"mid":"123","priceType":"GROSS"}`,
 }
diff --git a/adapters/algorix/algorix_test.go b/adapters/algorix/algorix_test.go
index 55c8b9ef..79cf8609 100644
--- a/adapters/algorix/algorix_test.go
+++ b/adapters/algorix/algorix_test.go
@@ -11,7 +11,7 @@ import (
 
 func TestJsonSamples(t *testing.T) {
 	bidder, buildErr := Builder(openrtb_ext.BidderAlgorix, config.Adapter{
-		Endpoint: "https://test.com?sid={{.SourceId}}&token={{.AccountID}}"})
+		Endpoint: "https://{{.Host}}.test.com?sid={{.SourceId}}&token={{.AccountID}}"})
 
 	if buildErr != nil {
 		t.Fatalf("Builder returned unexpected error %v", buildErr)
diff --git a/adapters/algorix/algorixtest/exemplary/sample-banner-with-palcementid.json b/adapters/algorix/algorixtest/exemplary/sample-banner-with-palcementid.json
index 4d1853f0..e50fb3a4 100644
--- a/adapters/algorix/algorixtest/exemplary/sample-banner-with-palcementid.json
+++ b/adapters/algorix/algorixtest/exemplary/sample-banner-with-palcementid.json
@@ -13,7 +13,8 @@
             "sid": "testSid",
             "token": "testToken",
             "placementId": "testPlacementId",
-            "appId": "testAppId"
+            "appId": "testAppId",
+            "region": "USE"
           }
         }
       }
@@ -23,7 +24,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "https://test.com?sid=testSid&token=testToken",
+        "uri": "https://use.xyz.test.com?sid=testSid&token=testToken",
         "body": {
           "id": "test-request-id",
           "imp": [
@@ -40,7 +41,8 @@
                   "sid": "testSid",
                   "token": "testToken",
                   "placementId": "testPlacementId",
-                  "appId": "testAppId"
+                  "appId": "testAppId",
+                  "region": "USE"
                 }
               }
             }
diff --git a/adapters/algorix/algorixtest/exemplary/sample-banner.json b/adapters/algorix/algorixtest/exemplary/sample-banner.json
index 118f89c1..d558214a 100644
--- a/adapters/algorix/algorixtest/exemplary/sample-banner.json
+++ b/adapters/algorix/algorixtest/exemplary/sample-banner.json
@@ -10,7 +10,8 @@
         "ext": {
           "bidder": {
             "sid": "testSid",
-            "token": "testToken"
+            "token": "testToken",
+            "region": "APAC"
           }
         }
       }
@@ -20,7 +21,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "https://test.com?sid=testSid&token=testToken",
+        "uri": "https://apac.xyz.test.com?sid=testSid&token=testToken",
         "body": {
           "id": "test-request-id",
           "imp": [
@@ -34,7 +35,8 @@
               "ext": {
                 "bidder": {
                   "sid": "testSid",
-                  "token": "testToken"
+                  "token": "testToken",
+                  "region": "APAC"
                 }
               }
             }
diff --git a/adapters/algorix/algorixtest/exemplary/sample-native.json b/adapters/algorix/algorixtest/exemplary/sample-native.json
index 3b24bd3a..36a0d1af 100644
--- a/adapters/algorix/algorixtest/exemplary/sample-native.json
+++ b/adapters/algorix/algorixtest/exemplary/sample-native.json
@@ -22,7 +22,7 @@
   "httpcalls": [
     {
       "expectedRequest": {
-        "uri": "https://test.com?sid=testSid&token=testToken",
+        "uri": "https://xyz.test.com?sid=testSid&token=testToken",
         "body": {
           "id": "test-request-id",
           "imp": [
diff --git a/adapters/algorix/algorixtest/exemplary/sample-nobid.json b/adapters/algorix/algorixtest/exemplary/sample-nobid.json
index c378ff0d..d4fbd561 100644
--- a/adapters/algorix/algorixtest/exemplary/sample-nobid.json
+++ b/adapters/algorix/algorixtest/exemplary/sample-nobid.json
@@ -22,7 +22,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "https://test.com?sid=testSid&token=testToken",
+        "uri": "https://xyz.test.com?sid=testSid&token=testToken",
         "body": {
           "id": "test-request-id",
           "imp": [
diff --git a/adapters/algorix/algorixtest/exemplary/sample-video.json b/adapters/algorix/algorixtest/exemplary/sample-video.json
index df3f6dcd..edb8fddb 100644
--- a/adapters/algorix/algorixtest/exemplary/sample-video.json
+++ b/adapters/algorix/algorixtest/exemplary/sample-video.json
@@ -26,7 +26,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "https://test.com?sid=testSid&token=testToken",
+        "uri": "https://xyz.test.com?sid=testSid&token=testToken",
         "body": {
           "id": "test-request-id",
           "imp": [
diff --git a/adapters/algorix/algorixtest/supplemental/bad_response.json b/adapters/algorix/algorixtest/supplemental/bad_response.json
index 17d84673..83ed5663 100644
--- a/adapters/algorix/algorixtest/supplemental/bad_response.json
+++ b/adapters/algorix/algorixtest/supplemental/bad_response.json
@@ -20,7 +20,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "https://test.com?sid=testSid&token=testToken",
+        "uri": "https://xyz.test.com?sid=testSid&token=testToken",
         "body": {
           "id": "test-request-id",
           "imp": [
diff --git a/adapters/algorix/algorixtest/supplemental/status_400.json b/adapters/algorix/algorixtest/supplemental/status_400.json
index f384c3b9..2085bf3c 100644
--- a/adapters/algorix/algorixtest/supplemental/status_400.json
+++ b/adapters/algorix/algorixtest/supplemental/status_400.json
@@ -20,7 +20,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "https://test.com?sid=testSid&token=testToken",
+        "uri": "https://xyz.test.com?sid=testSid&token=testToken",
         "body": {
           "id": "test-request-id",
           "imp": [
diff --git a/adapters/algorix/algorixtest/supplemental/status_500.json b/adapters/algorix/algorixtest/supplemental/status_500.json
index ca6cf14b..c7820917 100644
--- a/adapters/algorix/algorixtest/supplemental/status_500.json
+++ b/adapters/algorix/algorixtest/supplemental/status_500.json
@@ -20,7 +20,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "https://test.com?sid=testSid&token=testToken",
+        "uri": "https://xyz.test.com?sid=testSid&token=testToken",
         "body": {
           "id": "test-request-id",
           "imp": [
diff --git a/adapters/algorix/params_test.go b/adapters/algorix/params_test.go
index 3830b372..c33a3417 100644
--- a/adapters/algorix/params_test.go
+++ b/adapters/algorix/params_test.go
@@ -36,6 +36,8 @@ func TestInvalidParams(t *testing.T) {
 var validParams = []string{
 	`{"sid": "11233", "token": "sin", "placementId": "123", "appId": "abc"}`,
 	`{"sid": "11244", "token": "iad"}`,
+	`{"sid": "11244", "token": "iad", "region": "APAC"}`,
+	`{"sid": "11244", "token": "iad", "region": "USE"}`,
 }
 
 var invalidParams = []string{
@@ -47,4 +49,5 @@ var invalidParams = []string{
 	`{"sid": "11233", "token": "sin", "placementId": 123, "appId": "abc"}`,
 	`{"sid": "11233", "token": "sin", "placementId": "123", "appId": 456}`,
 	`{"sid": "11233", "token": "sin", "placementId": 123, "appId": 456}`,
+	`{"sid": "11233", "token": "sin", "region": 123}`,
 }
diff --git a/adapters/beachfront/beachfronttest/exemplary/adm-video-app.json b/adapters/beachfront/beachfronttest/exemplary/adm-video-app.json
index e20201bb..47507ba1 100644
--- a/adapters/beachfront/beachfronttest/exemplary/adm-video-app.json
+++ b/adapters/beachfront/beachfronttest/exemplary/adm-video-app.json
@@ -6,7 +6,6 @@
         "id": "video1",
         "ext": {
           "bidder": {
-            "bidfloor": 3.01,
             "appId": "videoAppId1"
           }
         },
@@ -43,7 +42,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 3.01,
               "id": "video1",
               "secure": 0
             }
diff --git a/adapters/beachfront/beachfronttest/exemplary/adm-video.json b/adapters/beachfront/beachfronttest/exemplary/adm-video.json
index 404c35ad..8fd8a459 100644
--- a/adapters/beachfront/beachfronttest/exemplary/adm-video.json
+++ b/adapters/beachfront/beachfronttest/exemplary/adm-video.json
@@ -6,7 +6,6 @@
         "id": "video1",
         "ext": {
           "bidder": {
-            "bidfloor": 3.01,
             "appId": "videoAppId1"
           }
         },
@@ -43,7 +42,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 3.01,
               "id": "video1",
               "secure": 1
             }
diff --git a/adapters/beachfront/beachfronttest/exemplary/banner.json b/adapters/beachfront/beachfronttest/exemplary/banner.json
index 11db9728..1707f3bb 100644
--- a/adapters/beachfront/beachfronttest/exemplary/banner.json
+++ b/adapters/beachfront/beachfronttest/exemplary/banner.json
@@ -57,7 +57,7 @@
           "dnt": 0,
           "ua": "",
           "adapterName": "BF_PREBID_S2S",
-          "adapterVersion": "0.9.2",
+          "adapterVersion": "1.0.0",
           "user": {},
           "schain": {
             "complete": 0,
diff --git a/adapters/beachfront/beachfronttest/exemplary/nurl-video.json b/adapters/beachfront/beachfronttest/exemplary/nurl-video.json
index b9b1881e..4a2a2d84 100644
--- a/adapters/beachfront/beachfronttest/exemplary/nurl-video.json
+++ b/adapters/beachfront/beachfronttest/exemplary/nurl-video.json
@@ -7,7 +7,6 @@
         "ext": {
           "bidder": {
             "videoResponseType": "nurl",
-            "bidfloor": 0.01,
             "appId": "videoAppId1"
           }
         },
diff --git a/adapters/beachfront/beachfronttest/supplemental/adm-video-app-alphanum-bundle.json b/adapters/beachfront/beachfronttest/supplemental/adm-video-app-alphanum-bundle.json
index 943a4583..aad4d1f5 100644
--- a/adapters/beachfront/beachfronttest/supplemental/adm-video-app-alphanum-bundle.json
+++ b/adapters/beachfront/beachfronttest/supplemental/adm-video-app-alphanum-bundle.json
@@ -6,7 +6,6 @@
         "id": "video1",
         "ext": {
           "bidder": {
-            "bidfloor": 3.01,
             "appId": "videoAppId1"
           }
         },
@@ -43,7 +42,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 3.01,
               "id": "video1",
               "secure": 0
             }
diff --git a/adapters/beachfront/beachfronttest/supplemental/adm-video-app-malformed-bundle.json b/adapters/beachfront/beachfronttest/supplemental/adm-video-app-malformed-bundle.json
index 9d0ca24a..6d2b3a12 100644
--- a/adapters/beachfront/beachfronttest/supplemental/adm-video-app-malformed-bundle.json
+++ b/adapters/beachfront/beachfronttest/supplemental/adm-video-app-malformed-bundle.json
@@ -6,7 +6,6 @@
         "id": "video1",
         "ext": {
           "bidder": {
-            "bidfloor": 3.01,
             "appId": "videoAppId1"
           }
         },
@@ -43,7 +42,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 3.01,
               "id": "video1",
               "secure": 0
             }
diff --git a/adapters/beachfront/beachfronttest/supplemental/adm-video-by-explicit.json b/adapters/beachfront/beachfronttest/supplemental/adm-video-by-explicit.json
index 25b4a1c4..7855639c 100644
--- a/adapters/beachfront/beachfronttest/supplemental/adm-video-by-explicit.json
+++ b/adapters/beachfront/beachfronttest/supplemental/adm-video-by-explicit.json
@@ -7,7 +7,6 @@
         "ext": {
           "bidder": {
             "videoResponseType": "adm",
-            "bidfloor": 3.01,
             "appId": "videoAppId1"
           }
         },
@@ -44,7 +43,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 3.01,
               "id": "video1",
               "secure": 1
             }
diff --git a/adapters/beachfront/beachfronttest/supplemental/adm-video-no-cat.json b/adapters/beachfront/beachfronttest/supplemental/adm-video-no-cat.json
index edde1301..2e6bbc5d 100644
--- a/adapters/beachfront/beachfronttest/supplemental/adm-video-no-cat.json
+++ b/adapters/beachfront/beachfronttest/supplemental/adm-video-no-cat.json
@@ -6,7 +6,6 @@
         "id": "video1",
         "ext": {
           "bidder": {
-            "bidfloor": 3.01,
             "appId": "videoAppId1"
           }
         },
@@ -43,7 +42,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 3.01,
               "id": "video1",
               "secure": 1
             }
diff --git a/adapters/beachfront/beachfronttest/supplemental/adm-video-no-ip.json b/adapters/beachfront/beachfronttest/supplemental/adm-video-no-ip.json
index d2cc2bc9..0fe36faf 100644
--- a/adapters/beachfront/beachfronttest/supplemental/adm-video-no-ip.json
+++ b/adapters/beachfront/beachfronttest/supplemental/adm-video-no-ip.json
@@ -6,7 +6,6 @@
         "id": "video1",
         "ext": {
           "bidder": {
-            "bidfloor": 3.01,
             "appId": "videoAppId1"
           }
         },
@@ -40,7 +39,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 3.01,
               "id": "video1",
               "secure": 1
             }
diff --git a/adapters/beachfront/beachfronttest/supplemental/adm-video-schain.json b/adapters/beachfront/beachfronttest/supplemental/adm-video-schain.json
index f249da47..56565acc 100644
--- a/adapters/beachfront/beachfronttest/supplemental/adm-video-schain.json
+++ b/adapters/beachfront/beachfronttest/supplemental/adm-video-schain.json
@@ -6,7 +6,6 @@
         "id": "video1",
         "ext": {
           "bidder": {
-            "bidfloor": 3.01,
             "appId": "videoAppId1"
           }
         },
@@ -60,7 +59,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 3.01,
               "id": "video1",
               "secure": 1
             }
diff --git a/adapters/beachfront/beachfronttest/supplemental/adm-video-unaccepted-currency.json b/adapters/beachfront/beachfronttest/supplemental/adm-video-unaccepted-currency.json
deleted file mode 100644
index c26b10ae..00000000
--- a/adapters/beachfront/beachfronttest/supplemental/adm-video-unaccepted-currency.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "adm-video-unaccepted-curency",
-    "imp": [
-      {
-        "id": "video1",
-        "bidfloorcur": "IRP",
-        "bidfloor": 695.61,
-        "ext": {
-          "bidder": {
-            "bidfloor": 3.01,
-            "appId": "videoAppId1"
-          }
-        },
-        "video": {
-          "mimes": [
-            "video/mp4"
-          ],
-          "context": "instream",
-          "w": 300,
-          "h": 250
-        }
-      }
-    ],
-    "site": {
-      "page": "https://some.domain.us/some/page.html"
-    },
-    "device":{
-      "ip":"192.168.168.168"
-    }
-  },
-  "expectedMakeRequestsErrors": [
-    {
-      "value": "unsupported bid currency, IRP. bids are currently accepted in USD only.",
-      "comparison": "literal"
-    }
-  ]
-}
diff --git a/adapters/beachfront/beachfronttest/supplemental/banner-204-with-body.json b/adapters/beachfront/beachfronttest/supplemental/banner-204-with-body.json
index af165c26..d9a2d14f 100644
--- a/adapters/beachfront/beachfronttest/supplemental/banner-204-with-body.json
+++ b/adapters/beachfront/beachfronttest/supplemental/banner-204-with-body.json
@@ -58,7 +58,7 @@
           "dnt": 0,
           "ua": "",
           "adapterName": "BF_PREBID_S2S",
-          "adapterVersion": "0.9.2",
+          "adapterVersion": "1.0.0",
           "user": {
           },
           "schain": {
diff --git a/adapters/beachfront/beachfronttest/supplemental/banner-204.json b/adapters/beachfront/beachfronttest/supplemental/banner-204.json
index 1c00f52c..eb24f592 100644
--- a/adapters/beachfront/beachfronttest/supplemental/banner-204.json
+++ b/adapters/beachfront/beachfronttest/supplemental/banner-204.json
@@ -58,7 +58,7 @@
           "dnt": 0,
           "ua": "",
           "adapterName": "BF_PREBID_S2S",
-          "adapterVersion": "0.9.2",
+          "adapterVersion": "1.0.0",
           "user": {
           },
           "schain": {
diff --git a/adapters/beachfront/beachfronttest/supplemental/banner-and-adm-video-by-explicit.json b/adapters/beachfront/beachfronttest/supplemental/banner-and-adm-video-by-explicit.json
index 283ba761..57853983 100644
--- a/adapters/beachfront/beachfronttest/supplemental/banner-and-adm-video-by-explicit.json
+++ b/adapters/beachfront/beachfronttest/supplemental/banner-and-adm-video-by-explicit.json
@@ -7,7 +7,6 @@
         "ext": {
           "bidder": {
             "videoResponseType": "adm",
-            "bidfloor": 0.41,
             "appIds": {
               "banner": "bannerAppId1",
               "video": "videoAppId1"
@@ -48,8 +47,8 @@
           "slots": [
             {
               "slot": "mix1",
+              "bidfloor": 0,
               "id": "bannerAppId1",
-              "bidfloor": 0.41,
               "sizes": [
                 {
                   "w": 300,
@@ -72,7 +71,7 @@
           "dnt": 0,
           "user": {},
           "adapterName": "BF_PREBID_S2S",
-          "adapterVersion": "0.9.2",
+          "adapterVersion": "1.0.0",
           "requestId": "banner-and-video",
           "schain": {
             "complete": 0,
@@ -109,7 +108,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 0.41,
               "secure": 1,
               "id": "mix1"
             }
diff --git a/adapters/beachfront/beachfronttest/supplemental/banner-and-adm-video-expected-204-response-on-banner.json b/adapters/beachfront/beachfronttest/supplemental/banner-and-adm-video-expected-204-response-on-banner.json
index 3026c133..9b0f1863 100644
--- a/adapters/beachfront/beachfronttest/supplemental/banner-and-adm-video-expected-204-response-on-banner.json
+++ b/adapters/beachfront/beachfronttest/supplemental/banner-and-adm-video-expected-204-response-on-banner.json
@@ -6,7 +6,6 @@
         "id": "mix1",
         "ext": {
           "bidder": {
-            "bidfloor": 0.41,
             "appIds": {
               "banner": "bannerAppId1",
               "video": "videoAppId1"
@@ -48,7 +47,7 @@
             {
               "slot": "mix1",
               "id": "bannerAppId1",
-              "bidfloor": 0.41,
+              "bidfloor": 0,
               "sizes": [
                 {
                   "w": 300,
@@ -71,7 +70,7 @@
           "dnt": 0,
           "user": {},
           "adapterName": "BF_PREBID_S2S",
-          "adapterVersion": "0.9.2",
+          "adapterVersion": "1.0.0",
           "requestId": "banner-and-video",
           "schain": {
             "complete": 0,
@@ -99,7 +98,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 0.41,
               "secure": 1,
               "id": "mix1"
             }
diff --git a/adapters/beachfront/beachfronttest/supplemental/banner-and-adm-video.json b/adapters/beachfront/beachfronttest/supplemental/banner-and-adm-video.json
index 73aa7df0..95073918 100644
--- a/adapters/beachfront/beachfronttest/supplemental/banner-and-adm-video.json
+++ b/adapters/beachfront/beachfronttest/supplemental/banner-and-adm-video.json
@@ -6,7 +6,6 @@
         "id": "mix1",
         "ext": {
           "bidder": {
-            "bidfloor": 0.41,
             "appIds": {
               "banner": "bannerAppId1",
               "video": "videoAppId1"
@@ -48,7 +47,7 @@
             {
               "slot": "mix1",
               "id": "bannerAppId1",
-              "bidfloor": 0.41,
+              "bidfloor": 0,
               "sizes": [
                 {
                   "w": 300,
@@ -71,7 +70,7 @@
           "dnt": 0,
           "user": {},
           "adapterName": "BF_PREBID_S2S",
-          "adapterVersion": "0.9.2",
+          "adapterVersion": "1.0.0",
           "requestId": "banner-and-video",
           "schain": {
             "complete": 0,
@@ -108,7 +107,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 0.41,
               "secure": 1,
               "id": "mix1"
             }
diff --git a/adapters/beachfront/beachfronttest/supplemental/banner-and-nurl-video.json b/adapters/beachfront/beachfronttest/supplemental/banner-and-nurl-video.json
index f1e06544..a05edc40 100644
--- a/adapters/beachfront/beachfronttest/supplemental/banner-and-nurl-video.json
+++ b/adapters/beachfront/beachfronttest/supplemental/banner-and-nurl-video.json
@@ -7,7 +7,6 @@
         "ext": {
           "bidder": {
             "videoResponseType": "nurl",
-            "bidfloor": 0.41,
             "appIds": {
               "banner": "bannerAppId1",
               "video": "videoAppId1"
@@ -46,7 +45,7 @@
             {
               "slot": "mix1",
               "id": "bannerAppId1",
-              "bidfloor": 0.41,
+              "bidfloor": 0,
               "sizes": [
                 {
                   "w": 300,
@@ -69,7 +68,7 @@
           "dnt": 0,
           "user": {},
           "adapterName": "BF_PREBID_S2S",
-          "adapterVersion": "0.9.2",
+          "adapterVersion": "1.0.0",
           "requestId": "banner-and-video",
           "schain": {
             "complete": 0,
@@ -106,7 +105,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 0.41,
               "secure": 1,
               "id": "mix1"
             }
diff --git a/adapters/beachfront/beachfronttest/supplemental/banner-bad-request-400.json b/adapters/beachfront/beachfronttest/supplemental/banner-bad-request-400.json
index 7463e2bf..1e54fea6 100644
--- a/adapters/beachfront/beachfronttest/supplemental/banner-bad-request-400.json
+++ b/adapters/beachfront/beachfronttest/supplemental/banner-bad-request-400.json
@@ -6,7 +6,6 @@
     },
     "imp": [
       {
-        "bidfloor": 0.02,
         "banner": {
           "format": [
             {
@@ -17,7 +16,6 @@
         },
         "ext": {
           "bidder": {
-            "bidfloor": 5.02,
             "appId": "dudAppId"
           }
         }
@@ -34,7 +32,7 @@
             {
               "slot": "",
               "id": "dudAppId",
-              "bidfloor": 0.02,
+              "bidfloor": 0,
               "sizes": [
                 {
                   "w": 300,
@@ -57,7 +55,7 @@
           "dnt": 0,
           "ua": "",
           "adapterName": "BF_PREBID_S2S",
-          "adapterVersion": "0.9.2",
+          "adapterVersion": "1.0.0",
           "user": {},
           "schain": {
             "complete": 0,
diff --git a/adapters/beachfront/beachfronttest/supplemental/banner-schain.json b/adapters/beachfront/beachfronttest/supplemental/banner-schain.json
index 4856e3e9..b2cede7a 100644
--- a/adapters/beachfront/beachfronttest/supplemental/banner-schain.json
+++ b/adapters/beachfront/beachfronttest/supplemental/banner-schain.json
@@ -74,7 +74,7 @@
           "dnt": 0,
           "ua": "",
           "adapterName": "BF_PREBID_S2S",
-          "adapterVersion": "0.9.2",
+          "adapterVersion": "1.0.0",
           "user": {},
           "schain": {
             "complete": 1,
diff --git a/adapters/beachfront/beachfronttest/supplemental/bidder_response_unmarshal_error_adm_video.json b/adapters/beachfront/beachfronttest/supplemental/bidder_response_unmarshal_error_adm_video.json
index 51c676f5..fe558c80 100644
--- a/adapters/beachfront/beachfronttest/supplemental/bidder_response_unmarshal_error_adm_video.json
+++ b/adapters/beachfront/beachfronttest/supplemental/bidder_response_unmarshal_error_adm_video.json
@@ -6,7 +6,6 @@
         "id": "video1",
         "ext": {
           "bidder": {
-            "bidfloor": 3.01,
             "appId": "videoAppId1"
           }
         },
@@ -43,7 +42,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 3.01,
               "id": "video1",
               "secure": 1
             }
diff --git a/adapters/beachfront/beachfronttest/supplemental/bidder_response_unmarshal_error_banner.json b/adapters/beachfront/beachfronttest/supplemental/bidder_response_unmarshal_error_banner.json
index dc709071..9b83e0d3 100644
--- a/adapters/beachfront/beachfronttest/supplemental/bidder_response_unmarshal_error_banner.json
+++ b/adapters/beachfront/beachfronttest/supplemental/bidder_response_unmarshal_error_banner.json
@@ -6,7 +6,6 @@
     },
     "imp": [
       {
-        "bidfloor": 0.02,
         "banner": {
           "format": [
             {
@@ -17,7 +16,6 @@
         },
         "ext": {
           "bidder": {
-            "bidfloor": 0.02,
             "appId": "bannerAppId1"
           }
         }
@@ -33,7 +31,7 @@
             {
               "slot": "",
               "id": "bannerAppId1",
-              "bidfloor": 0.02,
+              "bidfloor": 0,
               "sizes": [
                 {
                   "w": 300,
@@ -56,7 +54,7 @@
           "dnt": 0,
           "ua": "",
           "adapterName": "BF_PREBID_S2S",
-          "adapterVersion": "0.9.2",
+          "adapterVersion": "1.0.0",
           "user": {},
           "schain": {
             "complete": 0,
diff --git a/adapters/beachfront/beachfronttest/supplemental/bidder_response_unmarshal_error_nurl_video.json b/adapters/beachfront/beachfronttest/supplemental/bidder_response_unmarshal_error_nurl_video.json
index 7990b0a1..ff467f7b 100644
--- a/adapters/beachfront/beachfronttest/supplemental/bidder_response_unmarshal_error_nurl_video.json
+++ b/adapters/beachfront/beachfronttest/supplemental/bidder_response_unmarshal_error_nurl_video.json
@@ -6,7 +6,6 @@
         "id": "video1",
         "ext": {
           "bidder": {
-            "bidfloor": 3.01,
             "appId": "videoAppId1",
             "videoResponseType": "nurl"
           }
@@ -44,7 +43,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 3.01,
               "id": "video1",
               "secure": 1
             }
diff --git a/adapters/beachfront/beachfronttest/supplemental/bidfloor-four-variations-on-nothing-adm-video.json b/adapters/beachfront/beachfronttest/supplemental/bidfloor-four-variations-on-nothing-adm-video.json
deleted file mode 100644
index 147efb78..00000000
--- a/adapters/beachfront/beachfronttest/supplemental/bidfloor-four-variations-on-nothing-adm-video.json
+++ /dev/null
@@ -1,436 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "adm-video",
-    "imp": [
-      {
-        "id": "video1",
-        "ext": {
-          "bidder": {
-            "bidfloor": 0.01,
-            "appId": "videoAppId1"
-          }
-        },
-        "video": {
-          "mimes": [
-            "video/mp4"
-          ],
-          "context": "instream",
-          "w": 300,
-          "h": 250
-        }
-      }, {
-        "id": "video2",
-        "bidfloor": 0.01,
-        "ext": {
-          "bidder": {
-            "appId": "videoAppId1"
-          }
-        },
-        "video": {
-          "mimes": [
-            "video/mp4"
-          ],
-          "context": "instream",
-          "w": 300,
-          "h": 250
-        }
-      }, {
-        "id": "video3",
-        "ext": {
-          "bidder": {
-            "appId": "videoAppId1"
-          }
-        },
-        "video": {
-          "mimes": [
-            "video/mp4"
-          ],
-          "context": "instream",
-          "w": 300,
-          "h": 250
-        }
-      }, {
-        "id": "video4",
-        "bidfloor": 0.01,
-        "ext": {
-          "bidder": {
-            "bidfloor": 10.01,
-            "appId": "videoAppId1"
-          }
-        },
-        "video": {
-          "mimes": [
-            "video/mp4"
-          ],
-          "context": "instream",
-          "w": 300,
-          "h": 250
-        }
-      }
-    ],
-    "site": {
-      "page": "https://some.domain.us/some/page.html"
-    },
-    "device":{
-      "ip":"192.168.168.168"
-    }
-  },
-
-  "httpCalls": [
-    {
-      "expectedRequest": {
-        "uri": "https://qa.beachrtb.com/bid.json?exchange_id=videoAppId1",
-        "body": {
-          "id": "adm-video",
-          "imp": [
-            {
-              "video": {
-                "w": 300,
-                "h": 250,
-                "mimes": [
-                  "video/mp4"
-                ]
-              },
-              "id": "video1",
-              "secure": 1
-            }
-          ],
-          "site": {
-            "page": "https://some.domain.us/some/page.html",
-            "domain": "some.domain.us"
-          },
-          "cur": [
-            "USD"
-          ],
-          "device":{
-            "devicetype": 2,
-            "ip":"192.168.168.168"
-          }
-        }
-      },
-      "mockResponse": {
-        "status": 200,
-        "body": {
-          "id": "adm-video",
-          "seatBid": [
-            {
-              "bid": [
-                {
-                  "id": "5fd7c8a6ff2f1f0d42ee6427",
-                  "impid": "video1",
-                  "price": 20,
-                  "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
-                  "adid": "1088",
-                  "adomain": [
-                    "beachfront.io"
-                  ],
-                  "cid": "277",
-                  "crid": "532",
-                  "cat":["IAB2"],
-                  "w": 300,
-                  "h": 250,
-                  "ext": {
-                    "duration": 30
-                  }
-                }
-              ],
-              "seat": "bfio-s-1"
-            }
-          ]
-        }
-      }
-    }, {
-      "expectedRequest": {
-        "uri": "https://qa.beachrtb.com/bid.json?exchange_id=videoAppId1",
-        "body": {
-          "id": "adm-video",
-          "imp": [
-            {
-              "video": {
-                "w": 300,
-                "h": 250,
-                "mimes": [
-                  "video/mp4"
-                ]
-              },
-              "id": "video2",
-              "secure": 1
-            }
-          ],
-          "site": {
-            "page": "https://some.domain.us/some/page.html",
-            "domain": "some.domain.us"
-          },
-          "cur": [
-            "USD"
-          ],
-          "device":{
-            "devicetype": 2,
-            "ip":"192.168.168.168"
-          }
-        }
-      },
-      "mockResponse": {
-        "status": 200,
-        "body": {
-          "id": "adm-video",
-          "seatBid": [
-            {
-              "bid": [
-                {
-                  "id": "5fd7c8a6ff2f1f0d42ee6427",
-                  "impid": "video2",
-                  "price": 20,
-                  "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
-                  "adid": "1088",
-                  "adomain": [
-                    "beachfront.io"
-                  ],
-                  "cid": "277",
-                  "crid": "532",
-                  "cat":["IAB2"],
-                  "w": 300,
-                  "h": 250,
-                  "ext": {
-                    "duration": 30
-                  }
-                }
-              ],
-              "seat": "bfio-s-1"
-            }
-          ]
-        }
-      }
-    }, {
-      "expectedRequest": {
-        "uri": "https://qa.beachrtb.com/bid.json?exchange_id=videoAppId1",
-        "body": {
-          "id": "adm-video",
-          "imp": [
-            {
-              "video": {
-                "w": 300,
-                "h": 250,
-                "mimes": [
-                  "video/mp4"
-                ]
-              },
-              "id": "video3",
-              "secure": 1
-            }
-          ],
-          "site": {
-            "page": "https://some.domain.us/some/page.html",
-            "domain": "some.domain.us"
-          },
-          "cur": [
-            "USD"
-          ],
-          "device":{
-            "devicetype": 2,
-            "ip":"192.168.168.168"
-          }
-        }
-      },
-      "mockResponse": {
-        "status": 200,
-        "body": {
-          "id": "adm-video",
-          "seatBid": [
-            {
-              "bid": [
-                {
-                  "id": "5fd7c8a6ff2f1f0d42ee6427",
-                  "impid": "video3",
-                  "price": 20,
-                  "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
-                  "adid": "1088",
-                  "adomain": [
-                    "beachfront.io"
-                  ],
-                  "cid": "277",
-                  "crid": "532",
-                  "cat":["IAB2"],
-                  "w": 300,
-                  "h": 250,
-                  "ext": {
-                    "duration": 30
-                  }
-                }
-              ],
-              "seat": "bfio-s-1"
-            }
-          ]
-        }
-      }
-    }, {
-      "expectedRequest": {
-        "uri": "https://qa.beachrtb.com/bid.json?exchange_id=videoAppId1",
-        "body": {
-          "id": "adm-video",
-          "imp": [
-            {
-              "video": {
-                "w": 300,
-                "h": 250,
-                "mimes": [
-                  "video/mp4"
-                ]
-              },
-              "id": "video4",
-              "secure": 1
-            }
-          ],
-          "site": {
-            "page": "https://some.domain.us/some/page.html",
-            "domain": "some.domain.us"
-          },
-          "cur": [
-            "USD"
-          ],
-          "device":{
-            "devicetype": 2,
-            "ip":"192.168.168.168"
-          }
-        }
-      },
-      "mockResponse": {
-        "status": 200,
-        "body": {
-          "id": "adm-video",
-          "seatBid": [
-            {
-              "bid": [
-                {
-                  "id": "5fd7c8a6ff2f1f0d42ee6427",
-                  "impid": "video4",
-                  "price": 20,
-                  "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
-                  "adid": "1088",
-                  "adomain": [
-                    "beachfront.io"
-                  ],
-                  "cid": "277",
-                  "crid": "532",
-                  "cat":["IAB2"],
-                  "w": 300,
-                  "h": 250,
-                  "ext": {
-                    "duration": 30
-                  }
-                }
-              ],
-              "seat": "bfio-s-1"
-            }
-          ]
-        }
-      }
-
-    }
-  ],
-
-  "expectedBidResponses": [
-    {
-      "currency": "USD",
-      "bids": [
-        {
-          "bid": {
-            "id": "video1AdmVideo",
-            "impid": "video1",
-            "price": 20,
-            "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
-            "adid": "1088",
-            "adomain": [
-              "beachfront.io"
-            ],
-            "cid": "277",
-            "crid": "532",
-            "cat":["IAB2"],
-            "w": 300,
-            "h": 250,
-            "ext": {
-              "duration": 30
-            }
-          },
-          "type": "video"
-        }
-      ]
-    }, {
-      "currency": "USD",
-      "bids": [
-        {
-          "bid": {
-            "id": "video2AdmVideo",
-            "impid": "video2",
-            "price": 20,
-            "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
-            "adid": "1088",
-            "adomain": [
-              "beachfront.io"
-            ],
-            "cid": "277",
-            "crid": "532",
-            "cat":["IAB2"],
-            "w": 300,
-            "h": 250,
-            "ext": {
-              "duration": 30
-            }
-          },
-          "type": "video"
-        }
-      ]
-    }, {
-      "currency": "USD",
-      "bids": [
-        {
-          "bid": {
-            "id": "video3AdmVideo",
-            "impid": "video3",
-            "price": 20,
-            "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
-            "adid": "1088",
-            "adomain": [
-              "beachfront.io"
-            ],
-            "cid": "277",
-            "crid": "532",
-            "cat":["IAB2"],
-            "w": 300,
-            "h": 250,
-            "ext": {
-              "duration": 30
-            }
-          },
-          "type": "video"
-        }
-      ]
-    }, {
-      "currency": "USD",
-      "bids": [
-        {
-          "bid": {
-            "id": "video4AdmVideo",
-            "impid": "video4",
-            "price": 20,
-            "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
-            "adid": "1088",
-            "adomain": [
-              "beachfront.io"
-            ],
-            "cid": "277",
-            "crid": "532",
-            "cat":["IAB2"],
-            "w": 300,
-            "h": 250,
-            "ext": {
-              "duration": 30
-            }
-          },
-          "type": "video"
-        }
-      ]
-
-    }
-  ]
-}
diff --git a/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-converted.json b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-converted.json
new file mode 100644
index 00000000..ba361ef4
--- /dev/null
+++ b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-converted.json
@@ -0,0 +1,145 @@
+{
+  "mockBidRequest": {
+    "id": "adm-video",
+    "imp": [
+      {
+        "id": "video1",
+        "bidfloor": 1.80,
+        "bidfloorcur": "EUR",
+        "ext": {
+          "bidder": {
+            "bidfloor": 1.98,
+            "appId": "videoAppId1"
+          }
+        },
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "context": "instream",
+          "w": 300,
+          "h": 250
+        }
+      }
+    ],
+    "site": {
+      "page": "https://some.domain.us/some/page.html"
+    },
+    "device":{
+      "ip":"192.168.168.168"
+    },
+    "ext": {
+      "prebid": {
+        "currency": {
+          "rates": {
+            "MXN":{
+              "USD": 0.05,
+              "EUR": 0.03
+            },
+            "EUR": {
+              "USD": 1.20
+            }
+          },
+          "usepbsrates": false
+        }
+      }
+    }
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://qa.beachrtb.com/bid.json?exchange_id=videoAppId1",
+        "body": {
+          "id": "adm-video",
+          "imp": [
+            {
+              "bidfloor": 2.16,
+              "bidfloorcur": "USD",
+              "video": {
+                "w": 300,
+                "h": 250,
+                "mimes": [
+                  "video/mp4"
+                ]
+              },
+              "id": "video1",
+              "secure": 1
+            }
+          ],
+          "site": {
+            "page": "https://some.domain.us/some/page.html",
+            "domain": "some.domain.us"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device":{
+            "devicetype": 2,
+            "ip":"192.168.168.168"
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "adm-video",
+          "seatBid": [
+            {
+              "bid": [
+                {
+                  "id": "5fd7c8a6ff2f1f0d42ee6427",
+                  "impid": "video1",
+                  "price": 20,
+                  "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
+                  "adid": "1088",
+                  "adomain": [
+                    "beachfront.io"
+                  ],
+                  "cat":["IAB2"],
+                  "cid": "277",
+                  "crid": "532",
+                  "w": 300,
+                  "h": 250,
+                  "ext": {
+                    "duration": 30
+                  }
+                }
+              ],
+              "seat": "bfio-s-1"
+            }
+          ]
+        }
+      }
+    }
+  ],
+
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "video1AdmVideo",
+            "impid": "video1",
+            "price": 20,
+            "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
+            "adid": "1088",
+            "adomain": [
+              "beachfront.io"
+            ],
+            "cid": "277",
+            "crid": "532",
+            "cat":["IAB2"],
+            "w": 300,
+            "h": 250,
+            "ext": {
+              "duration": 30
+            }
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-ext-wins.json b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-ext-wins.json
new file mode 100644
index 00000000..b0bf84fa
--- /dev/null
+++ b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-ext-wins.json
@@ -0,0 +1,128 @@
+{
+  "mockBidRequest": {
+    "id": "adm-video",
+    "imp": [
+      {
+        "id": "video1",
+        "bidfloor": 1.90,
+        "ext": {
+          "bidder": {
+            "bidfloor": 2.90,
+            "appId": "videoAppId1"
+          }
+        },
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "context": "instream",
+          "w": 300,
+          "h": 250
+        }
+      }
+    ],
+    "site": {
+      "page": "https://some.domain.us/some/page.html"
+    },
+    "device":{
+      "ip":"192.168.168.168"
+    }
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://qa.beachrtb.com/bid.json?exchange_id=videoAppId1",
+        "body": {
+          "id": "adm-video",
+          "imp": [
+            {
+              "bidfloor": 2.90,
+              "bidfloorcur": "USD",
+              "video": {
+                "w": 300,
+                "h": 250,
+                "mimes": [
+                  "video/mp4"
+                ]
+              },
+              "id": "video1",
+              "secure": 1
+            }
+          ],
+          "site": {
+            "page": "https://some.domain.us/some/page.html",
+            "domain": "some.domain.us"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device":{
+            "devicetype": 2,
+            "ip":"192.168.168.168"
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "adm-video",
+          "seatBid": [
+            {
+              "bid": [
+                {
+                  "id": "5fd7c8a6ff2f1f0d42ee6427",
+                  "impid": "video1",
+                  "price": 20,
+                  "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
+                  "adid": "1088",
+                  "adomain": [
+                    "beachfront.io"
+                  ],
+                  "cat":["IAB2"],
+                  "cid": "277",
+                  "crid": "532",
+                  "w": 300,
+                  "h": 250,
+                  "ext": {
+                    "duration": 30
+                  }
+                }
+              ],
+              "seat": "bfio-s-1"
+            }
+          ]
+        }
+      }
+    }
+  ],
+
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "video1AdmVideo",
+            "impid": "video1",
+            "price": 20,
+            "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
+            "adid": "1088",
+            "adomain": [
+              "beachfront.io"
+            ],
+            "cid": "277",
+            "crid": "532",
+            "cat":["IAB2"],
+            "w": 300,
+            "h": 250,
+            "ext": {
+              "duration": 30
+            }
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-imp-wins.json b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-imp-wins.json
new file mode 100644
index 00000000..379fe196
--- /dev/null
+++ b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-imp-wins.json
@@ -0,0 +1,128 @@
+{
+  "mockBidRequest": {
+    "id": "adm-video",
+    "imp": [
+      {
+        "id": "video1",
+        "bidfloor": 2.01,
+        "ext": {
+          "bidder": {
+            "bidfloor": 1.90,
+            "appId": "videoAppId1"
+          }
+        },
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "context": "instream",
+          "w": 300,
+          "h": 250
+        }
+      }
+    ],
+    "site": {
+      "page": "https://some.domain.us/some/page.html"
+    },
+    "device":{
+      "ip":"192.168.168.168"
+    }
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://qa.beachrtb.com/bid.json?exchange_id=videoAppId1",
+        "body": {
+          "id": "adm-video",
+          "imp": [
+            {
+              "bidfloor": 2.01,
+              "bidfloorcur": "USD",
+              "video": {
+                "w": 300,
+                "h": 250,
+                "mimes": [
+                  "video/mp4"
+                ]
+              },
+              "id": "video1",
+              "secure": 1
+            }
+          ],
+          "site": {
+            "page": "https://some.domain.us/some/page.html",
+            "domain": "some.domain.us"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device":{
+            "devicetype": 2,
+            "ip":"192.168.168.168"
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "adm-video",
+          "seatBid": [
+            {
+              "bid": [
+                {
+                  "id": "5fd7c8a6ff2f1f0d42ee6427",
+                  "impid": "video1",
+                  "price": 20,
+                  "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
+                  "adid": "1088",
+                  "adomain": [
+                    "beachfront.io"
+                  ],
+                  "cat":["IAB2"],
+                  "cid": "277",
+                  "crid": "532",
+                  "w": 300,
+                  "h": 250,
+                  "ext": {
+                    "duration": 30
+                  }
+                }
+              ],
+              "seat": "bfio-s-1"
+            }
+          ]
+        }
+      }
+    }
+  ],
+
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "video1AdmVideo",
+            "impid": "video1",
+            "price": 20,
+            "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
+            "adid": "1088",
+            "adomain": [
+              "beachfront.io"
+            ],
+            "cid": "277",
+            "crid": "532",
+            "cat":["IAB2"],
+            "w": 300,
+            "h": 250,
+            "ext": {
+              "duration": 30
+            }
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-warning-and-fallback.json b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-warning-and-fallback.json
new file mode 100644
index 00000000..71b3161b
--- /dev/null
+++ b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-warning-and-fallback.json
@@ -0,0 +1,151 @@
+{
+  "mockBidRequest": {
+    "id": "adm-video",
+    "imp": [
+      {
+        "id": "video1",
+        "bidfloor": 1.90,
+        "bidfloorcur": "XYZ",
+        "ext": {
+          "bidder": {
+            "bidfloor": 1.20,
+            "appId": "videoAppId1"
+          }
+        },
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "context": "instream",
+          "w": 300,
+          "h": 250
+        }
+      }
+    ],
+    "site": {
+      "page": "https://some.domain.us/some/page.html"
+    },
+    "device":{
+      "ip":"192.168.168.168"
+    },
+    "ext": {
+      "prebid": {
+        "currency": {
+          "rates": {
+            "MXN":{
+              "USD": 0.05,
+              "EUR": 0.03
+            },
+            "EUR": {
+              "USD": 1.20
+            }
+          },
+          "usepbsrates": false
+        }
+      }
+    }
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://qa.beachrtb.com/bid.json?exchange_id=videoAppId1",
+        "body": {
+          "id": "adm-video",
+          "imp": [
+            {
+              "bidfloor": 1.20,
+              "bidfloorcur": "USD",
+              "video": {
+                "w": 300,
+                "h": 250,
+                "mimes": [
+                  "video/mp4"
+                ]
+              },
+              "id": "video1",
+              "secure": 1
+            }
+          ],
+          "site": {
+            "page": "https://some.domain.us/some/page.html",
+            "domain": "some.domain.us"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device":{
+            "devicetype": 2,
+            "ip":"192.168.168.168"
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "adm-video",
+          "seatBid": [
+            {
+              "bid": [
+                {
+                  "id": "5fd7c8a6ff2f1f0d42ee6427",
+                  "impid": "video1",
+                  "price": 20,
+                  "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
+                  "adid": "1088",
+                  "adomain": [
+                    "beachfront.io"
+                  ],
+                  "cat":["IAB2"],
+                  "cid": "277",
+                  "crid": "532",
+                  "w": 300,
+                  "h": 250,
+                  "ext": {
+                    "duration": 30
+                  }
+                }
+              ],
+              "seat": "bfio-s-1"
+            }
+          ]
+        }
+      }
+    }
+  ],
+
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "video1AdmVideo",
+            "impid": "video1",
+            "price": 20,
+            "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
+            "adid": "1088",
+            "adomain": [
+              "beachfront.io"
+            ],
+            "cid": "277",
+            "crid": "532",
+            "cat":["IAB2"],
+            "w": 300,
+            "h": 250,
+            "ext": {
+              "duration": 30
+            }
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ],
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "The following error was recieved from the currency converter while attempting to convert the imp.bidfloor value of 1.90 from XYZ to USD:\ncurrency: tag is not a recognized currency\nThe provided value of imp.ext.beachfront.bidfloor, 1.20 USD is being used as a fallback.",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-warning-no-fallback.json b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-warning-no-fallback.json
new file mode 100644
index 00000000..8f611156
--- /dev/null
+++ b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-warning-no-fallback.json
@@ -0,0 +1,55 @@
+{
+  "mockBidRequest": {
+    "id": "adm-video",
+    "imp": [
+      {
+        "id": "video1",
+        "bidfloor": 1.90,
+        "bidfloorcur": "XYZ",
+        "ext": {
+          "bidder": {
+            "appId": "videoAppId1"
+          }
+        },
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "context": "instream",
+          "w": 300,
+          "h": 250
+        }
+      }
+    ],
+    "site": {
+      "page": "https://some.domain.us/some/page.html"
+    },
+    "device":{
+      "ip":"192.168.168.168"
+    },
+    "ext": {
+      "prebid": {
+        "currency": {
+          "rates": {
+            "MXN":{
+              "USD": 0.05,
+              "EUR": 0.03
+            },
+            "EUR": {
+              "USD": 1.20
+            }
+          },
+          "usepbsrates": false
+        }
+      }
+    }
+  },
+
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "The following error was recieved from the currency converter while attempting to convert the imp.bidfloor value of 1.90 from XYZ to USD:\ncurrency: tag is not a recognized currency\nA value of imp.ext.beachfront.bidfloor was not provided. The bid is being skipped.",
+      "comparison": "literal"
+    }
+  ]
+
+}
diff --git a/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-warning-zeroed-fallback.json b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-warning-zeroed-fallback.json
new file mode 100644
index 00000000..8f611156
--- /dev/null
+++ b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-warning-zeroed-fallback.json
@@ -0,0 +1,55 @@
+{
+  "mockBidRequest": {
+    "id": "adm-video",
+    "imp": [
+      {
+        "id": "video1",
+        "bidfloor": 1.90,
+        "bidfloorcur": "XYZ",
+        "ext": {
+          "bidder": {
+            "appId": "videoAppId1"
+          }
+        },
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "context": "instream",
+          "w": 300,
+          "h": 250
+        }
+      }
+    ],
+    "site": {
+      "page": "https://some.domain.us/some/page.html"
+    },
+    "device":{
+      "ip":"192.168.168.168"
+    },
+    "ext": {
+      "prebid": {
+        "currency": {
+          "rates": {
+            "MXN":{
+              "USD": 0.05,
+              "EUR": 0.03
+            },
+            "EUR": {
+              "USD": 1.20
+            }
+          },
+          "usepbsrates": false
+        }
+      }
+    }
+  },
+
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "The following error was recieved from the currency converter while attempting to convert the imp.bidfloor value of 1.90 from XYZ to USD:\ncurrency: tag is not a recognized currency\nA value of imp.ext.beachfront.bidfloor was not provided. The bid is being skipped.",
+      "comparison": "literal"
+    }
+  ]
+
+}
diff --git a/adapters/beachfront/beachfronttest/supplemental/bidfloor-test-ext-wins-adm-video.json b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-zero-by-min-both.json
similarity index 95%
rename from adapters/beachfront/beachfronttest/supplemental/bidfloor-test-ext-wins-adm-video.json
rename to adapters/beachfront/beachfronttest/supplemental/currency-adm-video-zero-by-min-both.json
index eed3da99..c4d85323 100644
--- a/adapters/beachfront/beachfronttest/supplemental/bidfloor-test-ext-wins-adm-video.json
+++ b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-zero-by-min-both.json
@@ -4,9 +4,10 @@
     "imp": [
       {
         "id": "video1",
+        "bidfloor": 0.01,
         "ext": {
           "bidder": {
-            "bidfloor": 3.01,
+            "bidfloor": 0.01,
             "appId": "videoAppId1"
           }
         },
@@ -43,7 +44,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 3.01,
               "id": "video1",
               "secure": 1
             }
@@ -71,15 +71,15 @@
                 {
                   "id": "5fd7c8a6ff2f1f0d42ee6427",
                   "impid": "video1",
-                  "price": 200,
+                  "price": 20,
                   "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
                   "adid": "1088",
                   "adomain": [
                     "beachfront.io"
                   ],
+                  "cat":["IAB2"],
                   "cid": "277",
                   "crid": "532",
-                  "cat":["IAB2"],
                   "w": 300,
                   "h": 250,
                   "ext": {
@@ -103,7 +103,7 @@
           "bid": {
             "id": "video1AdmVideo",
             "impid": "video1",
-            "price": 200,
+            "price": 20,
             "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
             "adid": "1088",
             "adomain": [
diff --git a/adapters/beachfront/beachfronttest/supplemental/bidfloor-test-imp-wins-adm-video.json b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-zero-by-min-ext.json
similarity index 94%
rename from adapters/beachfront/beachfronttest/supplemental/bidfloor-test-imp-wins-adm-video.json
rename to adapters/beachfront/beachfronttest/supplemental/currency-adm-video-zero-by-min-ext.json
index edc63f2f..f4ac4e04 100644
--- a/adapters/beachfront/beachfronttest/supplemental/bidfloor-test-imp-wins-adm-video.json
+++ b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-zero-by-min-ext.json
@@ -4,10 +4,9 @@
     "imp": [
       {
         "id": "video1",
-        "bidfloor": 45.21,
         "ext": {
           "bidder": {
-            "bidfloor": 103.01,
+            "bidfloor": 0.01,
             "appId": "videoAppId1"
           }
         },
@@ -44,7 +43,6 @@
                   "video/mp4"
                 ]
               },
-              "bidfloor": 45.21,
               "id": "video1",
               "secure": 1
             }
@@ -72,15 +70,15 @@
                 {
                   "id": "5fd7c8a6ff2f1f0d42ee6427",
                   "impid": "video1",
-                  "price": 200,
+                  "price": 20,
                   "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
                   "adid": "1088",
                   "adomain": [
                     "beachfront.io"
                   ],
+                  "cat":["IAB2"],
                   "cid": "277",
                   "crid": "532",
-                  "cat":["IAB2"],
                   "w": 300,
                   "h": 250,
                   "ext": {
@@ -104,7 +102,7 @@
           "bid": {
             "id": "video1AdmVideo",
             "impid": "video1",
-            "price": 200,
+            "price": 20,
             "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
             "adid": "1088",
             "adomain": [
diff --git a/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-zero-by-min-imp.json b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-zero-by-min-imp.json
new file mode 100644
index 00000000..a574e99b
--- /dev/null
+++ b/adapters/beachfront/beachfronttest/supplemental/currency-adm-video-zero-by-min-imp.json
@@ -0,0 +1,125 @@
+{
+  "mockBidRequest": {
+    "id": "adm-video",
+    "imp": [
+      {
+        "id": "video1",
+        "bidfloor": 0.01,
+        "ext": {
+          "bidder": {
+            "appId": "videoAppId1"
+          }
+        },
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "context": "instream",
+          "w": 300,
+          "h": 250
+        }
+      }
+    ],
+    "site": {
+      "page": "https://some.domain.us/some/page.html"
+    },
+    "device":{
+      "ip":"192.168.168.168"
+    }
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://qa.beachrtb.com/bid.json?exchange_id=videoAppId1",
+        "body": {
+          "id": "adm-video",
+          "imp": [
+            {
+              "video": {
+                "w": 300,
+                "h": 250,
+                "mimes": [
+                  "video/mp4"
+                ]
+              },
+              "id": "video1",
+              "secure": 1
+            }
+          ],
+          "site": {
+            "page": "https://some.domain.us/some/page.html",
+            "domain": "some.domain.us"
+          },
+          "cur": [
+            "USD"
+          ],
+          "device":{
+            "devicetype": 2,
+            "ip":"192.168.168.168"
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "adm-video",
+          "seatBid": [
+            {
+              "bid": [
+                {
+                  "id": "5fd7c8a6ff2f1f0d42ee6427",
+                  "impid": "video1",
+                  "price": 20,
+                  "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
+                  "adid": "1088",
+                  "adomain": [
+                    "beachfront.io"
+                  ],
+                  "cat":["IAB2"],
+                  "cid": "277",
+                  "crid": "532",
+                  "w": 300,
+                  "h": 250,
+                  "ext": {
+                    "duration": 30
+                  }
+                }
+              ],
+              "seat": "bfio-s-1"
+            }
+          ]
+        }
+      }
+    }
+  ],
+
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "video1AdmVideo",
+            "impid": "video1",
+            "price": 20,
+            "adm": "<VAST version=\"2.0\"><Ad><Wrapper>http://example.com/vast.xml</Wrapper></Ad></VAST>",
+            "adid": "1088",
+            "adomain": [
+              "beachfront.io"
+            ],
+            "cid": "277",
+            "crid": "532",
+            "cat":["IAB2"],
+            "w": 300,
+            "h": 250,
+            "ext": {
+              "duration": 30
+            }
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/beachfront/beachfronttest/supplemental/six-nine-combo.json b/adapters/beachfront/beachfronttest/supplemental/six-nine-combo.json
index 1779248e..294bd13d 100644
--- a/adapters/beachfront/beachfronttest/supplemental/six-nine-combo.json
+++ b/adapters/beachfront/beachfronttest/supplemental/six-nine-combo.json
@@ -200,7 +200,7 @@
           "dnt": 0,
           "user": {},
           "adapterName": "BF_PREBID_S2S",
-          "adapterVersion": "0.9.2",
+          "adapterVersion": "1.0.0",
           "ip": "255.255.255.255",
           "requestId": "six-nine-combo",
           "schain": {
@@ -258,6 +258,7 @@
               "id": "ADMVideoWithBannerImp1",
               "secure": 0,
               "bidfloor": 1.01,
+              "bidfloorcur": "USD",
               "video": {
                 "mimes": [
                   "video/mp4"
@@ -317,6 +318,7 @@
               "id": "ADMVideoWithBannerImp2",
               "secure": 0,
               "bidfloor": 1.01,
+              "bidfloorcur": "USD",
               "video": {
                 "mimes": [
                   "video/mp4"
@@ -375,6 +377,7 @@
             {
               "id": "ADMVideoImp6",
               "bidfloor": 1.01,
+              "bidfloorcur": "USD",
               "secure": 0,
               "video": {
                 "mimes": [
@@ -435,6 +438,7 @@
             {
               "id": "NURLVideoImp3",
               "bidfloor": 1.01,
+              "bidfloorcur": "USD",
               "video": {
                 "mimes": [
                   "video/mp4"
diff --git a/adapters/beachfront/beachfronttest/supplemental/two-four-combo.json b/adapters/beachfront/beachfronttest/supplemental/two-four-combo.json
index 75f37188..7310d0b4 100644
--- a/adapters/beachfront/beachfronttest/supplemental/two-four-combo.json
+++ b/adapters/beachfront/beachfronttest/supplemental/two-four-combo.json
@@ -7,7 +7,8 @@
         "ext": {
           "bidder": {
             "videoResponseType": "adm",
-            "bidfloor": 1.01,
+            "bidfloor": 1.02,
+            "bidfloorcur": "USD",
             "appIds": {
               "banner": "bannerAppId1",
               "video": "videoAppId1"
@@ -36,6 +37,7 @@
           "bidder": {
             "videoResponsetype": "nurl",
             "bidfloor": 1.01,
+            "bidfloorcur": "USD",
             "appIds": {
               "banner": "bannerAppId2",
               "video": "videoAppId1"
@@ -75,7 +77,7 @@
             {
               "slot":"ComboADMVideoWithBannerImp1",
               "id":"bannerAppId1",
-              "bidfloor":1.01,
+              "bidfloor":1.02,
               "sizes":[
                 {
                   "w":300,
@@ -110,7 +112,7 @@
 
           },
           "adapterName":"BF_PREBID_S2S",
-          "adapterVersion":"0.9.2",
+          "adapterVersion":"1.0.0",
           "ip":"255.255.255.255",
           "requestId":"two-four-combo",
           "schain": {
@@ -159,7 +161,8 @@
                 "w":300,
                 "h":400
               },
-              "bidfloor":1.01,
+              "bidfloor":1.02,
+              "bidfloorcur": "USD",
               "secure":0
             }
           ],
@@ -229,6 +232,7 @@
                 "h":150
               },
               "bidfloor":1.01,
+              "bidfloorcur": "USD",
               "secure":0
             }
           ],
diff --git a/adapters/bizzclick/bizzclick_test.go b/adapters/bizzclick/bizzclick_test.go
new file mode 100644
index 00000000..baebb540
--- /dev/null
+++ b/adapters/bizzclick/bizzclick_test.go
@@ -0,0 +1,28 @@
+package bizzclick
+
+import (
+	"testing"
+
+	"github.com/prebid/prebid-server/adapters/adapterstest"
+	"github.com/prebid/prebid-server/config"
+	"github.com/prebid/prebid-server/openrtb_ext"
+	"github.com/stretchr/testify/assert"
+)
+
+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}}"})
+
+	if buildErr != nil {
+		t.Fatalf("Builder returned unexpected error %v", buildErr)
+	}
+
+	adapterstest.RunJSONBidderTest(t, "bizzclicktest", bidder)
+}
+
+func TestEndpointTemplateMalformed(t *testing.T) {
+	_, buildErr := Builder(openrtb_ext.BidderBizzclick, config.Adapter{
+		Endpoint: "{{Malformed}}"})
+
+	assert.Error(t, buildErr)
+}
diff --git a/adapters/bizzclick/bizzclicktest/exemplary/banner-app.json b/adapters/bizzclick/bizzclicktest/exemplary/banner-app.json
new file mode 100644
index 00000000..1ba1d155
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/exemplary/banner-app.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.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"
+            ],
+            "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/banner-web.json b/adapters/bizzclick/bizzclicktest/exemplary/banner-web.json
new file mode 100644
index 00000000..5c2baba6
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/exemplary/banner-web.json
@@ -0,0 +1,187 @@
+{
+  "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"
+    },
+    "site": {
+      "page": "test.com",
+      "publisher": {
+        "id": "123456789"
+      }
+    },
+    "imp": [
+      {
+        "id": "some-impression-id1",
+        "tagid": "ogTAGID",
+        "banner": {
+          "w":320,
+          "h":50
+        },
+        "ext": {
+          "bidder": {
+            "accountId": "accountId",
+            "placementId": "placementId"
+          }
+        }
+      },     
+       {
+        "id": "some-impression-id2",
+        "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.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-id1",
+              "tagid": "ogTAGID",
+              "banner": {
+                "w":320,
+                "h":50
+              }
+            },
+            {
+              "id": "some-impression-id2",
+              "tagid": "ogTAGID",
+              "banner": {
+                "w":320,
+                "h":50
+              }
+            }
+          ],
+          "site": {
+            "page": "test.com",
+            "publisher": {
+              "id": "123456789"
+            }
+          },
+          "user": {
+            "buyeruid": "awesome-user"
+          },
+          "tmax": 1000
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "awesome-resp-id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+                  "impid": "some-impression-id1",
+                  "price": 3.5,
+                  "adm": "awesome-markup",
+                  "adomain": [
+                    "awesome.com"
+                  ],
+                  "crid": "20",
+                  "w": 320,
+                  "h": 50
+                },
+                {
+                  "id": "a3ae1b4e2fc24a4fb45540082e98e162",
+                  "impid": "some-impression-id2",
+                  "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": "some-impression-id1",
+            "price": 3.5,
+            "adm": "awesome-markup",
+            "crid": "20",
+            "adomain": [
+              "awesome.com"
+            ],
+            "w": 320,
+            "h": 50
+          },
+          "type": "banner"
+        },
+        {
+          "bid":  {
+            "id": "a3ae1b4e2fc24a4fb45540082e98e162",
+            "impid": "some-impression-id2",
+            "price": 3.5,
+            "adm": "awesome-markup",
+            "crid": "20",
+            "adomain": [
+              "awesome.com"
+            ],
+            "w": 320,
+            "h": 50
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/bizzclick/bizzclicktest/exemplary/native-app.json b/adapters/bizzclick/bizzclicktest/exemplary/native-app.json
new file mode 100644
index 00000000..764f6006
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/exemplary/native-app.json
@@ -0,0 +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",
+        "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"
+            }
+          }
+        }
+      ]
+    },
+    "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",
+                "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
new file mode 100644
index 00000000..04a33e6f
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/exemplary/native-web.json
@@ -0,0 +1,133 @@
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "device": {
+      "ua": "test-user-agent",
+      "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245",
+      "language": "en",
+      "dnt": 0
+    },
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "site": {
+      "page": "test.com",
+      "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"
+          }
+        }
+      }
+    ]
+  },
+  "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": [
+            "2607:fb90:f27:4512:d800:cb23:a603:e245"
+          ]
+        },
+        "uri": "http://us.example.com/bid?rtb_seat_id=placementId&secret_key=accountId",
+        "body": {
+          "id": "some-request-id",
+          "device": {
+            "ua": "test-user-agent",
+            "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245",
+            "language": "en",
+            "dnt": 0
+          },
+          "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}}}"
+              }
+            }
+          ],
+          "site": {
+            "page": "test.com",
+            "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"
+                }
+              ],
+              "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"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/bizzclick/bizzclicktest/exemplary/video-app.json b/adapters/bizzclick/bizzclicktest/exemplary/video-app.json
new file mode 100644
index 00000000..18d38b8e
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/exemplary/video-app.json
@@ -0,0 +1,159 @@
+{
+  "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",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "w": 640,
+          "h": 480,
+          "minduration": 120,
+          "maxduration": 150
+        },
+        "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.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",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 120,
+                "maxduration": 150,
+                "w": 640,
+                "h": 480
+              },
+              "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",
+                  "w": 1280,
+                  "h": 720
+                }
+              ],
+              "seat": "bizzclick"
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids":[
+        {
+          "bid":  {
+            "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+            "impid": "some-impression-id",
+            "price": 3.5,
+            "adm": "awesome-markup",
+            "crid": "20",
+            "adomain": [
+              "awesome.com"
+            ],
+            "w": 1280,
+            "h": 720
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/bizzclick/bizzclicktest/exemplary/video-web.json b/adapters/bizzclick/bizzclicktest/exemplary/video-web.json
new file mode 100644
index 00000000..57ec0641
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/exemplary/video-web.json
@@ -0,0 +1,157 @@
+{
+  "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"
+    },
+    "site": {
+      "page": "test.com",
+      "publisher": {
+        "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"
+          }
+        }
+      }
+    ]
+  },
+  "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",
+              "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": 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",
+                  "w": 1280,
+                  "h": 720,
+                  "ext": {
+                    "prebid": {
+                      "type": "video"
+                    }
+                  }
+                }
+              ],
+              "seat": "bizzclick"
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+            "impid": "some-impression-id",
+            "price": 3.5,
+            "adm": "awesome-markup",
+            "adomain": [
+              "awesome.com"
+            ],
+            "crid": "20",
+            "w": 1280,
+            "h": 720,
+            "ext": {
+              "prebid": {
+                "type": "video"
+              }
+            }
+          },
+          "type":"video"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/bizzclick/bizzclicktest/supplemental/empty-seatbid-array.json b/adapters/bizzclick/bizzclicktest/supplemental/empty-seatbid-array.json
new file mode 100644
index 00000000..7b244c40
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/supplemental/empty-seatbid-array.json
@@ -0,0 +1,131 @@
+{
+  "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",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "w": 640,
+          "h": 480,
+          "minduration": 120,
+          "maxduration": 150
+        },
+        "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.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",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 120,
+                "maxduration": 150,
+                "w": 640,
+                "h": 480
+              },
+              "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": [
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+    "mockResponse": {
+      "status": 200,
+      "body": "invalid response"
+    },
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Empty SeatBid array",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/bizzclick/bizzclicktest/supplemental/invalid-bizzclick-ext-object.json b/adapters/bizzclick/bizzclicktest/supplemental/invalid-bizzclick-ext-object.json
new file mode 100644
index 00000000..77752d01
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/supplemental/invalid-bizzclick-ext-object.json
@@ -0,0 +1,29 @@
+{
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "ext.bidder not provided",
+      "comparison": "literal"
+    }
+  ],
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "some-impression-id",
+        "tagid": "my-adcode",
+        "video": {
+          "mimes": ["video/mp4"],
+          "w": 640,
+          "h": 480,
+          "minduration": 120,
+          "maxduration": 150
+        },
+        "ext": "Awesome"
+      }
+    ],
+    "site": {
+      "page": "test.com"
+    }
+  },
+  "httpCalls": []
+}
diff --git a/adapters/bizzclick/bizzclicktest/supplemental/invalid-response.json b/adapters/bizzclick/bizzclicktest/supplemental/invalid-response.json
new file mode 100644
index 00000000..57f36d3a
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/supplemental/invalid-response.json
@@ -0,0 +1,112 @@
+
+{
+  "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.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"
+          ],
+          "publisher": {
+            "id": "123456789"
+          }
+        },
+        "user": {
+          "buyeruid": "awesome-user"
+        },
+        "tmax": 1000
+      }
+    },
+    "mockResponse": {
+      "status": 200,
+      "body": "invalid response"
+    }
+  }],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Bad Server Response",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/bizzclick/bizzclicktest/supplemental/status-code-bad-request.json b/adapters/bizzclick/bizzclicktest/supplemental/status-code-bad-request.json
new file mode 100644
index 00000000..f0a3b91a
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/supplemental/status-code-bad-request.json
@@ -0,0 +1,93 @@
+
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "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",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "w": 640,
+          "h": 480,
+          "minduration": 120,
+          "maxduration": 150
+        },
+        "ext": {
+          "bidder": {
+            "accountId": "accountId",
+            "placementId": "placementId"
+          }
+        }
+      }
+    ]
+  },
+
+  "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
+            },
+            "tagid": "ogTAGID"
+          }
+        ],
+        "app":  {
+          "publisher": {
+            "id": "123456789"
+          },
+          "cat": [
+            "IAB22-1"
+          ],
+          "bundle": "com.app.awesome",
+          "name": "Awesome App",
+          "domain": "awesomeapp.com",
+          "id": "123456789"
+        },
+        "user": {
+          "buyeruid": "awesome-user"
+        },
+        "tmax": 1000
+      }
+    },
+    "mockResponse": {
+      "status": 400
+    }
+  }],
+  "expectedBidResponses": [],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Unexpected status code: [ 400 ]",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/bizzclick/bizzclicktest/supplemental/status-code-no-content.json b/adapters/bizzclick/bizzclicktest/supplemental/status-code-no-content.json
new file mode 100644
index 00000000..62aecf58
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/supplemental/status-code-no-content.json
@@ -0,0 +1,69 @@
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "site": {
+      "page": "test.com",
+      "publisher": {
+        "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"
+        }
+      }
+    }]
+  },
+
+  "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
+      }
+    },
+    "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
new file mode 100644
index 00000000..398f0b67
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/supplemental/status-code-other-error.json
@@ -0,0 +1,79 @@
+
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "site": {
+      "page": "test.com",
+      "publisher": {
+        "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"
+          }
+        }
+      }
+    ]
+  },
+
+  "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
+      }
+    },
+    "mockResponse": {
+      "status": 306
+    }
+  }],
+  "expectedBidResponses": [],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Unexpected status code: [ 306 ]. Run with request.debug = 1 for more info",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/bizzclick/bizzclicktest/supplemental/status-code-service-unavailable.json b/adapters/bizzclick/bizzclicktest/supplemental/status-code-service-unavailable.json
new file mode 100644
index 00000000..733b5f3f
--- /dev/null
+++ b/adapters/bizzclick/bizzclicktest/supplemental/status-code-service-unavailable.json
@@ -0,0 +1,79 @@
+
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "site": {
+      "page": "test.com",
+      "publisher": {
+        "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"
+          }
+        }
+      }
+    ]
+  },
+
+  "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
+      }
+    },
+    "mockResponse": {
+      "status": 503
+    }
+  }],
+  "expectedBidResponses": [],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Something went wrong, please contact your Account Manager. Status Code: [ 503 ] ",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/bizzclick/params_test.go b/adapters/bizzclick/params_test.go
new file mode 100644
index 00000000..34211b00
--- /dev/null
+++ b/adapters/bizzclick/params_test.go
@@ -0,0 +1,50 @@
+package bizzclick
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+var validParams = []string{
+	`{  "accountId": "hash",  "placementId": "hash"}`,
+}
+
+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.BidderBizzclick, json.RawMessage(validParam)); err != nil {
+			t.Errorf("Schema rejected Bizzclick params: %s", validParam)
+		}
+	}
+}
+
+var invalidParams = []string{
+	``,
+	`null`,
+	`true`,
+	`5`,
+	`4.2`,
+	`[]`,
+	`{}`,
+	`{"adCode": "string", "seatCode": 5, "originalPublisherid": "string"}`,
+	`{  "accountid": "" }`,
+}
+
+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.BidderBizzclick, json.RawMessage(invalidParam)); err == nil {
+			t.Errorf("Schema allowed unexpected params: %s", invalidParam)
+		}
+	}
+}
diff --git a/adapters/marsmedia/marsmediatest/exemplary/simple-banner-int-param.json b/adapters/marsmedia/marsmediatest/exemplary/simple-banner-int-param.json
new file mode 100644
index 00000000..4804a873
--- /dev/null
+++ b/adapters/marsmedia/marsmediatest/exemplary/simple-banner-int-param.json
@@ -0,0 +1,106 @@
+{
+    "mockBidRequest": {
+      "id": "test-request-id",
+      "imp": [
+        {
+          "id": "test-imp-id",
+          "at" : 1,
+          "banner": {
+            "format": [
+              {
+                  "w": 300,
+                  "h": 250
+              }
+            ]
+          },
+          "ext": {
+            "bidder": {
+              "zoneId": 9999
+            }
+          }
+        }
+      ]
+    },
+  
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "uri": "http://bid306.rtbsrv.com/bidder/?bid=f3xtet&zone=9999",
+          "body": {
+            "id": "test-request-id",
+            "at" : 1,
+            "imp": [
+              {
+                "id": "test-imp-id",
+                "banner": {
+                  "format": [
+                    {
+                        "w": 300,
+                        "h": 250
+                    }
+                  ],
+                  "w": 300,
+                  "h": 250
+                },
+                "ext": {
+                  "bidder": {
+                    "zoneId": 9999
+                  }
+                }
+              }
+            ]
+          }
+        },
+        "mockResponse": {
+          "status": 200,
+          "body": {
+            "id": "test-request-id",
+            "seatbid": [
+              {
+                "seat": "marsmedia",
+                "bid": [{
+                  "id": "1",
+                  "impid": "test-imp-id",
+                  "price": 1.1,
+                  "adid": "17586",
+                  "adm": "some-test-ad",
+                  "nurl" : "some-test-nurl",
+                  "iurl" : "some-test-iurl",
+                  "adomain": ["wooga.com"],
+                  "cid": "17586",
+                  "crid": "17586",
+                  "h": 250,
+                  "w": 300
+                }]
+              }
+            ],
+            "bidid": "5778926625248726496",
+            "cur": "USD"
+          }
+        }
+      }
+    ],
+  
+    "expectedBidResponses": [
+      {
+        "bids": [{
+          "bid": {
+            "id": "1",
+            "impid": "test-imp-id",
+            "price": 1.1,
+            "adm": "some-test-ad",
+            "adid": "17586",
+            "adomain": ["wooga.com"],
+            "cid": "17586",
+            "crid": "17586",
+            "nurl" : "some-test-nurl",
+            "iurl" : "some-test-iurl",
+            "h": 250,
+            "w": 300
+          },
+          "type": "banner"
+        }]
+      }
+    ]
+  }
+  
\ No newline at end of file
diff --git a/adapters/marsmedia/marsmediatest/supplemental/missing-param.json b/adapters/marsmedia/marsmediatest/supplemental/missing-param.json
index b88fba5a..e68b3f52 100644
--- a/adapters/marsmedia/marsmediatest/supplemental/missing-param.json
+++ b/adapters/marsmedia/marsmediatest/supplemental/missing-param.json
@@ -27,7 +27,7 @@
   },
   "expectedMakeRequestsErrors": [
     {
-      "value": "zoneId is empty",
+      "value": "ext.bidder.zoneId not provided",
       "comparison": "literal"
     }
   ]
diff --git a/adapters/marsmedia/params_test.go b/adapters/marsmedia/params_test.go
index 78acd72e..4a91ed6d 100644
--- a/adapters/marsmedia/params_test.go
+++ b/adapters/marsmedia/params_test.go
@@ -41,10 +41,10 @@ func TestInvalidParams(t *testing.T) {
 
 var validParams = []string{
 	`{"zoneId": "9999"}`,
+	`{"zoneId": 9999}`,
 }
 
 var invalidParams = []string{
-	`{"zoneId": 100}`,
 	`{"zoneId": true}`,
 	``,
 	`null`,
diff --git a/adapters/openrtb_util_test.go b/adapters/openrtb_util_test.go
index e09149a7..4a5d33b0 100644
--- a/adapters/openrtb_util_test.go
+++ b/adapters/openrtb_util_test.go
@@ -2,116 +2,100 @@ package adapters
 
 import (
 	"encoding/json"
-	"github.com/mxmCherry/openrtb/v15/openrtb2"
-	"reflect"
+	"errors"
 	"testing"
+
+	"github.com/mxmCherry/openrtb/v15/openrtb2"
+	"github.com/stretchr/testify/assert"
 )
 
-func TestExtractAdapterReqBidderParams(t *testing.T) {
-	type args struct {
-		bidRequest *openrtb2.BidRequest
-	}
+func TestExtractAdapterReqBidderParamsMap(t *testing.T) {
 	tests := []struct {
-		name    string
-		args    args
-		want    map[string]json.RawMessage
-		wantErr bool
+		name            string
+		givenBidRequest *openrtb2.BidRequest
+		want            map[string]json.RawMessage
+		wantErr         error
 	}{
 		{
-			name: "extract bidder params from nil req",
-			args: args{
-				bidRequest: nil,
-			},
-			want:    nil,
-			wantErr: true,
+			name:            "nil req",
+			givenBidRequest: nil,
+			want:            nil,
+			wantErr:         errors.New("error bidRequest should not be nil"),
 		},
 		{
-			name: "extract bidder params from nil req.Ext",
-			args: args{
-				bidRequest: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{}}`)},
-			},
-			want:    nil,
-			wantErr: false,
+			name:            "nil req.ext",
+			givenBidRequest: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{}}`)},
+			want:            nil,
+			wantErr:         nil,
 		},
 		{
-			name: "extract bidder params from req.Ext for input request in adapter code",
-			args: args{
-				bidRequest: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{"bidderparams": {"profile": 1234, "version": 1}}}`)},
-			},
-			want:    map[string]json.RawMessage{"profile": json.RawMessage(`1234`), "version": json.RawMessage(`1`)},
-			wantErr: false,
+			name:            "malformed req.ext",
+			givenBidRequest: &openrtb2.BidRequest{Ext: json.RawMessage("malformed")},
+			want:            nil,
+			wantErr:         errors.New("error decoding Request.ext : invalid character 'm' looking for beginning of value"),
+		},
+		{
+			name:            "extract bidder params from req.Ext for input request in adapter code",
+			givenBidRequest: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{"bidderparams": {"profile": 1234, "version": 1}}}`)},
+			want:            map[string]json.RawMessage{"profile": json.RawMessage(`1234`), "version": json.RawMessage(`1`)},
+			wantErr:         nil,
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := ExtractAdapterReqBidderParams(tt.args.bidRequest)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("ExtractReqExtBidderParams() error = %v, wantErr = %v", err, tt.wantErr)
-				return
-			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("ExtractReqExtBidderParams() got = %v, want = %v", got, tt.want)
-			}
+			got, err := ExtractReqExtBidderParamsMap(tt.givenBidRequest)
+			assert.Equal(t, tt.wantErr, err, "err")
+			assert.Equal(t, tt.want, got, "result")
 		})
 	}
 }
 
-func TestExtractReqExtBidderParams(t *testing.T) {
-	type args struct {
-		request *openrtb2.BidRequest
-	}
+func TestExtractReqExtBidderParamsMap(t *testing.T) {
 	tests := []struct {
-		name    string
-		args    args
-		want    map[string]map[string]json.RawMessage
-		wantErr bool
+		name            string
+		givenBidRequest *openrtb2.BidRequest
+		want            map[string]map[string]json.RawMessage
+		wantErr         error
 	}{
 		{
-			name: "extract bidder params from nil req",
-			args: args{
-				request: nil,
-			},
-			want:    nil,
-			wantErr: true,
+			name:            "nil req",
+			givenBidRequest: nil,
+			want:            nil,
+			wantErr:         errors.New("error bidRequest should not be nil"),
 		},
 		{
-			name: "extract bidder params from nil req.Ext.prebid",
-			args: args{
-				request: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{}}`)},
-			},
-			want:    nil,
-			wantErr: false,
+			name:            "nil req.ext",
+			givenBidRequest: &openrtb2.BidRequest{Ext: nil},
+			want:            nil,
+			wantErr:         nil,
 		},
 		{
-			name: "extract bidder params from nil req.Ext",
-			args: args{
-				request: &openrtb2.BidRequest{Ext: nil},
-			},
-			want:    nil,
-			wantErr: false,
+			name:            "malformed req.ext",
+			givenBidRequest: &openrtb2.BidRequest{Ext: json.RawMessage("malformed")},
+			want:            nil,
+			wantErr:         errors.New("error decoding Request.ext : invalid character 'm' looking for beginning of value"),
 		},
 		{
-			name: "extract bidder params from req.Ext for input request before adapter code",
-			args: args{
-				request: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{"bidderparams": {"pubmatic": {"profile": 1234, "version": 1}, "appnexus": {"key1": 123, "key2": {"innerKey1":"innerValue1"} } }}}`)},
-			},
+			name:            "nil req.ext.prebid",
+			givenBidRequest: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{}}`)},
+			want:            nil,
+			wantErr:         nil,
+		},
+		{
+			name:            "extract bidder params from req.Ext for input request before adapter code",
+			givenBidRequest: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{"bidderparams": {"pubmatic": {"profile": 1234, "version": 1}, "appnexus": {"key1": 123, "key2": {"innerKey1":"innerValue1"} } }}}`)},
 			want: map[string]map[string]json.RawMessage{
 				"pubmatic": {"profile": json.RawMessage(`1234`), "version": json.RawMessage(`1`)},
 				"appnexus": {"key1": json.RawMessage(`123`), "key2": json.RawMessage(`{"innerKey1":"innerValue1"}`)},
 			},
-			wantErr: false,
+			wantErr: nil,
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := ExtractReqExtBidderParams(tt.args.request)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("ExtractReqExtBidderParams() error = %v, wantErr = %v", err, tt.wantErr)
-				return
-			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("ExtractReqExtBidderParams() got = %v, want = %v", got, tt.want)
-			}
+			got, err := ExtractReqExtBidderParamsEmbeddedMap(tt.givenBidRequest)
+			assert.Equal(t, tt.wantErr, err, "err")
+			assert.Equal(t, tt.want, got, "result")
 		})
 	}
 }
diff --git a/adapters/orbidder/orbidder_test.go b/adapters/orbidder/orbidder_test.go
index 0eaed23a..bbda1c06 100644
--- a/adapters/orbidder/orbidder_test.go
+++ b/adapters/orbidder/orbidder_test.go
@@ -2,6 +2,10 @@ package orbidder
 
 import (
 	"encoding/json"
+	"errors"
+	"github.com/mxmCherry/openrtb/v15/openrtb2"
+	"github.com/prebid/prebid-server/adapters"
+	"github.com/stretchr/testify/mock"
 	"testing"
 
 	"github.com/prebid/prebid-server/adapters/adapterstest"
@@ -22,6 +26,16 @@ func TestUnmarshalOrbidderExtImp(t *testing.T) {
 	}, impExt)
 }
 
+func TestPreprocessExtensions(t *testing.T) {
+	for name, tc := range testCasesExtension {
+		t.Run(name, func(t *testing.T) {
+			imp := tc.imp
+			err := preprocessExtensions(&imp)
+			tc.assertError(t, err)
+		})
+	}
+}
+
 func TestJsonSamples(t *testing.T) {
 	bidder, buildErr := Builder(openrtb_ext.BidderOrbidder, config.Adapter{
 		Endpoint: "https://orbidder-test"})
@@ -32,3 +46,136 @@ func TestJsonSamples(t *testing.T) {
 
 	adapterstest.RunJSONBidderTest(t, "orbiddertest", bidder)
 }
+
+var testCasesCurrency = map[string]struct {
+	imp         openrtb2.Imp
+	setMock     func(m *mock.Mock)
+	expectedImp openrtb2.Imp
+	assertError func(t assert.TestingT, err error, msgAndArgs ...interface{}) bool
+}{
+	"EUR: no bidfloor, no currency": {
+		imp: openrtb2.Imp{
+			BidFloor:    0,
+			BidFloorCur: "",
+		},
+		setMock: func(m *mock.Mock) {},
+		expectedImp: openrtb2.Imp{
+			BidFloor:    0,
+			BidFloorCur: "EUR",
+		},
+		assertError: assert.NoError,
+	},
+	"EUR: bidfloor, no currency": {
+		imp: openrtb2.Imp{
+			BidFloor:    1,
+			BidFloorCur: "",
+		},
+		setMock: func(m *mock.Mock) {},
+		expectedImp: openrtb2.Imp{
+			BidFloor:    1,
+			BidFloorCur: "EUR",
+		},
+		assertError: assert.NoError,
+	},
+	"EUR: bidfloor and currency": {
+		imp: openrtb2.Imp{
+			BidFloor:    1,
+			BidFloorCur: "EUR",
+		},
+		setMock: func(m *mock.Mock) {},
+		expectedImp: openrtb2.Imp{
+			BidFloor:    1,
+			BidFloorCur: "EUR",
+		},
+		assertError: assert.NoError,
+	},
+	"USD: bidfloor with currency": {
+		imp: openrtb2.Imp{
+			BidFloor:    1,
+			BidFloorCur: "USD",
+		},
+		setMock: func(m *mock.Mock) {
+			m.On("GetRate", "USD", "EUR").Return(2.5, nil)
+		},
+		expectedImp: openrtb2.Imp{
+			BidFloor:    2.5,
+			BidFloorCur: "EUR",
+		},
+		assertError: assert.NoError,
+	},
+	"USD: no bidfloor": {
+		imp: openrtb2.Imp{
+			BidFloor:    0,
+			BidFloorCur: "USD",
+		},
+		setMock: func(m *mock.Mock) {},
+		expectedImp: openrtb2.Imp{
+			BidFloor:    0,
+			BidFloorCur: "EUR",
+		},
+		assertError: assert.NoError,
+	},
+	"ABC: invalid currency code": {
+		imp: openrtb2.Imp{
+			BidFloor:    1,
+			BidFloorCur: "ABC",
+		},
+		setMock: func(m *mock.Mock) {
+			m.On("GetRate", "ABC", "EUR").Return(0.0, errors.New("currency conversion error"))
+		},
+		expectedImp: openrtb2.Imp{
+			BidFloor:    1,
+			BidFloorCur: "ABC",
+		},
+		assertError: assert.Error,
+	},
+}
+
+var testCasesExtension = map[string]struct {
+	imp         openrtb2.Imp
+	assertError func(t assert.TestingT, err error, msgAndArgs ...interface{}) bool
+}{
+	"Valid Orbidder Extension": {
+		imp: openrtb2.Imp{
+			Ext: json.RawMessage(`{"bidder":{"accountId":"orbidder-test", "placementId":"center-banner", "bidfloor": 0.1}}`),
+		},
+		assertError: assert.NoError,
+	},
+	"Invalid Orbidder Extension": {
+		imp: openrtb2.Imp{
+			Ext: json.RawMessage(`{"there's'":{"something":"strange", "in the":"neighbourhood", "who you gonna call?": 0.1}}`),
+		},
+		assertError: assert.Error,
+	},
+}
+
+func TestPreprocessBidFloorCurrency(t *testing.T) {
+	for name, tc := range testCasesCurrency {
+		t.Run(name, func(t *testing.T) {
+			imp := tc.imp
+			mockConversions := &mockCurrencyConversion{}
+			tc.setMock(&mockConversions.Mock)
+			extraRequestInfo := adapters.ExtraRequestInfo{
+				CurrencyConversions: mockConversions,
+			}
+			err := preprocessBidFloorCurrency(&imp, &extraRequestInfo)
+			assert.True(t, mockConversions.AssertExpectations(t))
+			tc.assertError(t, err)
+			assert.Equal(t, tc.expectedImp, imp)
+		})
+	}
+}
+
+type mockCurrencyConversion struct {
+	mock.Mock
+}
+
+func (m *mockCurrencyConversion) GetRate(from string, to string) (float64, error) {
+	args := m.Called(from, to)
+	return args.Get(0).(float64), args.Error(1)
+}
+
+func (m *mockCurrencyConversion) GetRates() *map[string]map[string]float64 {
+	args := m.Called()
+	return args.Get(0).(*map[string]map[string]float64)
+}
diff --git a/adapters/orbidder/orbiddertest/exemplary/simple-app-banner.json b/adapters/orbidder/orbiddertest/exemplary/simple-app-banner.json
index 8697bff3..2315a52c 100644
--- a/adapters/orbidder/orbiddertest/exemplary/simple-app-banner.json
+++ b/adapters/orbidder/orbiddertest/exemplary/simple-app-banner.json
@@ -51,6 +51,7 @@
                   }
                 ]
               },
+              "bidfloorcur": "EUR",
               "ext": {
                 "bidder": {
                   "accountId": "orbidder-test",
diff --git a/adapters/orbidder/orbiddertest/supplemental/dsp-bad-request-example.json b/adapters/orbidder/orbiddertest/supplemental/dsp-bad-request-example.json
index 69496c4f..dc199d24 100644
--- a/adapters/orbidder/orbiddertest/supplemental/dsp-bad-request-example.json
+++ b/adapters/orbidder/orbiddertest/supplemental/dsp-bad-request-example.json
@@ -51,6 +51,7 @@
                   }
                 ]
               },
+              "bidfloorcur": "EUR",
               "ext": {
                 "bidder": {
                   "accountId": "orbidder-test",
diff --git a/adapters/orbidder/orbiddertest/supplemental/dsp-bad-response-example.json b/adapters/orbidder/orbiddertest/supplemental/dsp-bad-response-example.json
index d1c57a54..61e70d31 100644
--- a/adapters/orbidder/orbiddertest/supplemental/dsp-bad-response-example.json
+++ b/adapters/orbidder/orbiddertest/supplemental/dsp-bad-response-example.json
@@ -51,6 +51,7 @@
                   }
                 ]
               },
+              "bidfloorcur": "EUR",
               "ext": {
                 "bidder": {
                   "accountId": "orbidder-test",
diff --git a/adapters/orbidder/orbiddertest/supplemental/dsp-internal-server-error-example.json b/adapters/orbidder/orbiddertest/supplemental/dsp-internal-server-error-example.json
index 20ea36ab..66a766a9 100644
--- a/adapters/orbidder/orbiddertest/supplemental/dsp-internal-server-error-example.json
+++ b/adapters/orbidder/orbiddertest/supplemental/dsp-internal-server-error-example.json
@@ -51,6 +51,7 @@
                   }
                 ]
               },
+              "bidfloorcur": "EUR",
               "ext": {
                 "bidder": {
                   "accountId": "orbidder-test",
diff --git a/adapters/orbidder/orbiddertest/supplemental/dsp-invalid-accountid-example.json b/adapters/orbidder/orbiddertest/supplemental/dsp-invalid-accountid-example.json
index 6bc0482d..7944db44 100644
--- a/adapters/orbidder/orbiddertest/supplemental/dsp-invalid-accountid-example.json
+++ b/adapters/orbidder/orbiddertest/supplemental/dsp-invalid-accountid-example.json
@@ -51,6 +51,7 @@
                   }
                 ]
               },
+              "bidfloorcur": "EUR",
               "ext": {
                 "bidder": {
                   "accountId": "orbidder-test",
diff --git a/adapters/orbidder/orbiddertest/supplemental/empty-imp-request-error.json b/adapters/orbidder/orbiddertest/supplemental/empty-imp-request-error.json
deleted file mode 100644
index 0c5cf6d2..00000000
--- a/adapters/orbidder/orbiddertest/supplemental/empty-imp-request-error.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "test-request-id",
-    "imp": [
-    ],
-    "app": {
-      "bundle": "com.prebid"
-    },
-    "device": {
-      "ifa":"87857b31-8942-4646-ae80-ab9c95bf3fab"
-    }
-  },
-  "expectedMakeRequestsErrors": [
-    {
-      "value": "No impressions in request",
-      "comparison": "literal"
-    }
-  ]
-}
diff --git a/adapters/orbidder/orbiddertest/supplemental/no-content-response.json b/adapters/orbidder/orbiddertest/supplemental/no-content-response.json
index f3b1b287..0a1e5f0f 100644
--- a/adapters/orbidder/orbiddertest/supplemental/no-content-response.json
+++ b/adapters/orbidder/orbiddertest/supplemental/no-content-response.json
@@ -51,6 +51,7 @@
                                     }
                                 ]
                             },
+                            "bidfloorcur": "EUR",
                             "ext": {
                                 "bidder": {
                                     "accountId": "orbidder-test",
diff --git a/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json b/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json
index b6db9f48..1ea133ab 100644
--- a/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json
+++ b/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json
@@ -57,6 +57,7 @@
                   }
                 ]
               },
+              "bidfloorcur": "EUR",
               "ext": {
                 "bidder": {
                   "accountId": "orbidder-test",
diff --git a/adapters/rubicon/rubicon_test.go b/adapters/rubicon/rubicon_test.go
index 0d88937b..83c9e99a 100644
--- a/adapters/rubicon/rubicon_test.go
+++ b/adapters/rubicon/rubicon_test.go
@@ -665,7 +665,12 @@ func TestOpenRTBRequestWithImpAndAdSlotIncluded(t *testing.T) {
 	if err := json.Unmarshal(rubiconReq.Imp[0].Ext, &rpImpExt); err != nil {
 		t.Fatal("Error unmarshalling imp.ext")
 	}
-	assert.Equal(t, rpImpExt.GPID, "/test-adslot")
+
+	dfpAdUnitCode, err := jsonparser.GetString(rpImpExt.RP.Target, "dfp_ad_unit_code")
+	if err != nil {
+		t.Fatal("Error extracting dfp_ad_unit_code")
+	}
+	assert.Equal(t, dfpAdUnitCode, "/test-adslot")
 }
 
 func TestOpenRTBFirstPartyDataPopulating(t *testing.T) {
diff --git a/adapters/rubicon/rubicontest/exemplary/app-imp-fpd.json b/adapters/rubicon/rubicontest/exemplary/app-imp-fpd.json
index eec396f8..d688d7be 100644
--- a/adapters/rubicon/rubicontest/exemplary/app-imp-fpd.json
+++ b/adapters/rubicon/rubicontest/exemplary/app-imp-fpd.json
@@ -145,19 +145,26 @@
             "data": {
               "adserver": {
                 "name": "gam",
-                "adslot": "someAdSlot"
+                "adslot": "adSlotFromContextData"
               },
               "dataAttr1": "dataVal1",
               "dataAttr2": "dataVal2"
             }
           },
+          "data": {
+            "adserver": {
+              "name": "gam",
+              "adslot": "adSlotFromData"
+            }
+          },
           "bidder": {
             "video": {
             },
             "accountId": 1001,
             "siteId": 113932,
             "zoneId": 535510
-          }
+          },
+          "gpid": "gpid"
         }
       }
     ]
@@ -306,9 +313,9 @@
                 "h": 576
               },
               "ext": {
-                "gpid": "someAdSlot",
                 "rp": {
                   "target": {
+                    "dfp_ad_unit_code": "adSlotFromContextData",
                     "dataAttr1": [
                       "dataVal1"
                     ],
@@ -348,7 +355,8 @@
                     "mint_version": ""
                   },
                   "zone_id": 535510
-                }
+                },
+                "gpid": "gpid"
               }
             }
           ]
diff --git a/adapters/rubicon/rubicontest/exemplary/simple-video.json b/adapters/rubicon/rubicontest/exemplary/simple-video.json
index 592f9fb2..bb0b73d6 100644
--- a/adapters/rubicon/rubicontest/exemplary/simple-video.json
+++ b/adapters/rubicon/rubicontest/exemplary/simple-video.json
@@ -132,6 +132,9 @@
           "h": 576
         },
         "ext": {
+          "data": {
+            "pbadslot": "pbadslot"
+          },
           "bidder": {
             "video": {
             },
@@ -314,6 +317,7 @@
               "ext": {
                 "rp": {
                   "target": {
+                    "pbadslot": "pbadslot",
                     "pagecat": [
                       "val1",
                       "val2"
diff --git a/adapters/rubicon/rubicontest/exemplary/site-imp-fpd.json b/adapters/rubicon/rubicontest/exemplary/site-imp-fpd.json
index 56f5ce61..e28244d5 100644
--- a/adapters/rubicon/rubicontest/exemplary/site-imp-fpd.json
+++ b/adapters/rubicon/rubicontest/exemplary/site-imp-fpd.json
@@ -200,7 +200,7 @@
           "data": {
             "adserver": {
               "name": "gam",
-              "adslot": "someAdSlot"
+              "adslot": "adSlotFromData"
             },
             "dataAttr1": "dataVal1",
             "dataAttr2": "dataVal2"
@@ -428,7 +428,6 @@
                 "h": 576
               },
               "ext": {
-                "gpid": "someAdSlot",
                 "rp": {
                   "target": {
                     "dataAttr1": [
@@ -472,7 +471,8 @@
                     "sectioncat": [
                       "sectionCat1",
                       "sectionCat2"
-                    ]
+                    ],
+                    "dfp_ad_unit_code": "adSlotFromData"
                   },
                   "track": {
                     "mint": "",
diff --git a/adapters/rubicon/rubicontest/exemplary/user-fpd.json b/adapters/rubicon/rubicontest/exemplary/user-fpd.json
index b2be736f..9034c62c 100644
--- a/adapters/rubicon/rubicontest/exemplary/user-fpd.json
+++ b/adapters/rubicon/rubicontest/exemplary/user-fpd.json
@@ -257,7 +257,6 @@
                 "h": 576
               },
               "ext": {
-                "gpid": "someAdSlot",
                 "rp": {
                   "target": {
                     "dataAttr1": [
@@ -274,7 +273,8 @@
                     ],
                     "search": [
                       "someSearch"
-                    ]
+                    ],
+                    "dfp_ad_unit_code": "someAdSlot"
                   },
                   "track": {
                     "mint": "",
diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go
index f37c60f7..3f5eecfa 100644
--- a/endpoints/openrtb2/amp_auction_test.go
+++ b/endpoints/openrtb2/amp_auction_test.go
@@ -1235,7 +1235,7 @@ func TestBuildAmpObject(t *testing.T) {
 					},
 					AT:   1,
 					TMax: 500,
-					Ext:  json.RawMessage(`{"prebid":{"cache":{"bids":{"returnCreative":null},"vastxml":null},"targeting":{"pricegranularity":{"precision":2,"ranges":[{"min":0,"max":20,"increment":0.1}]},"includewinners":true,"includebidderkeys":true,"includebrandcategory":null,"includeformat":false,"durationrangesec":null,"preferdeals":false}}}`),
+					Ext:  json.RawMessage(`{"prebid":{"cache":{"bids":{"returnCreative":null},"vastxml":null},"channel":{"name":"amp","version":""},"targeting":{"pricegranularity":{"precision":2,"ranges":[{"min":0,"max":20,"increment":0.1}]},"includewinners":true,"includebidderkeys":true,"includebrandcategory":null,"includeformat":false,"durationrangesec":null,"preferdeals":false}}}`),
 				},
 				AuctionResponse: &openrtb2.BidResponse{
 					SeatBid: []openrtb2.SeatBid{{
@@ -1330,7 +1330,6 @@ func TestIdGeneration(t *testing.T) {
 		// Set up and run test
 		actualAmpObject, endpoint := AmpObjectTestSetup(t, "test", test.givenInStoredRequest, test.givenGenerateRequestID)
 		endpoint(recorder, request, nil)
-
 		assert.Equalf(t, test.expectedID, actualAmpObject.Request.ID, "Bid Request ID is incorrect: %s\n", test.description)
 	}
 }
diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go
index a2f03289..a25bb406 100644
--- a/endpoints/openrtb2/auction_test.go
+++ b/endpoints/openrtb2/auction_test.go
@@ -6,7 +6,6 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"github.com/prebid/prebid-server/firstpartydata"
 	"io"
 	"io/ioutil"
 	"net"
@@ -18,6 +17,8 @@ import (
 	"testing"
 	"time"
 
+	"github.com/prebid/prebid-server/firstpartydata"
+
 	analyticsConf "github.com/prebid/prebid-server/analytics/config"
 	"github.com/prebid/prebid-server/config"
 	"github.com/prebid/prebid-server/currency"
@@ -1145,6 +1146,541 @@ func TestStoredRequests(t *testing.T) {
 	}
 }
 
+func TestMergeBidderParams(t *testing.T) {
+	testCases := []struct {
+		description         string
+		givenRequest        openrtb2.BidRequest
+		expectedRequestImps []openrtb2.Imp
+	}{
+		{
+			description: "No Request Params",
+			givenRequest: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1}}`)}},
+			},
+			expectedRequestImps: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1}}`)}},
+		},
+		{
+			description: "No Request Params - Empty Object",
+			givenRequest: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1}}`)}},
+				Ext: json.RawMessage(`{"prebid":{"bidderparams":{}}}`),
+			},
+			expectedRequestImps: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1}}`)}},
+		},
+		{
+			description: "Malformed Request Params",
+			givenRequest: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1}}`)}},
+				Ext: json.RawMessage(`{"prebid":{"bidderparams":malformed}}`),
+			},
+			expectedRequestImps: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1}}`)}},
+		},
+		{
+			description: "No Imps",
+			givenRequest: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{},
+				Ext: json.RawMessage(`{"prebid":{"bidderparams":{"bidder1":{"b":2}}}}`),
+			},
+			expectedRequestImps: []openrtb2.Imp{},
+		},
+		{
+			description: "One Imp - imp.ext Modified",
+			givenRequest: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1}}`)}},
+				Ext: json.RawMessage(`{"prebid":{"bidderparams":{"bidder1":{"b":2}}}}`),
+			},
+			expectedRequestImps: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1,"b":2}}`)}},
+		},
+		{
+			description: "One Imp - imp.ext.prebid.bidder Modified",
+			givenRequest: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"prebid":{"bidder":{"bidder1":{"a":1}}}}`)}},
+				Ext: json.RawMessage(`{"prebid":{"bidderparams":{"bidder1":{"b":2}}}}`),
+			},
+			expectedRequestImps: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"prebid":{"bidder":{"bidder1":{"a":1,"b":2}}}}`)}},
+		},
+		{
+			description: "One Imp - imp.ext + imp.ext.prebid.bidder Modified - Different Bidders",
+			givenRequest: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1},"prebid":{"bidder":{"bidder2":{"a":"one"}}}}`)}},
+				Ext: json.RawMessage(`{"prebid":{"bidderparams":{"bidder1":{"b":2},"bidder2":{"b":"two"}}}}`),
+			},
+			expectedRequestImps: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1,"b":2},"prebid":{"bidder":{"bidder2":{"a":"one","b":"two"}}}}`)}},
+		},
+		{
+			description: "One Imp - imp.ext + imp.ext.prebid.bidder Modified - Same Bidder",
+			givenRequest: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1},"prebid":{"bidder":{"bidder1":{"a":"one"}}}}`)}},
+				Ext: json.RawMessage(`{"prebid":{"bidderparams":{"bidder1":{"b":2}}}}`),
+			},
+			expectedRequestImps: []openrtb2.Imp{{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1,"b":2},"prebid":{"bidder":{"bidder1":{"a":"one","b":2}}}}`)}},
+		},
+		{
+			description: "One Imp - No imp.ext",
+			givenRequest: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{{ID: "1"}},
+				Ext: json.RawMessage(`{"prebid":{"bidderparams":{"bidder1":{"b":2}}}}`),
+			},
+			expectedRequestImps: []openrtb2.Imp{{ID: "1"}},
+		},
+		{
+			description: "Multiple Imps - Modified Mixed",
+			givenRequest: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1},"prebid":{"bidder":{"bidder1":{"a":"one"}}}}`)},
+					{ID: "2", Ext: json.RawMessage(`{"bidder2":{"a":1,"b":"existing"},"prebid":{"bidder":{"bidder2":{"a":"one"}}}}`)}},
+				Ext: json.RawMessage(`{"prebid":{"bidderparams":{"bidder1":{"b":2},"bidder2":{"b":"two"}}}}`),
+			},
+			expectedRequestImps: []openrtb2.Imp{
+				{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1,"b":2},"prebid":{"bidder":{"bidder1":{"a":"one","b":2}}}}`)},
+				{ID: "2", Ext: json.RawMessage(`{"bidder2":{"a":1,"b":"existing"},"prebid":{"bidder":{"bidder2":{"a":"one","b":"two"}}}}`)}},
+		},
+		{
+			description: "Multiple Imps - None Modified Mixed",
+			givenRequest: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1},"prebid":{"bidder":{"bidder2":{"a":"one"}}}}`)},
+					{ID: "2", Ext: json.RawMessage(`{"bidder1":{"a":2},"prebid":{"bidder":{"bidder2":{"a":"two"}}}}`)}},
+				Ext: json.RawMessage(`{"prebid":{"bidderparams":{"bidder3":{"c":3}}}}`),
+			},
+			expectedRequestImps: []openrtb2.Imp{
+				{ID: "1", Ext: json.RawMessage(`{"bidder1":{"a":1},"prebid":{"bidder":{"bidder2":{"a":"one"}}}}`)},
+				{ID: "2", Ext: json.RawMessage(`{"bidder1":{"a":2},"prebid":{"bidder":{"bidder2":{"a":"two"}}}}`)}},
+		},
+		{
+			description: "Multiple Imps - One Malformed",
+			givenRequest: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "1", Ext: json.RawMessage(`malformed`)},
+					{ID: "2", Ext: json.RawMessage(`{"bidder2":{"a":1,"b":"existing"},"prebid":{"bidder":{"bidder2":{"a":"one"}}}}`)}},
+				Ext: json.RawMessage(`{"prebid":{"bidderparams":{"bidder1":{"b":2},"bidder2":{"b":"two"}}}}`),
+			},
+			expectedRequestImps: []openrtb2.Imp{
+				{ID: "1", Ext: json.RawMessage(`malformed`)},
+				{ID: "2", Ext: json.RawMessage(`{"bidder2":{"a":1,"b":"existing"},"prebid":{"bidder":{"bidder2":{"a":"one","b":"two"}}}}`)}},
+		},
+	}
+
+	for _, test := range testCases {
+		actualErr := mergeBidderParams(&openrtb_ext.RequestWrapper{BidRequest: &test.givenRequest})
+
+		// errors are only possible from the marshal operation, which is not testable
+		assert.NoError(t, actualErr, test.description+":err")
+
+		assert.Equal(t, test.givenRequest.Imp, test.expectedRequestImps, test.description+":imps")
+	}
+}
+
+func TestAddMissingReqExtParamsInImpExtPrebid(t *testing.T) {
+	testCases := []struct {
+		description            string
+		givenImpExtByBidder    map[string]json.RawMessage
+		givenReqExtParams      map[string]map[string]json.RawMessage
+		expectedModified       bool
+		expectedImpExtByBidder map[string]json.RawMessage
+	}{
+		{
+			description:            "No Prebid Section",
+			givenImpExtByBidder:    map[string]json.RawMessage{},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"bidder1": {"b": json.RawMessage(`2`)}},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{},
+		},
+		{
+			description:            "Malformed Prebid Section",
+			givenImpExtByBidder:    map[string]json.RawMessage{"prebid": json.RawMessage(`malformed`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"bidder1": {"b": json.RawMessage(`2`)}},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{"prebid": json.RawMessage(`malformed`)},
+		},
+		{
+			description:            "No Prebid Bidder Section",
+			givenImpExtByBidder:    map[string]json.RawMessage{"prebid": json.RawMessage(`{}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"bidder1": {"b": json.RawMessage(`2`)}},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{"prebid": json.RawMessage(`{}`)},
+		},
+		{
+			description:            "Malformed Prebid Bidder Section",
+			givenImpExtByBidder:    map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder": malformed}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"bidder1": {"b": json.RawMessage(`2`)}},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder": malformed}`)},
+		},
+		{
+			description:            "One Bidder - Modified (no collision)",
+			givenImpExtByBidder:    map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"bidder1":{"a":1}}}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"bidder1": {"b": json.RawMessage(`2`)}},
+			expectedModified:       true,
+			expectedImpExtByBidder: map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"bidder1":{"a":1,"b":2}}}`)},
+		},
+		{
+			description:            "One Bidder - Not Modified (imp.ext wins)",
+			givenImpExtByBidder:    map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"bidder1":{"a":1,"b":2}}}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"bidder1": {"b": json.RawMessage(`4`)}},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"bidder1":{"a":1,"b":2}}}`)},
+		},
+		{
+			description:            "One Bidder - Not Modified (reserved bidder ignored)",
+			givenImpExtByBidder:    map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"gpid":{"a":1}}}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"gpid": {"b": json.RawMessage(`2`)}},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"gpid":{"a":1}}}`)},
+		},
+		{
+			description:            "One Bidder - Not Modified (reserved bidder ignored - not embedded object)",
+			givenImpExtByBidder:    map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"gpid":1}}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"gpid": {"b": json.RawMessage(`2`)}},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"gpid":1}}`)},
+		},
+		{
+			description:            "One Bidder - Not Modified (malformed ignored)",
+			givenImpExtByBidder:    map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"bidder1":malformed}}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"bidder1": {"b": json.RawMessage(`2`)}},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"bidder1":malformed}}`)},
+		},
+		{
+			description:            "Multiple Bidders - Mixed",
+			givenImpExtByBidder:    map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"bidder1":{"a":1},"bidder2":{"a":"one","b":"two"}}}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"bidder1": {"b": json.RawMessage(`2`)}, "bidder2": {"b": json.RawMessage(`"three"`)}},
+			expectedModified:       true,
+			expectedImpExtByBidder: map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"bidder1":{"a":1,"b":2},"bidder2":{"a":"one","b":"two"}}}`)},
+		},
+		{
+			description:            "Multiple Bidders - None Modified",
+			givenImpExtByBidder:    map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"bidder1":{"a":1},"bidder2":{"a":"one","b":"two"}}}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{"prebid": json.RawMessage(`{"bidder":{"bidder1":{"a":1},"bidder2":{"a":"one","b":"two"}}}`)},
+		},
+	}
+
+	for _, test := range testCases {
+		actualModified, actualErr := addMissingReqExtParamsInImpExtPrebid(test.givenImpExtByBidder, test.givenReqExtParams)
+
+		// errors are only possible from the marshal operation, which is not testable
+		assert.NoError(t, actualErr, test.description+":err")
+
+		assert.Equal(t, test.expectedModified, actualModified, test.description+":modified")
+		assert.Equal(t, test.expectedImpExtByBidder, test.givenImpExtByBidder, test.description+":imp.ext")
+	}
+}
+
+func TestAddMissingReqExtParamsInImpExt(t *testing.T) {
+	testCases := []struct {
+		description            string
+		givenImpExtByBidder    map[string]json.RawMessage
+		givenReqExtParams      map[string]map[string]json.RawMessage
+		expectedModified       bool
+		expectedImpExtByBidder map[string]json.RawMessage
+	}{
+		{
+			description:            "One Bidder - Modified (no collision)",
+			givenImpExtByBidder:    map[string]json.RawMessage{"bidder1": json.RawMessage(`{"a":1}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"bidder1": {"b": json.RawMessage(`2`)}},
+			expectedModified:       true,
+			expectedImpExtByBidder: map[string]json.RawMessage{"bidder1": json.RawMessage(`{"a":1,"b":2}`)},
+		},
+		{
+			description:            "One Bidder - Not Modified (imp.ext wins)",
+			givenImpExtByBidder:    map[string]json.RawMessage{"bidder1": json.RawMessage(`{"a":1,"b":2}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"bidder1": {"b": json.RawMessage(`4`)}},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{"bidder1": json.RawMessage(`{"a":1,"b":2}`)},
+		},
+		{
+			description:            "One Bidder - Not Modified (reserved bidder ignored)",
+			givenImpExtByBidder:    map[string]json.RawMessage{"gpid": json.RawMessage(`{"a":1}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"gpid": {"b": json.RawMessage(`2`)}},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{"gpid": json.RawMessage(`{"a":1}`)},
+		},
+		{
+			description:            "One Bidder - Not Modified (reserved bidder ignored - not embedded object)",
+			givenImpExtByBidder:    map[string]json.RawMessage{"gpid": json.RawMessage(`1`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"gpid": {"b": json.RawMessage(`2`)}},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{"gpid": json.RawMessage(`1`)},
+		},
+		{
+			description:            "One Bidder - Not Modified (malformed ignored)",
+			givenImpExtByBidder:    map[string]json.RawMessage{"bidder1": json.RawMessage(`malformed`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"bidder1": {"b": json.RawMessage(`2`)}},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{"bidder1": json.RawMessage(`malformed`)},
+		},
+		{
+			description:            "Multiple Bidders - Mixed",
+			givenImpExtByBidder:    map[string]json.RawMessage{"bidder1": json.RawMessage(`{"a":1}`), "bidder2": json.RawMessage(`{"a":"one","b":"two"}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{"bidder1": {"b": json.RawMessage(`2`)}, "bidder2": {"b": json.RawMessage(`"three"`)}},
+			expectedModified:       true,
+			expectedImpExtByBidder: map[string]json.RawMessage{"bidder1": json.RawMessage(`{"a":1,"b":2}`), "bidder2": json.RawMessage(`{"a":"one","b":"two"}`)},
+		},
+		{
+			description:            "Multiple Bidders - None Modified",
+			givenImpExtByBidder:    map[string]json.RawMessage{"bidder1": json.RawMessage(`{"a":1}`), "bidder2": json.RawMessage(`{"a":"one","b":"two"}`)},
+			givenReqExtParams:      map[string]map[string]json.RawMessage{},
+			expectedModified:       false,
+			expectedImpExtByBidder: map[string]json.RawMessage{"bidder1": json.RawMessage(`{"a":1}`), "bidder2": json.RawMessage(`{"a":"one","b":"two"}`)},
+		},
+	}
+
+	for _, test := range testCases {
+		actualModified, actualErr := addMissingReqExtParamsInImpExt(test.givenImpExtByBidder, test.givenReqExtParams)
+
+		// errors are only possible from the marshal operation, which is not testable
+		assert.NoError(t, actualErr, test.description+":err")
+
+		assert.Equal(t, test.expectedModified, actualModified, test.description+":modified")
+		assert.Equal(t, test.expectedImpExtByBidder, test.givenImpExtByBidder, test.description+":imp.ext")
+	}
+}
+
+//impExtByBidder map[string]json.RawMessage, reqExtParams map[string]map[string]json.RawMessage) (bool, error) {
+
+func TestValidateRequest(t *testing.T) {
+	deps := &endpointDeps{
+		fakeUUIDGenerator{},
+		&nobidExchange{},
+		newParamsValidator(t),
+		&mockStoredReqFetcher{},
+		empty_fetcher.EmptyFetcher{},
+		empty_fetcher.EmptyFetcher{},
+		&config.Configuration{MaxRequestSize: maxSize},
+		&metricsConfig.NilMetricsEngine{},
+		analyticsConf.NewPBSAnalytics(&config.Analytics{}),
+		map[string]string{},
+		false,
+		[]byte{},
+		openrtb_ext.BuildBidderMap(),
+		nil,
+		nil,
+		hardcodedResponseIPValidator{response: true},
+	}
+
+	testCases := []struct {
+		description           string
+		givenIsAmp            bool
+		givenRequestWrapper   *openrtb_ext.RequestWrapper
+		expectedErrorList     []error
+		expectedChannelObject *openrtb_ext.ExtRequestPrebidChannel
+	}{
+		{
+			description: "No errors in bid request with request.ext.prebid.channel info, expect validate request to throw no errors",
+			givenRequestWrapper: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{
+					ID:  "Some-ID",
+					App: &openrtb2.App{},
+					Imp: []openrtb2.Imp{
+						{
+							ID: "Some-Imp-ID",
+							Banner: &openrtb2.Banner{
+								Format: []openrtb2.Format{
+									{
+										W: 600,
+										H: 500,
+									},
+									{
+										W: 300,
+										H: 600,
+									},
+								},
+							},
+							Ext: []byte(`{"appnexus":{"placementId": 12345678}}`),
+						},
+					},
+					Ext: []byte(`{"prebid":{"channel": {"name": "nameOfChannel", "version": "1.0"}}}`),
+				},
+			},
+			givenIsAmp:            false,
+			expectedErrorList:     []error{},
+			expectedChannelObject: &openrtb_ext.ExtRequestPrebidChannel{Name: "nameOfChannel", Version: "1.0"},
+		},
+		{
+			description: "Error in bid request with request.ext.prebid.channel.name being blank, expect validate request to return error",
+			givenRequestWrapper: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{
+					ID:  "Some-ID",
+					App: &openrtb2.App{},
+					Imp: []openrtb2.Imp{
+						{
+							ID: "Some-Imp-ID",
+							Banner: &openrtb2.Banner{
+								Format: []openrtb2.Format{
+									{
+										W: 600,
+										H: 500,
+									},
+									{
+										W: 300,
+										H: 600,
+									},
+								},
+							},
+							Ext: []byte(`{"appnexus":{"placementId": 12345678}}`),
+						},
+					},
+					Ext: []byte(`{"prebid":{"channel": {"name": "", "version": ""}}}`),
+				},
+			},
+			givenIsAmp:        false,
+			expectedErrorList: []error{errors.New("ext.prebid.channel.name can't be empty")},
+		},
+		{
+			description: "No errors in bid request with request.ext.prebid but no channel info, expect validate request to throw no errors and fill channel with app",
+			givenRequestWrapper: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{
+					ID:  "Some-ID",
+					App: &openrtb2.App{},
+					Imp: []openrtb2.Imp{
+						{
+							ID: "Some-Imp-ID",
+							Banner: &openrtb2.Banner{
+								Format: []openrtb2.Format{
+									{
+										W: 600,
+										H: 500,
+									},
+									{
+										W: 300,
+										H: 600,
+									},
+								},
+							},
+							Ext: []byte(`{"appnexus":{"placementId": 12345678}}`),
+						},
+					},
+					Ext: []byte(`{"prebid":{}}`),
+				},
+			},
+			givenIsAmp:            false,
+			expectedErrorList:     []error{},
+			expectedChannelObject: &openrtb_ext.ExtRequestPrebidChannel{Name: appChannel, Version: ""},
+		},
+	}
+
+	for _, test := range testCases {
+		errorList := deps.validateRequest(test.givenRequestWrapper, test.givenIsAmp)
+		assert.Equalf(t, test.expectedErrorList, errorList, "Error doesn't match: %s\n", test.description)
+
+		if len(errorList) == 0 {
+			requestExt, err := test.givenRequestWrapper.GetRequestExt()
+			assert.Empty(t, err, test.description)
+			requestPrebid := requestExt.GetPrebid()
+
+			assert.Equalf(t, test.expectedChannelObject, requestPrebid.Channel, "Channel information isn't correct: %s\n", test.description)
+		}
+	}
+}
+
+func TestValidateOrFillChannel(t *testing.T) {
+	testCases := []struct {
+		description           string
+		givenIsAmp            bool
+		givenRequestWrapper   *openrtb_ext.RequestWrapper
+		expectedError         error
+		expectedChannelObject *openrtb_ext.ExtRequestPrebidChannel
+	}{
+		{
+			description: "No request.ext info in app request, so we expect channel name to be set to app",
+			givenRequestWrapper: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{}},
+			},
+			givenIsAmp:            false,
+			expectedError:         nil,
+			expectedChannelObject: &openrtb_ext.ExtRequestPrebidChannel{Name: appChannel, Version: ""},
+		},
+		{
+			description: "No request.ext info in amp request, so we expect channel name to be set to amp",
+			givenRequestWrapper: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{},
+			},
+			givenIsAmp:            true,
+			expectedError:         nil,
+			expectedChannelObject: &openrtb_ext.ExtRequestPrebidChannel{Name: ampChannel, Version: ""},
+		},
+		{
+			description: "Channel object in request with populated name/version, we expect same name/version in object that's created",
+			givenRequestWrapper: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{Ext: []byte(`{"prebid":{"channel": {"name": "video", "version": "1.0"}}}`)},
+			},
+			givenIsAmp:            false,
+			expectedError:         nil,
+			expectedChannelObject: &openrtb_ext.ExtRequestPrebidChannel{Name: "video", Version: "1.0"},
+		},
+		{
+			description: "No channel object in site request, expect nil",
+			givenRequestWrapper: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{}, Ext: []byte(`{"prebid":{}}`)},
+			},
+			givenIsAmp:            false,
+			expectedError:         nil,
+			expectedChannelObject: nil,
+		},
+		{
+			description: "No channel name given in channel object, we expect error to be thrown",
+			givenRequestWrapper: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{}, Ext: []byte(`{"prebid":{"channel": {"name": "", "version": ""}}}`)},
+			},
+			givenIsAmp:            false,
+			expectedError:         errors.New("ext.prebid.channel.name can't be empty"),
+			expectedChannelObject: nil,
+		},
+		{
+			description: "App request, has request.ext, no request.ext.prebid, expect channel name to be filled with app",
+			givenRequestWrapper: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{}, Ext: []byte(`{}`)},
+			},
+			givenIsAmp:            false,
+			expectedError:         nil,
+			expectedChannelObject: &openrtb_ext.ExtRequestPrebidChannel{Name: appChannel, Version: ""},
+		},
+		{
+			description: "App request, has request.ext.prebid, but no channel object, expect channel name to be filled with app",
+			givenRequestWrapper: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{}, Ext: []byte(`{"prebid":{}}`)},
+			},
+			givenIsAmp:            false,
+			expectedError:         nil,
+			expectedChannelObject: &openrtb_ext.ExtRequestPrebidChannel{Name: appChannel, Version: ""},
+		},
+		{
+			description: "Amp request, has request.ext, no request.ext.prebid, expect channel name to be filled with amp",
+			givenRequestWrapper: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{Ext: []byte(`{}`)},
+			},
+			givenIsAmp:            true,
+			expectedError:         nil,
+			expectedChannelObject: &openrtb_ext.ExtRequestPrebidChannel{Name: ampChannel, Version: ""},
+		},
+		{
+			description: "Amp request, has request.ext.prebid, but no channel object, expect channel name to be filled with amp",
+			givenRequestWrapper: &openrtb_ext.RequestWrapper{
+				BidRequest: &openrtb2.BidRequest{Ext: []byte(`{"prebid":{}}`)},
+			},
+			givenIsAmp:            true,
+			expectedError:         nil,
+			expectedChannelObject: &openrtb_ext.ExtRequestPrebidChannel{Name: ampChannel, Version: ""},
+		},
+	}
+
+	for _, test := range testCases {
+		err := validateOrFillChannel(test.givenRequestWrapper, test.givenIsAmp)
+		assert.Equalf(t, test.expectedError, err, "Error doesn't match: %s\n", test.description)
+
+		if err == nil {
+			requestExt, err := test.givenRequestWrapper.GetRequestExt()
+			assert.Empty(t, err, test.description)
+			requestPrebid := requestExt.GetPrebid()
+
+			assert.Equalf(t, test.expectedChannelObject, requestPrebid.Channel, "Channel information isn't correct: %s\n", test.description)
+		}
+	}
+}
+
 func TestStoredRequestGenerateUuid(t *testing.T) {
 	uuid := "foo"
 
@@ -1699,7 +2235,7 @@ func TestCurrencyTrunc(t *testing.T) {
 		Cur: []string{"USD", "EUR"},
 	}
 
-	errL := deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: &req})
+	errL := deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: &req}, false)
 
 	expectedError := errortypes.Warning{Message: "A prebid request can only process one currency. Taking the first currency in the list, USD, as the active currency"}
 	assert.ElementsMatch(t, errL, []error{&expectedError})
@@ -1746,7 +2282,7 @@ func TestCCPAInvalid(t *testing.T) {
 		},
 	}
 
-	errL := deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: &req})
+	errL := deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: &req}, false)
 
 	expectedWarning := errortypes.Warning{
 		Message:     "CCPA consent is invalid and will be ignored. (request.regs.ext.us_privacy must contain 4 characters)",
@@ -1796,7 +2332,7 @@ func TestNoSaleInvalid(t *testing.T) {
 		Ext: json.RawMessage(`{"prebid": {"nosale": ["*", "appnexus"]} }`),
 	}
 
-	errL := deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: &req})
+	errL := deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: &req}, false)
 
 	expectedError := errors.New("request.ext.prebid.nosale is invalid: can only specify all bidders if no other bidders are provided")
 	assert.ElementsMatch(t, errL, []error{expectedError})
@@ -1844,7 +2380,7 @@ func TestValidateSourceTID(t *testing.T) {
 		},
 	}
 
-	deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: &req})
+	deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: &req}, false)
 	assert.NotEmpty(t, req.Source.TID, "Expected req.Source.TID to be filled with a randomly generated UID")
 }
 
@@ -1887,7 +2423,7 @@ func TestSChainInvalid(t *testing.T) {
 		Ext: json.RawMessage(`{"prebid":{"schains":[{"bidders":["appnexus"],"schain":{"complete":1,"nodes":[{"asi":"directseller1.com","sid":"00001","rid":"BidRequest1","hp":1}],"ver":"1.0"}}, {"bidders":["appnexus"],"schain":{"complete":1,"nodes":[{"asi":"directseller2.com","sid":"00002","rid":"BidRequest2","hp":1}],"ver":"1.0"}}]}}`),
 	}
 
-	errL := deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: &req})
+	errL := deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: &req}, false)
 
 	expectedError := errors.New("request.ext.prebid.schains contains multiple schains for bidder appnexus; it must contain no more than one per bidder.")
 	assert.ElementsMatch(t, errL, []error{expectedError})
@@ -2107,7 +2643,7 @@ func TestEidPermissionsInvalid(t *testing.T) {
 		Ext: json.RawMessage(`{"prebid": {"data": {"eidpermissions": [{"source":"a", "bidders":[]}]} } }`),
 	}
 
-	errL := deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: &req})
+	errL := deps.validateRequest(&openrtb_ext.RequestWrapper{BidRequest: &req}, false)
 
 	expectedError := errors.New(`request.ext.prebid.data.eidpermissions[0] missing or empty required field: "bidders"`)
 	assert.ElementsMatch(t, errL, []error{expectedError})
@@ -3585,9 +4121,6 @@ var testBidRequests = []string{
 		],
 		"ext": {
 			"prebid": {
-				"cache": {
-					"markup": 1
-				},
 				"targeting": {
 				}
 			}
@@ -3810,51 +4343,33 @@ func TestValidateBanner(t *testing.T) {
 }
 
 func TestParseRequestMergeBidderParams(t *testing.T) {
-	type args struct {
-		reqBody string
-	}
 	tests := []struct {
-		name           string
-		args           args
-		expectedImpExt json.RawMessage
-		expectedReqExt json.RawMessage
-		errL           int
+		name               string
+		givenRequestBody   string
+		expectedImpExt     json.RawMessage
+		expectedReqExt     json.RawMessage
+		expectedErrorCount int
 	}{
 		{
-			name: "add missing bidder-params from req.ext.prebid.bidderparams to imp[].ext.prebid.bidder",
-			args: args{
-				reqBody: validRequest(t, "req-ext-bidder-params.json"),
-			},
-			expectedImpExt: getObject(t, "req-ext-bidder-params.json", "expectedImpExt"),
-			expectedReqExt: getObject(t, "req-ext-bidder-params.json", "expectedReqExt"),
-			errL:           0,
-		},
-		{
-			name: "add missing bidder-params from req.ext.prebid.bidderparams to imp[].ext.prebid.bidder with preference for imp[].ext.prebid.bidder params",
-			args: args{
-				reqBody: validRequest(t, "req-ext-bidder-params-merge.json"),
-			},
-			expectedImpExt: getObject(t, "req-ext-bidder-params-merge.json", "expectedImpExt"),
-			expectedReqExt: getObject(t, "req-ext-bidder-params-merge.json", "expectedReqExt"),
-			errL:           0,
+			name:               "add missing bidder-params from req.ext.prebid.bidderparams to imp[].ext.prebid.bidder",
+			givenRequestBody:   validRequest(t, "req-ext-bidder-params.json"),
+			expectedImpExt:     getObject(t, "req-ext-bidder-params.json", "expectedImpExt"),
+			expectedReqExt:     getObject(t, "req-ext-bidder-params.json", "expectedReqExt"),
+			expectedErrorCount: 0,
 		},
 		{
-			name: "add missing bidder-params from req.ext.prebid.bidderparams to imp[].ext for backward compatibility",
-			args: args{
-				reqBody: validRequest(t, "req-ext-bidder-params-backward-compatible-merge.json"),
-			},
-			expectedImpExt: getObject(t, "req-ext-bidder-params-backward-compatible-merge.json", "expectedImpExt"),
-			expectedReqExt: getObject(t, "req-ext-bidder-params-backward-compatible-merge.json", "expectedReqExt"),
-			errL:           0,
+			name:               "add missing bidder-params from req.ext.prebid.bidderparams to imp[].ext.prebid.bidder with preference for imp[].ext.prebid.bidder params",
+			givenRequestBody:   validRequest(t, "req-ext-bidder-params-merge.json"),
+			expectedImpExt:     getObject(t, "req-ext-bidder-params-merge.json", "expectedImpExt"),
+			expectedReqExt:     getObject(t, "req-ext-bidder-params-merge.json", "expectedReqExt"),
+			expectedErrorCount: 0,
 		},
 		{
-			name: "add missing bidder-params from req.ext.prebid.bidderparams to imp[].ext.prebid.bidder for reserved keyword",
-			args: args{
-				reqBody: validRequest(t, "req-ext-bidder-params-merge-reserved-keyword.json"),
-			},
-			expectedImpExt: getObject(t, "req-ext-bidder-params-merge-reserved-keyword.json", "expectedImpExt"),
-			expectedReqExt: getObject(t, "req-ext-bidder-params-merge-reserved-keyword.json", "expectedReqExt"),
-			errL:           0,
+			name:               "add missing bidder-params from req.ext.prebid.bidderparams to imp[].ext for backward compatibility",
+			givenRequestBody:   validRequest(t, "req-ext-bidder-params-backward-compatible-merge.json"),
+			expectedImpExt:     getObject(t, "req-ext-bidder-params-backward-compatible-merge.json", "expectedImpExt"),
+			expectedReqExt:     getObject(t, "req-ext-bidder-params-backward-compatible-merge.json", "expectedReqExt"),
+			expectedErrorCount: 0,
 		},
 	}
 	for _, tt := range tests {
@@ -3867,7 +4382,7 @@ func TestParseRequestMergeBidderParams(t *testing.T) {
 				&mockStoredReqFetcher{},
 				empty_fetcher.EmptyFetcher{},
 				empty_fetcher.EmptyFetcher{},
-				&config.Configuration{MaxRequestSize: int64(len(tt.args.reqBody))},
+				&config.Configuration{MaxRequestSize: int64(len(tt.givenRequestBody))},
 				&metricsConfig.NilMetricsEngine{},
 				analyticsConf.NewPBSAnalytics(&config.Analytics{}),
 				map[string]string{},
@@ -3879,7 +4394,7 @@ func TestParseRequestMergeBidderParams(t *testing.T) {
 				hardcodedResponseIPValidator{response: true},
 			}
 
-			req := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(tt.args.reqBody))
+			req := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(tt.givenRequestBody))
 
 			resReq, _, errL := deps.parseRequest(req)
 
@@ -3902,7 +4417,7 @@ func TestParseRequestMergeBidderParams(t *testing.T) {
 
 			assert.Equal(t, eReqE, reqE, "req.Ext should match")
 
-			assert.Len(t, errL, tt.errL, "error length should match")
+			assert.Len(t, errL, tt.expectedErrorCount, "error length should match")
 		})
 	}
 }
diff --git a/exchange/utils_test.go b/exchange/utils_test.go
index d0b4006d..c10e294f 100644
--- a/exchange/utils_test.go
+++ b/exchange/utils_test.go
@@ -249,6 +249,7 @@ func TestCreateSanitizedImpExt(t *testing.T) {
 				"data":    json.RawMessage(`"anyData"`),
 				"context": json.RawMessage(`"anyContext"`),
 				"skadn":   json.RawMessage(`"anySKAdNetwork"`),
+				"gpid":    json.RawMessage(`"anyGPID"`),
 			},
 			givenImpExtPrebid: map[string]json.RawMessage{
 				"bidder": json.RawMessage(`"anyBidder"`),
@@ -257,6 +258,7 @@ func TestCreateSanitizedImpExt(t *testing.T) {
 				"data":    json.RawMessage(`"anyData"`),
 				"context": json.RawMessage(`"anyContext"`),
 				"skadn":   json.RawMessage(`"anySKAdNetwork"`),
+				"gpid":    json.RawMessage(`"anyGPID"`),
 			},
 			expectedError: "",
 		},
@@ -267,6 +269,7 @@ func TestCreateSanitizedImpExt(t *testing.T) {
 				"data":    json.RawMessage(`"anyData"`),
 				"context": json.RawMessage(`"anyContext"`),
 				"skadn":   json.RawMessage(`"anySKAdNetwork"`),
+				"gpid":    json.RawMessage(`"anyGPID"`),
 			},
 			givenImpExtPrebid: map[string]json.RawMessage{
 				"bidder":    json.RawMessage(`"anyBidder"`),
@@ -277,6 +280,7 @@ func TestCreateSanitizedImpExt(t *testing.T) {
 				"data":    json.RawMessage(`"anyData"`),
 				"context": json.RawMessage(`"anyContext"`),
 				"skadn":   json.RawMessage(`"anySKAdNetwork"`),
+				"gpid":    json.RawMessage(`"anyGPID"`),
 			},
 			expectedError: "",
 		},
@@ -287,12 +291,14 @@ func TestCreateSanitizedImpExt(t *testing.T) {
 				"data":      json.RawMessage(`"anyData"`),
 				"context":   json.RawMessage(`"anyContext"`),
 				"skadn":     json.RawMessage(`"anySKAdNetwork"`),
+				"gpid":      json.RawMessage(`"anyGPID"`),
 			},
 			givenImpExtPrebid: map[string]json.RawMessage{},
 			expected: map[string]json.RawMessage{
 				"data":    json.RawMessage(`"anyData"`),
 				"context": json.RawMessage(`"anyContext"`),
 				"skadn":   json.RawMessage(`"anySKAdNetwork"`),
+				"gpid":    json.RawMessage(`"anyGPID"`),
 			},
 			expectedError: "",
 		},
@@ -304,6 +310,7 @@ func TestCreateSanitizedImpExt(t *testing.T) {
 				"data":      json.RawMessage(`"anyData"`),
 				"context":   json.RawMessage(`"anyContext"`),
 				"skadn":     json.RawMessage(`"anySKAdNetwork"`),
+				"gpid":      json.RawMessage(`"anyGPID"`),
 			},
 			givenImpExtPrebid: map[string]json.RawMessage{
 				"bidder": json.RawMessage(`"anyBidder"`),
@@ -312,6 +319,7 @@ func TestCreateSanitizedImpExt(t *testing.T) {
 				"data":    json.RawMessage(`"anyData"`),
 				"context": json.RawMessage(`"anyContext"`),
 				"skadn":   json.RawMessage(`"anySKAdNetwork"`),
+				"gpid":    json.RawMessage(`"anyGPID"`),
 			},
 			expectedError: "",
 		},
@@ -323,6 +331,7 @@ func TestCreateSanitizedImpExt(t *testing.T) {
 				"data":      json.RawMessage(`"anyData"`),
 				"context":   json.RawMessage(`"anyContext"`),
 				"skadn":     json.RawMessage(`"anySKAdNetwork"`),
+				"gpid":      json.RawMessage(`"anyGPID"`),
 			},
 			givenImpExtPrebid: map[string]json.RawMessage{
 				"bidder":    json.RawMessage(`"anyBidder"`),
@@ -333,6 +342,7 @@ func TestCreateSanitizedImpExt(t *testing.T) {
 				"data":    json.RawMessage(`"anyData"`),
 				"context": json.RawMessage(`"anyContext"`),
 				"skadn":   json.RawMessage(`"anySKAdNetwork"`),
+				"gpid":    json.RawMessage(`"anyGPID"`),
 			},
 			expectedError: "",
 		},
@@ -343,6 +353,7 @@ func TestCreateSanitizedImpExt(t *testing.T) {
 				"data":    json.RawMessage(`"anyData"`),
 				"context": json.RawMessage(`"anyContext"`),
 				"skadn":   json.RawMessage(`"anySKAdNetwork"`),
+				"gpid":    json.RawMessage(`"anyGPID"`),
 			},
 			givenImpExtPrebid: map[string]json.RawMessage{
 				"malformed": json.RawMessage(`json`), // String value without quotes.
@@ -401,7 +412,7 @@ func TestExtractBidderExts(t *testing.T) {
 		},
 		{
 			description:              "Special Names Ignored - imp.ext.BIDDER",
-			givenImpExt:              map[string]json.RawMessage{"prebid": json.RawMessage(`{"prebid":"value1"}}`), "context": json.RawMessage(`{"firstPartyData":"value2"}}`), "skadn": json.RawMessage(`{"skAdNetwork":"value3"}}`)},
+			givenImpExt:              map[string]json.RawMessage{"prebid": json.RawMessage(`{"prebid":"value1"}}`), "context": json.RawMessage(`{"firstPartyData":"value2"}}`), "skadn": json.RawMessage(`{"skAdNetwork":"value3"}}`), "gpid": json.RawMessage(`{"gpid":"value4"}}`)},
 			givenImpExtPrebidBidders: map[string]json.RawMessage{},
 			expected:                 map[string]json.RawMessage{},
 		},
@@ -420,8 +431,8 @@ func TestExtractBidderExts(t *testing.T) {
 		{
 			description:              "Special Names Not Treated Differently - imp.ext.prebid.bidder.BIDDER",
 			givenImpExt:              map[string]json.RawMessage{},
-			givenImpExtPrebidBidders: map[string]json.RawMessage{"prebid": json.RawMessage(`{"prebid":"value1"}}`), "context": json.RawMessage(`{"firstPartyData":"value2"}}`), "skadn": json.RawMessage(`{"skAdNetwork":"value3"}}`)},
-			expected:                 map[string]json.RawMessage{"prebid": json.RawMessage(`{"prebid":"value1"}}`), "context": json.RawMessage(`{"firstPartyData":"value2"}}`), "skadn": json.RawMessage(`{"skAdNetwork":"value3"}}`)},
+			givenImpExtPrebidBidders: map[string]json.RawMessage{"prebid": json.RawMessage(`{"prebid":"value1"}}`), "context": json.RawMessage(`{"firstPartyData":"value2"}}`), "skadn": json.RawMessage(`{"skAdNetwork":"value3"}}`), "gpid": json.RawMessage(`{"gpid":"value4"}}`)},
+			expected:                 map[string]json.RawMessage{"prebid": json.RawMessage(`{"prebid":"value1"}}`), "context": json.RawMessage(`{"firstPartyData":"value2"}}`), "skadn": json.RawMessage(`{"skAdNetwork":"value3"}}`), "gpid": json.RawMessage(`{"gpid":"value4"}}`)},
 		},
 		{
 			description:              "Mixed - Both - imp.ext.BIDDER + imp.ext.prebid.bidder.BIDDER",
diff --git a/metrics/prometheus/prometheus_test.go b/metrics/prometheus/prometheus_test.go
index fc8abdb9..c7b293da 100644
--- a/metrics/prometheus/prometheus_test.go
+++ b/metrics/prometheus/prometheus_test.go
@@ -26,7 +26,7 @@ func TestMetricCountGatekeeping(t *testing.T) {
 	m := createMetricsForTesting()
 
 	// Gather All Metrics
-	metricFamilies, err := m.Registry.Gather()
+	metricFamilies, err := m.Gatherer.Gather()
 	assert.NoError(t, err, "gather metics")
 
 	// Summarize By Adapter Cardinality
diff --git a/openrtb_ext/bidders_test.go b/openrtb_ext/bidders_test.go
index 8bd25d9e..cde79f70 100644
--- a/openrtb_ext/bidders_test.go
+++ b/openrtb_ext/bidders_test.go
@@ -104,15 +104,15 @@ func TestIsBidderNameReserved(t *testing.T) {
 		{"general", true},
 		{"gEnErAl", true},
 		{"GENERAL", true},
-		{"skadn", true},
-		{"skADN", true},
-		{"SKADN", true},
+		{"gpid", true},
+		{"GPID", true},
+		{"GPid", true},
 		{"prebid", true},
 		{"PREbid", true},
 		{"PREBID", true},
-		{"bidder", true},
-		{"BIDDER", true},
-		{"BidDer", true},
+		{"skadn", true},
+		{"skADN", true},
+		{"SKADN", true},
 		{"notreserved", false},
 	}