Repository: prebid/prebid-server
Pull request #2972 (2023-07-26 01:31:49)

Prebid SDK Rendering API Extensions
For our Prebid SDK friends, per https://github.com/prebid/prebid-server/issues/2908.


Patch:
diff --git a/Makefile b/Makefile
index baf69caf..b5b7281e 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 
 all: deps test build-modules build
 
-.PHONY: deps test build-modules build image
+.PHONY: deps test build-modules build image format
 
 # deps will clean out the vendor directory and use go mod for a fresh install
 deps:
@@ -29,3 +29,7 @@ build: test
 # image will build a docker image
 image:
 	docker build -t prebid-server .
+
+# format runs format
+format:
+	./scripts/format.sh -f true
\ No newline at end of file
diff --git a/README.md b/README.md
index 9b657f35..cb64ed9a 100644
--- a/README.md
+++ b/README.md
@@ -47,6 +47,15 @@ go build .
 ./prebid-server
 ```
 
+Run format:
+```
+make format
+```
+or
+```bash
+./scripts/format.sh -f true
+```
+
 Load the landing page in your browser at `http://localhost:8000/`.
 For the full API reference, see [the endpoint documentation](https://docs.prebid.org/prebid-server/endpoints/pbs-endpoint-overview.html)
 
diff --git a/adapters/brightroll/brightroll.go b/adapters/brightroll/brightroll.go
deleted file mode 100644
index a917fe87..00000000
--- a/adapters/brightroll/brightroll.go
+++ /dev/null
@@ -1,263 +0,0 @@
-package brightroll
-
-import (
-	"encoding/json"
-	"fmt"
-	"net/http"
-	"strconv"
-
-	"github.com/prebid/openrtb/v19/adcom1"
-	"github.com/prebid/openrtb/v19/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"
-)
-
-type BrightrollAdapter struct {
-	URI       string
-	extraInfo ExtraInfo
-}
-
-type ExtraInfo struct {
-	Accounts []Account `json:"accounts"`
-}
-
-type Account struct {
-	ID       string   `json:"id"`
-	Badv     []string `json:"badv"`
-	Bcat     []string `json:"bcat"`
-	Battr    []int8   `json:"battr"`
-	BidFloor float64  `json:"bidfloor"`
-}
-
-func (a *BrightrollAdapter) MakeRequests(requestIn *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
-
-	request := *requestIn
-	errs := make([]error, 0, len(request.Imp))
-	if len(request.Imp) == 0 {
-		err := &errortypes.BadInput{
-			Message: "No impression in the bid request",
-		}
-		errs = append(errs, err)
-		return nil, errs
-	}
-
-	errors := make([]error, 0, 1)
-
-	var bidderExt adapters.ExtImpBidder
-	err := json.Unmarshal(request.Imp[0].Ext, &bidderExt)
-	if err != nil {
-		err = &errortypes.BadInput{
-			Message: "ext.bidder not provided",
-		}
-		errors = append(errors, err)
-		return nil, errors
-	}
-	var brightrollExt openrtb_ext.ExtImpBrightroll
-	err = json.Unmarshal(bidderExt.Bidder, &brightrollExt)
-	if err != nil {
-		err = &errortypes.BadInput{
-			Message: "ext.bidder.publisher not provided",
-		}
-		errors = append(errors, err)
-		return nil, errors
-	}
-	if brightrollExt.Publisher == "" {
-		err = &errortypes.BadInput{
-			Message: "publisher is empty",
-		}
-		errors = append(errors, err)
-		return nil, errors
-	}
-
-	var account *Account
-	for _, a := range a.extraInfo.Accounts {
-		if a.ID == brightrollExt.Publisher {
-			account = &a
-			break
-		}
-	}
-
-	if account == nil {
-		err = &errortypes.BadInput{
-			Message: "Invalid publisher",
-		}
-		errors = append(errors, err)
-		return nil, errors
-	}
-
-	validImpExists := false
-	for i := 0; i < len(request.Imp); i++ {
-		//Brightroll supports only banner and video impressions as of now
-		if request.Imp[i].Banner != nil {
-			bannerCopy := *request.Imp[i].Banner
-			if bannerCopy.W == nil && bannerCopy.H == nil && len(bannerCopy.Format) > 0 {
-				firstFormat := bannerCopy.Format[0]
-				bannerCopy.W = &(firstFormat.W)
-				bannerCopy.H = &(firstFormat.H)
-			}
-
-			if len(account.Battr) > 0 {
-				bannerCopy.BAttr = getBlockedCreativetypes(account.Battr)
-			}
-			request.Imp[i].Banner = &bannerCopy
-			validImpExists = true
-		} else if request.Imp[i].Video != nil {
-			validImpExists = true
-			if brightrollExt.Publisher == "adthrive" {
-				videoCopy := *request.Imp[i].Video
-				if len(account.Battr) > 0 {
-					videoCopy.BAttr = getBlockedCreativetypes(account.Battr)
-				}
-				request.Imp[i].Video = &videoCopy
-			}
-		}
-		if validImpExists && request.Imp[i].BidFloor == 0 && account.BidFloor > 0 {
-			request.Imp[i].BidFloor = account.BidFloor
-		}
-	}
-	if !validImpExists {
-		err := &errortypes.BadInput{
-			Message: fmt.Sprintf("No valid impression in the bid request"),
-		}
-		errs = append(errs, err)
-		return nil, errs
-	}
-
-	request.AT = 1 //Defaulting to first price auction for all prebid requests
-
-	if len(account.Bcat) > 0 {
-		request.BCat = account.Bcat
-	}
-
-	if len(account.Badv) > 0 {
-		request.BAdv = account.Badv
-	}
-	reqJSON, err := json.Marshal(request)
-	if err != nil {
-		errs = append(errs, err)
-		return nil, errs
-	}
-	thisURI := a.URI
-	thisURI = thisURI + "?publisher=" + brightrollExt.Publisher
-	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 {
-		addHeaderIfNonEmpty(headers, "User-Agent", request.Device.UA)
-		addHeaderIfNonEmpty(headers, "X-Forwarded-For", request.Device.IP)
-		addHeaderIfNonEmpty(headers, "Accept-Language", request.Device.Language)
-		if request.Device.DNT != nil {
-			addHeaderIfNonEmpty(headers, "DNT", strconv.Itoa(int(*request.Device.DNT)))
-		}
-	}
-
-	return []*adapters.RequestData{{
-		Method:  "POST",
-		Uri:     thisURI,
-		Body:    reqJSON,
-		Headers: headers,
-	}}, errors
-}
-
-func (a *BrightrollAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
-
-	if response.StatusCode == http.StatusNoContent {
-		return nil, nil
-	}
-
-	if response.StatusCode == http.StatusBadRequest {
-		return nil, []error{&errortypes.BadInput{
-			Message: fmt.Sprintf("Unexpected status code: %d. ", response.StatusCode),
-		}}
-	}
-
-	if response.StatusCode != http.StatusOK {
-		return nil, []error{&errortypes.BadServerResponse{
-			Message: fmt.Sprintf("unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
-		}}
-	}
-
-	var bidResp openrtb2.BidResponse
-	if err := json.Unmarshal(response.Body, &bidResp); err != nil {
-		return nil, []error{&errortypes.BadServerResponse{
-			Message: fmt.Sprintf("bad server response: %d. ", err),
-		}}
-	}
-
-	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid))
-	sb := bidResp.SeatBid[0]
-	for i := 0; i < len(sb.Bid); i++ {
-		bid := sb.Bid[i]
-		bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
-			Bid:     &bid,
-			BidType: getMediaTypeForImp(bid.ImpID, internalRequest.Imp),
-		})
-	}
-	return bidResponse, nil
-}
-
-func getBlockedCreativetypes(attr []int8) []adcom1.CreativeAttribute {
-	var creativeAttr []adcom1.CreativeAttribute
-	for i := 0; i < len(attr); i++ {
-		creativeAttr = append(creativeAttr, adcom1.CreativeAttribute(attr[i]))
-	}
-	return creativeAttr
-}
-
-// Adding header fields to request header
-func addHeaderIfNonEmpty(headers http.Header, headerName string, headerValue string) {
-	if len(headerValue) > 0 {
-		headers.Add(headerName, headerValue)
-	}
-}
-
-// getMediaTypeForImp figures out which media type this bid is for.
-func getMediaTypeForImp(impId string, imps []openrtb2.Imp) openrtb_ext.BidType {
-	mediaType := openrtb_ext.BidTypeBanner //default type
-	for _, imp := range imps {
-		if imp.ID == impId {
-			if imp.Video != nil {
-				mediaType = openrtb_ext.BidTypeVideo
-			}
-			return mediaType
-		}
-	}
-	return mediaType
-}
-
-// Builder builds a new instance of the Brightroll adapter for the given bidder with the given config.
-func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
-	extraInfo, err := getExtraInfo(config.ExtraAdapterInfo)
-	if err != nil {
-		return nil, err
-	}
-
-	bidder := &BrightrollAdapter{
-		URI:       config.Endpoint,
-		extraInfo: extraInfo,
-	}
-	return bidder, nil
-}
-
-func getExtraInfo(v string) (ExtraInfo, error) {
-	if len(v) == 0 {
-		return getDefaultExtraInfo(), nil
-	}
-
-	var extraInfo ExtraInfo
-	if err := json.Unmarshal([]byte(v), &extraInfo); err != nil {
-		return extraInfo, fmt.Errorf("invalid extra info: %v", err)
-	}
-
-	return extraInfo, nil
-}
-
-func getDefaultExtraInfo() ExtraInfo {
-	return ExtraInfo{
-		Accounts: []Account{},
-	}
-}
diff --git a/adapters/ownadx/ownadx.go b/adapters/ownadx/ownadx.go
new file mode 100644
index 00000000..c19343ba
--- /dev/null
+++ b/adapters/ownadx/ownadx.go
@@ -0,0 +1,213 @@
+package ownadx
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/prebid/openrtb/v19/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"
+	"net/http"
+	"text/template"
+)
+
+type adapter struct {
+	endpoint *template.Template
+}
+type bidExt struct {
+	MediaType string `json:"mediaType"`
+}
+
+func (adapter *adapter) getRequestData(bidRequest *openrtb2.BidRequest, impExt *openrtb_ext.ExtImpOwnAdx, imps []openrtb2.Imp) (*adapters.RequestData, error) {
+	pbidRequest := createBidRequest(bidRequest, imps)
+	reqJSON, err := json.Marshal(pbidRequest)
+	if err != nil {
+		return nil, &errortypes.BadInput{
+			Message: "Prebid bidder request not valid or can't be marshalled. Err: " + err.Error(),
+		}
+	}
+	url, err := adapter.buildEndpointURL(impExt)
+	if err != nil {
+		return nil, &errortypes.BadInput{
+			Message: "Error while creating endpoint. Err: " + err.Error(),
+		}
+	}
+
+	headers := http.Header{}
+	headers.Add("Content-Type", "application/json;charset=utf-8")
+	headers.Add("Accept", "application/json")
+	headers.Add("x-openrtb-version", "2.5")
+
+	return &adapters.RequestData{
+		Method:  "POST",
+		Uri:     url,
+		Body:    reqJSON,
+		Headers: headers}, nil
+
+}
+func createBidRequest(rtbBidRequest *openrtb2.BidRequest, imps []openrtb2.Imp) *openrtb2.BidRequest {
+	bidRequest := *rtbBidRequest
+	bidRequest.Imp = imps
+	return &bidRequest
+}
+func (adapter *adapter) buildEndpointURL(params *openrtb_ext.ExtImpOwnAdx) (string, error) {
+	endpointParams := macros.EndpointTemplateParams{
+		ZoneID:    params.SspId,
+		AccountID: params.SeatId,
+		SourceId:  params.TokenId,
+	}
+	return macros.ResolveMacros(adapter.endpoint, endpointParams)
+}
+
+func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpOwnAdx, error) {
+	var bidderExt adapters.ExtImpBidder
+	if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
+		return nil, &errortypes.BadInput{
+			Message: "Bidder extension not valid or can't be unmarshalled",
+		}
+	}
+
+	var ownAdxExt openrtb_ext.ExtImpOwnAdx
+	if err := json.Unmarshal(bidderExt.Bidder, &ownAdxExt); err != nil {
+		return nil, &errortypes.BadInput{
+			Message: "Error while unmarshaling bidder extension",
+		}
+	}
+
+	return &ownAdxExt, nil
+}
+
+func (adapter *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+
+	errs := make([]error, 0, len(request.Imp))
+	if len(request.Imp) == 0 {
+		errs = append(errs, &errortypes.BadInput{
+			Message: "No impression in the bid request"},
+		)
+		return nil, errs
+	}
+	extImps, errors := groupImpsByExt(request.Imp)
+	if len(errors) != 0 {
+		errs = append(errs, errors...)
+	}
+	if len(extImps) == 0 {
+		return nil, errs
+	}
+	reqDetail := make([]*adapters.RequestData, 0, len(extImps))
+	for k, imps := range extImps {
+		bidRequest, err := adapter.getRequestData(request, &k, imps)
+		if err != nil {
+			errs = append(errs, err)
+		} else {
+			reqDetail = append(reqDetail, bidRequest)
+		}
+	}
+	return reqDetail, errs
+}
+func groupImpsByExt(imps []openrtb2.Imp) (map[openrtb_ext.ExtImpOwnAdx][]openrtb2.Imp, []error) {
+	respExt := make(map[openrtb_ext.ExtImpOwnAdx][]openrtb2.Imp)
+	errors := make([]error, 0, len(imps))
+	for _, imp := range imps {
+		ownAdxExt, err := getImpressionExt(&(imp))
+		if err != nil {
+			errors = append(errors, err)
+			continue
+		}
+
+		respExt[*ownAdxExt] = append(respExt[*ownAdxExt], imp)
+	}
+	return respExt, errors
+}
+
+func (adapter *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+	if response.StatusCode == http.StatusNoContent {
+		return nil, nil
+	}
+	if response.StatusCode == http.StatusBadRequest {
+		return nil, []error{
+			&errortypes.BadServerResponse{
+				Message: fmt.Sprintf("Bad request: %d", response.StatusCode),
+			},
+		}
+	}
+	if response.StatusCode != http.StatusOK {
+		return nil, []error{
+			&errortypes.BadServerResponse{
+				Message: fmt.Sprintf("Unexpected status code: %d. Run with request.test = 1 for more info.", response.StatusCode),
+			},
+		}
+	}
+	var bidResp openrtb2.BidResponse
+	if err := json.Unmarshal(response.Body, &bidResp); err != nil {
+		return nil, []error{
+			&errortypes.BadServerResponse{
+				Message: fmt.Sprintf("Bad server response "),
+			},
+		}
+	}
+	if len(bidResp.SeatBid) == 0 {
+		return nil, []error{
+			&errortypes.BadServerResponse{
+				Message: fmt.Sprintf("Array SeatBid cannot be empty "),
+			},
+		}
+	}
+
+	seatBid := bidResp.SeatBid[0]
+	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid))
+	if len(seatBid.Bid) == 0 {
+		return nil, []error{
+			&errortypes.BadServerResponse{
+				Message: fmt.Sprintf("Bid cannot be empty "),
+			},
+		}
+	}
+	for i := 0; i < len(seatBid.Bid); i++ {
+		var bidType openrtb_ext.BidType
+		bid := seatBid.Bid[i]
+
+		bidType, err := getMediaType(bid)
+		if err != nil {
+			return nil, []error{&errortypes.BadServerResponse{
+				Message: "Bid type is invalid",
+			}}
+		}
+		bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
+			Bid:     &bid,
+			BidType: bidType,
+		})
+	}
+
+	return bidResponse, nil
+}
+
+// Builder builds a new instance of the OwnAdx adapter for the given bidder with the given config
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
+	template, err := template.New("endpointTemplate").Parse(config.Endpoint)
+	if err != nil {
+		return nil, fmt.Errorf("unable to parse endpoint url template: %v", err)
+	}
+
+	bidder := &adapter{
+		endpoint: template,
+	}
+
+	return bidder, nil
+}
+
+func getMediaType(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
+	switch bid.MType {
+	case openrtb2.MarkupBanner:
+		return openrtb_ext.BidTypeBanner, nil
+	case openrtb2.MarkupVideo:
+		return openrtb_ext.BidTypeVideo, nil
+	case openrtb2.MarkupAudio:
+		return openrtb_ext.BidTypeAudio, nil
+	case openrtb2.MarkupNative:
+		return openrtb_ext.BidTypeNative, nil
+	default:
+		return "", fmt.Errorf("invalid BidType: %d", bid.MType)
+	}
+}
diff --git a/adapters/rtbhouse/rtbhouse.go b/adapters/rtbhouse/rtbhouse.go
index c8afb0c4..dc67df9a 100644
--- a/adapters/rtbhouse/rtbhouse.go
+++ b/adapters/rtbhouse/rtbhouse.go
@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"net/http"
+	"strings"
 
 	"github.com/prebid/openrtb/v19/openrtb2"
 	"github.com/prebid/prebid-server/adapters"
@@ -12,6 +13,15 @@ import (
 	"github.com/prebid/prebid-server/openrtb_ext"
 )
 
+const (
+	BidderCurrency string = "USD"
+)
+
+// RTBHouseAdapter implements the Bidder interface.
+type RTBHouseAdapter struct {
+	endpoint string
+}
+
 // Builder builds a new instance of the RTBHouse adapter for the given bidder with the given config.
 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
 	bidder := &RTBHouseAdapter{
@@ -20,11 +30,6 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co
 	return bidder, nil
 }
 
-// RTBHouseAdapter implements the Bidder interface.
-type RTBHouseAdapter struct {
-	endpoint string
-}
-
 // MakeRequests prepares the HTTP requests which should be made to fetch bids.
 func (adapter *RTBHouseAdapter) MakeRequests(
 	openRTBRequest *openrtb2.BidRequest,
@@ -33,7 +38,48 @@ func (adapter *RTBHouseAdapter) MakeRequests(
 	requestsToBidder []*adapters.RequestData,
 	errs []error,
 ) {
-	openRTBRequestJSON, err := json.Marshal(openRTBRequest)
+
+	reqCopy := *openRTBRequest
+	reqCopy.Imp = []openrtb2.Imp{}
+	for _, imp := range openRTBRequest.Imp {
+		var bidFloorCur = imp.BidFloorCur
+		var bidFloor = imp.BidFloor
+		if bidFloorCur == "" && bidFloor == 0 {
+			rtbhouseExt, err := getImpressionExt(imp)
+			if err != nil {
+				return nil, []error{err}
+			}
+			if rtbhouseExt.BidFloor > 0 && len(reqCopy.Cur) > 0 {
+				bidFloorCur = reqCopy.Cur[0]
+				bidFloor = rtbhouseExt.BidFloor
+			}
+		}
+
+		// Check if imp comes with bid floor amount defined in a foreign currency
+		if bidFloor > 0 && bidFloorCur != "" && strings.ToUpper(bidFloorCur) != BidderCurrency {
+			// Convert to US dollars
+			convertedValue, err := reqInfo.ConvertCurrency(bidFloor, bidFloorCur, BidderCurrency)
+			if err != nil {
+				return nil, []error{err}
+			}
+
+			bidFloorCur = BidderCurrency
+			bidFloor = convertedValue
+		}
+
+		if bidFloor > 0 && bidFloorCur == BidderCurrency {
+			// Update after conversion. All imp elements inside request.Imp are shallow copies
+			// therefore, their non-pointer values are not shared memory and are safe to modify.
+			imp.BidFloorCur = bidFloorCur
+			imp.BidFloor = bidFloor
+		}
+
+		// Set the CUR of bid to BIDDER_CURRENCY after converting all floors
+		reqCopy.Cur = []string{BidderCurrency}
+		reqCopy.Imp = append(reqCopy.Imp, imp)
+	}
+
+	openRTBRequestJSON, err := json.Marshal(reqCopy)
 	if err != nil {
 		errs = append(errs, err)
 		return nil, errs
@@ -52,6 +98,24 @@ func (adapter *RTBHouseAdapter) MakeRequests(
 	return requestsToBidder, errs
 }
 
+func getImpressionExt(imp openrtb2.Imp) (*openrtb_ext.ExtImpRTBHouse, error) {
+	var bidderExt adapters.ExtImpBidder
+	if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
+		return nil, &errortypes.BadInput{
+			Message: "Bidder extension not provided or can't be unmarshalled",
+		}
+	}
+
+	var rtbhouseExt openrtb_ext.ExtImpRTBHouse
+	if err := json.Unmarshal(bidderExt.Bidder, &rtbhouseExt); err != nil {
+		return nil, &errortypes.BadInput{
+			Message: "Error while unmarshaling bidder extension",
+		}
+	}
+
+	return &rtbhouseExt, nil
+}
+
 const unexpectedStatusCodeFormat = "" +
 	"Unexpected status code: %d. Run with request.debug = 1 for more info"
 
@@ -97,6 +161,8 @@ func (adapter *RTBHouseAdapter) MakeBids(
 		}
 	}
 
+	bidderResponse.Currency = BidderCurrency
+
 	return bidderResponse, nil
 
 }
diff --git a/adapters/vox/vox.go b/adapters/vox/vox.go
new file mode 100644
index 00000000..0b56fcbf
--- /dev/null
+++ b/adapters/vox/vox.go
@@ -0,0 +1,86 @@
+package vox
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/prebid/openrtb/v19/openrtb2"
+	"github.com/prebid/prebid-server/adapters"
+	"github.com/prebid/prebid-server/config"
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+type adapter struct {
+	endpoint string
+}
+
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
+	bidder := &adapter{
+		endpoint: config.Endpoint,
+	}
+	return bidder, nil
+}
+
+func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+	requestJSON, err := json.Marshal(request)
+	if err != nil {
+		return nil, []error{err}
+	}
+
+	requestData := &adapters.RequestData{
+		Method: "POST",
+		Uri:    a.endpoint,
+		Body:   requestJSON,
+	}
+
+	return []*adapters.RequestData{requestData}, nil
+}
+
+func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+	if adapters.IsResponseStatusCodeNoContent(responseData) {
+		return nil, nil
+	}
+
+	if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil {
+		return nil, []error{err}
+	}
+
+	var response openrtb2.BidResponse
+	if err := json.Unmarshal(responseData.Body, &response); err != nil {
+		return nil, []error{err}
+	}
+
+	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
+	bidResponse.Currency = response.Cur
+
+	for _, seatBid := range response.SeatBid {
+		for i, bid := range seatBid.Bid {
+			bidType, err := getMediaTypeForBid(bid)
+			if err != nil {
+				return nil, []error{err}
+			}
+
+			b := &adapters.TypedBid{
+				Bid:     &seatBid.Bid[i],
+				BidType: bidType,
+			}
+			bidResponse.Bids = append(bidResponse.Bids, b)
+		}
+	}
+
+	return bidResponse, nil
+}
+
+func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
+	switch bid.MType {
+	case openrtb2.MarkupBanner:
+		return openrtb_ext.BidTypeBanner, nil
+	case openrtb2.MarkupVideo:
+		return openrtb_ext.BidTypeVideo, nil
+	case openrtb2.MarkupAudio:
+		return openrtb_ext.BidTypeAudio, nil
+	case openrtb2.MarkupNative:
+		return openrtb_ext.BidTypeNative, nil
+	default:
+		return "", fmt.Errorf("Unable to fetch mediaType in multi-format: %s", bid.ImpID)
+	}
+}
diff --git a/config/bidderinfo.go b/config/bidderinfo.go
index b4d79001..630952a6 100644
--- a/config/bidderinfo.go
+++ b/config/bidderinfo.go
@@ -162,7 +162,7 @@ type SyncerEndpoint struct {
 	// startup:
 	//
 	//  {{.ExternalURL}} - This will be replaced with the host server's externally reachable http path.
-	//  {{.SyncerKey}}   - This will be replaced with the syncer key.
+	//  {{.BidderName}}  - This will be replaced with the bidder name.
 	//  {{.SyncType}}    - This will be replaced with the sync type, either 'b' for iframe syncs or 'i'
 	//                     for redirect/image syncs.
 	//  {{.UserMacro}}   - This will be replaced with the bidder server's user id macro.
diff --git a/endpoints/setuid.go b/endpoints/setuid.go
index 905fa26b..25fb2465 100644
--- a/endpoints/setuid.go
+++ b/endpoints/setuid.go
@@ -39,13 +39,6 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use
 	encoder := usersync.Base64Encoder{}
 	decoder := usersync.Base64Decoder{}
 
-	// convert map of syncers by bidder to map of syncers by key
-	// - its safe to assume that if multiple bidders map to the same key, the syncers are interchangeable.
-	syncersByKey := make(map[string]usersync.Syncer, len(syncersByBidder))
-	for _, v := range syncersByBidder {
-		syncersByKey[v.Key()] = v
-	}
-
 	return httprouter.Handle(func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
 		so := analytics.SetUIDObject{
 			Status: http.StatusOK,
@@ -65,7 +58,7 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use
 
 		query := r.URL.Query()
 
-		syncer, err := getSyncer(query, syncersByKey)
+		syncer, err := getSyncer(query, syncersByBidder)
 		if err != nil {
 			w.WriteHeader(http.StatusBadRequest)
 			w.Write([]byte(err.Error()))
@@ -313,14 +306,14 @@ func parseConsentFromGppStr(gppQueryValue string) (string, error) {
 	return gdprConsent, nil
 }
 
-func getSyncer(query url.Values, syncersByKey map[string]usersync.Syncer) (usersync.Syncer, error) {
-	key := query.Get("bidder")
+func getSyncer(query url.Values, syncersByBidder map[string]usersync.Syncer) (usersync.Syncer, error) {
+	bidder := query.Get("bidder")
 
-	if key == "" {
+	if bidder == "" {
 		return nil, errors.New(`"bidder" query param is required`)
 	}
 
-	syncer, syncerExists := syncersByKey[key]
+	syncer, syncerExists := syncersByBidder[bidder]
 	if !syncerExists {
 		return nil, errors.New("The bidder name provided is not supported by Prebid Server")
 	}
diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go
index f8344525..a1038d71 100755
--- a/exchange/adapter_builders.go
+++ b/exchange/adapter_builders.go
@@ -56,7 +56,6 @@ import (
 	"github.com/prebid/prebid-server/adapters/bmtm"
 	"github.com/prebid/prebid-server/adapters/boldwin"
 	"github.com/prebid/prebid-server/adapters/brave"
-	"github.com/prebid/prebid-server/adapters/brightroll"
 	"github.com/prebid/prebid-server/adapters/ccx"
 	"github.com/prebid/prebid-server/adapters/coinzilla"
 	"github.com/prebid/prebid-server/adapters/colossus"
@@ -128,6 +127,7 @@ import (
 	"github.com/prebid/prebid-server/adapters/operaads"
 	"github.com/prebid/prebid-server/adapters/orbidder"
 	"github.com/prebid/prebid-server/adapters/outbrain"
+	"github.com/prebid/prebid-server/adapters/ownadx"
 	"github.com/prebid/prebid-server/adapters/pangle"
 	"github.com/prebid/prebid-server/adapters/pubmatic"
 	"github.com/prebid/prebid-server/adapters/pubnative"
@@ -169,6 +169,7 @@ import (
 	"github.com/prebid/prebid-server/adapters/vidoomy"
 	"github.com/prebid/prebid-server/adapters/visiblemeasures"
 	"github.com/prebid/prebid-server/adapters/visx"
+	"github.com/prebid/prebid-server/adapters/vox"
 	"github.com/prebid/prebid-server/adapters/vrtcal"
 	"github.com/prebid/prebid-server/adapters/xeworks"
 	"github.com/prebid/prebid-server/adapters/yahooAds"
@@ -242,7 +243,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderBmtm:              bmtm.Builder,
 		openrtb_ext.BidderBoldwin:           boldwin.Builder,
 		openrtb_ext.BidderBrave:             brave.Builder,
-		openrtb_ext.BidderBrightroll:        brightroll.Builder,
 		openrtb_ext.BidderCcx:               ccx.Builder,
 		openrtb_ext.BidderCoinzilla:         coinzilla.Builder,
 		openrtb_ext.BidderColossus:          colossus.Builder,
@@ -321,6 +321,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderOperaads:          operaads.Builder,
 		openrtb_ext.BidderOrbidder:          orbidder.Builder,
 		openrtb_ext.BidderOutbrain:          outbrain.Builder,
+		openrtb_ext.BidderOwnAdx:            ownadx.Builder,
 		openrtb_ext.BidderPangle:            pangle.Builder,
 		openrtb_ext.BidderPGAM:              adtelligent.Builder,
 		openrtb_ext.BidderPubmatic:          pubmatic.Builder,
@@ -369,6 +370,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderViewdeos:          adtelligent.Builder,
 		openrtb_ext.BidderVisibleMeasures:   visiblemeasures.Builder,
 		openrtb_ext.BidderVisx:              visx.Builder,
+		openrtb_ext.BidderVox:               vox.Builder,
 		openrtb_ext.BidderVrtcal:            vrtcal.Builder,
 		openrtb_ext.BidderXeworks:           xeworks.Builder,
 		openrtb_ext.BidderYahooAds:          yahooAds.Builder,
diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go
index 9551ab3e..624a22ce 100644
--- a/exchange/adapter_util.go
+++ b/exchange/adapter_util.go
@@ -97,6 +97,7 @@ func GetDisabledBiddersErrorMessages(infos config.BidderInfos) map[string]string
 		"oftmedia":       `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`,
 		"groupm":         `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`,
 		"verizonmedia":   `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`,
+		"brightroll":     `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`,
 	}
 
 	for name, info := range infos {
diff --git a/exchange/utils.go b/exchange/utils.go
index 5b29fd62..8fd8f8c3 100644
--- a/exchange/utils.go
+++ b/exchange/utils.go
@@ -363,12 +363,13 @@ func buildRequestExtForBidder(bidder string, requestExt json.RawMessage, request
 	}
 
 	if requestExtParsed != nil {
-		prebid.CurrencyConversions = requestExtParsed.Prebid.CurrencyConversions
-		prebid.Integration = requestExtParsed.Prebid.Integration
 		prebid.Channel = requestExtParsed.Prebid.Channel
+		prebid.CurrencyConversions = requestExtParsed.Prebid.CurrencyConversions
 		prebid.Debug = requestExtParsed.Prebid.Debug
-		prebid.Server = requestExtParsed.Prebid.Server
+		prebid.Integration = requestExtParsed.Prebid.Integration
 		prebid.MultiBid = buildRequestExtMultiBid(bidder, requestExtParsed.Prebid.MultiBid, alternateBidderCodes)
+		prebid.Sdk = requestExtParsed.Prebid.Sdk
+		prebid.Server = requestExtParsed.Prebid.Server
 	}
 
 	// Marshal New Prebid Object
diff --git a/openrtb_ext/bid.go b/openrtb_ext/bid.go
index 20bbf0b3..7dc620d4 100644
--- a/openrtb_ext/bid.go
+++ b/openrtb_ext/bid.go
@@ -50,6 +50,7 @@ type ExtBidPrebidCacheBids struct {
 
 // ExtBidPrebidMeta defines the contract for bidresponse.seatbid.bid[i].ext.prebid.meta
 type ExtBidPrebidMeta struct {
+	AdapterCode          string          `json:"adaptercode,omitempty"`
 	AdvertiserDomains    []string        `json:"advertiserDomains,omitempty"`
 	AdvertiserID         int             `json:"advertiserId,omitempty"`
 	AdvertiserName       string          `json:"advertiserName,omitempty"`
@@ -57,14 +58,15 @@ type ExtBidPrebidMeta struct {
 	AgencyName           string          `json:"agencyName,omitempty"`
 	BrandID              int             `json:"brandId,omitempty"`
 	BrandName            string          `json:"brandName,omitempty"`
-	DemandSource         string          `json:"demandSource,omitempty"`
 	DChain               json.RawMessage `json:"dchain,omitempty"`
+	DemandSource         string          `json:"demandSource,omitempty"`
 	MediaType            string          `json:"mediaType,omitempty"`
 	NetworkID            int             `json:"networkId,omitempty"`
 	NetworkName          string          `json:"networkName,omitempty"`
 	PrimaryCategoryID    string          `json:"primaryCatId,omitempty"`
+	RendererName         string          `json:"rendererName,omitempty"`
+	RendererVersion      string          `json:"rendererVersion,omitempty"`
 	SecondaryCategoryIDs []string        `json:"secondaryCatIds,omitempty"`
-	AdapterCode          string          `json:"adaptercode,omitempty"`
 }
 
 // ExtBidPrebidVideo defines the contract for bidresponse.seatbid.bid[i].ext.prebid.video
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index 978af5e0..e9cc81f8 100644
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -142,7 +142,6 @@ const (
 	BidderBmtm              BidderName = "bmtm"
 	BidderBoldwin           BidderName = "boldwin"
 	BidderBrave             BidderName = "brave"
-	BidderBrightroll        BidderName = "brightroll"
 	BidderCcx               BidderName = "ccx"
 	BidderCoinzilla         BidderName = "coinzilla"
 	BidderColossus          BidderName = "colossus"
@@ -221,6 +220,7 @@ const (
 	BidderOperaads          BidderName = "operaads"
 	BidderOrbidder          BidderName = "orbidder"
 	BidderOutbrain          BidderName = "outbrain"
+	BidderOwnAdx            BidderName = "ownadx"
 	BidderPangle            BidderName = "pangle"
 	BidderPGAM              BidderName = "pgam"
 	BidderPubmatic          BidderName = "pubmatic"
@@ -269,6 +269,7 @@ const (
 	BidderViewdeos          BidderName = "viewdeos"
 	BidderVisibleMeasures   BidderName = "visiblemeasures"
 	BidderVisx              BidderName = "visx"
+	BidderVox               BidderName = "vox"
 	BidderVrtcal            BidderName = "vrtcal"
 	BidderXeworks           BidderName = "xeworks"
 	BidderYahooAds          BidderName = "yahooAds"
@@ -341,7 +342,6 @@ func CoreBidderNames() []BidderName {
 		BidderBmtm,
 		BidderBoldwin,
 		BidderBrave,
-		BidderBrightroll,
 		BidderCcx,
 		BidderCoinzilla,
 		BidderColossus,
@@ -420,6 +420,7 @@ func CoreBidderNames() []BidderName {
 		BidderOperaads,
 		BidderOrbidder,
 		BidderOutbrain,
+		BidderOwnAdx,
 		BidderPangle,
 		BidderPGAM,
 		BidderPubmatic,
@@ -468,6 +469,7 @@ func CoreBidderNames() []BidderName {
 		BidderViewdeos,
 		BidderVisibleMeasures,
 		BidderVisx,
+		BidderVox,
 		BidderVrtcal,
 		BidderXeworks,
 		BidderYahooAds,
diff --git a/openrtb_ext/imp_brightroll.go b/openrtb_ext/imp_brightroll.go
deleted file mode 100644
index bd42d4aa..00000000
--- a/openrtb_ext/imp_brightroll.go
+++ /dev/null
@@ -1,6 +0,0 @@
-package openrtb_ext
-
-// ExtImpBrightroll defines the contract for bidrequest.imp[i].ext.prebid.bidder.brightroll
-type ExtImpBrightroll struct {
-	Publisher string `json:"publisher"`
-}
diff --git a/openrtb_ext/imp_ownadx.go b/openrtb_ext/imp_ownadx.go
new file mode 100644
index 00000000..caac600b
--- /dev/null
+++ b/openrtb_ext/imp_ownadx.go
@@ -0,0 +1,7 @@
+package openrtb_ext
+
+type ExtImpOwnAdx struct {
+	SspId   string `json:"sspId"`
+	SeatId  string `json:"seatId"`
+	TokenId string `json:"tokenId"`
+}
diff --git a/openrtb_ext/imp_rtbhouse.go b/openrtb_ext/imp_rtbhouse.go
new file mode 100644
index 00000000..747ea158
--- /dev/null
+++ b/openrtb_ext/imp_rtbhouse.go
@@ -0,0 +1,10 @@
+package openrtb_ext
+
+// ExtImpRTBHouse defines the contract for bidrequest.imp[i].ext.prebid.bidder.rtbhouse
+type ExtImpRTBHouse struct {
+	PublisherId string `json:"publisherId"`
+	Region      string `json:"region"`
+
+	BidFloor float64 `json:"bidfloor,omitempty"`
+	Channel  string  `json:"channel,omitempty"`
+}
diff --git a/openrtb_ext/imp_vox.go b/openrtb_ext/imp_vox.go
new file mode 100644
index 00000000..a6152507
--- /dev/null
+++ b/openrtb_ext/imp_vox.go
@@ -0,0 +1,7 @@
+package openrtb_ext
+
+type ImpExtVox struct {
+	PlacementID  string   `json:"placementId"`
+	ImageUrl     string   `json:"imageUrl"`
+	DisplaySizes []string `json:"displaySizes"`
+}
diff --git a/openrtb_ext/request.go b/openrtb_ext/request.go
index adf00fcd..6f39f0be 100644
--- a/openrtb_ext/request.go
+++ b/openrtb_ext/request.go
@@ -41,52 +41,54 @@ type ExtRequest struct {
 
 // ExtRequestPrebid defines the contract for bidrequest.ext.prebid
 type ExtRequestPrebid struct {
-	Aliases              map[string]string         `json:"aliases,omitempty"`
-	AliasGVLIDs          map[string]uint16         `json:"aliasgvlids,omitempty"`
-	BidAdjustmentFactors map[string]float64        `json:"bidadjustmentfactors,omitempty"`
-	BidderConfigs        []BidderConfig            `json:"bidderconfig,omitempty"`
-	BidderParams         json.RawMessage           `json:"bidderparams,omitempty"`
-	Cache                *ExtRequestPrebidCache    `json:"cache,omitempty"`
-	Channel              *ExtRequestPrebidChannel  `json:"channel,omitempty"`
-	CurrencyConversions  *ExtRequestCurrency       `json:"currency,omitempty"`
-	Data                 *ExtRequestPrebidData     `json:"data,omitempty"`
-	Debug                bool                      `json:"debug,omitempty"`
-	Events               json.RawMessage           `json:"events,omitempty"`
-	Experiment           *Experiment               `json:"experiment,omitempty"`
-	Integration          string                    `json:"integration,omitempty"`
-	MultiBid             []*ExtMultiBid            `json:"multibid,omitempty"`
-	Passthrough          json.RawMessage           `json:"passthrough,omitempty"`
-	SChains              []*ExtRequestPrebidSChain `json:"schains,omitempty"`
-	Server               *ExtRequestPrebidServer   `json:"server,omitempty"`
-	StoredRequest        *ExtStoredRequest         `json:"storedrequest,omitempty"`
-	SupportDeals         bool                      `json:"supportdeals,omitempty"`
-	Targeting            *ExtRequestTargeting      `json:"targeting,omitempty"`
+	AdServerTargeting    []AdServerTarget                `json:"adservertargeting,omitempty"`
+	Aliases              map[string]string               `json:"aliases,omitempty"`
+	AliasGVLIDs          map[string]uint16               `json:"aliasgvlids,omitempty"`
+	BidAdjustmentFactors map[string]float64              `json:"bidadjustmentfactors,omitempty"`
+	BidAdjustments       *ExtRequestPrebidBidAdjustments `json:"bidadjustments,omitempty"`
+	BidderConfigs        []BidderConfig                  `json:"bidderconfig,omitempty"`
+	BidderParams         json.RawMessage                 `json:"bidderparams,omitempty"`
+	Cache                *ExtRequestPrebidCache          `json:"cache,omitempty"`
+	Channel              *ExtRequestPrebidChannel        `json:"channel,omitempty"`
+	CurrencyConversions  *ExtRequestCurrency             `json:"currency,omitempty"`
+	Data                 *ExtRequestPrebidData           `json:"data,omitempty"`
+	Debug                bool                            `json:"debug,omitempty"`
+	Events               json.RawMessage                 `json:"events,omitempty"`
+	Experiment           *Experiment                     `json:"experiment,omitempty"`
+	Floors               *PriceFloorRules                `json:"floors,omitempty"`
+	Integration          string                          `json:"integration,omitempty"`
+	MultiBid             []*ExtMultiBid                  `json:"multibid,omitempty"`
+	MultiBidMap          map[string]ExtMultiBid          `json:"-"`
+	Passthrough          json.RawMessage                 `json:"passthrough,omitempty"`
+	SChains              []*ExtRequestPrebidSChain       `json:"schains,omitempty"`
+	Sdk                  *ExtRequestSdk                  `json:"sdk,omitempty"`
+	Server               *ExtRequestPrebidServer         `json:"server,omitempty"`
+	StoredRequest        *ExtStoredRequest               `json:"storedrequest,omitempty"`
+	SupportDeals         bool                            `json:"supportdeals,omitempty"`
+	Targeting            *ExtRequestTargeting            `json:"targeting,omitempty"`
+
+	//AlternateBidderCodes is populated with host's AlternateBidderCodes config if not defined in request
+	AlternateBidderCodes *ExtAlternateBidderCodes `json:"alternatebiddercodes,omitempty"`
+
+	// Macros specifies list of custom macros along with the values. This is used while forming
+	// the tracker URLs, where PBS will replace the Custom Macro with its value with url-encoding
+	Macros map[string]string `json:"macros,omitempty"`
 
 	// NoSale specifies bidders with whom the publisher has a legal relationship where the
 	// passing of personally identifiable information doesn't constitute a sale per CCPA law.
 	// The array may contain a single sstar ('*') entry to represent all bidders.
 	NoSale []string `json:"nosale,omitempty"`
 
-	//AlternateBidderCodes is populated with host's AlternateBidderCodes config if not defined in request
-	AlternateBidderCodes *ExtAlternateBidderCodes `json:"alternatebiddercodes,omitempty"`
+	// ReturnAllBidStatus if true populates bidresponse.ext.prebid.seatnonbid with all bids which was
+	// either rejected, nobid, input error
+	ReturnAllBidStatus bool `json:"returnallbidstatus,omitempty"`
 
-	Floors      *PriceFloorRules       `json:"floors,omitempty"`
-	MultiBidMap map[string]ExtMultiBid `json:"-"`
 	// Trace controls the level of detail in the output information returned from executing hooks.
 	// There are two options:
 	// - verbose: sets maximum level of output information
 	// - basic: excludes debugmessages and analytic_tags from output
 	// any other value or an empty string disables trace output at all.
 	Trace string `json:"trace,omitempty"`
-
-	// Macros specifies list of custom macros along with the values. This is used while forming
-	// the tracker URLs, where PBS will replace the Custom Macro with its value with url-encoding
-	Macros            map[string]string               `json:"macros,omitempty"`
-	AdServerTargeting []AdServerTarget                `json:"adservertargeting,omitempty"`
-	BidAdjustments    *ExtRequestPrebidBidAdjustments `json:"bidadjustments,omitempty"`
-	// ReturnAllBidStatus if true populates bidresponse.ext.prebid.seatnonbid with all bids which was
-	// either rejected, nobid, input error
-	ReturnAllBidStatus bool `json:"returnallbidstatus,omitempty"`
 }
 
 type AdServerTarget struct {
@@ -345,6 +347,15 @@ type ExtRequestPrebidDataEidPermission struct {
 	Bidders []string `json:"bidders"`
 }
 
+type ExtRequestSdk struct {
+	Renderers []ExtRequestSdkRenderer `json:"renderers,omitempty"`
+}
+
+type ExtRequestSdkRenderer struct {
+	Name    string `json:"name,omitempty"`
+	Version string `json:"version,omitempty"`
+}
+
 type ExtMultiBid struct {
 	Bidder                 string   `json:"bidder,omitempty"`
 	Bidders                []string `json:"bidders,omitempty"`
diff --git a/scripts/format.sh b/scripts/format.sh
new file mode 100755
index 00000000..d5f33e51
--- /dev/null
+++ b/scripts/format.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+die() { echo -e "$@" 1>&2 ; exit 1;  }
+
+AUTOFMT=true
+while getopts 'f:' OPTION; do
+  case "$OPTION" in
+    f)
+      AUTOFMT="$OPTARG"
+      ;;
+  esac
+done
+
+# Build a list of all the top-level directories in the project.
+for DIRECTORY in */ ; do
+  GOGLOB="$GOGLOB ${DIRECTORY%/}"
+done
+GOGLOB="${GOGLOB/ docs/}"
+GOGLOB="${GOGLOB/ vendor/}"
+
+# Check that there are no formatting issues
+GOFMT_LINES=`gofmt -s -l $GOGLOB | tr '\\\\' '/' | wc -l | xargs`
+if $AUTOFMT; then
+  # if there are files with formatting issues, they will be automatically corrected using the gofmt -w <file> command
+  if [[ $GOFMT_LINES -ne 0 ]]; then
+    FMT_FILES=`gofmt -s -l $GOGLOB | tr '\\\\' '/' | xargs`
+    for FILE in $FMT_FILES; do
+        echo "Running: gofmt -s -w $FILE"
+        `gofmt -s -w $FILE`
+    done
+  fi
+else
+  test $GOFMT_LINES -eq 0 || die "gofmt needs to be run, ${GOFMT_LINES} files have issues.  Below is a list of files to review:\n`gofmt -s -l $GOGLOB`"
+fi
\ No newline at end of file
diff --git a/static/bidder-info/brightroll.yaml b/static/bidder-info/brightroll.yaml
deleted file mode 100644
index 196344e9..00000000
--- a/static/bidder-info/brightroll.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-endpoint: "http://east-bid.ybp.yahoo.com/bid/appnexuspbs"
-maintainer:
-  email: "dsp-supply-prebid@verizonmedia.com"
-gvlVendorID: 25
-capabilities:
-  app:
-    mediaTypes:
-      - banner
-      - video
-  site:
-    mediaTypes:
-      - banner
-      - video
-userSync:
-  redirect:
-    url: "https://pr-bh.ybp.yahoo.com/sync/appnexusprebidserver/?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&url={{.RedirectURL}}"
-    userMacro: "$UID"
diff --git a/static/bidder-info/ownadx.yaml b/static/bidder-info/ownadx.yaml
new file mode 100644
index 00000000..37567db1
--- /dev/null
+++ b/static/bidder-info/ownadx.yaml
@@ -0,0 +1,12 @@
+endpoint: "https://pbs.prebid-ownadx.com/bidder/bid/{{.AccountID}}/{{.ZoneID}}?token={{.SourceId}}"
+maintainer:
+  email: prebid-team@techbravo.com
+capabilities:
+  app:
+    mediaTypes:
+      - banner
+      - video
+  site:
+    mediaTypes:
+      - banner
+      - video
diff --git a/static/bidder-info/rtbhouse.yaml b/static/bidder-info/rtbhouse.yaml
index 6a116448..ad2fbfcb 100644
--- a/static/bidder-info/rtbhouse.yaml
+++ b/static/bidder-info/rtbhouse.yaml
@@ -1,6 +1,7 @@
 endpoint: "http://prebidserver-s2s-ams.creativecdn.com/bidder/prebidserver/bids"
 maintainer:
   email: "prebid@rtbhouse.com"
+endpointCompression: gzip
 gvlVendorID: 16
 capabilities:
   site:
diff --git a/static/bidder-info/vox.yaml b/static/bidder-info/vox.yaml
new file mode 100644
index 00000000..e2b5c902
--- /dev/null
+++ b/static/bidder-info/vox.yaml
@@ -0,0 +1,19 @@
+endpoint: "https://ssp.hybrid.ai/prebid/server/v1/auction"
+maintainer:
+  email: prebid@hybrid.ai
+endpointCompression: gzip
+gvlVendorID: 206
+modifyingVastXmlAllowed: true
+capabilities:
+  site:
+    mediaTypes:
+      - banner
+      - video
+  app:
+    mediaTypes:
+      - banner
+      - video
+userSync:
+  redirect:
+    url: "https://ssp.hybrid.ai/prebid/server/v1/userSync?consent={{.GDPRConsent}}&redirect={{.RedirectURL}}"
+    userMacro: $UID
\ No newline at end of file
diff --git a/static/bidder-params/brightroll.json b/static/bidder-params/brightroll.json
deleted file mode 100644
index 48e48d8a..00000000
--- a/static/bidder-params/brightroll.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "$schema": "http://json-schema.org/draft-04/schema#",
-  "title": "Brightroll Adapter Params",
-  "description": "A schema which validates params accepted by the Brightroll adapter",
-  "type": "object",
-  "properties": {
-      "publisher": {
-        "type": "string",
-        "description": "Publisher Name to use."
-    }
-  },
-  "required": ["publisher"]
-}
diff --git a/static/bidder-params/ownadx.json b/static/bidder-params/ownadx.json
new file mode 100644
index 00000000..f529e74c
--- /dev/null
+++ b/static/bidder-params/ownadx.json
@@ -0,0 +1,27 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "title": "OwnAdx Adapter Params",
+  "description": "A schema which validates params accepted by the OwnAdx adapter",
+  "type": "object",
+
+  "properties": {
+    "sspId": {
+      "type": "string",
+      "description": "Ssp ID"
+    },
+    "seatId": {
+      "type": "string",
+      "description": "Seat ID"
+    },
+    "tokenId": {
+      "type": "string",
+      "description": "Token ID"
+    }
+  },
+
+  "oneOf": [
+    { "required": ["sspId"] },
+    { "required": ["feedId"] },
+    { "required": ["token"] }
+  ]
+}
diff --git a/static/bidder-params/rtbhouse.json b/static/bidder-params/rtbhouse.json
index 00732bed..727f51bc 100644
--- a/static/bidder-params/rtbhouse.json
+++ b/static/bidder-params/rtbhouse.json
@@ -7,6 +7,18 @@
         "publisherId": {
             "type": "string",
             "description": "The publisher’s ID provided by RTB House"
+        },
+        "region": {
+            "type": "string",
+            "description": "The publisher’s assigned datacenter region"
+        },
+        "bidfloor": {
+            "type": "number",
+            "description": "(optional) Minimum bid price in CPM that will be considered"
+        },
+        "channel": {
+            "type": "string",
+            "description": "Inventory channel identifier, limited to 50 characters"
         }
     },
     "required": ["publisherId"]
diff --git a/static/bidder-params/vox.json b/static/bidder-params/vox.json
new file mode 100644
index 00000000..2ae65e99
--- /dev/null
+++ b/static/bidder-params/vox.json
@@ -0,0 +1,27 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "title": "Vox Adapter Params",
+  "description": "A schema which validates params accepted by the Vox adapter",
+  "type": "object",
+
+  "properties": {
+    "placementId": {
+      "type": "string",
+      "description": "Placement ID"
+    },
+    "imageUrl": {
+      "type": "string",
+      "description": "An URL of image on which banner should be put(InImage Ad format)."
+    },
+    "displaySizes": {
+      "type": "array",
+      "items": {
+        "type": "string",
+        "description": "<Width>x<Height>(Example: 123x90, 720x100)"
+      },
+      "description": "Display banner sizes which could be shown on top of image."
+    }
+  },
+
+  "required": ["placementId"]
+}
\ No newline at end of file
diff --git a/usersync/syncer.go b/usersync/syncer.go
index 2e0e4102..fb14201f 100644
--- a/usersync/syncer.go
+++ b/usersync/syncer.go
@@ -63,7 +63,7 @@ var ErrSyncerKeyRequired = errors.New("key is required")
 
 // NewSyncer creates a new Syncer from the provided configuration, or return an error if macro substition
 // fails or an endpoint url is invalid.
-func NewSyncer(hostConfig config.UserSync, syncerConfig config.Syncer) (Syncer, error) {
+func NewSyncer(hostConfig config.UserSync, syncerConfig config.Syncer, bidder string) (Syncer, error) {
 	if syncerConfig.Key == "" {
 		return nil, ErrSyncerKeyRequired
 	}
@@ -80,7 +80,7 @@ func NewSyncer(hostConfig config.UserSync, syncerConfig config.Syncer) (Syncer,
 
 	if syncerConfig.IFrame != nil {
 		var err error
-		syncer.iframe, err = buildTemplate(syncerConfig.Key, setuidSyncTypeIFrame, hostConfig, syncerConfig.ExternalURL, *syncerConfig.IFrame)
+		syncer.iframe, err = buildTemplate(bidder, setuidSyncTypeIFrame, hostConfig, syncerConfig.ExternalURL, *syncerConfig.IFrame)
 		if err != nil {
 			return nil, fmt.Errorf("iframe %v", err)
 		}
@@ -91,7 +91,7 @@ func NewSyncer(hostConfig config.UserSync, syncerConfig config.Syncer) (Syncer,
 
 	if syncerConfig.Redirect != nil {
 		var err error
-		syncer.redirect, err = buildTemplate(syncerConfig.Key, setuidSyncTypeRedirect, hostConfig, syncerConfig.ExternalURL, *syncerConfig.Redirect)
+		syncer.redirect, err = buildTemplate(bidder, setuidSyncTypeRedirect, hostConfig, syncerConfig.ExternalURL, *syncerConfig.Redirect)
 		if err != nil {
 			return nil, fmt.Errorf("redirect %v", err)
 		}
@@ -114,13 +114,14 @@ func resolveDefaultSyncType(syncerConfig config.Syncer) SyncType {
 var (
 	macroRegexExternalHost = regexp.MustCompile(`{{\s*\.ExternalURL\s*}}`)
 	macroRegexSyncerKey    = regexp.MustCompile(`{{\s*\.SyncerKey\s*}}`)
+	macroRegexBidderName   = regexp.MustCompile(`{{\s*\.BidderName\s*}}`)
 	macroRegexSyncType     = regexp.MustCompile(`{{\s*\.SyncType\s*}}`)
 	macroRegexUserMacro    = regexp.MustCompile(`{{\s*\.UserMacro\s*}}`)
 	macroRegexRedirect     = regexp.MustCompile(`{{\s*\.RedirectURL\s*}}`)
 	macroRegex             = regexp.MustCompile(`{{\s*\..*?\s*}}`)
 )
 
-func buildTemplate(key, syncTypeValue string, hostConfig config.UserSync, syncerExternalURL string, syncerEndpoint config.SyncerEndpoint) (*template.Template, error) {
+func buildTemplate(bidderName, syncTypeValue string, hostConfig config.UserSync, syncerExternalURL string, syncerEndpoint config.SyncerEndpoint) (*template.Template, error) {
 	redirectTemplate := syncerEndpoint.RedirectURL
 	if redirectTemplate == "" {
 		redirectTemplate = hostConfig.RedirectURL
@@ -128,7 +129,8 @@ func buildTemplate(key, syncTypeValue string, hostConfig config.UserSync, syncer
 
 	externalURL := chooseExternalURL(syncerEndpoint.ExternalURL, syncerExternalURL, hostConfig.ExternalURL)
 
-	redirectURL := macroRegexSyncerKey.ReplaceAllLiteralString(redirectTemplate, key)
+	redirectURL := macroRegexSyncerKey.ReplaceAllLiteralString(redirectTemplate, bidderName)
+	redirectURL = macroRegexBidderName.ReplaceAllLiteralString(redirectURL, bidderName)
 	redirectURL = macroRegexSyncType.ReplaceAllLiteralString(redirectURL, syncTypeValue)
 	redirectURL = macroRegexUserMacro.ReplaceAllLiteralString(redirectURL, syncerEndpoint.UserMacro)
 	redirectURL = macroRegexExternalHost.ReplaceAllLiteralString(redirectURL, externalURL)
@@ -136,7 +138,7 @@ func buildTemplate(key, syncTypeValue string, hostConfig config.UserSync, syncer
 
 	url := macroRegexRedirect.ReplaceAllString(syncerEndpoint.URL, redirectURL)
 
-	templateName := strings.ToLower(key) + "_usersync_url"
+	templateName := strings.ToLower(bidderName) + "_usersync_url"
 	return template.New(templateName).Parse(url)
 }
 
diff --git a/usersync/syncersbuilder.go b/usersync/syncersbuilder.go
index c521d36d..9a52a740 100644
--- a/usersync/syncersbuilder.go
+++ b/usersync/syncersbuilder.go
@@ -59,17 +59,16 @@ func BuildSyncers(hostConfig *config.Configuration, bidderInfos config.BidderInf
 			continue
 		}
 
-		syncer, err := NewSyncer(hostUserSyncConfig, primaryCfg.cfg)
-		if err != nil {
-			errs = append(errs, SyncerBuildError{
-				Bidder:    primaryCfg.name,
-				SyncerKey: key,
-				Err:       err,
-			})
-			continue
-		}
-
 		for _, bidder := range cfgGroup {
+			syncer, err := NewSyncer(hostUserSyncConfig, primaryCfg.cfg, bidder.name)
+			if err != nil {
+				errs = append(errs, SyncerBuildError{
+					Bidder:    primaryCfg.name,
+					SyncerKey: key,
+					Err:       err,
+				})
+				continue
+			}
 			syncers[bidder.name] = syncer
 		}
 	}
diff --git a/validate.sh b/validate.sh
index b81ade34..becd42ce 100755
--- a/validate.sh
+++ b/validate.sh
@@ -17,29 +17,7 @@ while true; do
   esac
 done
 
-die() { echo -e "$@" 1>&2 ; exit 1;  }
-
-# Build a list of all the top-level directories in the project.
-for DIRECTORY in */ ; do
-  GOGLOB="$GOGLOB ${DIRECTORY%/}"
-done
-GOGLOB="${GOGLOB/ docs/}"
-GOGLOB="${GOGLOB/ vendor/}"
-
-# Check that there are no formatting issues
-GOFMT_LINES=`gofmt -s -l $GOGLOB | tr '\\\\' '/' | wc -l | xargs`
-if $AUTOFMT; then
-  # if there are files with formatting issues, they will be automatically corrected using the gofmt -w <file> command
-  if [[ $GOFMT_LINES -ne 0 ]]; then
-    FMT_FILES=`gofmt -s -l $GOGLOB | tr '\\\\' '/' | xargs`
-    for FILE in $FMT_FILES; do
-        echo "Running: gofmt -s -w $FILE"
-        `gofmt -s -w $FILE`
-    done
-  fi
-else
-  test $GOFMT_LINES -eq 0 || die "gofmt needs to be run, ${GOFMT_LINES} files have issues.  Below is a list of files to review:\n`gofmt -s -l $GOGLOB`"
-fi
+./scripts/format.sh -f $AUTOFMT
 
 # Run the actual tests. Make sure there's enough coverage too, if the flags call for it.
 if $COVERAGE; then


Test patch:
diff --git a/adapters/brightroll/brightroll_test.go b/adapters/brightroll/brightroll_test.go
deleted file mode 100644
index 4cf0f46f..00000000
--- a/adapters/brightroll/brightroll_test.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package brightroll
-
-import (
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-
-	"github.com/prebid/prebid-server/adapters/adapterstest"
-	"github.com/prebid/prebid-server/config"
-	"github.com/prebid/prebid-server/openrtb_ext"
-)
-
-func TestEmptyConfig(t *testing.T) {
-	bidder, buildErr := Builder(openrtb_ext.BidderBrightroll, config.Adapter{
-		Endpoint:         `http://test-bid.ybp.yahoo.com/bid/appnexuspbs`,
-		ExtraAdapterInfo: ``,
-	}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
-
-	if buildErr != nil {
-		t.Fatalf("Builder returned unexpected error %v", buildErr)
-	}
-
-	ex := ExtraInfo{
-		Accounts: []Account{},
-	}
-	expected := &BrightrollAdapter{
-		URI:       "http://test-bid.ybp.yahoo.com/bid/appnexuspbs",
-		extraInfo: ex,
-	}
-	assert.Equal(t, expected, bidder)
-}
-
-func TestNonEmptyConfig(t *testing.T) {
-	bidder, buildErr := Builder(openrtb_ext.BidderBrightroll, config.Adapter{
-		Endpoint:         `http://test-bid.ybp.yahoo.com/bid/appnexuspbs`,
-		ExtraAdapterInfo: `{"accounts": [{"id": "test","bidfloor":0.1}]}`,
-	}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
-
-	if buildErr != nil {
-		t.Fatalf("Builder returned unexpected error %v", buildErr)
-	}
-
-	ex := ExtraInfo{
-		Accounts: []Account{{ID: "test", BidFloor: 0.1}},
-	}
-	expected := &BrightrollAdapter{
-		URI:       "http://test-bid.ybp.yahoo.com/bid/appnexuspbs",
-		extraInfo: ex,
-	}
-	assert.Equal(t, expected, bidder)
-}
-
-func TestMalformedEmpty(t *testing.T) {
-	_, buildErr := Builder(openrtb_ext.BidderBrightroll, config.Adapter{
-		Endpoint:         `http://test-bid.ybp.yahoo.com/bid/appnexuspbs`,
-		ExtraAdapterInfo: `malformed`,
-	}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
-
-	assert.Error(t, buildErr)
-}
-
-func TestJsonSamples(t *testing.T) {
-	bidder, buildErr := Builder(openrtb_ext.BidderBrightroll, config.Adapter{
-		Endpoint:         `http://test-bid.ybp.yahoo.com/bid/appnexuspbs`,
-		ExtraAdapterInfo: `{"accounts": [{"id": "adthrive","badv": [], "bcat": ["IAB8-5","IAB8-18"],"battr": [1,2,3], "bidfloor":0.0}]}`,
-	}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
-
-	if buildErr != nil {
-		t.Fatalf("Builder returned unexpected error %v", buildErr)
-	}
-
-	adapterstest.RunJSONBidderTest(t, "brightrolltest", bidder)
-}
diff --git a/adapters/brightroll/brightrolltest/exemplary/banner-native-audio.json b/adapters/brightroll/brightrolltest/exemplary/banner-native-audio.json
deleted file mode 100644
index f67fa259..00000000
--- a/adapters/brightroll/brightrolltest/exemplary/banner-native-audio.json
+++ /dev/null
@@ -1,169 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "test-request-id",
-    "imp": [
-      {
-        "id": "test-imp-id",
-        "banner": {
-          "format": [
-            {
-              "w": 300,
-              "h": 250
-            },
-            {
-              "w": 300,
-              "h": 600
-            }
-          ]
-        },
-        "ext": {
-          "bidder": {
-            "publisher": "adthrive"
-          }
-        }
-      },
-      {
-        "id": "unsupported-native-imp",
-        "native": {
-          "ver": "1.1",
-          "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}"
-        },
-        "ext": {
-          "bidder": {
-            "publisher": "adthrive"
-          }
-        }
-      },
-      {
-        "id": "unsupported-audio-imp",
-        "audio": {
-          "mimes": [
-            "video/mp4"
-          ]
-        },
-        "ext": {
-          "bidder": {
-            "publisher": "adthrive"
-          }
-        }
-      }
-    ]
-  },
-  "httpCalls": [
-    {
-      "expectedRequest": {
-        "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive",
-        "body": {
-          "id": "test-request-id",
-          "at":1,
-          "bcat": [
-            "IAB8-5",
-            "IAB8-18"
-          ],
-          "imp": [
-            {
-              "id": "test-imp-id",
-              "banner": {
-                "battr": [
-                  1,
-                  2,
-                  3
-                ],
-                "format": [
-                  {
-                    "w": 300,
-                    "h": 250
-                  },
-                  {
-                    "w": 300,
-                    "h": 600
-                  }
-                ],
-                "w": 300,
-                "h": 250
-              },
-              "ext": {
-                "bidder": {
-                  "publisher": "adthrive"
-                }
-              }
-            },
-            {
-              "id": "unsupported-native-imp",
-              "native": {
-                "ver": "1.1",
-                "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}"
-              },
-              "ext": {
-                "bidder": {
-                  "publisher": "adthrive"
-                }
-              }
-            },
-            {
-              "id": "unsupported-audio-imp",
-              "audio": {
-                "mimes": [
-                  "video/mp4"
-                ]
-              },
-              "ext": {
-                "bidder": {
-                  "publisher": "adthrive"
-                }
-              }
-            }
-          ]
-        }
-      },
-      "mockResponse": {
-        "status": 200,
-        "body": {
-          "id": "test-request-id",
-          "seatbid": [
-            {
-              "seat": "958",
-              "bid": [{
-                "id": "7706636740145184841",
-                "impid": "test-imp-id",
-                "price": 0.500000,
-                "adid": "29681110",
-                "adm": "some-test-ad",
-                "adomain": ["yahoo.com"],
-                "cid": "958",
-                "crid": "29681110",
-                "h": 250,
-                "w": 300
-              }]
-            }
-          ],
-          "bidid": "5778926625248726496",
-          "cur": "USD"
-        }
-      }
-    }
-  ],
-
-  "expectedBidResponses": [
-    {
-      "bids": [
-        {
-          "bid": {
-            "id": "7706636740145184841",
-            "impid": "test-imp-id",
-            "price": 0.5,
-            "adm": "some-test-ad",
-            "adid": "29681110",
-            "adomain": ["yahoo.com"],
-            "cid": "958",
-            "crid": "29681110",
-            "w": 300,
-            "h": 250
-          },
-          "type": "banner"
-        }
-      ]
-    }
-  ]
-
-}
diff --git a/adapters/brightroll/brightrolltest/exemplary/banner-video-native.json b/adapters/brightroll/brightrolltest/exemplary/banner-video-native.json
deleted file mode 100644
index 97081b70..00000000
--- a/adapters/brightroll/brightrolltest/exemplary/banner-video-native.json
+++ /dev/null
@@ -1,176 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "test-request-id",
-    "imp": [
-      {
-        "id": "test-imp-id",
-        "banner": {
-          "format": [
-            {
-              "w": 300,
-              "h": 250
-            },
-            {
-              "w": 300,
-              "h": 600
-            }
-          ]
-        },
-        "ext": {
-          "bidder": {
-            "publisher": "adthrive"
-          }
-        }
-      },
-      {
-        "id": "unsupported-native-imp",
-        "native": {
-          "ver": "1.1",
-          "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}"
-        },
-        "ext": {
-          "bidder": {
-            "publisher": "adthrive"
-          }
-        }
-      },
-      {
-        "id": "test-imp-video-id",
-        "video": {
-          "mimes": ["video/mp4"],
-          "protocols": [2, 5],
-          "w": 1024,
-          "h": 576
-        },
-        "ext": {
-          "bidder": {
-            "publisher": "adthrive"
-          }
-        }
-      }
-    ]
-  },
-  "httpCalls": [
-    {
-      "expectedRequest": {
-        "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive",
-        "body": {
-          "id": "test-request-id",
-          "at":1,
-          "bcat": [
-            "IAB8-5",
-            "IAB8-18"
-          ],
-          "imp": [
-            {
-              "id": "test-imp-id",
-              "banner": {
-                "battr": [
-                  1,
-                  2,
-                  3
-                ],
-                "format": [
-                  {
-                    "w": 300,
-                    "h": 250
-                  },
-                  {
-                    "w": 300,
-                    "h": 600
-                  }
-                ],
-                "w": 300,
-                "h": 250
-              },
-              "ext": {
-                "bidder": {
-                  "publisher": "adthrive"
-                }
-              }
-            },
-            {
-              "id": "unsupported-native-imp",
-              "native": {
-                "ver": "1.1",
-                "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}"
-              },
-              "ext": {
-                "bidder": {
-                  "publisher": "adthrive"
-                }
-              }
-            },
-            {
-              "id": "test-imp-video-id",
-              "video": {
-                "battr": [
-                  1,
-                  2,
-                  3
-                ],
-                "mimes": ["video/mp4"],
-                "protocols": [2, 5],
-                "w": 1024,
-                "h": 576
-              },
-              "ext": {
-                "bidder": {
-                  "publisher": "adthrive"
-                }
-              }
-            }
-          ]
-        }
-      },
-      "mockResponse": {
-        "status": 200,
-        "body": {
-          "id": "test-request-id",
-          "seatbid": [
-            {
-              "seat": "958",
-              "bid": [{
-                "id": "7706636740145184841",
-                "impid": "test-imp-video-id",
-                "price": 0.500000,
-                "adid": "29681110",
-                "adm": "some-test-ad",
-                "adomain": ["yahoo.com"],
-                "cid": "958",
-                "crid": "29681110",
-                "h": 576,
-                "w": 1024
-              }]
-            }
-          ],
-          "bidid": "5778926625248726496",
-          "cur": "USD"
-        }
-      }
-    }
-  ],
-
-  "expectedBidResponses": [
-    {
-      "bids": [
-        {
-          "bid": {
-            "id": "7706636740145184841",
-            "impid": "test-imp-video-id",
-            "price": 0.5,
-            "adm": "some-test-ad",
-            "adid": "29681110",
-            "adomain": ["yahoo.com"],
-            "cid": "958",
-            "crid": "29681110",
-            "w": 1024,
-            "h": 576
-          },
-          "type": "video"
-        }
-      ]
-    }
-  ]
-
-}
diff --git a/adapters/brightroll/brightrolltest/exemplary/banner-video.json b/adapters/brightroll/brightrolltest/exemplary/banner-video.json
deleted file mode 100644
index 17441152..00000000
--- a/adapters/brightroll/brightrolltest/exemplary/banner-video.json
+++ /dev/null
@@ -1,152 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "test-request-id",
-    "imp": [
-      {
-        "id": "test-imp-id",
-        "banner": {
-          "format": [
-            {
-              "w": 300,
-              "h": 250
-            },
-            {
-              "w": 300,
-              "h": 600
-            }
-          ]
-        },
-        "ext": {
-          "bidder": {
-            "publisher": "adthrive"
-          }
-        }
-      },
-      {
-        "id": "test-imp-video-id",
-        "video": {
-          "mimes": ["video/mp4"],
-          "protocols": [2, 5],
-          "w": 1024,
-          "h": 576
-        },
-        "ext": {
-          "bidder": {
-            "publisher": "adthrive"
-          }
-        }
-      }
-    ]
-  },
-  "httpCalls": [
-    {
-      "expectedRequest": {
-        "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive",
-        "body": {
-          "id": "test-request-id",
-          "at":1,
-          "bcat": [
-            "IAB8-5",
-            "IAB8-18"
-          ],
-          "imp": [
-            {
-              "id": "test-imp-id",
-              "banner": {
-                "battr": [
-                  1,
-                  2,
-                  3
-                ],
-                "format": [
-                  {
-                    "w": 300,
-                    "h": 250
-                  },
-                  {
-                    "w": 300,
-                    "h": 600
-                  }
-                ],
-                "w": 300,
-                "h": 250
-              },
-              "ext": {
-                "bidder": {
-                  "publisher": "adthrive"
-                }
-              }
-            },
-            {
-              "id": "test-imp-video-id",
-              "video": {
-                "battr": [
-                  1,
-                  2,
-                  3
-                ],
-                "mimes": ["video/mp4"],
-                "protocols": [2, 5],
-                "w": 1024,
-                "h": 576
-              },
-              "ext": {
-                "bidder": {
-                  "publisher": "adthrive"
-                }
-              }
-            }
-          ]
-        }
-      },
-      "mockResponse": {
-        "status": 200,
-        "body": {
-          "id": "test-request-id",
-          "seatbid": [
-            {
-              "seat": "958",
-              "bid": [{
-                "id": "7706636740145184841",
-                "impid": "test-imp-video-id",
-                "price": 0.500000,
-                "adid": "29681110",
-                "adm": "some-test-ad",
-                "adomain": ["yahoo.com"],
-                "cid": "958",
-                "crid": "29681110",
-                "h": 576,
-                "w": 1024
-              }]
-            }
-          ],
-          "bidid": "5778926625248726496",
-          "cur": "USD"
-        }
-      }
-    }
-  ],
-
-  "expectedBidResponses": [
-    {
-      "bids": [
-        {
-          "bid": {
-            "id": "7706636740145184841",
-            "impid": "test-imp-video-id",
-            "price": 0.5,
-            "adm": "some-test-ad",
-            "adid": "29681110",
-            "adomain": ["yahoo.com"],
-            "cid": "958",
-            "crid": "29681110",
-            "w": 1024,
-            "h": 576
-          },
-          "type": "video"
-        }
-      ]
-    }
-  ]
-
-}
diff --git a/adapters/brightroll/brightrolltest/exemplary/simple-banner.json b/adapters/brightroll/brightrolltest/exemplary/simple-banner.json
deleted file mode 100644
index f5903850..00000000
--- a/adapters/brightroll/brightrolltest/exemplary/simple-banner.json
+++ /dev/null
@@ -1,119 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "test-request-id",
-    "imp": [
-      {
-        "id": "test-imp-id",
-        "banner": {
-          "format": [
-            {
-              "w": 300,
-              "h": 250
-            },
-            {
-              "w": 300,
-              "h": 600
-            }
-          ]
-        },
-        "ext": {
-          "bidder": {
-            "publisher": "adthrive"
-          }
-        }
-      }
-    ]
-  },
-
-  "httpCalls": [
-    {
-      "expectedRequest": {
-        "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive",
-        "body": {
-          "id": "test-request-id",
-          "at":1,
-          "bcat": [
-            "IAB8-5",
-            "IAB8-18"
-          ],
-          "imp": [
-            {
-              "id": "test-imp-id",
-              "banner": {
-                "battr": [
-                  1,
-                  2,
-                  3
-                ],
-                "format": [
-                  {
-                    "w": 300,
-                    "h": 250
-                  },
-                  {
-                    "w": 300,
-                    "h": 600
-                  }
-                ],
-                "w": 300,
-                "h": 250
-              },
-              "ext": {
-                "bidder": {
-                  "publisher": "adthrive"
-                }
-              }
-            }
-          ]
-        }
-      },
-      "mockResponse": {
-        "status": 200,
-        "body": {
-          "id": "test-request-id",
-          "seatbid": [
-            {
-              "seat": "958",
-              "bid": [{
-                "id": "7706636740145184841",
-                "impid": "test-imp-id",
-                "price": 0.500000,
-                "adid": "29681110",
-                "adm": "some-test-ad",
-                "adomain": ["yahoo.com"],
-                "cid": "958",
-                "crid": "29681110",
-                "h": 250,
-                "w": 300
-              }]
-            }
-          ],
-          "bidid": "5778926625248726496",
-          "cur": "USD"
-        }
-      }
-    }
-  ],
-
-  "expectedBidResponses": [
-    {
-      "bids": [
-        {
-          "bid": {
-            "id": "7706636740145184841",
-            "impid": "test-imp-id",
-            "price": 0.5,
-            "adm": "some-test-ad",
-            "adid": "29681110",
-            "adomain": ["yahoo.com"],
-            "cid": "958",
-            "crid": "29681110",
-            "w": 300,
-            "h": 250
-          },
-          "type": "banner"
-        }
-      ]
-    }
-  ]
-}
diff --git a/adapters/brightroll/brightrolltest/exemplary/simple-video.json b/adapters/brightroll/brightrolltest/exemplary/simple-video.json
deleted file mode 100644
index 88539276..00000000
--- a/adapters/brightroll/brightrolltest/exemplary/simple-video.json
+++ /dev/null
@@ -1,98 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "test-request-id",
-    "imp": [
-      {
-        "id": "test-imp-id",
-        "video": {
-          "mimes": ["video/mp4"],
-          "protocols": [2, 5],
-          "w": 1024,
-          "h": 576
-        },
-        "ext":{
-          "bidder":{
-            "publisher": "adthrive"
-          }
-        }
-      }
-    ]
-  },
-
-  "httpCalls": [
-    {
-      "expectedRequest": {
-        "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive",
-        "body": {
-          "id": "test-request-id",
-          "at":1,
-          "bcat": [
-            "IAB8-5",
-            "IAB8-18"
-          ],
-          "imp": [
-            {
-              "id": "test-imp-id",
-              "video": {
-                "battr": [
-                  1,
-                  2,
-                  3
-                ],
-                "mimes": ["video/mp4"],
-                "protocols": [2, 5],
-                "w": 1024,
-                "h": 576
-              },
-              "ext": {
-                "bidder": {
-                  "publisher": "adthrive"
-                }
-              }
-            }
-          ]
-        }
-      },
-      "mockResponse": {
-        "status": 200,
-        "body": {
-          "id": "test-request-id",
-          "cur": "USD",
-          "seatbid": [
-            {
-              "seat": "Brightroll",
-              "bid": [{
-                "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
-                "impid": "test-imp-id",
-                "price": 0.500000,
-                "adm": "some-test-ad",
-                "crid": "crid_10",
-                "w": 1024,
-                "h": 576
-              }]
-            }
-          ]
-        }
-      }
-    }
-  ],
-
-  "expectedBidResponses": [
-    {
-      "bids": [
-        {
-          "bid": {
-            "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
-            "impid": "test-imp-id",
-            "price": 0.5,
-            "adm": "some-test-ad",
-            "crid": "crid_10",
-            "w": 1024,
-            "h": 576
-          },
-          "type": "video"
-        }
-      ]
-    }
-  ]
-}
diff --git a/adapters/brightroll/brightrolltest/exemplary/valid-extension.json b/adapters/brightroll/brightrolltest/exemplary/valid-extension.json
deleted file mode 100644
index 9a5e571c..00000000
--- a/adapters/brightroll/brightrolltest/exemplary/valid-extension.json
+++ /dev/null
@@ -1,96 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "test-request-id",
-    "imp": [
-      {
-        "id": "test-imp-id",
-        "video": {
-          "mimes": ["video/mp4"],
-          "protocols": [2, 5],
-          "w": 1024,
-          "h": 576
-        },
-        "ext":{
-          "bidder":{
-            "publisher": "adthrive"
-           }
-        }
-      }
-    ]
-  },
-
-  "httpCalls": [
-    {
-      "expectedRequest": {
-        "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive",
-        "body": {
-          "id": "test-request-id",
-          "at":1,
-          "bcat": [
-            "IAB8-5",
-            "IAB8-18"
-          ],
-          "imp": [
-            {
-              "id": "test-imp-id",
-              "video": {
-                "battr": [
-                  1,
-                  2,
-                  3
-                ],
-                "mimes": ["video/mp4"],
-                "protocols": [2, 5],
-                "w": 1024,
-                "h": 576
-              },
-              "ext": {
-                "bidder": {
-                  "publisher": "adthrive"
-                }
-              }
-            }
-          ]
-        }
-      },
-      "mockResponse": {
-        "status": 200,
-        "body": {
-          "id": "test-request-id",
-          "cur": "USD",
-          "seatbid": [
-            {
-              "seat": "brightroll",
-              "bid": [{
-                "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
-                "impid": "test-imp-id",
-                "price": 0.500000,
-                "adm": "some-test-ad",
-                "crid": "crid_10",
-                "w": 1024,
-                "h": 576
-              }]
-            }
-          ]
-        }
-      }
-    }
-  ],
-
-  "expectedBidResponses": [
-    {
-      "bids": [{
-        "bid": {
-          "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
-          "impid": "test-imp-id",
-          "price": 0.5,
-          "adm": "some-test-ad",
-          "crid": "crid_10",
-          "w": 1024,
-          "h": 576
-        },
-        "type": "video"
-      }]
-    }
-  ]
-}
diff --git a/adapters/brightroll/brightrolltest/exemplary/video-and-audio.json b/adapters/brightroll/brightrolltest/exemplary/video-and-audio.json
deleted file mode 100644
index 4184842b..00000000
--- a/adapters/brightroll/brightrolltest/exemplary/video-and-audio.json
+++ /dev/null
@@ -1,121 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "test-request-id",
-    "imp": [
-      {
-        "id": "test-imp-video-id",
-        "video": {
-          "mimes": ["video/mp4"],
-          "protocols": [2, 5],
-          "w": 1024,
-          "h": 576
-        },
-        "ext": {
-          "bidder": {
-            "publisher": "adthrive"
-          }
-        }
-      },
-      {
-        "id": "unsupported-audio-imp",
-        "audio": {
-          "mimes": [
-            "video/mp4"
-          ]
-        },
-        "ext": {
-          "bidder": {
-            "publisher": "adthrive"
-          }
-        }
-      }
-    ]
-  },
-  "httpCalls": [
-    {
-      "expectedRequest": {
-        "uri": "http://test-bid.ybp.yahoo.com/bid/appnexuspbs?publisher=adthrive",
-        "body": {
-          "id": "test-request-id",
-          "at":1,
-          "bcat": [
-            "IAB8-5",
-            "IAB8-18"
-          ],
-          "imp": [
-            {
-              "id": "test-imp-video-id",
-              "video": {
-                "battr": [
-                  1,
-                  2,
-                  3
-                ],
-                "mimes": ["video/mp4"],
-                "protocols": [2, 5],
-                "w": 1024,
-                "h": 576
-              },
-              "ext": {
-                "bidder": {
-                  "publisher": "adthrive"
-                }
-              }
-            },
-            {
-              "id": "unsupported-audio-imp",
-              "audio": {
-                "mimes": [
-                  "video/mp4"
-                ]
-              },
-              "ext": {
-                "bidder": {
-                  "publisher": "adthrive"
-                }
-              }
-            }
-          ]
-        }
-      },
-      "mockResponse": {
-        "status": 200,
-        "body": {
-          "id": "test-request-id",
-          "cur": "USD",
-          "seatbid": [
-            {
-              "seat": "brightroll",
-              "bid": [{
-                "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
-                "impid": "test-imp-video-id",
-                "price": 0.500000,
-                "adm": "some-test-ad",
-                "crid": "crid_10",
-                "w": 1024,
-                "h": 576
-              }]
-            }
-          ]
-        }
-      }
-    }
-  ],
-
-  "expectedBidResponses": [
-    {
-      "bids": [{
-        "bid": {
-          "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
-          "impid": "test-imp-video-id",
-          "price": 0.5,
-          "adm": "some-test-ad",
-          "crid": "crid_10",
-          "w": 1024,
-          "h": 576
-        },
-        "type": "video"
-      }]
-    }
-  ]
-}
diff --git a/adapters/brightroll/brightrolltest/supplemental/invalid-extension.json b/adapters/brightroll/brightrolltest/supplemental/invalid-extension.json
deleted file mode 100644
index 35b15638..00000000
--- a/adapters/brightroll/brightrolltest/supplemental/invalid-extension.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "test-request-id",
-    "imp": [
-      {
-        "id": "test-invalid-ext-id",
-        "banner": {
-          "format": [
-            {
-              "w": 300,
-              "h": 250
-            },
-            {
-              "w": 300,
-              "h": 600
-            }
-          ]
-        },
-        "ext": {
-        }
-
-      }
-    ]
-  },
-  "expectedMakeRequestsErrors": [
-    {
-      "value": "ext.bidder.publisher not provided",
-      "comparison": "literal"
-    }
-  ]
-}
diff --git a/adapters/brightroll/brightrolltest/supplemental/invalid-imp.json b/adapters/brightroll/brightrolltest/supplemental/invalid-imp.json
deleted file mode 100644
index 01beec71..00000000
--- a/adapters/brightroll/brightrolltest/supplemental/invalid-imp.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "test-request-id",
-    "ext": {
-      "bidder": {
-        "publisher": "adthrive"
-      }
-    }
-  },
-  "expectedMakeRequestsErrors": [
-    {
-      "value": "No impression in the bid request",
-      "comparison": "literal"
-    }
-  ]
-}
diff --git a/adapters/brightroll/brightrolltest/supplemental/invalid-publisher.json b/adapters/brightroll/brightrolltest/supplemental/invalid-publisher.json
deleted file mode 100644
index da48108a..00000000
--- a/adapters/brightroll/brightrolltest/supplemental/invalid-publisher.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "test-request-id",
-    "imp": [
-      {
-        "id": "test-missing-req-param-id",
-        "banner": {
-          "format": [
-            {
-              "w": 300,
-              "h": 250
-            },
-            {
-              "w": 300,
-              "h": 600
-            }
-          ]
-        },
-        "ext": {
-          "bidder": {
-            "publisher":"test"
-          }
-        }
-
-      }
-    ]
-  },
-  "expectedMakeRequestsErrors": [
-    {
-      "value": "Invalid publisher",
-      "comparison": "literal"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/adapters/brightroll/brightrolltest/supplemental/missing-extension.json b/adapters/brightroll/brightrolltest/supplemental/missing-extension.json
deleted file mode 100644
index 82ec775d..00000000
--- a/adapters/brightroll/brightrolltest/supplemental/missing-extension.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "test-request-id",
-    "imp": [
-      {
-        "id": "test-missing-ext-id",
-        "video": {
-          "mimes": ["video/mp4"],
-          "protocols": [2, 5],
-          "w": 1024,
-          "h": 576
-        }
-      }
-    ]
-  },
-  "expectedMakeRequestsErrors": [
-    {
-      "value": "ext.bidder not provided",
-      "comparison": "literal"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/adapters/brightroll/brightrolltest/supplemental/missing-param.json b/adapters/brightroll/brightrolltest/supplemental/missing-param.json
deleted file mode 100644
index 08e82c0e..00000000
--- a/adapters/brightroll/brightrolltest/supplemental/missing-param.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
-  "mockBidRequest": {
-    "id": "test-request-id",
-    "imp": [
-      {
-        "id": "test-missing-req-param-id",
-        "banner": {
-          "format": [
-            {
-              "w": 300,
-              "h": 250
-            },
-            {
-              "w": 300,
-              "h": 600
-            }
-          ]
-        },
-        "ext": {
-          "bidder": {
-            "publisher":""
-          }
-        }
-
-      }
-    ]
-  },
-  "expectedMakeRequestsErrors": [
-    {
-      "value": "publisher is empty",
-      "comparison": "literal"
-    }
-  ]
-}
diff --git a/adapters/brightroll/params_test.go b/adapters/brightroll/params_test.go
deleted file mode 100644
index c14ee6d7..00000000
--- a/adapters/brightroll/params_test.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package brightroll
-
-import (
-	"encoding/json"
-	"testing"
-
-	"github.com/prebid/prebid-server/openrtb_ext"
-)
-
-// This file actually intends to test static/bidder-params/brightroll.json
-//
-// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.brightroll
-
-// TestValidParams makes sure that the Brightroll schema accepts all imp.ext fields which we intend to support.
-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.BidderBrightroll, json.RawMessage(validParam)); err != nil {
-			t.Errorf("Schema rejected Brightroll params: %s", validParam)
-		}
-	}
-}
-
-// TestInvalidParams makes sure that the Brightroll schema rejects all the imp.ext fields we don't support.
-func TestInvalidParams(t *testing.T) {
-	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
-	if err != nil {
-		t.Fatalf("Failed to fetch the json-schemas. %v", err)
-	}
-
-	for _, invalidParam := range invalidParams {
-		if err := validator.Validate(openrtb_ext.BidderBrightroll, json.RawMessage(invalidParam)); err == nil {
-			t.Errorf("Schema allowed unexpected params: %s", invalidParam)
-		}
-	}
-}
-
-var validParams = []string{
-	`{"publisher": "testpublisher"}`,
-	`{"publisher": "123"}`,
-	`{"publisher": "cafemedia"}`,
-	`{"publisher": "test", "headerbidding": false}`,
-}
-
-var invalidParams = []string{
-	`{"publisher": 100}`,
-	`{"headerbidding": false}`,
-	`{"publisher": true}`,
-	`{"publisherId": 123, "headerbidding": true}`,
-	`{"publisherID": "1"}`,
-	``,
-	`null`,
-	`true`,
-	`9`,
-	`1.2`,
-	`[]`,
-	`{}`,
-}
diff --git a/adapters/gamma/params_test.go b/adapters/gamma/params_test.go
index 56f1b591..c6a149c2 100644
--- a/adapters/gamma/params_test.go
+++ b/adapters/gamma/params_test.go
@@ -8,8 +8,6 @@ import (
 )
 
 // This file actually intends to test static/bidder-params/gamma.json
-//
-// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.brightroll
 
 // TestValidParams makes sure that the Gamma schema accepts all imp.ext fields which we intend to support.
 func TestValidParams(t *testing.T) {
diff --git a/adapters/ownadx/ownadx_test.go b/adapters/ownadx/ownadx_test.go
new file mode 100644
index 00000000..9bd7ba70
--- /dev/null
+++ b/adapters/ownadx/ownadx_test.go
@@ -0,0 +1,17 @@
+package ownadx
+
+import (
+	"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"
+	"testing"
+)
+
+func TestJsonSamples(t *testing.T) {
+	bidder, buildErr := Builder(openrtb_ext.BidderOwnAdx, config.Adapter{
+		Endpoint: "https://pbs.prebid-ownadx.com/bidder/bid/{{.AccountID}}/{{.ZoneID}}?token={{.SourceId}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
+
+	assert.NoError(t, buildErr)
+	adapterstest.RunJSONBidderTest(t, "ownadxtest", bidder)
+}
diff --git a/adapters/ownadx/ownadxtest/exemplary/banner.json b/adapters/ownadx/ownadxtest/exemplary/banner.json
new file mode 100644
index 00000000..f77321c5
--- /dev/null
+++ b/adapters/ownadx/ownadxtest/exemplary/banner.json
@@ -0,0 +1,166 @@
+{
+  "mockBidRequest": {
+    "id": "id",
+    "imp": [
+      {
+        "id": "id",
+        "secure": 1,
+        "bidfloor": 0.01,
+        "bidfloorcur": "USD",
+        "banner": {
+          "w": 300,
+          "h": 250
+        },
+        "ext": {
+          "bidder": {
+            "tokenId": "126151698247",
+            "sspId": "11",
+            "seatId": "2"
+          }
+        }
+      }
+    ],
+    "device": {
+      "ua": "UA",
+      "ip": "123.3.4.123"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "userid"
+    },
+    "site": {
+      "id": "id",
+      "domain": "test,com",
+      "cat": [
+        "IAB12"
+      ],
+      "publisher": {
+        "id": "pubid"
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247",
+        "body": {
+          "id": "id",
+          "imp": [
+            {
+              "id": "id",
+              "secure": 1,
+              "bidfloor": 0.01,
+              "bidfloorcur": "USD",
+              "banner": {
+                "w": 300,
+                "h": 250
+              },
+              "ext": {
+                "bidder": {
+                  "tokenId": "126151698247",
+                  "sspId": "11",
+                  "seatId": "2"
+                }
+              }
+            }
+          ],
+          "device": {
+            "ua": "UA",
+            "ip": "123.3.4.123"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          },
+          "user": {
+            "id": "userid"
+          },
+          "site": {
+            "id": "id",
+            "domain": "test,com",
+            "cat": [
+              "IAB12"
+            ],
+            "publisher": {
+              "id": "pubid"
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "id",
+          "bidid": "id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "mtype": 1,
+                  "id": "id",
+                  "impid": "id",
+                  "price": 0.1,
+                  "nurl": "http://test.com/nurl",
+                  "burl": "http://test.com/burl",
+                  "adm": "<span>Test</span>",
+                  "adomain": [
+                    "test.com"
+                  ],
+                  "cat": [
+                    "IAB1"
+                  ],
+                  "cid": "cid",
+                  "crid": "crid",
+                  "w": 300,
+                  "h": 250,
+                  "ext": {
+                    "mediaType": "banner"
+                  }
+                }
+              ],
+              "seat": "seat"
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "mtype": 1,
+            "id": "id",
+            "impid": "id",
+            "price": 0.1,
+            "nurl": "http://test.com/nurl",
+            "burl": "http://test.com/burl",
+            "adm": "<span>Test</span>",
+            "adomain": [
+              "test.com"
+            ],
+            "cat": [
+              "IAB1"
+            ],
+            "cid": "cid",
+            "crid": "crid",
+            "w": 300,
+            "h": 250,
+            "ext": {
+              "mediaType": "banner"
+            }
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/ownadx/ownadxtest/exemplary/video.json b/adapters/ownadx/ownadxtest/exemplary/video.json
new file mode 100644
index 00000000..7cac425c
--- /dev/null
+++ b/adapters/ownadx/ownadxtest/exemplary/video.json
@@ -0,0 +1,196 @@
+{
+  "mockBidRequest": {
+    "id": "id",
+    "imp": [
+      {
+        "id": "id",
+        "secure": 1,
+        "bidfloor": 0.01,
+        "bidfloorcur": "USD",
+        "video": {
+          "mimes": [
+            "video/mp4",
+            "video/ogg",
+            "video/webm"
+          ],
+          "minduration": 3,
+          "maxduration": 3000,
+          "protocols": [
+            2,
+            3,
+            5,
+            6,
+            7,
+            8
+          ],
+          "w": 480,
+          "h": 320,
+          "linearity": 1,
+          "playbackmethod": [
+            2
+          ],
+          "pos": 0
+        },
+        "ext": {
+          "bidder": {
+            "tokenId": "126151698247",
+            "sspId": "11",
+            "seatId": "2"
+          }
+        }
+      }
+    ],
+    "device": {
+      "ua": "UA",
+      "ip": "123.3.4.123"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "userid"
+    },
+    "site": {
+      "id": "id",
+      "domain": "test,com",
+      "cat": [
+        "IAB12"
+      ],
+      "publisher": {
+        "id": "pubid"
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247",
+        "body": {
+          "id": "id",
+          "imp": [
+            {
+              "id": "id",
+              "secure": 1,
+              "bidfloor": 0.01,
+              "bidfloorcur": "USD",
+              "video": {
+                "mimes": [
+                  "video/mp4",
+                  "video/ogg",
+                  "video/webm"
+                ],
+                "minduration": 3,
+                "maxduration": 3000,
+                "protocols": [
+                  2,
+                  3,
+                  5,
+                  6,
+                  7,
+                  8
+                ],
+                "w": 480,
+                "h": 320,
+                "linearity": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "pos": 0
+              },
+              "ext": {
+                "bidder": {
+                  "tokenId": "126151698247",
+                  "sspId": "11",
+                  "seatId": "2"
+                }
+              }
+            }
+          ],
+          "device": {
+            "ua": "UA",
+            "ip": "123.3.4.123"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          },
+          "user": {
+            "id": "userid"
+          },
+          "site": {
+            "id": "id",
+            "domain": "test,com",
+            "cat": [
+              "IAB12"
+            ],
+            "publisher": {
+              "id": "pubid"
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "id",
+          "bidid": "id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "id",
+                  "impid": "id",
+                  "price": 0.1,
+                  "nurl": "http://test.com/nurl",
+                  "burl": "http://test.com/burl",
+                  "adm": "<VAST>",
+                  "adomain": [
+                    "test.com"
+                  ],
+                  "cat": [
+                    "IAB1"
+                  ],
+                  "cid": "cid",
+                  "crid": "crid",
+                  "mtype": 2
+                }
+              ],
+              "seat": "seat"
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "id",
+            "impid": "id",
+            "price": 0.1,
+            "nurl": "http://test.com/nurl",
+            "burl": "http://test.com/burl",
+            "adm": "<VAST>",
+            "adomain": [
+              "test.com"
+            ],
+            "cat": [
+              "IAB1"
+            ],
+            "cid": "cid",
+            "crid": "crid",
+            "mtype": 2
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/ownadx/ownadxtest/supplemental/bad-server-response.json b/adapters/ownadx/ownadxtest/supplemental/bad-server-response.json
new file mode 100644
index 00000000..61b6da04
--- /dev/null
+++ b/adapters/ownadx/ownadxtest/supplemental/bad-server-response.json
@@ -0,0 +1,108 @@
+{
+  "mockBidRequest": {
+    "id": "id",
+    "imp": [
+      {
+        "id": "id",
+        "secure": 1,
+        "bidfloor": 0.01,
+        "bidfloorcur": "USD",
+        "banner": {
+          "w": 300,
+          "h": 250
+        },
+        "ext": {
+          "bidder": {
+            "tokenId": "126151698247",
+            "sspId": "11",
+            "seatId": "2"
+          }
+        }
+      }
+    ],
+    "device": {
+      "ua": "UA",
+      "ip": "123.3.4.123"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "userid"
+    },
+    "site": {
+      "id": "id",
+      "domain": "test,com",
+      "cat": [
+        "IAB12"
+      ],
+      "publisher": {
+        "id": "pubid"
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247",
+        "body": {
+          "id": "id",
+          "imp": [
+            {
+              "id": "id",
+              "secure": 1,
+              "bidfloor": 0.01,
+              "bidfloorcur": "USD",
+              "banner": {
+                "w": 300,
+                "h": 250
+              },
+              "ext": {
+                "bidder": {
+                  "tokenId": "126151698247",
+                  "sspId": "11",
+                  "seatId": "2"
+                }
+              }
+            }
+          ],
+          "device": {
+            "ua": "UA",
+            "ip": "123.3.4.123"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          },
+          "user": {
+            "id": "userid"
+          },
+          "site": {
+            "id": "id",
+            "domain": "test,com",
+            "cat": [
+              "IAB12"
+            ],
+            "publisher": {
+              "id": "pubid"
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200
+
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Bad server response ",
+      "comparison": "literal"
+    }
+  ],
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/ownadx/ownadxtest/supplemental/bid-empty-.json b/adapters/ownadx/ownadxtest/supplemental/bid-empty-.json
new file mode 100644
index 00000000..8d40e878
--- /dev/null
+++ b/adapters/ownadx/ownadxtest/supplemental/bid-empty-.json
@@ -0,0 +1,118 @@
+{
+  "mockBidRequest": {
+    "id": "id",
+    "imp": [
+      {
+        "id": "id",
+        "secure": 1,
+        "bidfloor": 0.01,
+        "bidfloorcur": "USD",
+        "banner": {
+          "w": 300,
+          "h": 250
+        },
+        "ext": {
+          "bidder": {
+            "tokenId": "126151698247",
+            "sspId": "11",
+            "seatId": "2"
+          }
+        }
+      }
+    ],
+    "device": {
+      "ua": "UA",
+      "ip": "123.3.4.123"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "userid"
+    },
+    "site": {
+      "id": "id",
+      "domain": "test,com",
+      "cat": [
+        "IAB12"
+      ],
+      "publisher": {
+        "id": "pubid"
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247",
+        "body": {
+          "id": "id",
+          "imp": [
+            {
+              "id": "id",
+              "secure": 1,
+              "bidfloor": 0.01,
+              "bidfloorcur": "USD",
+              "banner": {
+                "w": 300,
+                "h": 250
+              },
+              "ext": {
+                "bidder": {
+                  "tokenId": "126151698247",
+                  "sspId": "11",
+                  "seatId": "2"
+                }
+              }
+            }
+          ],
+          "device": {
+            "ua": "UA",
+            "ip": "123.3.4.123"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          },
+          "user": {
+            "id": "userid"
+          },
+          "site": {
+            "id": "id",
+            "domain": "test,com",
+            "cat": [
+              "IAB12"
+            ],
+            "publisher": {
+              "id": "pubid"
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "id",
+          "bidid": "id",
+          "seatbid": [
+            {
+              "seat": "seat"
+            }
+          ],
+          "cur": "USD"
+        }
+
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Bid cannot be empty ",
+      "comparison": "literal"
+    }
+  ],
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/ownadx/ownadxtest/supplemental/bidext-type.json b/adapters/ownadx/ownadxtest/supplemental/bidext-type.json
new file mode 100644
index 00000000..b1d63428
--- /dev/null
+++ b/adapters/ownadx/ownadxtest/supplemental/bidext-type.json
@@ -0,0 +1,141 @@
+{
+  "mockBidRequest": {
+    "id": "id",
+    "imp": [
+      {
+        "id": "id",
+        "secure": 1,
+        "bidfloor": 0.01,
+        "bidfloorcur": "USD",
+        "banner": {
+          "w": 300,
+          "h": 250
+        },
+        "ext": {
+          "bidder": {
+            "tokenId": "126151698247",
+            "sspId": "11",
+            "seatId": "2"
+          }
+        }
+      }
+    ],
+    "device": {
+      "ua": "UA",
+      "ip": "123.3.4.123"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "userid"
+    },
+    "site": {
+      "id": "id",
+      "domain": "test,com",
+      "cat": [
+        "IAB12"
+      ],
+      "publisher": {
+        "id": "pubid"
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247",
+        "body": {
+          "id": "id",
+          "imp": [
+            {
+              "id": "id",
+              "secure": 1,
+              "bidfloor": 0.01,
+              "bidfloorcur": "USD",
+              "banner": {
+                "w": 300,
+                "h": 250
+              },
+              "ext": {
+                "bidder": {
+                  "tokenId": "126151698247",
+                  "sspId": "11",
+                  "seatId": "2"
+                }
+              }
+            }
+          ],
+          "device": {
+            "ua": "UA",
+            "ip": "123.3.4.123"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          },
+          "user": {
+            "id": "userid"
+          },
+          "site": {
+            "id": "id",
+            "domain": "test,com",
+            "cat": [
+              "IAB12"
+            ],
+            "publisher": {
+              "id": "pubid"
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "id",
+          "bidid": "id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "id",
+                  "impid": "id",
+                  "price": 0.1,
+                  "nurl": "http://test.com/nurl",
+                  "burl": "http://test.com/burl",
+                  "adm": "<span>Test</span>",
+                  "adomain": [
+                    "test.com"
+                  ],
+                  "cat": [
+                    "IAB1"
+                  ],
+                  "cid": "cid",
+                  "crid": "crid",
+                  "w": 300,
+                  "h": 250,
+                  "ext": {
+
+                  }
+                }
+              ],
+              "seat": "seat"
+            }
+          ],
+          "cur": "USD"
+        }
+
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Bid type is invalid",
+      "comparison": "literal"
+    }
+  ],
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/ownadx/ownadxtest/supplemental/http-status-204.json b/adapters/ownadx/ownadxtest/supplemental/http-status-204.json
new file mode 100644
index 00000000..4b7f8663
--- /dev/null
+++ b/adapters/ownadx/ownadxtest/supplemental/http-status-204.json
@@ -0,0 +1,51 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "w": 300,
+          "h": 250
+        },
+        "ext": {
+          "bidder": {
+            "tokenId": "126151698247",
+            "sspId": "11",
+            "seatId": "2"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "w": 300,
+                "h": 250
+              },
+              "ext": {
+                "bidder": {
+                  "tokenId": "126151698247",
+                  "sspId": "11",
+                  "seatId": "2"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 204
+      }
+    }
+  ],
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/ownadx/ownadxtest/supplemental/http-status-400.json b/adapters/ownadx/ownadxtest/supplemental/http-status-400.json
new file mode 100644
index 00000000..035bc323
--- /dev/null
+++ b/adapters/ownadx/ownadxtest/supplemental/http-status-400.json
@@ -0,0 +1,57 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "w": 300,
+          "h": 250
+        },
+        "ext": {
+          "bidder": {
+            "tokenId": "126151698247",
+            "sspId": "11",
+            "seatId": "2"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247",
+        "body": {
+          "id": "test-request-id",
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "w": 300,
+                "h": 250
+              },
+              "ext": {
+                "bidder": {
+                  "tokenId": "126151698247",
+                  "sspId": "11",
+                  "seatId": "2"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 400
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Bad request: 400",
+      "comparison": "literal"
+    }
+  ],
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/ownadx/ownadxtest/supplemental/invalid-req-empty-imp.json b/adapters/ownadx/ownadxtest/supplemental/invalid-req-empty-imp.json
new file mode 100644
index 00000000..0407ed6c
--- /dev/null
+++ b/adapters/ownadx/ownadxtest/supplemental/invalid-req-empty-imp.json
@@ -0,0 +1,34 @@
+{
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "No impression in the bid request",
+      "comparison": "literal"
+    }
+  ],
+  "mockBidRequest": {
+    "id": "id",
+    "device": {
+      "ua": "UA",
+      "ip": "123.3.4.123"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "userid"
+    },
+    "site": {
+      "id": "id",
+      "domain": "test,com",
+      "cat": [
+        "IAB12"
+      ],
+      "publisher": {
+        "id": "pubid"
+      }
+    }
+  },
+  "httpCalls": []
+}
diff --git a/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp-ext.json b/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp-ext.json
new file mode 100644
index 00000000..9b8ba0d1
--- /dev/null
+++ b/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp-ext.json
@@ -0,0 +1,47 @@
+{
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "Bidder extension not valid or can't be unmarshalled",
+      "comparison": "literal"
+    }
+  ],
+  "mockBidRequest": {
+    "id": "id",
+    "imp": [
+      {
+        "id": "id",
+        "secure": 1,
+        "bidfloor": 0.01,
+        "bidfloorcur": "USD",
+        "banner": {
+          "w": 300,
+          "h": 250
+        }
+
+      }
+    ],
+    "device": {
+      "ua": "UA",
+      "ip": "123.3.4.123"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "userid"
+    },
+    "site": {
+      "id": "id",
+      "domain": "test,com",
+      "cat": [
+        "IAB12"
+      ],
+      "publisher": {
+        "id": "pubid"
+      }
+    }
+  },
+  "httpCalls": []
+}
diff --git a/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp.ext.bidder.json b/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp.ext.bidder.json
new file mode 100644
index 00000000..b04e037d
--- /dev/null
+++ b/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp.ext.bidder.json
@@ -0,0 +1,49 @@
+{
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "Error while unmarshaling bidder extension",
+      "comparison": "literal"
+    }
+  ],
+  "mockBidRequest": {
+    "id": "id",
+    "imp": [
+      {
+        "id": "id",
+        "secure": 1,
+        "bidfloor": 0.01,
+        "bidfloorcur": "USD",
+        "banner": {
+          "w": 300,
+          "h": 250
+        },
+        "ext": {
+          "bidder": []
+        }
+      }
+    ],
+    "device": {
+      "ua": "UA",
+      "ip": "123.3.4.123"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "userid"
+    },
+    "site": {
+      "id": "id",
+      "domain": "test,com",
+      "cat": [
+        "IAB12"
+      ],
+      "publisher": {
+        "id": "pubid"
+      }
+    }
+  },
+  "httpCalls": []
+}
diff --git a/adapters/ownadx/ownadxtest/supplemental/seatbid-empty-.json b/adapters/ownadx/ownadxtest/supplemental/seatbid-empty-.json
new file mode 100644
index 00000000..f49ece3e
--- /dev/null
+++ b/adapters/ownadx/ownadxtest/supplemental/seatbid-empty-.json
@@ -0,0 +1,113 @@
+{
+  "mockBidRequest": {
+    "id": "id",
+    "imp": [
+      {
+        "id": "id",
+        "secure": 1,
+        "bidfloor": 0.01,
+        "bidfloorcur": "USD",
+        "banner": {
+          "w": 300,
+          "h": 250
+        },
+        "ext": {
+          "bidder": {
+            "tokenId": "126151698247",
+            "sspId": "11",
+            "seatId": "2"
+          }
+        }
+      }
+    ],
+    "device": {
+      "ua": "UA",
+      "ip": "123.3.4.123"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "userid"
+    },
+    "site": {
+      "id": "id",
+      "domain": "test,com",
+      "cat": [
+        "IAB12"
+      ],
+      "publisher": {
+        "id": "pubid"
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247",
+        "body": {
+          "id": "id",
+          "imp": [
+            {
+              "id": "id",
+              "secure": 1,
+              "bidfloor": 0.01,
+              "bidfloorcur": "USD",
+              "banner": {
+                "w": 300,
+                "h": 250
+              },
+              "ext": {
+                "bidder": {
+                  "tokenId": "126151698247",
+                  "sspId": "11",
+                  "seatId": "2"
+                }
+              }
+            }
+          ],
+          "device": {
+            "ua": "UA",
+            "ip": "123.3.4.123"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          },
+          "user": {
+            "id": "userid"
+          },
+          "site": {
+            "id": "id",
+            "domain": "test,com",
+            "cat": [
+              "IAB12"
+            ],
+            "publisher": {
+              "id": "pubid"
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "id",
+          "bidid": "id",
+          "cur": "USD"
+        }
+
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Array SeatBid cannot be empty ",
+      "comparison": "literal"
+    }
+  ],
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/ownadx/ownadxtest/supplemental/unexpected-status.json b/adapters/ownadx/ownadxtest/supplemental/unexpected-status.json
new file mode 100644
index 00000000..f501a110
--- /dev/null
+++ b/adapters/ownadx/ownadxtest/supplemental/unexpected-status.json
@@ -0,0 +1,107 @@
+{
+  "mockBidRequest": {
+    "id": "id",
+    "imp": [
+      {
+        "id": "id",
+        "secure": 1,
+        "bidfloor": 0.01,
+        "bidfloorcur": "USD",
+        "banner": {
+          "w": 300,
+          "h": 250
+        },
+        "ext": {
+          "bidder": {
+            "tokenId": "126151698247",
+            "sspId": "11",
+            "seatId": "2"
+          }
+        }
+      }
+    ],
+    "device": {
+      "ua": "UA",
+      "ip": "123.3.4.123"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    },
+    "user": {
+      "id": "userid"
+    },
+    "site": {
+      "id": "id",
+      "domain": "test,com",
+      "cat": [
+        "IAB12"
+      ],
+      "publisher": {
+        "id": "pubid"
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247",
+        "body": {
+          "id": "id",
+          "imp": [
+            {
+              "id": "id",
+              "secure": 1,
+              "bidfloor": 0.01,
+              "bidfloorcur": "USD",
+              "banner": {
+                "w": 300,
+                "h": 250
+              },
+              "ext": {
+                "bidder": {
+                  "tokenId": "126151698247",
+                  "sspId": "11",
+                  "seatId": "2"
+                }
+              }
+            }
+          ],
+          "device": {
+            "ua": "UA",
+            "ip": "123.3.4.123"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          },
+          "user": {
+            "id": "userid"
+          },
+          "site": {
+            "id": "id",
+            "domain": "test,com",
+            "cat": [
+              "IAB12"
+            ],
+            "publisher": {
+              "id": "pubid"
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 403
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Unexpected status code: 403. Run with request.test = 1 for more info.",
+      "comparison": "literal"
+    }
+  ],
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json b/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json
new file mode 100644
index 00000000..95bfb1e4
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json
@@ -0,0 +1,123 @@
+{
+    "mockBidRequest": {
+      "id": "test-request-id",
+      "imp": [
+        {
+          "id": "test-imp-id",
+          "banner": {
+            "format": [
+              {
+                "w": 300,
+                "h": 250
+              }
+            ]
+          },
+          "bidfloor": 1.00,
+          "bidfloorcur": "EUR",
+          "ext": {
+            "bidder": {
+              "placementId": "12345"
+            }
+          }
+        }
+      ],
+      "ext": {
+        "prebid": {
+          "currency": {
+            "rates": {
+              "EUR": {
+                "USD": 0.05
+              }
+            },
+            "usepbsrates": false
+          }
+        }
+      }
+    },
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "uri": "http://localhost/prebid_server",
+          "body": {
+            "id": "test-request-id",
+            "cur": ["USD"],
+            "imp": [
+              {
+                "banner": {
+                  "format": [
+                    {
+                      "h": 250,
+                      "w": 300
+                    }
+                  ]
+                },
+                "bidfloor": 0.05,
+                "bidfloorcur": "USD",
+                "ext": {
+                  "bidder": {
+                    "placementId": "12345"
+                  }
+                },
+                "id": "test-imp-id"
+              }
+            ],
+            "ext": {
+              "prebid": {
+                "currency": {
+                  "rates": {
+                    "EUR": {
+                      "USD": 0.05
+                    }
+                  },
+                  "usepbsrates": false
+                }
+              }
+             }
+          }
+        },
+        "mockResponse": {
+          "status": 200,
+          "body": {
+            "id": "test-response-id",
+            "cur": "USD",
+            "seatbid": [{
+              "seat": "rtbhouse",
+              "bid": [{
+                "id": "randomid",
+                "impid": "test-imp-id",
+                "price": 300,
+                "adid": "12345678",
+                "adm": "some-test-ad",
+                "cid": "987",
+                "crid": "12345678",
+                "h": 250,
+                "w": 300
+                }
+              ]
+            }]
+          }
+        }
+      }
+    ],
+    "expectedBidResponses": [
+      {
+        "currency": "USD",
+        "bids": [
+          {
+            "bid": {
+              "id": "randomid",
+              "impid": "test-imp-id",
+              "price": 300,
+              "adid": "12345678",
+              "adm": "some-test-ad",
+              "cid": "987",
+              "crid": "12345678",
+              "h": 250,
+              "w": 300
+            },
+            "type": "banner"
+          }
+        ]
+      }
+    ]
+  }
diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json
index 3a636450..2a8c4681 100644
--- a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json
+++ b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json
@@ -23,6 +23,7 @@
             "uri": "http://localhost/prebid_server",
             "body": {
                 "id": "test-request-id",
+                "cur": ["USD"],
                 "site": {
                     "page": "https://good.site/url"
                 },
diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json b/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json
index f84f5555..e0861fb0 100644
--- a/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json
+++ b/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json
@@ -26,6 +26,7 @@
         "uri": "http://localhost/prebid_server",
         "body": {
           "id": "test-request-id",
+          "cur": ["USD"],
           "imp": [
             {
               "id": "test-imp-id",
diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/currency-missing-conversion.json b/adapters/rtbhouse/rtbhousetest/supplemental/currency-missing-conversion.json
new file mode 100644
index 00000000..d7d65e43
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/supplemental/currency-missing-conversion.json
@@ -0,0 +1,43 @@
+{
+    "mockBidRequest": {
+      "id": "test-request-id",
+      "imp": [
+        {
+          "id": "banner-imp-id",
+          "banner": {
+            "format": [
+              {
+                "w": 300,
+                "h": 250
+              }
+            ]
+          },
+          "bidfloor": 1.00,
+          "bidfloorcur": "JPY",
+          "ext": {
+            "bidder": {
+              "placement": "12345"
+            }
+          }
+        }
+      ],
+      "ext": {
+        "prebid": {
+          "currency": {
+              "rates": {
+              "MXN": {
+                  "USD": 0.05
+              }
+              },
+              "usepbsrates": false
+          }
+        }
+      }
+    },
+    "expectedMakeRequestsErrors": [
+      {
+        "value": "Currency conversion rate not found: 'JPY' => 'USD'",
+        "comparison": "literal"
+      }
+    ]
+  }
diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/status_204.json b/adapters/rtbhouse/rtbhousetest/supplemental/status_204.json
index 0702c103..bb7754ec 100644
--- a/adapters/rtbhouse/rtbhousetest/supplemental/status_204.json
+++ b/adapters/rtbhouse/rtbhousetest/supplemental/status_204.json
@@ -26,6 +26,7 @@
         "uri": "http://localhost/prebid_server",
         "body": {
           "id": "test-request-id",
+          "cur": ["USD"],
           "imp": [
             {
               "id": "test-imp-id",
diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/status_400.json b/adapters/rtbhouse/rtbhousetest/supplemental/status_400.json
index 65d21406..0b527932 100644
--- a/adapters/rtbhouse/rtbhousetest/supplemental/status_400.json
+++ b/adapters/rtbhouse/rtbhousetest/supplemental/status_400.json
@@ -26,6 +26,7 @@
         "uri": "http://localhost/prebid_server",
         "body": {
           "id": "test-request-id",
+          "cur": ["USD"],
           "imp": [
             {
               "id": "test-imp-id",
diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/status_418.json b/adapters/rtbhouse/rtbhousetest/supplemental/status_418.json
index 4c5dd576..6ff3860e 100644
--- a/adapters/rtbhouse/rtbhousetest/supplemental/status_418.json
+++ b/adapters/rtbhouse/rtbhousetest/supplemental/status_418.json
@@ -26,6 +26,7 @@
         "uri": "http://localhost/prebid_server",
         "body": {
           "id": "test-request-id",
+          "cur": ["USD"],
           "imp": [
             {
               "id": "test-imp-id",
diff --git a/adapters/vox/params_test.go b/adapters/vox/params_test.go
new file mode 100644
index 00000000..be148d3b
--- /dev/null
+++ b/adapters/vox/params_test.go
@@ -0,0 +1,56 @@
+package vox
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+func TestValidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json schema. %v", err)
+	}
+
+	for _, p := range validParams {
+		if err := validator.Validate(openrtb_ext.BidderVox, json.RawMessage(p)); err != nil {
+			t.Errorf("Schema rejected valid params: %s", p)
+		}
+	}
+}
+
+func TestInvalidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json schema. %v", err)
+	}
+
+	for _, p := range invalidParams {
+		if err := validator.Validate(openrtb_ext.BidderVox, json.RawMessage(p)); err == nil {
+			t.Errorf("Schema allowed invalid params: %s", p)
+		}
+	}
+}
+
+var validParams = []string{
+	`{"placementId": "64be6fe6685a271d37e900d2"}`,
+	`{"placementId": "Any String Basically"}`,
+	`{"placementId":""}`,
+	`{"placementId":"id", "imageUrl":"http://site.com/img1.png"}`,
+	`{"placementId":"id", "imageUrl":"http://site.com/img1.png", "displaySizes":["123x90", "1x1", "987x1111"]}`,
+}
+
+var invalidParams = []string{
+	`{"placementId": 42}`,
+	`{"placementId": null}`,
+	`{"placementId": 3.1415}`,
+	`{"placementId": true}`,
+	`{"placementId": false}`,
+	`{"placementId":"id", "imageUrl": null}`,
+	`{"placementId":"id", "imageUrl": true}`,
+	`{"placementId":"id", "imageUrl": []}`,
+	`{"placementId":"id", "imageUrl": "http://some.url", "displaySizes": null}`,
+	`{"placementId":"id", "imageUrl": "http://some.url", "displaySizes": {}}`,
+	`{"placementId":"id", "imageUrl": "http://some.url", "displaySizes": "String"}`,
+}
diff --git a/adapters/vox/vox_test.go b/adapters/vox/vox_test.go
new file mode 100644
index 00000000..95d11a8a
--- /dev/null
+++ b/adapters/vox/vox_test.go
@@ -0,0 +1,21 @@
+package vox
+
+import (
+	"testing"
+
+	"github.com/prebid/prebid-server/adapters/adapterstest"
+	"github.com/prebid/prebid-server/config"
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+func TestJsonSamples(t *testing.T) {
+	bidder, buildErr := Builder(openrtb_ext.BidderVox, config.Adapter{
+		Endpoint: "http://somecoolurlfor.vox"},
+		config.Server{ExternalUrl: "http://somecoolurlfor.vox", GvlID: 1, DataCenter: "2"})
+
+	if buildErr != nil {
+		t.Fatalf("Builder returned unexpected error: %v", buildErr)
+	}
+
+	adapterstest.RunJSONBidderTest(t, "voxtest", bidder)
+}
diff --git a/adapters/vox/voxtest/exemplary/banner.json b/adapters/vox/voxtest/exemplary/banner.json
new file mode 100644
index 00000000..898fcea4
--- /dev/null
+++ b/adapters/vox/voxtest/exemplary/banner.json
@@ -0,0 +1,82 @@
+{
+  "mockBidRequest": {
+    "id": "cf4b0abb-7ccc-4057-9914-c85f467260c6",
+    "site": {
+      "page": "http://some.site/url/page?id=338"
+    },
+    "cur": [ "USD" ],
+    "imp": [{
+        "id": "8a7510f9-0ca1-44c4-a8c6-1ce639b5eef9",
+        "banner": { "w": 100, "h": 100 },
+        "bidfloorcur": "USD",
+        "ext": {
+          "bidder": {
+            "placementId":"64b939146d66df22ccae95c5"
+          }
+        }
+      }]
+  },
+
+  "httpCalls": [{
+      "expectedRequest": {
+        "uri": "http://somecoolurlfor.vox",
+        "headers": {},
+        "body": {
+          "id": "cf4b0abb-7ccc-4057-9914-c85f467260c6",
+          "site": {
+            "page": "http://some.site/url/page?id=338"
+          },
+          "imp": [
+            {
+              "id": "8a7510f9-0ca1-44c4-a8c6-1ce639b5eef9",
+              "banner": {
+                "w": 100,
+                "h": 100
+              },
+              "bidfloorcur": "USD",
+              "ext": {
+                "bidder": {
+                  "placementId": "64b939146d66df22ccae95c5"
+                }
+              }
+            }
+          ],
+          "cur": [ "USD" ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "headers": {},
+        "body": {
+          "id": "cf4b0abb-7ccc-4057-9914-c85f467260c6",
+          "cur": "USD",
+          "seatbid": [{
+            "bid": [{
+              "id": "e6a143f3-5176-4607-b09e-0e67e358b0b6",
+              "impid": "8a7510f9-0ca1-44c4-a8c6-1ce639b5eef9",
+              "price": 3.1415,
+              "adm": "<html><h1>Hi, there</h1></html>",
+              "w": 50,
+              "h": 50,
+              "mtype": 1
+            }]
+           }]
+        }}
+    }],
+
+    "expectedBidResponses": [{
+      "bids": [{
+        "currency": "USD",
+        "bid": {
+          "id": "e6a143f3-5176-4607-b09e-0e67e358b0b6",
+          "impid": "8a7510f9-0ca1-44c4-a8c6-1ce639b5eef9",
+          "price": 3.1415,
+          "adm": "<html><h1>Hi, there</h1></html>",
+          "w": 50,
+          "h": 50,
+          "mtype": 1
+        },
+        "type": "banner"
+      }]
+    }]
+}
\ No newline at end of file
diff --git a/adapters/vox/voxtest/exemplary/video.json b/adapters/vox/voxtest/exemplary/video.json
new file mode 100644
index 00000000..37464da1
--- /dev/null
+++ b/adapters/vox/voxtest/exemplary/video.json
@@ -0,0 +1,87 @@
+{
+  "mockBidRequest": {
+    "id": "9a4bdb67-43ef-488f-937d-cd01e9dce43d",
+    "site": {
+      "page": "http://blog.com/article/1"
+    },
+    "cur": ["PLN"],
+    "imp": [{
+        "id": "d190d6f3-5264-4df5-91b2-8a9c72cbeb6a",
+        "bidfloorcur": "PLN",
+        "video": {
+          "mimes": ["video/mp4"],
+          "minduration": 5,
+          "maxduration": 15,
+          "w": 1280,
+          "h": 720
+        },
+        "ext": {
+          "bidder": {
+            "placementId":"64b9486efecad2330718e233"
+          }
+        }
+      }]
+  },
+
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "http://somecoolurlfor.vox",
+      "header": {},
+      "body": {
+        "id": "9a4bdb67-43ef-488f-937d-cd01e9dce43d",
+        "site": {
+          "page": "http://blog.com/article/1"
+        },
+        "cur": [ "PLN" ],
+        "imp": [{
+            "id": "d190d6f3-5264-4df5-91b2-8a9c72cbeb6a",
+            "bidfloorcur": "PLN",
+            "video": {
+              "mimes": ["video/mp4"],
+              "minduration": 5,
+              "maxduration": 15,
+              "w": 1280,
+              "h": 720
+            },
+            "ext": {
+              "bidder": {
+                "placementId":"64b9486efecad2330718e233"
+              }
+            }
+          }]
+      }
+    },
+
+    "mockResponse": {
+      "status": 200,
+      "headers": {},
+      "body": {
+        "id":"d64fdeae-cb1c-4322-8fb6-18f5ec49bb76",
+        "cur": "PLN",
+        "seatbid": [{
+          "bid": [{
+            "id": "05349123-29e2-4be0-b662-48914f75ebe1",
+            "impid": "d190d6f3-5264-4df5-91b2-8a9c72cbeb6a",
+            "price": 2.149,
+            "adm": "<VAST>...</VAST>",
+            "mtype": 2
+          }]
+        }]
+      }
+    }
+  }],
+
+  "expectedBidResponses": [{
+    "bids": [{
+      "currency": "PLN",
+      "bid": {
+        "id": "05349123-29e2-4be0-b662-48914f75ebe1",
+        "impid": "d190d6f3-5264-4df5-91b2-8a9c72cbeb6a",
+        "price": 2.149,
+        "adm": "<VAST>...</VAST>",
+        "mtype": 2
+      },
+      "type": "video"
+    }]
+  }]
+}
\ No newline at end of file
diff --git a/adapters/vox/voxtest/supplemental/response_204_to_nocontent.json b/adapters/vox/voxtest/supplemental/response_204_to_nocontent.json
new file mode 100644
index 00000000..0a49b85d
--- /dev/null
+++ b/adapters/vox/voxtest/supplemental/response_204_to_nocontent.json
@@ -0,0 +1,45 @@
+{
+  "mockBidRequest": {
+    "id": "Some Id (445455)",
+    "cur": ["AUD"],
+    "imp": [{
+      "id": "Impression id #1",
+      "banner": {},
+      "bidfloorcur": "AUD",
+      "ext": {
+        "bidder": {
+          "placementId": "64b94ad4ed136806629dd51c"
+        }
+      }
+    }]
+  },
+
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "http://somecoolurlfor.vox",
+      "headers": {},
+      "body": {
+        "id": "Some Id (445455)",
+        "cur": ["AUD"],
+        "imp": [{
+          "id": "Impression id #1",
+          "banner": {},
+          "bidfloorcur": "AUD",
+          "ext": {
+            "bidder": {
+              "placementId": "64b94ad4ed136806629dd51c"
+            }
+          }
+        }]
+      }
+    },
+
+    "mockResponse": {
+      "status": 204,
+      "headers": {},
+      "body": {}
+    }
+  }],
+
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/vox/voxtest/supplemental/response_500_to_error.json b/adapters/vox/voxtest/supplemental/response_500_to_error.json
new file mode 100644
index 00000000..f245ef45
--- /dev/null
+++ b/adapters/vox/voxtest/supplemental/response_500_to_error.json
@@ -0,0 +1,56 @@
+{
+  "mockBidRequest": {
+    "id": "It is hard to make up ids.",
+    "site": {
+      "page": "http://catsanddogs.com/article/887"
+    },
+    "cur": ["USD"],
+    "imp": [{
+      "id": "Impression id #4",
+      "bidfloorcur": "USD",
+      "video": { "w": 1280, "h": 720, "mimes": ["video/mp4"] },
+      "ext": {
+        "bidder": {
+          "placementId": "64b94ca2b5eb3605e0a0e3be"
+        }
+      }
+    }]
+  },
+
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "http://somecoolurlfor.vox",
+      "heades": {},
+      "body": {
+        "id": "It is hard to make up ids.",
+        "site": {
+          "page": "http://catsanddogs.com/article/887"
+        },
+        "cur": ["USD"],
+        "imp": [{
+          "id": "Impression id #4",
+          "bidfloorcur": "USD",
+          "video": { "w": 1280, "h": 720, "mimes": ["video/mp4"] },
+          "ext": {
+            "bidder": {
+              "placementId": "64b94ca2b5eb3605e0a0e3be"
+            }
+          }
+        }]
+      }
+    },
+
+    "mockResponse": {
+      "status": 500,
+      "headers": {},
+      "body": {}
+    }
+  }],
+
+  "expectedBidResponses": [],
+
+  "expectedMakeBidsErrors": [{
+    "value": "Unexpected status code: 500",
+    "comparison": "regex"
+  }]
+}
\ No newline at end of file
diff --git a/config/config_test.go b/config/config_test.go
index 402f9ada..30733372 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -885,7 +885,6 @@ func TestUserSyncFromEnv(t *testing.T) {
 	assert.Nil(t, cfg.BidderInfos["bidder2"].Syncer.Redirect)
 	assert.Nil(t, cfg.BidderInfos["bidder2"].Syncer.SupportCORS)
 
-	assert.Nil(t, cfg.BidderInfos["brightroll"].Syncer)
 }
 
 func TestBidderInfoFromEnv(t *testing.T) {
diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go
index 4be48811..b39f6e03 100644
--- a/endpoints/openrtb2/auction_test.go
+++ b/endpoints/openrtb2/auction_test.go
@@ -1627,7 +1627,7 @@ func TestValidateRequest(t *testing.T) {
 							Ext: []byte(`{"appnexus":{"placementId": 12345678}}`),
 						},
 					},
-					Ext: []byte(`{"prebid":{"aliases":{"brightroll":"appnexus"}, "aliasgvlids":{"pubmatic1":1}}}`),
+					Ext: []byte(`{"prebid":{"aliases":{"yahoossp":"appnexus"}, "aliasgvlids":{"pubmatic1":1}}}`),
 				},
 			},
 			givenIsAmp:            false,
@@ -1658,11 +1658,11 @@ func TestValidateRequest(t *testing.T) {
 							Ext: []byte(`{"appnexus":{"placementId": 12345678}}`),
 						},
 					},
-					Ext: []byte(`{"prebid":{"aliases":{"brightroll":"appnexus"}, "aliasgvlids":{"brightroll":0}}}`),
+					Ext: []byte(`{"prebid":{"aliases":{"yahoossp":"appnexus"}, "aliasgvlids":{"yahoossp":0}}}`),
 				},
 			},
 			givenIsAmp:            false,
-			expectedErrorList:     []error{errors.New("request.ext.prebid.aliasgvlids. Invalid vendorId 0 for alias: brightroll. Choose a different vendorId, or remove this entry.")},
+			expectedErrorList:     []error{errors.New("request.ext.prebid.aliasgvlids. Invalid vendorId 0 for alias: yahoossp. Choose a different vendorId, or remove this entry.")},
 			expectedChannelObject: &openrtb_ext.ExtRequestPrebidChannel{Name: appChannel, Version: ""},
 		},
 		{
@@ -1689,7 +1689,7 @@ func TestValidateRequest(t *testing.T) {
 							Ext: []byte(`{"appnexus":{"placementId": 12345678}}`),
 						},
 					},
-					Ext: []byte(`{"prebid":{"aliases":{"brightroll":"appnexus"}, "aliasgvlids":{"brightroll":1}}}`),
+					Ext: []byte(`{"prebid":{"aliases":{"yahoossp":"appnexus"}, "aliasgvlids":{"yahoossp":1}}}`),
 				},
 			},
 			givenIsAmp:            false,
diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go
index 9176041e..65bc2655 100644
--- a/endpoints/setuid_test.go
+++ b/endpoints/setuid_test.go
@@ -50,7 +50,7 @@ func TestSetUIDEndpoint(t *testing.T) {
 			description:            "Set uid for valid bidder",
 		},
 		{
-			uri:                    "/setuid?bidder=adnxs&uid=123",
+			uri:                    "/setuid?bidder=appnexus&uid=123",
 			syncersBidderNameToKey: map[string]string{"appnexus": "adnxs"},
 			existingSyncs:          nil,
 			gdprAllowsHostCookies:  true,
diff --git a/exchange/adapter_util_test.go b/exchange/adapter_util_test.go
index 3b818bdd..2f3c8e9a 100644
--- a/exchange/adapter_util_test.go
+++ b/exchange/adapter_util_test.go
@@ -222,6 +222,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) {
 				"oftmedia":       `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`,
 				"groupm":         `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`,
 				"verizonmedia":   `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`,
+				"brightroll":     `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`,
 			},
 		},
 		{
@@ -236,6 +237,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) {
 				"oftmedia":       `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`,
 				"groupm":         `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`,
 				"verizonmedia":   `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`,
+				"brightroll":     `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`,
 			},
 		},
 		{
@@ -251,6 +253,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) {
 				"oftmedia":       `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`,
 				"groupm":         `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`,
 				"verizonmedia":   `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`,
+				"brightroll":     `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`,
 			},
 		},
 		{
@@ -266,6 +269,7 @@ func TestGetDisabledBiddersErrorMessages(t *testing.T) {
 				"oftmedia":       `Bidder "oftmedia" is no longer available in Prebid Server. Please update your configuration.`,
 				"groupm":         `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`,
 				"verizonmedia":   `Bidder "verizonmedia" is no longer available in Prebid Server. Please update your configuration.`,
+				"brightroll":     `Bidder "brightroll" is no longer available in Prebid Server. Please update your configuration.`,
 			},
 		},
 	}
diff --git a/exchange/exchangetest/request-ext-prebid-filtering.json b/exchange/exchangetest/request-ext-prebid-filtering.json
index 499f779a..4355f517 100644
--- a/exchange/exchangetest/request-ext-prebid-filtering.json
+++ b/exchange/exchangetest/request-ext-prebid-filtering.json
@@ -60,6 +60,14 @@
                         "rubicon": {
                             "not": "permitted-for-appnexus"
                         }
+                    },
+                    "sdk": {
+                        "renderers": [
+                            {
+                                "name": "test-name",
+                                "version": "test-version"
+                            }
+                        ]
                     }
                 }
             }
@@ -108,6 +116,14 @@
                             "bidderparams": {
                                 "param1": 1,
                                 "paramA": "A"
+                            },
+                            "sdk": {
+                                "renderers": [
+                                    {
+                                        "name": "test-name",
+                                        "version": "test-version"
+                                    }
+                                ]
                             }
                         }
                     }
diff --git a/exchange/utils_test.go b/exchange/utils_test.go
index 973edc53..a736dcfa 100644
--- a/exchange/utils_test.go
+++ b/exchange/utils_test.go
@@ -74,8 +74,6 @@ func assertReq(t *testing.T, bidderRequests []BidderRequest,
 	assert.NotEqual(t, bidderRequests, 0, "cleanOpenRTBRequest should split request into individual bidder requests")
 
 	// assert for PI data
-	// Both appnexus and brightroll should be allowed since brightroll
-	// is used as an alias for appnexus in the test request
 	for _, req := range bidderRequests {
 		if !applyCOPPA && consentedVendors[req.BidderName.String()] {
 			assert.NotEqual(t, req.BidRequest.User.BuyerUID, "", "cleanOpenRTBRequest shouldn't clean PI data as per COPPA or for a consented vendor as per GDPR or per CCPA")
@@ -459,7 +457,7 @@ func TestCleanOpenRTBRequests(t *testing.T) {
 			bidReqAssertions: assertReq,
 			hasError:         false,
 			applyCOPPA:       false,
-			consentedVendors: map[string]bool{"appnexus": true, "brightroll": true},
+			consentedVendors: map[string]bool{"appnexus": true},
 		},
 	}
 
@@ -508,13 +506,6 @@ func TestCleanOpenRTBRequestsWithFPD(t *testing.T) {
 	}
 	fpd[openrtb_ext.BidderName("rubicon")] = &apnFpd
 
-	brightrollFpd := firstpartydata.ResolvedFirstPartyData{
-		Site: &openrtb2.Site{Name: "fpdBrightrollSite"},
-		App:  &openrtb2.App{Name: "fpdBrightrollApp"},
-		User: &openrtb2.User{Keywords: "fpdBrightrollUser"},
-	}
-	fpd[openrtb_ext.BidderName("brightroll")] = &brightrollFpd
-
 	emptyTCF2Config := gdpr.NewTCF2Config(config.TCF2{}, config.AccountGDPR{})
 
 	testCases := []struct {
@@ -2392,14 +2383,14 @@ func TestBuildRequestExtForBidder(t *testing.T) {
 		{
 			description:  "Prebid - Allowed Fields Only",
 			bidderParams: nil,
-			requestExt:   json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}}}`),
-			expectedJson: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}}}`),
+			requestExt:   json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}}}`),
+			expectedJson: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}}}`),
 		},
 		{
 			description:  "Prebid - Allowed Fields + Bidder Params",
 			bidderParams: map[string]json.RawMessage{bidder: bidderParams},
-			requestExt:   json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}}}`),
-			expectedJson: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "bidderparams":"bar"}}`),
+			requestExt:   json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}}}`),
+			expectedJson: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}, "bidderparams":"bar"}}`),
 		},
 		{
 			description:  "Other",
@@ -2410,8 +2401,8 @@ func TestBuildRequestExtForBidder(t *testing.T) {
 		{
 			description:  "Prebid + Other + Bider Params",
 			bidderParams: map[string]json.RawMessage{bidder: bidderParams},
-			requestExt:   json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}}}`),
-			expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "bidderparams":"bar"}}`),
+			requestExt:   json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}}}`),
+			expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}, "bidderparams":"bar"}}`),
 		},
 		{
 			description:          "Prebid + AlternateBidderCodes in pbs config but current bidder not in AlternateBidderCodes config",
@@ -2580,9 +2571,9 @@ func newAdapterAliasBidRequest(t *testing.T) *openrtb2.BidRequest {
 					H: 600,
 				}},
 			},
-			Ext: json.RawMessage(`{"appnexus": {"placementId": 1},"brightroll": {"placementId": 105}}`),
+			Ext: json.RawMessage(`{"appnexus": {"placementId": 1},"somealias": {"placementId": 105}}`),
 		}},
-		Ext: json.RawMessage(`{"prebid":{"aliases":{"brightroll":"appnexus"}}}`),
+		Ext: json.RawMessage(`{"prebid":{"aliases":{"somealias":"appnexus"}}}`),
 	}
 }
 
@@ -3196,17 +3187,17 @@ func Test_parseAliasesGVLIDs(t *testing.T) {
 			"AliasGVLID Parsed Correctly",
 			args{
 				orig: &openrtb2.BidRequest{
-					Ext: json.RawMessage(`{"prebid":{"aliases":{"brightroll":"appnexus"}, "aliasgvlids":{"brightroll":1}}}`),
+					Ext: json.RawMessage(`{"prebid":{"aliases":{"somealiascode":"appnexus"}, "aliasgvlids":{"somealiascode":1}}}`),
 				},
 			},
-			map[string]uint16{"brightroll": 1},
+			map[string]uint16{"somealiascode": 1},
 			false,
 		},
 		{
 			"AliasGVLID parsing error",
 			args{
 				orig: &openrtb2.BidRequest{
-					Ext: json.RawMessage(`{"prebid":{"aliases":{"brightroll":"appnexus"}, "aliasgvlids": {"brightroll":"abc"}`),
+					Ext: json.RawMessage(`{"prebid":{"aliases":{"somealiascode":"appnexus"}, "aliasgvlids": {"somealiascode":"abc"}`),
 				},
 			},
 			nil,
@@ -3216,7 +3207,7 @@ func Test_parseAliasesGVLIDs(t *testing.T) {
 			"Invalid AliasGVLID",
 			args{
 				orig: &openrtb2.BidRequest{
-					Ext: json.RawMessage(`{"prebid":{"aliases":{"brightroll":"appnexus"}, "aliasgvlids":"abc"}`),
+					Ext: json.RawMessage(`{"prebid":{"aliases":{"somealiascode":"appnexus"}, "aliasgvlids":"abc"}`),
 				},
 			},
 			nil,
@@ -3226,7 +3217,7 @@ func Test_parseAliasesGVLIDs(t *testing.T) {
 			"Missing AliasGVLID",
 			args{
 				orig: &openrtb2.BidRequest{
-					Ext: json.RawMessage(`{"prebid":{"aliases":{"brightroll":"appnexus"}}`),
+					Ext: json.RawMessage(`{"prebid":{"aliases":{"somealiascode":"appnexus"}}`),
 				},
 			},
 			nil,
diff --git a/usersync/syncer_test.go b/usersync/syncer_test.go
index 6e727c3a..c309b899 100644
--- a/usersync/syncer_test.go
+++ b/usersync/syncer_test.go
@@ -26,6 +26,7 @@ func TestNewSyncer(t *testing.T) {
 	testCases := []struct {
 		description         string
 		givenKey            string
+		givenBidderName     string
 		givenIFrameConfig   *config.SyncerEndpoint
 		givenRedirectConfig *config.SyncerEndpoint
 		givenExternalURL    string
@@ -37,6 +38,7 @@ func TestNewSyncer(t *testing.T) {
 		{
 			description:         "Missing Key",
 			givenKey:            "",
+			givenBidderName:     "",
 			givenIFrameConfig:   iframeConfig,
 			givenRedirectConfig: nil,
 			expectedError:       "key is required",
@@ -44,6 +46,7 @@ func TestNewSyncer(t *testing.T) {
 		{
 			description:         "Missing Endpoints",
 			givenKey:            "a",
+			givenBidderName:     "bidderA",
 			givenIFrameConfig:   nil,
 			givenRedirectConfig: nil,
 			expectedError:       "at least one endpoint (iframe and/or redirect) is required",
@@ -51,6 +54,7 @@ func TestNewSyncer(t *testing.T) {
 		{
 			description:         "IFrame & Redirect Endpoints",
 			givenKey:            "a",
+			givenBidderName:     "bidderA",
 			givenIFrameConfig:   iframeConfig,
 			givenRedirectConfig: redirectConfig,
 			expectedDefault:     SyncTypeIFrame,
@@ -60,13 +64,15 @@ func TestNewSyncer(t *testing.T) {
 		{
 			description:         "IFrame - Parse Error",
 			givenKey:            "a",
+			givenBidderName:     "bidderA",
 			givenIFrameConfig:   errParseConfig,
 			givenRedirectConfig: nil,
-			expectedError:       "iframe template: a_usersync_url:1: function \"malformed\" not defined",
+			expectedError:       "iframe template: biddera_usersync_url:1: function \"malformed\" not defined",
 		},
 		{
 			description:         "IFrame - Validation Error",
 			givenKey:            "a",
+			givenBidderName:     "bidderA",
 			givenIFrameConfig:   errInvalidConfig,
 			givenRedirectConfig: nil,
 			expectedError:       "iframe composed url: \"notAURL:http%3A%2F%2Fhost.com%2Fhost\" is invalid",
@@ -74,13 +80,15 @@ func TestNewSyncer(t *testing.T) {
 		{
 			description:         "Redirect - Parse Error",
 			givenKey:            "a",
+			givenBidderName:     "bidderA",
 			givenIFrameConfig:   nil,
 			givenRedirectConfig: errParseConfig,
-			expectedError:       "redirect template: a_usersync_url:1: function \"malformed\" not defined",
+			expectedError:       "redirect template: biddera_usersync_url:1: function \"malformed\" not defined",
 		},
 		{
 			description:         "Redirect - Validation Error",
 			givenKey:            "a",
+			givenBidderName:     "bidderA",
 			givenIFrameConfig:   nil,
 			givenRedirectConfig: errInvalidConfig,
 			expectedError:       "redirect composed url: \"notAURL:http%3A%2F%2Fhost.com%2Fhost\" is invalid",
@@ -88,6 +96,7 @@ func TestNewSyncer(t *testing.T) {
 		{
 			description:         "Syncer Level External URL",
 			givenKey:            "a",
+			givenBidderName:     "bidderA",
 			givenExternalURL:    "http://syncer.com",
 			givenIFrameConfig:   iframeConfig,
 			givenRedirectConfig: redirectConfig,
@@ -106,7 +115,7 @@ func TestNewSyncer(t *testing.T) {
 			ExternalURL: test.givenExternalURL,
 		}
 
-		result, err := NewSyncer(hostConfig, syncerConfig)
+		result, err := NewSyncer(hostConfig, syncerConfig, test.givenBidderName)
 
 		if test.expectedError == "" {
 			assert.NoError(t, err, test.description+":err")
@@ -196,7 +205,7 @@ func TestBuildTemplate(t *testing.T) {
 			expectedRendered: "hasNoComposedMacros,gdpr=A",
 		},
 		{
-			description: "All Composed Macros",
+			description: "All Composed Macros - SyncerKey",
 			givenSyncerEndpoint: config.SyncerEndpoint{
 				URL:         "https://bidder.com/sync?redirect={{.RedirectURL}}",
 				RedirectURL: "{{.ExternalURL}}/setuid?bidder={{.SyncerKey}}&f={{.SyncType}}&gdpr={{.GDPR}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&uid={{.UserMacro}}",
@@ -205,6 +214,16 @@ func TestBuildTemplate(t *testing.T) {
 			},
 			expectedRendered: "https://bidder.com/sync?redirect=http%3A%2F%2Fsyncer.com%2Fsetuid%3Fbidder%3DanyKey%26f%3Dx%26gdpr%3DA%26gpp%3DD%26gpp_sid%3D1%26uid%3D%24UID%24",
 		},
+		{
+			description: "All Composed Macros - BidderName",
+			givenSyncerEndpoint: config.SyncerEndpoint{
+				URL:         "https://bidder.com/sync?redirect={{.RedirectURL}}",
+				RedirectURL: "{{.ExternalURL}}/setuid?bidder={{.BidderName}}&f={{.SyncType}}&gdpr={{.GDPR}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&uid={{.UserMacro}}",
+				ExternalURL: "http://syncer.com",
+				UserMacro:   "$UID$",
+			},
+			expectedRendered: "https://bidder.com/sync?redirect=http%3A%2F%2Fsyncer.com%2Fsetuid%3Fbidder%3DanyKey%26f%3Dx%26gdpr%3DA%26gpp%3DD%26gpp_sid%3D1%26uid%3D%24UID%24",
+		},
 		{
 			description: "Redirect URL + External URL From Host",
 			givenSyncerEndpoint: config.SyncerEndpoint{
diff --git a/usersync/syncersbuilder_test.go b/usersync/syncersbuilder_test.go
index b3672a50..fbc18639 100644
--- a/usersync/syncersbuilder_test.go
+++ b/usersync/syncersbuilder_test.go
@@ -48,7 +48,7 @@ func TestBuildSyncers(t *testing.T) {
 			givenConfig:      hostConfig,
 			givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAPopulated},
 			expectedIFramesURLs: map[string]string{
-				"bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fa%2Fhost",
+				"bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder1%2Fhost",
 			},
 		},
 		{
@@ -64,7 +64,7 @@ func TestBuildSyncers(t *testing.T) {
 			givenConfig:      hostConfig,
 			givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAError},
 			expectedErrors: []string{
-				"cannot create syncer for bidder bidder1 with key a: iframe template: a_usersync_url:1: function \"xRedirectURL\" not defined",
+				"cannot create syncer for bidder bidder1 with key a: iframe template: bidder1_usersync_url:1: function \"xRedirectURL\" not defined",
 			},
 		},
 		{
@@ -72,8 +72,8 @@ func TestBuildSyncers(t *testing.T) {
 			givenConfig:      hostConfig,
 			givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAPopulated, "bidder2": infoKeyBPopulated},
 			expectedIFramesURLs: map[string]string{
-				"bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fa%2Fhost",
-				"bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fb%2Fhost",
+				"bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder1%2Fhost",
+				"bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder2%2Fhost",
 			},
 		},
 		{
@@ -81,8 +81,8 @@ func TestBuildSyncers(t *testing.T) {
 			givenConfig:      hostConfig,
 			givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAPopulated, "bidder2": infoKeyAEmpty},
 			expectedIFramesURLs: map[string]string{
-				"bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fa%2Fhost",
-				"bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fa%2Fhost",
+				"bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder1%2Fhost",
+				"bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder2%2Fhost",
 			},
 		},
 		{
@@ -106,7 +106,8 @@ func TestBuildSyncers(t *testing.T) {
 			givenConfig:      hostConfig,
 			givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAEmpty, "bidder2": infoKeyAError},
 			expectedErrors: []string{
-				"cannot create syncer for bidder bidder2 with key a: iframe template: a_usersync_url:1: function \"xRedirectURL\" not defined",
+				"cannot create syncer for bidder bidder2 with key a: iframe template: bidder1_usersync_url:1: function \"xRedirectURL\" not defined",
+				"cannot create syncer for bidder bidder2 with key a: iframe template: bidder2_usersync_url:1: function \"xRedirectURL\" not defined",
 			},
 		},
 		{
@@ -114,7 +115,7 @@ func TestBuildSyncers(t *testing.T) {
 			givenConfig:      hostConfig,
 			givenBidderInfos: map[string]config.BidderInfo{"bidder1": {}, "bidder2": infoKeyBPopulated},
 			expectedIFramesURLs: map[string]string{
-				"bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fb%2Fhost",
+				"bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder2%2Fhost",
 			},
 		},
 		{
@@ -122,7 +123,7 @@ func TestBuildSyncers(t *testing.T) {
 			givenConfig:      hostConfig,
 			givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyADisabled, "bidder2": infoKeyBPopulated},
 			expectedIFramesURLs: map[string]string{
-				"bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fb%2Fhost",
+				"bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder2%2Fhost",
 			},
 		},
 		{
@@ -130,7 +131,7 @@ func TestBuildSyncers(t *testing.T) {
 			givenConfig:      hostConfig,
 			givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyASupportsOnly, "bidder2": infoKeyBPopulated},
 			expectedIFramesURLs: map[string]string{
-				"bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fb%2Fhost",
+				"bidder2": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhost.com%2Fbidder2%2Fhost",
 			},
 		},
 		{
@@ -138,7 +139,7 @@ func TestBuildSyncers(t *testing.T) {
 			givenConfig:      hostConfig,
 			givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAError, "bidder2": infoKeyBEmpty},
 			expectedErrors: []string{
-				"cannot create syncer for bidder bidder1 with key a: iframe template: a_usersync_url:1: function \"xRedirectURL\" not defined",
+				"cannot create syncer for bidder bidder1 with key a: iframe template: bidder1_usersync_url:1: function \"xRedirectURL\" not defined",
 				"cannot create syncer for bidder bidder2 with key b: at least one endpoint (iframe and/or redirect) is required",
 			},
 		},
@@ -147,7 +148,7 @@ func TestBuildSyncers(t *testing.T) {
 			givenConfig:      config.Configuration{ExternalURL: "http://host.com", UserSync: config.UserSync{ExternalURL: "http://hostoverride.com", RedirectURL: "{{.ExternalURL}}/{{.SyncerKey}}/host"}},
 			givenBidderInfos: map[string]config.BidderInfo{"bidder1": infoKeyAPopulated},
 			expectedIFramesURLs: map[string]string{
-				"bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhostoverride.com%2Fa%2Fhost",
+				"bidder1": "https://bidder.com/iframe?redirect=http%3A%2F%2Fhostoverride.com%2Fbidder1%2Fhost",
 			},
 		},
 	}