Repository: prebid/prebid-server
Pull request #1578 (2020-11-11 11:17:37)

Fix Beachfront JSON tests
We recently discovered that the `RunJSONBidderTest` function, responsible for running the adapter specific JSON tests does not complain if the JSON test doesn't follow the required structure and we also found that a lot of the adapters weren't actually following the required struct, which meant those bid responses weren't actually getting asserted while running tests.

This PR fixes the JSON tests for the `Beachfront` adapter. (Created a separate PR for beachfront because a few of their tests required changes and so it might be easy for the reviewer to just focus on their tests rather than with a bunch of other adapter tests)

I updated the `RunJSONBidderTest` function minimally on my local machine to actually complain when a JSON test doesn't adhere with the required structure and fixed them accordingly. However, I am not pushing the `RunJSONBidderTest` changes yet because that will break the the tests for the rest of the adapters as well and leave `master` in a weird state. I am planning to push the changes for other adapters as another few PRs and once those are in, I will put a PR for the changes in the `RunJSONBidderTest` function as well. At that point all adapters tests should be fixed and the tests should be in the expected state.


Patch:
diff --git a/adapters/adform/adform.go b/adapters/adform/adform.go
index 5881f4ab..d7e5deda 100644
--- a/adapters/adform/adform.go
+++ b/adapters/adform/adform.go
@@ -79,6 +79,7 @@ type adformBid struct {
 	Height       uint64  `json:"height,omitempty"`
 	DealId       string  `json:"deal_id,omitempty"`
 	CreativeId   string  `json:"win_crid,omitempty"`
+	VastContent  string  `json:"vast_content,omitempty"`
 }
 
 const priceTypeGross = "gross"
@@ -241,7 +242,8 @@ func toPBSBidSlice(adformBids []*adformBid, r *adformRequest) pbs.PBSBidSlice {
 	bids := make(pbs.PBSBidSlice, 0)
 
 	for i, bid := range adformBids {
-		if bid.Banner == "" || bid.ResponseType != "banner" {
+		adm, bidType := getAdAndType(bid)
+		if adm == "" {
 			continue
 		}
 		pbsBid := pbs.PBSBid{
@@ -249,12 +251,12 @@ func toPBSBidSlice(adformBids []*adformBid, r *adformRequest) pbs.PBSBidSlice {
 			AdUnitCode:        r.adUnits[i].adUnitCode,
 			BidderCode:        r.bidderCode,
 			Price:             bid.Price,
-			Adm:               bid.Banner,
+			Adm:               adm,
 			Width:             bid.Width,
 			Height:            bid.Height,
 			DealId:            bid.DealId,
 			Creative_id:       bid.CreativeId,
-			CreativeMediaType: string(openrtb_ext.BidTypeBanner),
+			CreativeMediaType: string(bidType),
 		}
 
 		bids = append(bids, &pbsBid)
@@ -632,21 +634,23 @@ func toOpenRtbBidResponse(adformBids []*adformBid, r *openrtb.BidRequest) *adapt
 	}
 
 	for i, bid := range adformBids {
-		if bid.Banner == "" || bid.ResponseType != "banner" {
+		adm, bidType := getAdAndType(bid)
+		if adm == "" {
 			continue
 		}
+
 		openRtbBid := openrtb.Bid{
 			ID:     r.Imp[i].ID,
 			ImpID:  r.Imp[i].ID,
 			Price:  bid.Price,
-			AdM:    bid.Banner,
+			AdM:    adm,
 			W:      bid.Width,
 			H:      bid.Height,
 			DealID: bid.DealId,
 			CrID:   bid.CreativeId,
 		}
 
-		bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{Bid: &openRtbBid, BidType: openrtb_ext.BidTypeBanner})
+		bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{Bid: &openRtbBid, BidType: bidType})
 		currency = bid.Currency
 	}
 
@@ -654,3 +658,12 @@ func toOpenRtbBidResponse(adformBids []*adformBid, r *openrtb.BidRequest) *adapt
 
 	return bidResponse
 }
+
+func getAdAndType(bid *adformBid) (string, openrtb_ext.BidType) {
+	if bid.ResponseType == "banner" {
+		return bid.Banner, openrtb_ext.BidTypeBanner
+	} else if bid.ResponseType == "vast_content" {
+		return bid.VastContent, openrtb_ext.BidTypeVideo
+	}
+	return "", ""
+}
diff --git a/adapters/adpone/usersync.go b/adapters/adpone/usersync.go
index 480ecb82..67d4c998 100644
--- a/adapters/adpone/usersync.go
+++ b/adapters/adpone/usersync.go
@@ -7,7 +7,7 @@ import (
 	"github.com/prebid/prebid-server/usersync"
 )
 
-const adponeGDPRVendorID = uint16(16)
+const adponeGDPRVendorID = uint16(799)
 const adponeFamilyName = "adpone"
 
 func NewadponeSyncer(urlTemplate *template.Template) usersync.Usersyncer {
diff --git a/adapters/adtelligent/usersync.go b/adapters/adtelligent/usersync.go
index cda3b62a..087b5bdd 100644
--- a/adapters/adtelligent/usersync.go
+++ b/adapters/adtelligent/usersync.go
@@ -8,5 +8,5 @@ import (
 )
 
 func NewAdtelligentSyncer(temp *template.Template) usersync.Usersyncer {
-	return adapters.NewSyncer("adtelligent", 0, temp, adapters.SyncTypeRedirect)
+	return adapters.NewSyncer("adtelligent", 410, temp, adapters.SyncTypeRedirect)
 }
diff --git a/adapters/dmx/dmx.go b/adapters/dmx/dmx.go
index dfb97f33..6da7823a 100644
--- a/adapters/dmx/dmx.go
+++ b/adapters/dmx/dmx.go
@@ -168,6 +168,7 @@ func (adapter *DmxAdapter) MakeRequests(request *openrtb.BidRequest, req *adapte
 		Body:    oJson,
 		Headers: headers,
 	}
+
 	reqsBidder = append(reqsBidder, reqBidder)
 	return
 }
@@ -221,35 +222,29 @@ func (adapter *DmxAdapter) MakeBids(request *openrtb.BidRequest, externalRequest
 }
 
 func fetchParams(params dmxExt, inst openrtb.Imp, ins openrtb.Imp, imps []openrtb.Imp, banner *openrtb.Banner, video *openrtb.Video, intVal int8) []openrtb.Imp {
+	var tempimp openrtb.Imp
+	tempimp = inst
 	if params.Bidder.TagId != "" {
-		ins = openrtb.Imp{
-			ID:     inst.ID,
-			TagID:  params.Bidder.TagId,
-			Ext:    inst.Ext,
-			Secure: &intVal,
-		}
+		tempimp.TagID = params.Bidder.TagId
+		tempimp.Secure = &intVal
 	}
 
 	if params.Bidder.DmxId != "" {
-		ins = openrtb.Imp{
-			ID:     inst.ID,
-			TagID:  params.Bidder.DmxId,
-			Ext:    inst.Ext,
-			Secure: &intVal,
-		}
+		tempimp.TagID = params.Bidder.DmxId
+		tempimp.Secure = &intVal
 	}
 	if banner != nil {
-		ins.Banner = banner
+		tempimp.Banner = banner
 	}
 
 	if video != nil {
-		ins.Video = video
+		tempimp.Video = video
 	}
 
-	if ins.TagID == "" {
+	if tempimp.TagID == "" {
 		return imps
 	}
-	imps = append(imps, ins)
+	imps = append(imps, tempimp)
 	return imps
 }
 
diff --git a/adapters/eplanning/usersync.go b/adapters/eplanning/usersync.go
index 252c106a..faa7fa82 100644
--- a/adapters/eplanning/usersync.go
+++ b/adapters/eplanning/usersync.go
@@ -8,5 +8,5 @@ import (
 )
 
 func NewEPlanningSyncer(temp *template.Template) usersync.Usersyncer {
-	return adapters.NewSyncer("eplanning", 0, temp, adapters.SyncTypeIframe)
+	return adapters.NewSyncer("eplanning", 90, temp, adapters.SyncTypeIframe)
 }
diff --git a/adapters/silvermob/silvermob.go b/adapters/silvermob/silvermob.go
new file mode 100644
index 00000000..be7a1762
--- /dev/null
+++ b/adapters/silvermob/silvermob.go
@@ -0,0 +1,188 @@
+package silvermob
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/golang/glog"
+	"net/http"
+	"text/template"
+
+	"github.com/mxmCherry/openrtb"
+	"github.com/prebid/prebid-server/adapters"
+	"github.com/prebid/prebid-server/errortypes"
+	"github.com/prebid/prebid-server/macros"
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+type SilverMobAdapter struct {
+	endpoint template.Template
+}
+
+func NewSilverMobBidder(endpointTemplate string) *SilverMobAdapter {
+	template, err := template.New("endpointTemplate").Parse(endpointTemplate)
+	if err != nil {
+		glog.Fatal("Unable to parse endpoint url template")
+		return nil
+	}
+	return &SilverMobAdapter{endpoint: *template}
+}
+
+func GetHeaders(request *openrtb.BidRequest) *http.Header {
+	headers := http.Header{}
+	headers.Add("Content-Type", "application/json;charset=utf-8")
+	headers.Add("Accept", "application/json")
+	headers.Add("X-Openrtb-Version", "2.5")
+
+	if request.Device != nil {
+		if len(request.Device.UA) > 0 {
+			headers.Add("User-Agent", request.Device.UA)
+		}
+
+		if len(request.Device.IPv6) > 0 {
+			headers.Add("X-Forwarded-For", request.Device.IPv6)
+		}
+
+		if len(request.Device.IP) > 0 {
+			headers.Add("X-Forwarded-For", request.Device.IP)
+		}
+	}
+
+	return &headers
+}
+
+func (a *SilverMobAdapter) MakeRequests(
+	openRTBRequest *openrtb.BidRequest,
+	reqInfo *adapters.ExtraRequestInfo,
+) (
+	[]*adapters.RequestData,
+	[]error,
+) {
+	requestCopy := *openRTBRequest
+	impCount := len(openRTBRequest.Imp)
+	requestData := make([]*adapters.RequestData, 0, impCount)
+	errs := []error{}
+
+	var err error
+
+	for _, imp := range openRTBRequest.Imp {
+		var silvermobExt *openrtb_ext.ExtSilverMob
+
+		silvermobExt, err = a.getImpressionExt(&imp)
+
+		if err != nil {
+			errs = append(errs, err)
+			continue
+		}
+
+		url, err := a.buildEndpointURL(silvermobExt)
+		if err != nil {
+			errs = append(errs, err)
+			continue
+		}
+
+		requestCopy.Imp = []openrtb.Imp{imp}
+		reqJSON, err := json.Marshal(requestCopy)
+		if err != nil {
+			errs = append(errs, err)
+			continue
+		}
+
+		reqData := &adapters.RequestData{
+			Method:  http.MethodPost,
+			Body:    reqJSON,
+			Uri:     url,
+			Headers: *GetHeaders(&requestCopy),
+		}
+
+		requestData = append(requestData, reqData)
+	}
+
+	return requestData, errs
+}
+
+func (a *SilverMobAdapter) getImpressionExt(imp *openrtb.Imp) (*openrtb_ext.ExtSilverMob, error) {
+	var bidderExt adapters.ExtImpBidder
+	if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
+		return nil, &errortypes.BadInput{
+			Message: fmt.Sprintf("error unmarshaling imp.ext: %s", err.Error()),
+		}
+	}
+	var silvermobExt openrtb_ext.ExtSilverMob
+	if err := json.Unmarshal(bidderExt.Bidder, &silvermobExt); err != nil {
+		return nil, &errortypes.BadInput{
+			Message: fmt.Sprintf("error unmarshaling imp.ext.bidder: %s", err.Error()),
+		}
+	}
+	return &silvermobExt, nil
+}
+
+func (a *SilverMobAdapter) buildEndpointURL(params *openrtb_ext.ExtSilverMob) (string, error) {
+	endpointParams := macros.EndpointTemplateParams{ZoneID: params.ZoneID, Host: params.Host}
+	return macros.ResolveMacros(a.endpoint, endpointParams)
+}
+
+func (a *SilverMobAdapter) MakeBids(
+	openRTBRequest *openrtb.BidRequest,
+	requestToBidder *adapters.RequestData,
+	bidderRawResponse *adapters.ResponseData,
+) (
+	bidderResponse *adapters.BidderResponse,
+	errs []error,
+) {
+
+	if bidderRawResponse.StatusCode == http.StatusNoContent {
+		return nil, nil
+	}
+
+	if bidderRawResponse.StatusCode == http.StatusBadRequest {
+		return nil, []error{&errortypes.BadInput{
+			Message: fmt.Sprintf("Bad Request status code: %d. Run with request.debug = 1 for more info", bidderRawResponse.StatusCode),
+		}}
+	}
+
+	if bidderRawResponse.StatusCode != http.StatusOK {
+		return nil, []error{fmt.Errorf("Unexpected status code: %d. Run with request.debug = 1 for more info", bidderRawResponse.StatusCode)}
+	}
+
+	responseBody := bidderRawResponse.Body
+	var bidResp openrtb.BidResponse
+	if err := json.Unmarshal(responseBody, &bidResp); err != nil {
+		return nil, []error{&errortypes.BadServerResponse{
+			Message: fmt.Sprintf("Error unmarshaling server Response: %s", err),
+		}}
+	}
+
+	if len(bidResp.SeatBid) == 0 {
+		return nil, []error{&errortypes.BadServerResponse{
+			Message: "Empty SeatBid array",
+		}}
+	}
+
+	bidResponse := adapters.NewBidderResponseWithBidsCapacity(1)
+
+	for _, sb := range bidResp.SeatBid {
+		for _, bid := range sb.Bid {
+			bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
+				Bid:     &bid,
+				BidType: getMediaTypeForImp(bid.ImpID, openRTBRequest.Imp),
+			})
+		}
+	}
+
+	return bidResponse, nil
+}
+
+func getMediaTypeForImp(impId string, imps []openrtb.Imp) openrtb_ext.BidType {
+	mediaType := openrtb_ext.BidTypeBanner
+	for _, imp := range imps {
+		if imp.ID == impId {
+			if imp.Video != nil {
+				mediaType = openrtb_ext.BidTypeVideo
+			} else if imp.Native != nil {
+				mediaType = openrtb_ext.BidTypeNative
+			}
+			return mediaType
+		}
+	}
+	return mediaType
+}
diff --git a/config/accounts.go b/config/accounts.go
index 162818eb..5ec818b8 100644
--- a/config/accounts.go
+++ b/config/accounts.go
@@ -1,9 +1,61 @@
 package config
 
+// IntegrationType enumerates the values of integrations Prebid Server can configure for an account
+type IntegrationType string
+
+// Possible values of integration types Prebid Server can configure for an account
+const (
+	IntegrationTypeAMP   IntegrationType = "amp"
+	IntegrationTypeApp   IntegrationType = "app"
+	IntegrationTypeVideo IntegrationType = "video"
+	IntegrationTypeWeb   IntegrationType = "web"
+)
+
 // Account represents a publisher account configuration
 type Account struct {
 	ID            string      `mapstructure:"id" json:"id"`
 	Disabled      bool        `mapstructure:"disabled" json:"disabled"`
 	CacheTTL      DefaultTTLs `mapstructure:"cache_ttl" json:"cache_ttl"`
 	EventsEnabled bool        `mapstructure:"events_enabled" json:"events_enabled"`
+	GDPR          AccountGDPR `mapstructure:"gdpr" json:"gdpr"`
+}
+
+// AccountGDPR represents account-specific GDPR configuration
+type AccountGDPR struct {
+	Enabled            *bool                  `mapstructure:"enabled" json:"enabled,omitempty"`
+	IntegrationEnabled AccountGDPRIntegration `mapstructure:"integration_enabled" json:"integration_enabled"`
+}
+
+// EnabledForIntegrationType indicates whether GDPR is turned on at the account level for the specified integration type
+// by using the integration type setting if defined or the general GDPR setting if defined; otherwise it returns nil
+func (a *AccountGDPR) EnabledForIntegrationType(integrationType IntegrationType) *bool {
+	var integrationEnabled *bool
+
+	switch integrationType {
+	case IntegrationTypeAMP:
+		integrationEnabled = a.IntegrationEnabled.AMP
+	case IntegrationTypeApp:
+		integrationEnabled = a.IntegrationEnabled.App
+	case IntegrationTypeVideo:
+		integrationEnabled = a.IntegrationEnabled.Video
+	case IntegrationTypeWeb:
+		integrationEnabled = a.IntegrationEnabled.Web
+	}
+
+	if integrationEnabled != nil {
+		return integrationEnabled
+	}
+	if a.Enabled != nil {
+		return a.Enabled
+	}
+
+	return nil
+}
+
+// AccountGDPRIntegration indicates whether GDPR is enabled for each integration type
+type AccountGDPRIntegration struct {
+	AMP   *bool `mapstructure:"amp" json:"amp,omitempty"`
+	App   *bool `mapstructure:"app" json:"app,omitempty"`
+	Video *bool `mapstructure:"video" json:"video,omitempty"`
+	Web   *bool `mapstructure:"web" json:"web,omitempty"`
 }
diff --git a/config/config.go b/config/config.go
index c2db7b7d..045aea3c 100755
--- a/config/config.go
+++ b/config/config.go
@@ -210,6 +210,7 @@ type Privacy struct {
 }
 
 type GDPR struct {
+	Enabled                 bool         `mapstructure:"enabled"`
 	HostVendorID            int          `mapstructure:"host_vendor_id"`
 	UsersyncIfAmbiguous     bool         `mapstructure:"usersync_if_ambiguous"`
 	Timeouts                GDPRTimeouts `mapstructure:"timeouts_ms"`
@@ -992,6 +993,7 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("adapters.rubicon.disabled", true)
 	v.SetDefault("adapters.rubicon.endpoint", "http://exapi-us-east.rubiconproject.com/a/api/exchange.json")
 	v.SetDefault("adapters.sharethrough.endpoint", "http://btlr.sharethrough.com/FGMrCMMc/v1")
+	v.SetDefault("adapters.silvermob.endpoint", "http://{{.Host}}.silvermob.com/marketplace/api/dsp/bid/{{.ZoneID}}")
 	v.SetDefault("adapters.smaato.endpoint", "https://prebid.ad.smaato.net/oapi/prebid")
 	v.SetDefault("adapters.smartadserver.endpoint", "https://ssb-global.smartadserver.com")
 	v.SetDefault("adapters.smartrtb.endpoint", "http://market-east.smrtb.com/json/publisher/rtb?pubid={{.PublisherID}}")
@@ -1027,6 +1029,7 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("analytics.pubstack.buffers.count", 100)
 	v.SetDefault("analytics.pubstack.buffers.timeout", "900s")
 	v.SetDefault("amp_timeout_adjustment_ms", 0)
+	v.SetDefault("gdpr.enabled", true)
 	v.SetDefault("gdpr.host_vendor_id", 0)
 	v.SetDefault("gdpr.usersync_if_ambiguous", false)
 	v.SetDefault("gdpr.timeouts_ms.init_vendorlist_fetches", 0)
diff --git a/exchange/adapter_map.go b/exchange/adapter_map.go
index ff72165b..9800ccd7 100755
--- a/exchange/adapter_map.go
+++ b/exchange/adapter_map.go
@@ -74,6 +74,7 @@ import (
 	"github.com/prebid/prebid-server/adapters/rtbhouse"
 	"github.com/prebid/prebid-server/adapters/rubicon"
 	"github.com/prebid/prebid-server/adapters/sharethrough"
+	"github.com/prebid/prebid-server/adapters/silvermob"
 	"github.com/prebid/prebid-server/adapters/smaato"
 	"github.com/prebid/prebid-server/adapters/smartadserver"
 	"github.com/prebid/prebid-server/adapters/smartrtb"
@@ -176,6 +177,7 @@ func newAdapterMap(client *http.Client, cfg *config.Configuration, infos adapter
 			cfg.Adapters[string(openrtb_ext.BidderRubicon)].XAPI.Tracker),
 
 		openrtb_ext.BidderSharethrough:     sharethrough.NewSharethroughBidder(cfg.Adapters[string(openrtb_ext.BidderSharethrough)].Endpoint),
+		openrtb_ext.BidderSilverMob:        silvermob.NewSilverMobBidder(cfg.Adapters[string(openrtb_ext.BidderSilverMob)].Endpoint),
 		openrtb_ext.BidderSmaato:           smaato.NewSmaatoBidder(cfg.Adapters[string(openrtb_ext.BidderSmaato)].Endpoint),
 		openrtb_ext.BidderSmartadserver:    smartadserver.NewSmartadserverBidder(cfg.Adapters[string(openrtb_ext.BidderSmartadserver)].Endpoint),
 		openrtb_ext.BidderSmartRTB:         smartrtb.NewSmartRTBBidder(cfg.Adapters[string(openrtb_ext.BidderSmartRTB)].Endpoint),
diff --git a/exchange/exchange.go b/exchange/exchange.go
index 2e8fe76f..3a5f785b 100644
--- a/exchange/exchange.go
+++ b/exchange/exchange.go
@@ -122,7 +122,7 @@ func (e *exchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidReque
 
 	// Slice of BidRequests, each a copy of the original cleaned to only contain bidder data for the named bidder
 	blabels := make(map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels)
-	cleanRequests, aliases, privacyLabels, errs := cleanOpenRTBRequests(ctx, bidRequest, requestExt, usersyncs, blabels, labels, e.gDPR, usersyncIfAmbiguous, e.privacyConfig)
+	cleanRequests, aliases, privacyLabels, errs := cleanOpenRTBRequests(ctx, bidRequest, requestExt, usersyncs, blabels, labels, e.gDPR, usersyncIfAmbiguous, e.privacyConfig, account)
 
 	e.me.RecordRequestPrivacy(privacyLabels)
 
diff --git a/exchange/utils.go b/exchange/utils.go
index 63e56e84..f6fcc711 100644
--- a/exchange/utils.go
+++ b/exchange/utils.go
@@ -19,6 +19,13 @@ import (
 	"github.com/prebid/prebid-server/privacy/lmt"
 )
 
+var integrationTypeMap = map[pbsmetrics.RequestType]config.IntegrationType{
+	pbsmetrics.ReqTypeAMP:      config.IntegrationTypeAMP,
+	pbsmetrics.ReqTypeORTB2App: config.IntegrationTypeApp,
+	pbsmetrics.ReqTypeVideo:    config.IntegrationTypeVideo,
+	pbsmetrics.ReqTypeORTB2Web: config.IntegrationTypeWeb,
+}
+
 const unknownBidder string = ""
 
 func BidderToPrebidSChains(req *openrtb_ext.ExtRequest) (map[string]*openrtb_ext.ExtRequestPrebidSChainSChain, error) {
@@ -53,7 +60,8 @@ func cleanOpenRTBRequests(ctx context.Context,
 	labels pbsmetrics.Labels,
 	gDPR gdpr.Permissions,
 	usersyncIfAmbiguous bool,
-	privacyConfig config.Privacy) (requestsByBidder map[openrtb_ext.BidderName]*openrtb.BidRequest, aliases map[string]string, privacyLabels pbsmetrics.PrivacyLabels, errs []error) {
+	privacyConfig config.Privacy,
+	account *config.Account) (requestsByBidder map[openrtb_ext.BidderName]*openrtb.BidRequest, aliases map[string]string, privacyLabels pbsmetrics.PrivacyLabels, errs []error) {
 
 	impsByBidder, errs := splitImps(orig.Imp)
 	if len(errs) > 0 {
@@ -94,7 +102,9 @@ func cleanOpenRTBRequests(ctx context.Context,
 	privacyLabels.COPPAEnforced = privacyEnforcement.COPPA
 	privacyLabels.LMTEnforced = lmtEnforcer.ShouldEnforce(unknownBidder)
 
-	if gdpr == 1 {
+	gdprEnabled := gdprEnabled(account, privacyConfig, integrationTypeMap[labels.RType])
+
+	if gdpr == 1 && gdprEnabled {
 		privacyLabels.GDPREnforced = true
 		parsedConsent, err := vendorconsent.ParseString(consent)
 		if err == nil {
@@ -109,7 +119,7 @@ func cleanOpenRTBRequests(ctx context.Context,
 		privacyEnforcement.CCPA = ccpaEnforcer.ShouldEnforce(bidder.String())
 
 		// GDPR
-		if gdpr == 1 {
+		if gdpr == 1 && gdprEnabled {
 			coreBidder := resolveBidder(bidder.String(), aliases)
 
 			var publisherID = labels.PubID
@@ -127,6 +137,13 @@ func cleanOpenRTBRequests(ctx context.Context,
 	return
 }
 
+func gdprEnabled(account *config.Account, privacyConfig config.Privacy, integrationType config.IntegrationType) bool {
+	if accountEnabled := account.GDPR.EnabledForIntegrationType(integrationType); accountEnabled != nil {
+		return *accountEnabled
+	}
+	return privacyConfig.GDPR.Enabled
+}
+
 func extractCCPA(orig *openrtb.BidRequest, privacyConfig config.Privacy, aliases map[string]string) (privacy.PolicyEnforcer, error) {
 	ccpaPolicy, err := ccpa.ReadFromRequest(orig)
 	if err != nil {
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index b98c80ae..0fac0800 100755
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -93,6 +93,7 @@ const (
 	BidderRTBHouse         BidderName = "rtbhouse"
 	BidderRubicon          BidderName = "rubicon"
 	BidderSharethrough     BidderName = "sharethrough"
+	BidderSilverMob        BidderName = "silvermob"
 	BidderSmaato           BidderName = "smaato"
 	BidderSmartadserver    BidderName = "smartadserver"
 	BidderSmartRTB         BidderName = "smartrtb"
@@ -187,6 +188,7 @@ var BidderMap = map[string]BidderName{
 	"rtbhouse":          BidderRTBHouse,
 	"rubicon":           BidderRubicon,
 	"sharethrough":      BidderSharethrough,
+	"silvermob":         BidderSilverMob,
 	"smaato":            BidderSmaato,
 	"smartadserver":     BidderSmartadserver,
 	"smartrtb":          BidderSmartRTB,
diff --git a/openrtb_ext/imp_silvermob.go b/openrtb_ext/imp_silvermob.go
new file mode 100644
index 00000000..9b246553
--- /dev/null
+++ b/openrtb_ext/imp_silvermob.go
@@ -0,0 +1,7 @@
+package openrtb_ext
+
+// ExtSilverMob defines the contract for bidrequest.imp[i].ext.silvermob
+type ExtSilverMob struct {
+	ZoneID string `json:"zoneid"`
+	Host   string `json:"host"`
+}
diff --git a/static/bidder-info/adform.yaml b/static/bidder-info/adform.yaml
index 8aafd9f6..4dce10b9 100644
--- a/static/bidder-info/adform.yaml
+++ b/static/bidder-info/adform.yaml
@@ -4,6 +4,8 @@ capabilities:
   app:
     mediaTypes:
       - banner
+      - video
   site:
     mediaTypes:
       - banner
+      - video
diff --git a/static/bidder-info/silvermob.yaml b/static/bidder-info/silvermob.yaml
new file mode 100644
index 00000000..5f1e4809
--- /dev/null
+++ b/static/bidder-info/silvermob.yaml
@@ -0,0 +1,8 @@
+maintainer:
+  email: "support@silvermob.com"
+capabilities:
+  app:
+    mediaTypes:
+      - banner
+      - video
+      - native
\ No newline at end of file
diff --git a/static/bidder-params/silvermob.json b/static/bidder-params/silvermob.json
new file mode 100644
index 00000000..8ebc85a2
--- /dev/null
+++ b/static/bidder-params/silvermob.json
@@ -0,0 +1,17 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "SilverMob Adapter Params",
+    "description": "A schema which validates params accepted by the SilverMob adapter",
+    "type": "object",
+    "properties": {
+      "zoneid": {
+        "type": "string",
+        "description": "Zone ID"
+      },
+      "host": {
+        "type": "string",
+        "description": "Host"
+      }
+    },
+    "required": ["zoneid", "host"]
+  }
\ No newline at end of file


Test patch:
diff --git a/adapters/adform/adform_test.go b/adapters/adform/adform_test.go
index f2277762..0bfb95b6 100644
--- a/adapters/adform/adform_test.go
+++ b/adapters/adform/adform_test.go
@@ -107,6 +107,16 @@ func createAdformServerResponse(testData aBidInfo) ([]byte, error) {
 			DealId:       testData.tags[2].dealId,
 			CreativeId:   testData.tags[2].creativeId,
 		},
+		{
+			ResponseType: "vast_content",
+			VastContent:  testData.tags[3].content,
+			Price:        testData.tags[3].price,
+			Currency:     "EUR",
+			Width:        testData.width,
+			Height:       testData.height,
+			DealId:       testData.tags[3].dealId,
+			CreativeId:   testData.tags[3].creativeId,
+		},
 	}
 	adformServerResponse, err := json.Marshal(bids)
 	return adformServerResponse, err
@@ -123,10 +133,21 @@ func TestAdformBasicResponse(t *testing.T) {
 	if err != nil {
 		t.Fatalf("Should not have gotten adapter error: %v", err)
 	}
-	if len(bids) != 2 {
-		t.Fatalf("Received %d bids instead of 2", len(bids))
+	if len(bids) != 3 {
+		t.Fatalf("Received %d bids instead of 3", len(bids))
+	}
+	expectedTypes := []openrtb_ext.BidType{
+		openrtb_ext.BidTypeBanner,
+		openrtb_ext.BidTypeBanner,
+		openrtb_ext.BidTypeVideo,
 	}
-	for _, bid := range bids {
+
+	for i, bid := range bids {
+
+		if bid.CreativeMediaType != string(expectedTypes[i]) {
+			t.Errorf("Expected a %s bid. Got: %s", expectedTypes[i], bid.CreativeMediaType)
+		}
+
 		matched := false
 		for _, tag := range adformTestData.tags {
 			if bid.AdUnitCode == tag.code {
@@ -224,7 +245,7 @@ func preparePrebidRequest(serverUrl string, t *testing.T) *pbs.PBSRequest {
 
 func preparePrebidRequestBody(requestData aBidInfo, t *testing.T) *bytes.Buffer {
 	prebidRequest := pbs.PBSRequest{
-		AdUnits: make([]pbs.AdUnit, 3),
+		AdUnits: make([]pbs.AdUnit, 4),
 		Device: &openrtb.Device{
 			UA:  requestData.deviceUA,
 			IP:  requestData.deviceIP,
@@ -326,6 +347,7 @@ func createTestData(secure bool) aBidInfo {
 			{mid: 32344, keyValues: "color:red,age:30-40", keyWords: "red,blue", cdims: "300x300,400x200", priceType: "gross", code: "code1", price: 1.23, content: "banner-content1", dealId: "dealId1", creativeId: "creativeId1"},
 			{mid: 32345, priceType: "net", code: "code2", minp: 23.1, cdims: "300x200"}, // no bid for ad unit
 			{mid: 32346, code: "code3", price: 1.24, content: "banner-content2", dealId: "dealId2", url: "https://adform.com?a=b"},
+			{mid: 32347, code: "code4", content: "vast-xml"},
 		},
 		secure:   secure,
 		currency: "EUR",
@@ -379,6 +401,11 @@ func createOpenRtbRequest(testData *aBidInfo) *openrtb.BidRequest {
 func TestOpenRTBStandardResponse(t *testing.T) {
 	testData := createTestData(true)
 	request := createOpenRtbRequest(&testData)
+	expectedTypes := []openrtb_ext.BidType{
+		openrtb_ext.BidTypeBanner,
+		openrtb_ext.BidTypeBanner,
+		openrtb_ext.BidTypeVideo,
+	}
 
 	responseBody, err := createAdformServerResponse(testData)
 	if err != nil {
@@ -390,16 +417,17 @@ func TestOpenRTBStandardResponse(t *testing.T) {
 	bidder := new(AdformAdapter)
 	bidResponse, errs := bidder.MakeBids(request, nil, httpResponse)
 
-	if len(bidResponse.Bids) != 2 {
-		t.Fatalf("Expected 2 bids. Got %d", len(bidResponse.Bids))
+	if len(bidResponse.Bids) != 3 {
+		t.Fatalf("Expected 3 bids. Got %d", len(bidResponse.Bids))
 	}
 	if len(errs) != 0 {
 		t.Errorf("Expected 0 errors. Got %d", len(errs))
 	}
 
-	for _, typeBid := range bidResponse.Bids {
-		if typeBid.BidType != openrtb_ext.BidTypeBanner {
-			t.Errorf("Expected a banner bid. Got: %s", bidResponse.Bids[0].BidType)
+	for i, typeBid := range bidResponse.Bids {
+
+		if typeBid.BidType != expectedTypes[i] {
+			t.Errorf("Expected a %s bid. Got: %s", expectedTypes[i], typeBid.BidType)
 		}
 		bid := typeBid.Bid
 		matched := false
@@ -561,10 +589,10 @@ func assertAdformServerRequest(testData aBidInfo, r *http.Request, isOpenRtb boo
 	var midsWithCurrency = ""
 	var queryString = ""
 	if isOpenRtb {
-		midsWithCurrency = "bWlkPTMyMzQ0JnJjdXI9RVVSJm1rdj1jb2xvcjpyZWQsYWdlOjMwLTQwJm1rdz1yZWQsYmx1ZSZjZGltcz0zMDB4MzAwLDQwMHgyMDA&bWlkPTMyMzQ1JnJjdXI9RVVSJmNkaW1zPTMwMHgyMDAmbWlucD0yMy4xMA&bWlkPTMyMzQ2JnJjdXI9RVVS"
+		midsWithCurrency = "bWlkPTMyMzQ0JnJjdXI9RVVSJm1rdj1jb2xvcjpyZWQsYWdlOjMwLTQwJm1rdz1yZWQsYmx1ZSZjZGltcz0zMDB4MzAwLDQwMHgyMDA&bWlkPTMyMzQ1JnJjdXI9RVVSJmNkaW1zPTMwMHgyMDAmbWlucD0yMy4xMA&bWlkPTMyMzQ2JnJjdXI9RVVS&bWlkPTMyMzQ3JnJjdXI9RVVS"
 		queryString = "CC=1&adid=6D92078A-8246-4BA4-AE5B-76104861E7DC&eids=eyJ0ZXN0LmNvbSI6eyJvdGhlcl91c2VyX2lkIjpbMF0sInNvbWVfdXNlcl9pZCI6WzFdfSwidGVzdDIub3JnIjp7Im90aGVyX3VzZXJfaWQiOlsyXX19&fd=1&gdpr=1&gdpr_consent=abc&ip=111.111.111.111&pt=gross&rp=4&stid=transaction-id&url=https%3A%2F%2Fadform.com%3Fa%3Db&" + midsWithCurrency
 	} else {
-		midsWithCurrency = "bWlkPTMyMzQ0JnJjdXI9VVNEJm1rdj1jb2xvcjpyZWQsYWdlOjMwLTQwJm1rdz1yZWQsYmx1ZSZjZGltcz0zMDB4MzAwLDQwMHgyMDA&bWlkPTMyMzQ1JnJjdXI9VVNEJmNkaW1zPTMwMHgyMDAmbWlucD0yMy4xMA&bWlkPTMyMzQ2JnJjdXI9VVNE" // no way to pass currency in legacy adapter
+		midsWithCurrency = "bWlkPTMyMzQ0JnJjdXI9VVNEJm1rdj1jb2xvcjpyZWQsYWdlOjMwLTQwJm1rdz1yZWQsYmx1ZSZjZGltcz0zMDB4MzAwLDQwMHgyMDA&bWlkPTMyMzQ1JnJjdXI9VVNEJmNkaW1zPTMwMHgyMDAmbWlucD0yMy4xMA&bWlkPTMyMzQ2JnJjdXI9VVNE&bWlkPTMyMzQ3JnJjdXI9VVNE" // no way to pass currency in legacy adapter
 		queryString = "CC=1&adid=6D92078A-8246-4BA4-AE5B-76104861E7DC&fd=1&gdpr=1&gdpr_consent=abc&ip=111.111.111.111&pt=gross&rp=4&stid=transaction-id&" + midsWithCurrency
 	}
 
@@ -646,7 +674,7 @@ func TestPriceTypeUrlParameterCreation(t *testing.T) {
 // Asserts that toOpenRtbBidResponse() creates a *adapters.BidderResponse with
 // the currency of the last valid []*adformBid element and the expected number of bids
 func TestToOpenRtbBidResponse(t *testing.T) {
-	expectedBids := 3
+	expectedBids := 4
 	lastCurrency, anotherCurrency, emptyCurrency := "EUR", "USD", ""
 
 	request := &openrtb.BidRequest{
@@ -672,6 +700,11 @@ func TestToOpenRtbBidResponse(t *testing.T) {
 				Ext:    json.RawMessage(`{"bidder1": { "mid": "32344" }}`),
 				Banner: &openrtb.Banner{},
 			},
+			{
+				ID:     "video-imp-no4",
+				Ext:    json.RawMessage(`{"bidder1": { "mid": "32345" }}`),
+				Banner: &openrtb.Banner{},
+			},
 		},
 		Device: &openrtb.Device{UA: "ua", IP: "ip"},
 		User:   &openrtb.User{BuyerUID: "buyerUID"},
@@ -703,6 +736,16 @@ func TestToOpenRtbBidResponse(t *testing.T) {
 			ResponseType: "banner",
 			Banner:       "banner-content4",
 			Price:        1.25,
+			Currency:     emptyCurrency,
+			Width:        300,
+			Height:       200,
+			DealId:       "dealId4",
+			CreativeId:   "creativeId4",
+		},
+		{
+			ResponseType: "vast_content",
+			VastContent:  "vast-content",
+			Price:        1.25,
 			Currency:     lastCurrency,
 			Width:        300,
 			Height:       200,
diff --git a/adapters/adform/adformtest/exemplary/multiformat-impression.json b/adapters/adform/adformtest/exemplary/multiformat-impression.json
new file mode 100644
index 00000000..efd4aca6
--- /dev/null
+++ b/adapters/adform/adformtest/exemplary/multiformat-impression.json
@@ -0,0 +1,99 @@
+{
+    "mockBidRequest": {
+      "id": "test-request-id",
+      "imp": [
+        {
+          "id": "banner-imp-id",
+          "banner": {
+            "format": [
+              {
+                "w": 300,
+                "h": 250
+              }
+            ]
+          },
+          "ext": {
+            "bidder": {
+              "mid": 12345
+            }
+          }
+        },
+        {
+            "id": "video-imp-id",
+            "video": {
+              "w": 640,
+              "h": 480
+            },
+            "ext": {
+              "bidder": {
+                "mid": 54321
+              }
+            }
+          }
+      ]
+    },
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "uri": "http://adx.adform.net/adx?CC=1&fd=1&gdpr=&gdpr_consent=&ip=&rp=4&stid=&bWlkPTEyMzQ1JnJjdXI9VVNE&bWlkPTU0MzIxJnJjdXI9VVNE"
+        },
+        "mockResponse": {
+          "status": 200,
+          "body": [
+            {
+              "response": "banner",
+              "banner": "<adm>",
+              "win_bid": 0.5,
+              "win_cur": "USD",
+              "width": 300,
+              "height": 250,
+              "deal_id": null,
+              "win_crid": "20078830"
+            },
+            {
+                "response": "vast_content",
+                "vast_content": "<vast>",
+                "win_bid": 0.7,
+                "win_cur": "USD",
+                "width": 640,
+                "height": 480,
+                "deal_id": "DID-123-22",
+                "win_crid": "20078831"
+              }
+          ]
+        }
+      }
+    ],
+    "expectedBidResponses": [
+      {
+        "currency": "USD",
+        "bids": [
+          {
+            "bid": {
+              "id": "banner-imp-id",
+              "impid": "banner-imp-id",
+              "price": 0.5,
+              "adm": "<adm>",
+              "crid": "20078830",
+              "w": 300,
+              "h": 250
+            },
+            "type": "banner"
+          },
+          {
+            "bid": {
+              "id": "video-imp-id",
+              "impid": "video-imp-id",
+              "price": 0.7,
+              "adm": "<vast>",
+              "crid": "20078831",
+              "dealid": "DID-123-22",
+              "w": 640,
+              "h": 480
+            },
+            "type": "video"
+          }
+        ]
+      }
+    ]
+  }
diff --git a/adapters/adform/adformtest/exemplary/single-banner-impression.json b/adapters/adform/adformtest/exemplary/single-banner-impression.json
new file mode 100644
index 00000000..fd7f3cde
--- /dev/null
+++ b/adapters/adform/adformtest/exemplary/single-banner-impression.json
@@ -0,0 +1,64 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "mid": 12345
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://adx.adform.net/adx?CC=1&fd=1&gdpr=&gdpr_consent=&ip=&rp=4&stid=&bWlkPTEyMzQ1JnJjdXI9VVNE"
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": [
+          {
+            "response": "banner",
+            "banner": "<adm>",
+            "win_bid": 0.5,
+            "win_cur": "USD",
+            "width": 300,
+            "height": 250,
+            "deal_id": null,
+            "win_crid": "20078830"
+          }
+        ]
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "test-imp-id",
+            "impid": "test-imp-id",
+            "price": 0.5,
+            "adm": "<adm>",
+            "crid": "20078830",
+            "w": 300,
+            "h": 250
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/adform/adformtest/exemplary/single-video-impression.json b/adapters/adform/adformtest/exemplary/single-video-impression.json
new file mode 100644
index 00000000..e22977e6
--- /dev/null
+++ b/adapters/adform/adformtest/exemplary/single-video-impression.json
@@ -0,0 +1,60 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "video": {
+          "w": 640,
+          "h": 480
+        },
+        "ext": {
+          "bidder": {
+            "mid": 54321
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://adx.adform.net/adx?CC=1&fd=1&gdpr=&gdpr_consent=&ip=&rp=4&stid=&bWlkPTU0MzIxJnJjdXI9VVNE"
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": [
+          {
+            "response": "vast_content",
+            "vast_content": "<vast>",
+            "win_bid": 0.5,
+            "win_cur": "USD",
+            "width": 640,
+            "height": 480,
+            "deal_id": null,
+            "win_crid": "20078830"
+          }
+        ]
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "test-imp-id",
+            "impid": "test-imp-id",
+            "price": 0.5,
+            "adm": "<vast>",
+            "crid": "20078830",
+            "w": 640,
+            "h": 480
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/adform/adformtest/params/race/video.json b/adapters/adform/adformtest/params/race/video.json
new file mode 100644
index 00000000..51f8f1b9
--- /dev/null
+++ b/adapters/adform/adformtest/params/race/video.json
@@ -0,0 +1,3 @@
+{
+    "mid": "858300"
+}
diff --git a/adapters/adtelligent/usersync_test.go b/adapters/adtelligent/usersync_test.go
index 1cc5dfe4..fa157d22 100644
--- a/adapters/adtelligent/usersync_test.go
+++ b/adapters/adtelligent/usersync_test.go
@@ -25,6 +25,6 @@ func TestAdtelligentSyncer(t *testing.T) {
 	assert.NoError(t, err)
 	assert.Equal(t, "//sync.adtelligent.com/csync?t=p&ep=0&redir=localhost%2Fsetuid%3Fbidder%3Dadtelligent%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%7Buid%7D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
-	assert.EqualValues(t, 0, syncer.GDPRVendorID())
+	assert.EqualValues(t, 410, syncer.GDPRVendorID())
 	assert.Equal(t, false, syncInfo.SupportCORS)
 }
diff --git a/adapters/beachfront/beachfronttest/exemplary/minimal-banner.json b/adapters/beachfront/beachfronttest/exemplary/minimal-banner.json
index 51ce4e92..6672e2af 100644
--- a/adapters/beachfront/beachfronttest/exemplary/minimal-banner.json
+++ b/adapters/beachfront/beachfronttest/exemplary/minimal-banner.json
@@ -24,7 +24,6 @@
       }
     ]
   },
-
   "httpCalls": [
     {
       "expectedRequest": {
@@ -57,38 +56,40 @@
           "ua": "",
           "adapterName": "BF_PREBID_S2S",
           "adapterVersion": "0.9.0",
-          "user": {
-          }
+          "user": {}
         }
       },
       "mockResponse": {
         "status": 200,
         "body": [
           {
-            "crid":"crid_1",
-            "price":2.942808,
-            "w":300,
-            "h":250,
-            "slot":"div-gpt-ad-1460505748561-0",
-            "adm":"<div id=\"44861168\"><script>!function(){console.log\"Hello, ad.\";}();<\/script><\/div>"
+            "crid": "crid_1",
+            "price": 2.942808,
+            "w": 300,
+            "h": 250,
+            "slot": "div-gpt-ad-1460505748561-0",
+            "adm": "<div id=\"44861168\"><script>!function(){console.log\"Hello, ad.\";}();<\/script><\/div>"
           }
         ]
       }
     }
   ],
-
-  "expectedBids": [
+  "expectedBidResponses": [
     {
-      "bid": {
-        "id": "12345678",
-        "impid": "test-slot",
-        "price": 2,
-        "adm": "\u003cdiv id=\"12345678\" style=\"width:300;height:250;background-color:black;color:white;\"\u003e300x250\u003c\\div\u003e",
-        "crid": "crid_1",
-        "w": 300,
-        "h": 250
-      },
-      "type": "banner"
+      "bids": [
+        {
+          "bid": {
+            "id": "div-gpt-ad-1460505748561-0Banner",
+            "impid": "div-gpt-ad-1460505748561-0",
+            "price": 2.942808,
+            "adm": "<div id=\"44861168\"><script>!function(){console.log\"Hello, ad.\";}();<\/script><\/div>",
+            "crid": "crid_1",
+            "w": 300,
+            "h": 250
+          },
+          "type": "banner"
+        }
+      ]
     }
   ]
 }
diff --git a/adapters/beachfront/beachfronttest/exemplary/simple-adm-video.json b/adapters/beachfront/beachfronttest/exemplary/simple-adm-video.json
index 0ff7790b..cb1f4c20 100644
--- a/adapters/beachfront/beachfronttest/exemplary/simple-adm-video.json
+++ b/adapters/beachfront/beachfronttest/exemplary/simple-adm-video.json
@@ -1,34 +1,33 @@
 {
-  "mockBidRequest":
-  {
-    "id":"61b87329-8790-47b7-90dd-c53ae7ce1723",
-    "tmax":1000,
-    "source":{
-      "tid":"61b87329-8790-47b7-90dd-c53ae7ce1723"
+  "mockBidRequest": {
+    "id": "61b87329-8790-47b7-90dd-c53ae7ce1723",
+    "tmax": 1000,
+    "source": {
+      "tid": "61b87329-8790-47b7-90dd-c53ae7ce1723"
     },
-    "imp":[
+    "imp": [
       {
-        "id":"video1",
-        "ext":{
-          "bidder":{
-            "videoResponseType" : "adm",
-            "bidfloor":0.01,
-            "appId":"11bc5dd5-7421-4dd8-c926-40fa653bec76"
+        "id": "video1",
+        "ext": {
+          "bidder": {
+            "videoResponseType": "adm",
+            "bidfloor": 0.01,
+            "appId": "11bc5dd5-7421-4dd8-c926-40fa653bec76"
           }
         },
-        "video":{
-          "mimes":[
+        "video": {
+          "mimes": [
             "video/mp4"
           ],
-          "context":"instream",
-          "w":300,
-          "h":250
+          "context": "instream",
+          "w": 300,
+          "h": 250
         }
       }
     ],
-    "site":{
-      "publisher":{
-        "id":"publisher1"
+    "site": {
+      "publisher": {
+        "id": "publisher1"
       },
       "page": "http://example.com/whatever/something.html"
     },
@@ -42,7 +41,6 @@
       "ua": "Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16"
     }
   },
-
   "httpCalls": [
     {
       "expectedRequest": {
@@ -63,8 +61,8 @@
             }
           ],
           "site": {
-            "publisher":{
-              "id":"publisher1"
+            "publisher": {
+              "id": "publisher1"
             },
             "page": "http://example.com/whatever/something.html",
             "domain": "example.com"
@@ -75,10 +73,9 @@
             "ip": "192.168.255.255"
           },
           "source": {
-           "tid": "61b87329-8790-47b7-90dd-c53ae7ce1723"
+            "tid": "61b87329-8790-47b7-90dd-c53ae7ce1723"
           },
           "tmax": 1000,
-
           "cur": [
             "USD"
           ],
@@ -87,12 +84,12 @@
             "buyeruid": "some-buyer"
           }
         }
-        },
+      },
       "mockResponse": {
-        "status" : 200,
+        "status": 200,
         "body": {
-          "id":"61b87329-8790-47b7-90dd-c53ae7ce1723",
-          "seatBid":[
+          "id": "61b87329-8790-47b7-90dd-c53ae7ce1723",
+          "seatBid": [
             {
               "bid": [
                 {
@@ -122,31 +119,32 @@
       }
     }
   ],
-
-  "expectedBids": [
+  "expectedBidResponses": [
     {
-
-      "bid":[
+      "bids": [
         {
-          "id": "video1AdmVideo",
-          "impid": "video1",
-          "price": 20,
-          "adm": "<?xml version=\"1.0\" encoding=\"utf-8\"?><VAST version=\"2.0\"><Ad id=\"VPAID\"><InLine><AdSystem version=\"2.0\">IO</AdSystem><AdTitle>Neptune</AdTitle><Impression></Impression><Creatives><Creative sequence=\"1\"><Linear><Duration>00:00:15</Duration><MediaFiles><MediaFile delivery=\"progressive\" width=\"640\" height=\"480\" scalable=\"1\" type=\"application/javascript\" apiFramework=\"VPAID\"><![CDATA[http://player-cdn.beachfrontmedia.com/players/neptune/3/17/5/neptune-player.js]]></MediaFile></MediaFiles><AdParameters><![CDATA[{\"dsp\":\"5d8393417cbc8e5aa4fe2202,0.01\",\"inventory_id\":\"bid:95d219a2-6025-44ba-bff8-1dca987beaae:11bc5dd5-7421-4dd8-c926-40fa653bec76:${AUCTION_PRICE}:20.0\",\"request_endpoint\":\"//useast.bfmio.com/getmu\",\"inventory_type\":\"pre\"}]]></AdParameters></Linear></Creative></Creatives></InLine></Ad></VAST>",
-          "adid": "1088",
-          "adomain": [
-            "beachfront.io"
-          ],
-          "cid": "277",
-          "crid": "532",
-          "w": 300,
-          "h": 250,
-          "ext": {
-            "prebid": {
-              "type": "video"
+          "bid": {
+            "id": "video1AdmVideo",
+            "impid": "video1",
+            "price": 20,
+            "adm": "<?xml version=\"1.0\" encoding=\"utf-8\"?><VAST version=\"2.0\"><Ad id=\"VPAID\"><InLine><AdSystem version=\"2.0\">IO</AdSystem><AdTitle>Neptune</AdTitle><Impression></Impression><Creatives><Creative sequence=\"1\"><Linear><Duration>00:00:15</Duration><MediaFiles><MediaFile delivery=\"progressive\" width=\"640\" height=\"480\" scalable=\"1\" type=\"application/javascript\" apiFramework=\"VPAID\"><![CDATA[http://player-cdn.beachfrontmedia.com/players/neptune/3/17/5/neptune-player.js]]></MediaFile></MediaFiles><AdParameters><![CDATA[{\"dsp\":\"5d8393417cbc8e5aa4fe2202,0.01\",\"inventory_id\":\"bid:95d219a2-6025-44ba-bff8-1dca987beaae:11bc5dd5-7421-4dd8-c926-40fa653bec76:${AUCTION_PRICE}:20.0\",\"request_endpoint\":\"//useast.bfmio.com/getmu\",\"inventory_type\":\"pre\"}]]></AdParameters></Linear></Creative></Creatives></InLine></Ad></VAST>",
+            "adid": "1088",
+            "adomain": [
+              "beachfront.io"
+            ],
+            "cid": "277",
+            "crid": "532",
+            "w": 300,
+            "h": 250,
+            "ext": {
+              "prebid": {
+                "type": "video"
+              }
             }
-          }
+          },
+          "type": "video"
         }
       ]
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/adapters/beachfront/beachfronttest/exemplary/simple-mix.json b/adapters/beachfront/beachfronttest/exemplary/simple-mix.json
index eb5d9b07..cc2b4158 100644
--- a/adapters/beachfront/beachfronttest/exemplary/simple-mix.json
+++ b/adapters/beachfront/beachfronttest/exemplary/simple-mix.json
@@ -1,25 +1,23 @@
 {
-  "mockBidRequest":
-  {
-    "id":"61b87329-8790-47b7-90dd-c53ae7ce1723",
-    "tmax":1000,
-    "source":{
-      "tid":"61b87329-8790-47b7-90dd-c53ae7ce1723"
+  "mockBidRequest": {
+    "id": "61b87329-8790-47b7-90dd-c53ae7ce1723",
+    "tmax": 1000,
+    "source": {
+      "tid": "61b87329-8790-47b7-90dd-c53ae7ce1723"
     },
-    "imp":[
+    "imp": [
       {
-        "id":"mix1",
-        "ext":{
-          "bidder":{
-            "videoResponseType" : "adm",
-            "bidfloor":0.41,
+        "id": "mix1",
+        "ext": {
+          "bidder": {
+            "videoResponseType": "adm",
+            "bidfloor": 0.41,
             "appIds": {
               "banner": "487cf244-5e95-43cb-e7b9-bb540873ca7e",
               "video": "11bc5dd5-7421-4dd8-c926-40fa653bec76"
             }
           }
         },
-
         "banner": {
           "format": [
             {
@@ -28,18 +26,17 @@
             }
           ]
         },
-
-        "video":{
-          "mimes":[
+        "video": {
+          "mimes": [
             "video/mp4"
           ],
-          "context":"instream",
-          "w":300,
-          "h":250
+          "context": "instream",
+          "w": 300,
+          "h": 250
         }
       }
     ],
-    "site":{
+    "site": {
       "page": "http://example.com/somepage.html"
     },
     "user": {
@@ -51,7 +48,6 @@
       "ua": "Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16"
     }
   },
-
   "httpCalls": [
     {
       "expectedRequest": {
@@ -89,24 +85,22 @@
           "ip": "192.168.255.255",
           "requestId": "61b87329-8790-47b7-90dd-c53ae7ce1723"
         }
-      } ,
+      },
       "mockResponse": {
-        "status" : 200,
-        "body" :
-          [
-            {
-              "crid":"crid_1",
-              "price":9.5019655,
-              "w":300,
-              "h":250,
-              "slot":"mix1",
-              "adm":"<div id=\"44861168\"><script>!function(){console.log\"Hello, ad.\";}();<\/script><\/div>"
-            }
-          ]
+        "status": 200,
+        "body": [
+          {
+            "crid": "crid_1",
+            "price": 9.5019655,
+            "w": 300,
+            "h": 250,
+            "slot": "mix1",
+            "adm": "<div id=\"44861168\"><script>!function(){console.log\"Hello, ad.\";}();<\/script><\/div>"
+          }
+        ]
       }
-
-
-    }, {
+    },
+    {
       "expectedRequest": {
         "uri": "https://reachms.bfmio.com/bid.json?exchange_id=11bc5dd5-7421-4dd8-c926-40fa653bec76",
         "body": {
@@ -119,7 +113,6 @@
                 "mimes": [
                   "video/mp4"
                 ]
-
               },
               "bidfloor": 0.41,
               "secure": 0,
@@ -149,7 +142,7 @@
         }
       },
       "mockResponse": {
-        "status" : 200,
+        "status": 200,
         "body": {
           "id": "61b87329-8790-47b7-90dd-c53ae7ce1723",
           "seatbid": [
@@ -179,40 +172,41 @@
       }
     }
   ],
-
-  "expectedBids": [
+  "expectedBidResponses": [
     {
-
-      "bid":[
+      "bids": [
         {
-          "id":"61b87329-8790-47b7-90dd-c53ae7ce1723",
-          "impid":"video1",
-          "price":9.605201,
-          "nurl":"https://evt.bfmio.com/getmu?aid=bid:0d32aea6-d199-4803-a188-bd7cf7be1e12:11bc5dd5-7421-4dd8-c926-40fa653bec76:0.01:0.01&v=1&dsp=5afda03c7c2d2bfaee55a3f0,0.01&i_type=pre",
-          "crid":"0d32aea6-d199-4803-a188-bd7cf7be1e12",
-          "w":1500,
-          "h":1280,
-          "ext":{
-            "prebid":{
-              "type":"video"
-            },
-            "bidder":{
-
-            }
-          }
-        }, {
-          "id": "61b87329-8790-47b7-90dd-c53ae7ce1723",
-          "impid": "mix1",
-          "price": 9.5019655,
-          "adm": "<div id=\"44861168\"><script>!function(){console.log\"Hello, ad.\";}();<\/script><\/div>",
-          "crid": "crid_1",
-          "w": 300,
-          "h": 250,
-          "ext": {
-            "prebid": {
-              "type": "banner"
-            }
-          }
+          "bid": {
+            "id": "mix1Banner",
+            "impid": "mix1",
+            "price": 9.5019655,
+            "adm": "<div id=\"44861168\"><script>!function(){console.log\"Hello, ad.\";}();<\/script><\/div>",
+            "crid": "crid_1",
+            "w": 300,
+            "h": 250
+          },
+          "type": "banner"
+        }
+      ]
+    },
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "mix1AdmVideo",
+            "impid": "mix1",
+            "price": 20,
+            "adm": "<?xml version=\"1.0\" encoding=\"utf-8\"?><VAST version=\"2.0\"><Ad id=\"VPAID\"><InLine><AdSystem version=\"2.0\">IO</AdSystem><AdTitle>Neptune</AdTitle><Impression></Impression><Creatives><Creative sequence=\"1\"><Linear><Duration>00:00:15</Duration><MediaFiles><MediaFile delivery=\"progressive\" width=\"640\" height=\"480\" scalable=\"1\" type=\"application/javascript\" apiFramework=\"VPAID\"><![CDATA[http://player-cdn.beachfrontmedia.com/players/neptune/3/17/5/neptune-player.js]]></MediaFile></MediaFiles><AdParameters><![CDATA[{\"dsp\":\"5d839458f73decdc1572b7f6,0.41\",\"inventory_id\":\"bid:26826cf7-f8bb-4e47-a636-769d83dd9b4f:11bc5dd5-7421-4dd8-c926-40fa653bec76:${AUCTION_PRICE}:20.0\",\"request_endpoint\":\"//useast.bfmio.com/getmu\",\"inventory_type\":\"pre\"}]]></AdParameters></Linear></Creative></Creatives></InLine></Ad></VAST>",
+            "adid": "1088",
+            "adomain": [
+              "beachfront.io"
+            ],
+            "cid": "277",
+            "crid": "532",
+            "w": 300,
+            "h": 250
+          },
+          "type": "video"
         }
       ]
     }
diff --git a/adapters/beachfront/beachfronttest/exemplary/simple-nurl-video.json b/adapters/beachfront/beachfronttest/exemplary/simple-nurl-video.json
index cc3bfe34..0f96d9f2 100644
--- a/adapters/beachfront/beachfronttest/exemplary/simple-nurl-video.json
+++ b/adapters/beachfront/beachfronttest/exemplary/simple-nurl-video.json
@@ -1,33 +1,32 @@
 {
-  "mockBidRequest":
-  {
-    "id":"61b87329-8790-47b7-90dd-c53ae7ce1723",
-    "tmax":1000,
-    "source":{
-      "tid":"61b87329-8790-47b7-90dd-c53ae7ce1723"
+  "mockBidRequest": {
+    "id": "61b87329-8790-47b7-90dd-c53ae7ce1723",
+    "tmax": 1000,
+    "source": {
+      "tid": "61b87329-8790-47b7-90dd-c53ae7ce1723"
     },
-    "imp":[
+    "imp": [
       {
-        "id":"video1",
-        "ext":{
-          "bidder":{
-            "bidfloor":0.01,
-            "appId":"11bc5dd5-7421-4dd8-c926-40fa653bec76"
+        "id": "video1",
+        "ext": {
+          "bidder": {
+            "bidfloor": 0.01,
+            "appId": "11bc5dd5-7421-4dd8-c926-40fa653bec76"
           }
         },
-        "video":{
-          "mimes":[
+        "video": {
+          "mimes": [
             "video/mp4"
           ],
-          "context":"instream",
-          "w":300,
-          "h":250
+          "context": "instream",
+          "w": 300,
+          "h": 250
         }
       }
     ],
-    "site":{
-      "publisher":{
-        "id":"publisher1"
+    "site": {
+      "publisher": {
+        "id": "publisher1"
       },
       "page": "http://example.com/whatever/something.html"
     },
@@ -41,7 +40,6 @@
       "ua": "Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16"
     }
   },
-
   "httpCalls": [
     {
       "expectedRequest": {
@@ -63,8 +61,8 @@
             }
           ],
           "site": {
-            "publisher":{
-              "id":"publisher1"
+            "publisher": {
+              "id": "publisher1"
             },
             "page": "http://example.com/whatever/something.html",
             "domain": "example.com"
@@ -75,10 +73,9 @@
             "ip": "192.168.255.255"
           },
           "source": {
-           "tid": "61b87329-8790-47b7-90dd-c53ae7ce1723"
+            "tid": "61b87329-8790-47b7-90dd-c53ae7ce1723"
           },
           "tmax": 1000,
-
           "cur": [
             "USD"
           ],
@@ -89,58 +86,57 @@
         }
       },
       "mockResponse": {
-        "status" : 200,
+        "status": 200,
         "body": {
-          "id":"61b87329-8790-47b7-90dd-c53ae7ce1723",
-          "seatBid":[
-              {
-                "bid": [
-                  {
-                    "id": "video1NurlVideo",
-                    "impid": "video1",
-                    "price": 20,
-                    "nurl": "https://useast.bfmio.com/getBids?aid=bid:70b99087-1b92-4e81-bc42-05c940fd6014:11bc5dd5-7421-4dd8-c926-40fa653bec76:20.0:20.0&v=1&dsp=5d8391a85f35945a70c9ddf0,0.01&i_type=pre",
-                    "crid": "70b99087-1b92-4e81-bc42-05c940fd6014",
-                    "w": 300,
-                    "h": 250,
-                    "ext": {
-                      "prebid": {
-                        "type": "video"
-                      },
-                      "bidder": {}
-                    }
+          "id": "61b87329-8790-47b7-90dd-c53ae7ce1723",
+          "seatBid": [
+            {
+              "bid": [
+                {
+                  "id": "video1NurlVideo",
+                  "impid": "video1",
+                  "price": 20,
+                  "nurl": "https://useast.bfmio.com/getBids?aid=bid:70b99087-1b92-4e81-bc42-05c940fd6014:11bc5dd5-7421-4dd8-c926-40fa653bec76:20.0:20.0&v=1&dsp=5d8391a85f35945a70c9ddf0,0.01&i_type=pre",
+                  "crid": "70b99087-1b92-4e81-bc42-05c940fd6014",
+                  "w": 300,
+                  "h": 250,
+                  "ext": {
+                    "prebid": {
+                      "type": "video"
+                    },
+                    "bidder": {}
                   }
-                ],
-                "seat": "beachfront"
-              }
-            ]
+                }
+              ],
+              "seat": "beachfront"
+            }
+          ]
         }
       }
     }
   ],
-
-  "expectedBids": [
+  "expectedBidResponses": [
     {
-
-      "bid":[
+      "bids": [
         {
-          "id":"61b87329-8790-47b7-90dd-c53ae7ce1723",
-          "impid":"video1",
-          "price":9.605201,
-          "nurl":"https://evt.bfmio.com/getmu?aid=bid:0d32aea6-d199-4803-a188-bd7cf7be1e12:11bc5dd5-7421-4dd8-c926-40fa653bec76:0.01:0.01&v=1&dsp=5afda03c7c2d2bfaee55a3f0,0.01&i_type=pre",
-          "crid":"0d32aea6-d199-4803-a188-bd7cf7be1e12",
-          "w":1500,
-          "h":1280,
-          "ext":{
-            "prebid":{
-              "type":"video"
-            },
-            "bidder":{
-
+          "bid": {
+            "id": "video1NurlVideo",
+            "impid": "video1",
+            "price": 20,
+            "nurl": "https://useast.bfmio.com/getBids?aid=bid:70b99087-1b92-4e81-bc42-05c940fd6014:11bc5dd5-7421-4dd8-c926-40fa653bec76:20.0:20.0&v=1&dsp=5d8391a85f35945a70c9ddf0,0.01&i_type=pre",
+            "crid": "70b99087-1b92-4e81-bc42-05c940fd6014",
+            "w": 300,
+            "h": 250,
+            "ext": {
+              "prebid": {
+                "type": "video"
+              },
+              "bidder": {}
             }
-          }
+          },
+          "type": "video"
         }
       ]
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/adapters/beachfront/beachfronttest/supplemental/minimal-banner-empty_array-200.json b/adapters/beachfront/beachfronttest/supplemental/minimal-banner-empty_array-200.json
index 7bdbc73c..01207f22 100644
--- a/adapters/beachfront/beachfronttest/supplemental/minimal-banner-empty_array-200.json
+++ b/adapters/beachfront/beachfronttest/supplemental/minimal-banner-empty_array-200.json
@@ -68,5 +68,5 @@
     }
   ],
 
-  "expectedBids": []
+  "expectedBidResponses": []
 }
diff --git a/adapters/beachfront/beachfronttest/supplemental/minimal-mobile-video.json b/adapters/beachfront/beachfronttest/supplemental/minimal-mobile-video.json
index af8b1885..5556f6e7 100644
--- a/adapters/beachfront/beachfronttest/supplemental/minimal-mobile-video.json
+++ b/adapters/beachfront/beachfronttest/supplemental/minimal-mobile-video.json
@@ -2,34 +2,33 @@
   "mockBidRequest": {
     "id": "some_test_ad",
     "app": {
-      "bundle":"_org.prebid.mobile.demoapp",
+      "bundle": "_org.prebid.mobile.demoapp",
       "id": "some-mobile-app"
     },
     "imp": [
       {
-        "id":"video1",
-        "ext":{
-          "bidder":{
-            "bidfloor":0.01,
-            "appId":"11bc5dd5-7421-4dd8-c926-40fa653bec76",
-            "videoResponseType" : "nurl"
+        "id": "video1",
+        "ext": {
+          "bidder": {
+            "bidfloor": 0.01,
+            "appId": "11bc5dd5-7421-4dd8-c926-40fa653bec76",
+            "videoResponseType": "nurl"
           }
         },
-        "video":{
-          "mimes":[
+        "video": {
+          "mimes": [
             "video/mp4"
           ],
-          "w":300,
-          "h":250
+          "w": 300,
+          "h": 250
         }
       }
     ],
-    "device":{
+    "device": {
       "devicetype": 1,
-      "ifa":"bb956625-df13-4568-b60b-eb5cbf76e986"
+      "ifa": "bb956625-df13-4568-b60b-eb5cbf76e986"
     }
   },
-
   "httpCalls": [
     {
       "expectedRequest": {
@@ -48,7 +47,7 @@
               "id": "video1",
               "secure": 0,
               "video": {
-                "mimes":[
+                "mimes": [
                   "video/mp4"
                 ],
                 "h": 250,
@@ -67,71 +66,54 @@
       "mockResponse": {
         "status": 200,
         "body": {
-          "id":"61b87329-8790-47b7-90dd-c53ae7ce1723",
-          "seatBid":[
+          "id": "61b87329-8790-47b7-90dd-c53ae7ce1723",
+          "seatBid": [
             {
-              "bid":[
+              "bid": [
                 {
-                  "w":0,
-                  "h":0,
+                  "w": 0,
+                  "h": 0,
                   "id": "0",
-                  "impid":"",
-                  "price":0.01,
-                  "adid":"",
-                  "nurl":"https://evt.bfmio.com/getmu?aid=bid:0d32aea6-d199-4803-a188-bd7cf7be1e12:11bc5dd5-7421-4dd8-c926-40fa653bec76:0.01:0.01&v=1&dsp=5afda03c7c2d2bfaee55a3f0,0.01&i_type=pre",
-                  "adm":"",
-                  "adomain":[
-
-                  ],
-                  "iurl":"",
-                  "cid":"",
-                  "crid":"",
-                  "attr":[
-
-                  ],
-                  "ext":{
-
-                  },
-                  "cat":[
-
-                  ]
+                  "impid": "",
+                  "price": 0.01,
+                  "adid": "",
+                  "nurl": "https://evt.bfmio.com/getmu?aid=bid:0d32aea6-d199-4803-a188-bd7cf7be1e12:11bc5dd5-7421-4dd8-c926-40fa653bec76:0.01:0.01&v=1&dsp=5afda03c7c2d2bfaee55a3f0,0.01&i_type=pre",
+                  "adm": "",
+                  "adomain": [],
+                  "iurl": "",
+                  "cid": "",
+                  "crid": "",
+                  "attr": [],
+                  "ext": {},
+                  "cat": []
                 }
               ],
-              "seat":"",
-              "group":0,
-              "ext":{
-
-              }
+              "seat": "",
+              "group": 0,
+              "ext": {}
             }
           ]
         }
       }
     }
   ],
-
-  "expectedBids": [
+  "expectedBidResponses": [
     {
-
-      "bid":[
+      "bids": [
         {
-          "id":"61b87329-8790-47b7-90dd-c53ae7ce1723",
-          "impid":"video1",
-          "price":9.605201,
-          "nurl":"https://evt.bfmio.com/getmu?aid=bid:0d32aea6-d199-4803-a188-bd7cf7be1e12:11bc5dd5-7421-4dd8-c926-40fa653bec76:0.01:0.01&v=1&dsp=5afda03c7c2d2bfaee55a3f0,0.01&i_type=pre",
-          "crid":"0d32aea6-d199-4803-a188-bd7cf7be1e12",
-          "w":1500,
-          "h":1280,
-          "ext":{
-            "prebid":{
-              "type":"video"
-            },
-            "bidder":{
-
-            }
-          }
+          "bid": {
+            "id": "video1NurlVideo",
+            "impid": "video1",
+            "price": 0.01,
+            "nurl": "https://evt.bfmio.com/getmu?aid=bid:0d32aea6-d199-4803-a188-bd7cf7be1e12:11bc5dd5-7421-4dd8-c926-40fa653bec76:0.01:0.01&v=1&dsp=5afda03c7c2d2bfaee55a3f0,0.01&i_type=pre",
+            "crid": "0d32aea6-d199-4803-a188-bd7cf7be1e12",
+            "w": 300,
+            "h": 250,
+            "ext":{}
+          },
+          "type": "video"
         }
       ]
     }
   ]
-
 }
diff --git a/adapters/beachfront/beachfronttest/supplemental/minimal-site-banner.json b/adapters/beachfront/beachfronttest/supplemental/minimal-site-banner.json
index 27b24357..a12f7fd9 100644
--- a/adapters/beachfront/beachfronttest/supplemental/minimal-site-banner.json
+++ b/adapters/beachfront/beachfronttest/supplemental/minimal-site-banner.json
@@ -1,94 +1,95 @@
 {
-    "mockBidRequest": {
-      "id": "some_test_ad",
-      "site": {
-        "page": "test.opposingviews.com"
-      },
-      "imp": [
-        {
-          "bidfloor": 0.02,
-          "banner": {
-            "format": [
-              {
-                "w": 300,
-                "h": 250
-              }
-            ]
-          },
-          "ext": {
-            "bidder": {
-              "bidfloor": 0.02,
-              "appId": "3b16770b-17af-4d22-daff-9606bdf2c9c3"
-            }
-          }
-        }
-      ]
+  "mockBidRequest": {
+    "id": "some_test_ad",
+    "site": {
+      "page": "test.opposingviews.com"
     },
-  
-    "httpCalls": [
+    "imp": [
       {
-        "expectedRequest": {
-          "uri": "https://display.bfmio.com/prebid_display",
-          "body": {
-            "slots": [
-              {
-                "slot": "",
-                "id": "3b16770b-17af-4d22-daff-9606bdf2c9c3",
-                "bidfloor": 0.02,
-                "sizes": [
-                  {
-                    "w": 300,
-                    "h": 250
-                  }
-                ]
-              }
-            ],
-            "domain": "test.opposingviews.com",
-            "page": "test.opposingviews.com",
-            "requestId": "some_test_ad",
-            "referrer": "",
-            "search": "",
-            "secure": 0,
-            "isMobile": 0,
-            "ip": "",
-            "deviceModel": "",
-            "deviceOs": "",
-            "dnt": 0,
-            "ua": "",
-            "adapterName": "BF_PREBID_S2S",
-            "adapterVersion": "0.9.0",
-            "user": {
-            }
-          }
-        },
-        "mockResponse": {
-          "status": 200,
-          "body": [
+        "bidfloor": 0.02,
+        "banner": {
+          "format": [
             {
-              "crid":"crid_1",
-              "price":2.942808,
-              "w":300,
-              "h":250,
-              "slot":"div-gpt-ad-1460505748561-0",
-              "adm":"<div id=\"44861168\"><script>!function(){console.log\"Hello, ad.\";}();<\/script><\/div>"
+              "w": 300,
+              "h": 250
             }
           ]
-        }
-      }
-    ],
-  
-    "expectedBids": [
-      {
-        "bid": {
-          "id": "12345678",
-          "impid": "test-slot",
-          "price": 2,
-          "adm": "\u003cdiv id=\"12345678\" style=\"width:300;height:250;background-color:black;color:white;\"\u003e300x250\u003c\\div\u003e",
-          "crid": "crid_1",
-          "w": 300,
-          "h": 250
         },
-        "type": "banner"
+        "ext": {
+          "bidder": {
+            "bidfloor": 0.02,
+            "appId": "3b16770b-17af-4d22-daff-9606bdf2c9c3"
+          }
+        }
       }
     ]
-  }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://display.bfmio.com/prebid_display",
+        "body": {
+          "slots": [
+            {
+              "slot": "",
+              "id": "3b16770b-17af-4d22-daff-9606bdf2c9c3",
+              "bidfloor": 0.02,
+              "sizes": [
+                {
+                  "w": 300,
+                  "h": 250
+                }
+              ]
+            }
+          ],
+          "domain": "test.opposingviews.com",
+          "page": "test.opposingviews.com",
+          "requestId": "some_test_ad",
+          "referrer": "",
+          "search": "",
+          "secure": 0,
+          "isMobile": 0,
+          "ip": "",
+          "deviceModel": "",
+          "deviceOs": "",
+          "dnt": 0,
+          "ua": "",
+          "adapterName": "BF_PREBID_S2S",
+          "adapterVersion": "0.9.0",
+          "user": {}
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": [
+          {
+            "crid": "crid_1",
+            "price": 2.942808,
+            "w": 300,
+            "h": 250,
+            "slot": "div-gpt-ad-1460505748561-0",
+            "adm": "<div id=\"44861168\"><script>!function(){console.log\"Hello, ad.\";}();<\/script><\/div>"
+          }
+        ]
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "div-gpt-ad-1460505748561-0Banner",
+            "impid": "div-gpt-ad-1460505748561-0",
+            "price": 2.942808,
+            "adm": "<div id=\"44861168\"><script>!function(){console.log\"Hello, ad.\";}();<\/script><\/div>",
+            "crid": "crid_1",
+            "w": 300,
+            "h": 250
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/beachfront/beachfronttest/supplemental/mobile-banner.json b/adapters/beachfront/beachfronttest/supplemental/mobile-banner.json
index ea38d7ad..17cc7d32 100644
--- a/adapters/beachfront/beachfronttest/supplemental/mobile-banner.json
+++ b/adapters/beachfront/beachfronttest/supplemental/mobile-banner.json
@@ -109,22 +109,20 @@
     }
   ],
 
-  "expectedBids": [
+  "expectedBidResponses": [
     {
-      "Bid": {
-        "id": "763e3312-19d5-4b07-a61d-890147e863a1",
-        "impid": "div-gpt-ad-1460505748561-0",
-        "price": 2.942808,
-        "adm": "\u003cdiv id=\"12345678\" style=\"width:300;height:250;background-color:black;color:white;\"\u003e300x250\u003c\\div\u003e",
-        "crid": "crid_1",
-        "w": 300,
-        "h": 250
-      },
-      "ext": {
-        "prebid": {
-          "type": "banner"
-        }
-      }
+      "bids": [{
+        "bid": {
+          "id": "div-gpt-ad-1460505748561-0Banner",
+          "impid": "div-gpt-ad-1460505748561-0",
+          "price": 2.942808,
+          "adm":"<div id=\"44861168\"><script>!function(){console.log\"Hello, ad.\";}();<\/script><\/div>",
+          "crid": "crid_1",
+          "w": 300,
+          "h": 250
+        },
+        "type": "banner"
+      }]
     }
   ]
 }
diff --git a/adapters/beachfront/beachfronttest/supplemental/multi-banner.json b/adapters/beachfront/beachfronttest/supplemental/multi-banner.json
index 46699511..1d355dba 100644
--- a/adapters/beachfront/beachfronttest/supplemental/multi-banner.json
+++ b/adapters/beachfront/beachfronttest/supplemental/multi-banner.json
@@ -119,18 +119,20 @@
     }
   ],
 
-  "expectedBids": [
+  "expectedBidResponses": [
     {
-      "Bid": {
-        "id": "12345678",
-        "impid": "test-slot",
-        "price": 2,
-        "adm": "\u003cdiv id=\"12345678\" style=\"width:300;height:250;background-color:black;color:white;\"\u003e300x250\u003c\\div\u003e",
-        "crid": "crid_1",
-        "w": 300,
-        "h": 250
-      },
-      "type": "banner"
+      "bids": [{
+        "bid": {
+          "id": "div-gpt-ad-1460505748561-0Banner",
+          "impid": "div-gpt-ad-1460505748561-0",
+          "price": 2.942808,
+          "adm":"<div id=\"44861168\"><script>!function(){console.log\"Hello, ad.\";}();<\/script><\/div>",
+          "crid": "crid_1",
+          "w": 300,
+          "h": 250
+        },
+        "type": "banner"
+      }]
     }
   ]
 }
diff --git a/adapters/beachfront/beachfronttest/supplemental/multi-video.json b/adapters/beachfront/beachfronttest/supplemental/multi-video.json
index 05f02a4d..8ccd0a8d 100644
--- a/adapters/beachfront/beachfronttest/supplemental/multi-video.json
+++ b/adapters/beachfront/beachfronttest/supplemental/multi-video.json
@@ -1,35 +1,34 @@
-{ "mockBidRequest":
-  {
-    "id":"61b87329-8790-47b7-90dd-c53ae7ce1723",
-    "tmax":1000,
-    "source":{
-      "tid":"61b87329-8790-47b7-90dd-c53ae7ce1723"
+{
+  "mockBidRequest": {
+    "id": "61b87329-8790-47b7-90dd-c53ae7ce1723",
+    "tmax": 1000,
+    "source": {
+      "tid": "61b87329-8790-47b7-90dd-c53ae7ce1723"
     },
-    "imp":[
+    "imp": [
       {
-        "id":"multivideo",
-        "ext":{
-          "bidder":{
-            "bidfloor":3.01,
+        "id": "multivideo",
+        "ext": {
+          "bidder": {
+            "bidfloor": 3.01,
             "videoResponseType": "both",
-            "appId":"11bc5dd5-7421-4dd8-c926-40fa653bec76"
+            "appId": "11bc5dd5-7421-4dd8-c926-40fa653bec76"
           }
         },
-        "video":{
-          "mimes":[
-            "video/mp4", "video/webm"
+        "video": {
+          "mimes": [
+            "video/mp4",
+            "video/webm"
           ],
-          "context":"instream",
-          "w":600,
-          "h":450
+          "context": "instream",
+          "w": 600,
+          "h": 450
         }
       }
-
-
     ],
-    "site":{
-      "publisher":{
-        "id":"publisher1"
+    "site": {
+      "publisher": {
+        "id": "publisher1"
       },
       "page": "http://example.com/whatever"
     },
@@ -42,16 +41,15 @@
       "ua": "Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16"
     }
   },
-
   "httpCalls": [
-      {
+    {
       "expectedRequest": {
         "uri": "https://reachms.bfmio.com/bid.json?exchange_id=11bc5dd5-7421-4dd8-c926-40fa653bec76",
         "body": {
           "id": "61b87329-8790-47b7-90dd-c53ae7ce1723",
           "imp": [
             {
-              "id":"multivideo",
+              "id": "multivideo",
               "secure": 0,
               "video": {
                 "mimes": [
@@ -118,132 +116,120 @@
           "cur": "USD"
         }
       }
-    }, {
-
+    },
+    {
       "expectedRequest": {
         "uri": "https://reachms.bfmio.com/bid.json?exchange_id=11bc5dd5-7421-4dd8-c926-40fa653bec76&prebidserver",
         "body": {
-          "isPrebid":true,
-          "id":"61b87329-8790-47b7-90dd-c53ae7ce1723",
-          "imp":[
+          "isPrebid": true,
+          "id": "61b87329-8790-47b7-90dd-c53ae7ce1723",
+          "imp": [
             {
-              "id":"multivideo",
+              "id": "multivideo",
               "secure": 0,
-              "video":{
-                "mimes":[
+              "video": {
+                "mimes": [
                   "video/mp4",
                   "video/webm"
                 ],
-                "w":600,
-                "h":450
+                "w": 600,
+                "h": 450
               },
-              "bidfloor":3.01
+              "bidfloor": 3.01
             }
           ],
-          "site":{
-            "domain":"example.com",
-            "page":"http://example.com/whatever",
-            "publisher":{
-              "id":"publisher1"
+          "site": {
+            "domain": "example.com",
+            "page": "http://example.com/whatever",
+            "publisher": {
+              "id": "publisher1"
             }
           },
-          "device":{
-            "ua":"Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16",
-            "ip":"192.168.255.255",
-            "devicetype":2
+          "device": {
+            "ua": "Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16",
+            "ip": "192.168.255.255",
+            "devicetype": 2
           },
-          "user":{
-            "id":"some-user",
-            "buyeruid":"some-buyer"
+          "user": {
+            "id": "some-user",
+            "buyeruid": "some-buyer"
           },
-          "tmax":1000,
-          "cur":[
+          "tmax": 1000,
+          "cur": [
             "USD"
           ],
-          "source":{
-            "tid":"61b87329-8790-47b7-90dd-c53ae7ce1723"
+          "source": {
+            "tid": "61b87329-8790-47b7-90dd-c53ae7ce1723"
           }
         }
       },
-
       "mockResponse": {
         "status": 200,
         "body": {
-          "id":"61b87329-8790-47b7-90dd-c53ae7ce1723",
-          "seatBid":[
+          "id": "61b87329-8790-47b7-90dd-c53ae7ce1723",
+          "seatBid": [
             {
-              "bid":[
+              "bid": [
                 {
-                  "id":"multivideo",
-                  "price":20.0,
-                  "nurl":"https://useast.bfmio.com/getBids?aid=bid:b489a745-e577-4fcb-815d-0b6a1e052ec7:11bc5dd5-7421-4dd8-c926-40fa653bec76:20.0:20.0&v=1&dsp=5d8231a48d308d0a1f9b4526,0.61&i_type=pre",
-                  "adomain":[
-
-                  ],
-                  "cat":[
-
-                  ],
-                  "attr":[
-
-                  ],
-                  "w":0,
-                  "h":0,
-                  "ext":{
-
-                  }
+                  "id": "multivideo",
+                  "price": 20.0,
+                  "nurl": "https://useast.bfmio.com/getBids?aid=bid:b489a745-e577-4fcb-815d-0b6a1e052ec7:11bc5dd5-7421-4dd8-c926-40fa653bec76:20.0:20.0&v=1&dsp=5d8231a48d308d0a1f9b4526,0.61&i_type=pre",
+                  "adomain": [],
+                  "cat": [],
+                  "attr": [],
+                  "w": 0,
+                  "h": 0,
+                  "ext": {}
                 }
               ],
-              "group":0,
-              "ext":{
-
-              }
+              "group": 0,
+              "ext": {}
             }
           ]
         }
       }
     }
   ],
-
-  "expectedBids": [
+  "expectedBidResponses": [
     {
-
-      "bid": [
+      "bids": [
         {
-          "id": "multivideoNurlVideo",
-          "impid": "multivideo",
-          "price": 20,
-          "nurl": "https://useast.bfmio.com/getBids?aid=bid:6daefa55-0e8b-4366-b238-bb2de01b0a7c:11bc5dd5-7421-4dd8-c926-40fa653bec76:20.0:20.0&v=1&dsp=5d8395cb13fe4ef822af7293,3.01&i_type=pre",
-          "crid": "6daefa55-0e8b-4366-b238-bb2de01b0a7c",
-          "w": 600,
-          "h": 450,
-          "ext": {
-            "prebid": {
-              "type": "video"
-            },
-            "bidder": {}
-          }
-        },
+          "bid": {
+            "id": "multivideoAdmVideo",
+            "impid": "multivideo",
+            "price": 20,
+            "adm": "<?xml version=\"1.0\" encoding=\"utf-8\"?><VAST version=\"2.0\"><Ad id=\"VPAID\"><InLine><AdSystem version=\"2.0\">IO</AdSystem><AdTitle>Neptune</AdTitle><Impression></Impression><Creatives><Creative sequence=\"1\"><Linear><Duration>00:00:15</Duration><MediaFiles><MediaFile delivery=\"progressive\" width=\"640\" height=\"480\" scalable=\"1\" type=\"application/javascript\" apiFramework=\"VPAID\"><![CDATA[http://player-cdn.beachfrontmedia.com/players/neptune/3/17/5/neptune-player.js]]></MediaFile></MediaFiles><AdParameters><![CDATA[{\"dsp\":\"5d8231a4254b2eca804965a3,3.01\",\"inventory_id\":\"bid:1680831c-83a2-42a3-a790-a683d780749a:11bc5dd5-7421-4dd8-c926-40fa653bec76:${AUCTION_PRICE}:20.0\",\"request_endpoint\":\"//useast.bfmio.com/getmu\",\"inventory_type\":\"pre\"}]]></AdParameters></Linear></Creative></Creatives></InLine></Ad></VAST>",
+            "adid": "1088",
+            "adomain": [
+              "beachfront.io"
+            ],
+            "cid": "277",
+            "crid": "532",
+            "w": 600,
+            "h": 450
+          },
+          "type": "video"
+        }
+      ],
+      "seat": "beachfront"
+    },
+    {
+      "bids": [
         {
-          "id": "multivideoAdmVideo",
-          "impid": "multivideo",
-          "price": 20,
-          "adm": "<?xml version=\"1.0\" encoding=\"utf-8\"?><VAST version=\"2.0\"><Ad id=\"VPAID\"><InLine><AdSystem version=\"2.0\">IO</AdSystem><AdTitle>Neptune</AdTitle><Impression></Impression><Creatives><Creative sequence=\"1\"><Linear><Duration>00:00:15</Duration><MediaFiles><MediaFile delivery=\"progressive\" width=\"640\" height=\"480\" scalable=\"1\" type=\"application/javascript\" apiFramework=\"VPAID\"><![CDATA[http://player-cdn.beachfrontmedia.com/players/neptune/3/17/5/neptune-player.js]]></MediaFile></MediaFiles><AdParameters><![CDATA[{\"dsp\":\"5d8395cb9107b5524e1fd6be,3.01\",\"inventory_id\":\"bid:f3ff87ed-7d92-48d5-8610-40023c318afc:11bc5dd5-7421-4dd8-c926-40fa653bec76:${AUCTION_PRICE}:20.0\",\"request_endpoint\":\"//useast.bfmio.com/getmu\",\"inventory_type\":\"pre\"}]]></AdParameters></Linear></Creative></Creatives></InLine></Ad></VAST>",
-          "adid": "1088",
-          "adomain": [
-            "beachfront.io"
-          ],
-          "cid": "277",
-          "crid": "532",
-          "w": 600,
-          "h": 450,
-          "ext": {
-            "prebid": {
-              "type": "video"
-            }
-          }
+          "bid": {
+            "id": "multivideoNurlVideo",
+            "impid": "multivideo",
+            "price": 20,
+            "nurl": "https://useast.bfmio.com/getBids?aid=bid:b489a745-e577-4fcb-815d-0b6a1e052ec7:11bc5dd5-7421-4dd8-c926-40fa653bec76:20.0:20.0&v=1&dsp=5d8231a48d308d0a1f9b4526,0.61&i_type=pre",
+            "crid": "b489a745-e577-4fcb-815d-0b6a1e052ec7",
+            "w": 600,
+            "h": 450,
+            "ext": {}
+          },
+          "type": "video"
         }
       ],
       "seat": "beachfront"
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-banner.json b/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-banner.json
index 8a9e6b05..fc1bb910 100644
--- a/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-banner.json
+++ b/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-banner.json
@@ -32,4 +32,4 @@
       "comparison": "literal"
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-but-another-good-video.json b/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-but-another-good-video.json
index dec0b51b..963a2adc 100644
--- a/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-but-another-good-video.json
+++ b/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-but-another-good-video.json
@@ -169,4 +169,4 @@
       "comparison": "literal"
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-video.json b/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-video.json
index a2f028ec..3082ff20 100644
--- a/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-video.json
+++ b/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-video.json
@@ -38,4 +38,4 @@
       "comparison": "literal"
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/adapters/dmx/dmxtest/exemplary/imp-populated-banner.json b/adapters/dmx/dmxtest/exemplary/imp-populated-banner.json
new file mode 100644
index 00000000..f2b30bb4
--- /dev/null
+++ b/adapters/dmx/dmxtest/exemplary/imp-populated-banner.json
@@ -0,0 +1,139 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "app":{
+      "bundle":"302324249",
+      "id":"ed6207cefff74c14878963566683c070",
+      "name":"Skout - iOS Match Buy",
+      "publisher":{
+        "id":"10400"
+      },
+      "storeurl":"https://itunes.apple.com/app/id302324249"
+    },
+    "imp": [
+      {
+        "bidfloor": 0.35,
+        "id": "test-imp-id",
+        "banner": {
+          "w": 300,
+          "h": 250,
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            },
+            {
+              "w": 300,
+              "h": 600
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "dmxid": "123454",
+            "publisher_id": "10400"
+          }
+        }
+      }
+    ]
+  },
+
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "",
+        "body": {
+          "id": "test-request-id",
+          "app":{
+            "bundle":"302324249",
+            "id":"ed6207cefff74c14878963566683c070",
+            "name":"Skout - iOS Match Buy",
+            "publisher":{
+              "id":"10400"
+            },
+            "storeurl":"https://itunes.apple.com/app/id302324249"
+          },
+          "imp": [
+            {
+              "bidfloor": 0.35,
+              "id": "test-imp-id",
+              "tagid": "123454",
+              "secure": 1,
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 250
+                  },
+                  {
+                    "w": 300,
+                    "h": 600
+                  }
+                ],
+                "w": 300,
+                "h": 250
+              },
+              "ext": {
+                "bidder": {
+                  "publisher_id": "10400",
+                  "dmxid": "123454"
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "seat": "958",
+              "bid": [{
+                "id": "7706636740145184841",
+                "impid": "test-imp-id",
+                "price": 1.75,
+                "adid": "29681110",
+                "adm": "<div>banner-ads</div>",
+                "adomain": ["dmx.districtm.io"],
+                "iurl": "https://dmx.districtm.io/b/v2",
+                "cid": "958",
+                "crid": "29681110",
+                "h": 250,
+                "w": 300
+              }]
+            }
+          ],
+          "bidid": "5778926625248726496",
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "7706636740145184841",
+            "impid": "test-imp-id",
+            "price": 1.75,
+            "adm": "<div>banner-ads</div>",
+            "adid": "29681110",
+            "adomain": ["dmx.districtm.io"],
+            "iurl": "https://dmx.districtm.io/b/v2",
+            "cid": "958",
+            "crid": "29681110",
+            "w": 300,
+            "h": 250
+
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/eplanning/usersync_test.go b/adapters/eplanning/usersync_test.go
index 890832ba..85770689 100644
--- a/adapters/eplanning/usersync_test.go
+++ b/adapters/eplanning/usersync_test.go
@@ -20,6 +20,6 @@ func TestEPlanningSyncer(t *testing.T) {
 	assert.NoError(t, err)
 	assert.Equal(t, "https://ads.us.e-planning.net/uspd/1/?du=https%3A%2F%2Fads.us.e-planning.net%2Fgetuid%2F1%2F5a1ad71d2d53a0f5%3Flocalhost%2Fsetuid%3Fbidder%3Deplanning%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
 	assert.Equal(t, "iframe", syncInfo.Type)
-	assert.EqualValues(t, 0, syncer.GDPRVendorID())
+	assert.EqualValues(t, 90, syncer.GDPRVendorID())
 	assert.Equal(t, false, syncInfo.SupportCORS)
 }
diff --git a/adapters/silvermob/params_test.go b/adapters/silvermob/params_test.go
new file mode 100644
index 00000000..13009f6a
--- /dev/null
+++ b/adapters/silvermob/params_test.go
@@ -0,0 +1,56 @@
+package silvermob
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+// TestValidParams makes sure that the silvermob 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.BidderSilverMob, json.RawMessage(validParam)); err != nil {
+			t.Errorf("Schema rejected silvermob params: %s", validParam)
+		}
+	}
+}
+
+// TestInvalidParams makes sure that the silvermob 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.BidderSilverMob, json.RawMessage(invalidParam)); err == nil {
+			t.Errorf("Schema allowed unexpected params: %s", invalidParam)
+		}
+	}
+}
+
+var validParams = []string{
+	`{"zoneid": "16", "host": "us"}`,
+	`{"zoneid": "16", "host": "eu"}`,
+}
+
+var invalidParams = []string{
+	``,
+	`null`,
+	`true`,
+	`5`,
+	`4.2`,
+	`[]`,
+	`{}`,
+	`{"ZoneID": "asd", "Host": "123"}`,
+	`{}`,
+	`{"ZoneID": "asd"}`,
+	`{"Host": "111"}`,
+	`{"zoneid": 16, "host": 111}`,
+}
diff --git a/adapters/silvermob/silvermob_test.go b/adapters/silvermob/silvermob_test.go
new file mode 100644
index 00000000..f75b16fe
--- /dev/null
+++ b/adapters/silvermob/silvermob_test.go
@@ -0,0 +1,11 @@
+package silvermob
+
+import (
+	"testing"
+
+	"github.com/prebid/prebid-server/adapters/adapterstest"
+)
+
+func TestJsonSamples(t *testing.T) {
+	adapterstest.RunJSONBidderTest(t, "silvermobtest", NewSilverMobBidder("http://{{.Host}}.example.com/api/dsp/bid/{{.ZoneID}}"))
+}
diff --git a/adapters/silvermob/silvermobtest/exemplary/banner-app.json b/adapters/silvermob/silvermobtest/exemplary/banner-app.json
new file mode 100644
index 00000000..7a2a4fef
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/exemplary/banner-app.json
@@ -0,0 +1,163 @@
+{
+    "mockBidRequest": {
+      "id": "some-request-id",
+      "device": {
+        "ua": "test-user-agent",
+        "ip": "123.123.123.123",
+        "language": "en",
+        "dnt": 0
+      },
+      "tmax": 1000,
+      "user": {
+        "buyeruid": "awesome-user"
+      },
+      "app": {
+        "publisher": {
+          "id": "123456789"
+        },
+        "cat": [
+          "IAB22-1"
+        ],
+        "bundle": "com.app.awesome",
+        "name": "Awesome App",
+        "domain": "awesomeapp.com",
+        "id": "123456789"
+      },
+      "imp": [
+        {
+          "id": "some-impression-id",
+          "tagid": "ogTAGID",
+          "banner": {
+            "w":320,
+            "h":50
+          },
+          "ext": {
+            "bidder": {
+              "host": "eu",
+              "zoneid": "0"
+            }
+          }
+        }
+      ]
+    },
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "headers": {
+            "Content-Type": [
+              "application/json;charset=utf-8"
+            ],
+            "Accept": [
+              "application/json"
+            ],
+            "X-Openrtb-Version": [
+              "2.5"
+            ],
+            "User-Agent": [
+              "test-user-agent"
+            ],
+            "X-Forwarded-For": [
+              "123.123.123.123"
+            ]
+          },
+          "uri": "http://eu.example.com/api/dsp/bid/0",
+          "body": {
+            "id": "some-request-id",
+            "device": {
+              "ua": "test-user-agent",
+              "ip": "123.123.123.123",
+              "language": "en",
+              "dnt": 0
+            },
+            "imp": [
+              {
+                "id": "some-impression-id",
+                "banner": {
+                    "w":320,
+                    "h":50
+                },
+                "tagid": "ogTAGID",
+                "ext": {
+                  "bidder": {
+                    "host": "eu",
+                    "zoneid": "0"
+                  }
+                }
+              }
+            ],
+            "app": {
+              "id": "123456789",
+              "name": "Awesome App",
+              "bundle": "com.app.awesome",
+              "domain": "awesomeapp.com",
+              "cat": [
+                "IAB22-1"
+              ],
+              "publisher": {
+                "id": "123456789"
+              }
+            },
+            "user": {
+              "buyeruid": "awesome-user"
+            },
+            "tmax": 1000
+          }
+        },
+        "mockResponse": {
+          "status": 200,
+          "body": {
+            "id": "awesome-resp-id",
+            "seatbid": [
+              {
+                "bid": [
+                  {
+                    "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+                    "impid": "1",
+                    "price": 3.5,
+                    "adm": "awesome-markup",
+                    "adomain": [
+                      "awesome.com"
+                    ],
+                    "crid": "20",
+                    "w":320,
+                    "h":50
+                  }
+                ],
+              "type": "banner",
+                "seat": "silvermob"
+              }
+            ],
+            "cur": "USD",
+            "ext": {
+              "responsetimemillis": {
+                "silvermob": 154
+              },
+              "tmaxrequest": 1000
+            }
+          }
+        }
+      }
+    ],
+    "expectedBidResponses": [ 
+      {
+        "bids":[
+          {
+            "bid":{
+              "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+              "impid": "1",
+              "price": 3.5,
+              "adm": "awesome-markup",
+              "adomain": [
+                "awesome.com"
+              ],
+              "crid": "20",
+              "w":320,
+              "h":50
+            },
+            "type": "banner"
+          }
+        ]
+      }
+    ]
+  }
+  
\ No newline at end of file
diff --git a/adapters/silvermob/silvermobtest/exemplary/banner-multi-app.json b/adapters/silvermob/silvermobtest/exemplary/banner-multi-app.json
new file mode 100644
index 00000000..531704c5
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/exemplary/banner-multi-app.json
@@ -0,0 +1,293 @@
+{
+    "mockBidRequest": {
+      "id": "some-request-id",
+      "device": {
+        "ua": "test-user-agent",
+        "ip": "123.123.123.123",
+        "language": "en",
+        "dnt": 0
+      },
+      "tmax": 1000,
+      "user": {
+        "buyeruid": "awesome-user"
+      },
+      "app": {
+        "publisher": {
+          "id": "123456789"
+        },
+        "cat": [
+          "IAB22-1"
+        ],
+        "bundle": "com.app.awesome",
+        "name": "Awesome App",
+        "domain": "awesomeapp.com",
+        "id": "123456789"
+      },
+      "imp": [
+        {
+          "id": "some-impression-id",
+          "tagid": "ogTAGID",
+          "banner": {
+            "w":320,
+            "h":50
+          },
+          "ext": {
+            "bidder": {
+              "host": "eu",
+              "zoneid": "0"
+            }
+          }
+        },
+        {
+            "id": "another-impression-id",
+            "tagid": "ogTAGID",
+            "banner": {
+              "w":320,
+              "h":480
+            },
+            "ext": {
+              "bidder": {
+                "host": "eu",
+                "zoneid": "1"
+              }
+            }
+          }
+      ]
+    },
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "headers": {
+            "Content-Type": [
+              "application/json;charset=utf-8"
+            ],
+            "Accept": [
+              "application/json"
+            ],
+            "X-Openrtb-Version": [
+              "2.5"
+            ],
+            "User-Agent": [
+              "test-user-agent"
+            ],
+            "X-Forwarded-For": [
+              "123.123.123.123"
+            ]
+          },
+          "uri": "http://eu.example.com/api/dsp/bid/0",
+          "body": {
+            "id": "some-request-id",
+            "device": {
+              "ua": "test-user-agent",
+              "ip": "123.123.123.123",
+              "language": "en",
+              "dnt": 0
+            },
+            "imp": [
+              {
+                "id": "some-impression-id",
+                "banner": {
+                    "w":320,
+                    "h":50
+                },
+                "tagid": "ogTAGID",
+                "ext": {
+                  "bidder": {
+                    "host": "eu",
+                    "zoneid": "0"
+                  }
+                }
+              }
+            ],
+            "app": {
+              "id": "123456789",
+              "name": "Awesome App",
+              "bundle": "com.app.awesome",
+              "domain": "awesomeapp.com",
+              "cat": [
+                "IAB22-1"
+              ],
+              "publisher": {
+                "id": "123456789"
+              }
+            },
+            "user": {
+              "buyeruid": "awesome-user"
+            },
+            "tmax": 1000
+          }
+        },
+        "mockResponse": {
+          "status": 200,
+          "body": {
+            "id": "awesome-resp-id",
+            "seatbid": [
+              {
+                "bid": [
+                  {
+                    "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+                    "impid": "some-impression-id",
+                    "price": 3.5,
+                    "adm": "awesome-markup",
+                    "adomain": [
+                      "awesome.com"
+                    ],
+                    "crid": "20",
+                    "w":320,
+                    "h":50
+                  }
+                ],
+              "type": "banner",
+                "seat": "silvermob"
+              }
+            ],
+            "cur": "USD",
+            "ext": {
+              "responsetimemillis": {
+                "silvermob": 154
+              },
+              "tmaxrequest": 1000
+            }
+          }
+        }
+      },
+      {
+        "expectedRequest": {
+          "headers": {
+            "Content-Type": [
+              "application/json;charset=utf-8"
+            ],
+            "Accept": [
+              "application/json"
+            ],
+            "X-Openrtb-Version": [
+              "2.5"
+            ],
+            "User-Agent": [
+              "test-user-agent"
+            ],
+            "X-Forwarded-For": [
+              "123.123.123.123"
+            ]
+          },
+          "uri": "http://eu.example.com/api/dsp/bid/1",
+          "body": {
+            "id": "some-request-id",
+            "device": {
+              "ua": "test-user-agent",
+              "ip": "123.123.123.123",
+              "language": "en",
+              "dnt": 0
+            },
+            "imp": [
+              {
+                "id": "another-impression-id",
+                "banner": {
+                    "w":320,
+                    "h":480
+                },
+                "tagid": "ogTAGID",
+                "ext": {
+                  "bidder": {
+                    "host": "eu",
+                    "zoneid": "1"
+                  }
+                }
+              }
+            ],
+            "app": {
+              "id": "123456789",
+              "name": "Awesome App",
+              "bundle": "com.app.awesome",
+              "domain": "awesomeapp.com",
+              "cat": [
+                "IAB22-1"
+              ],
+              "publisher": {
+                "id": "123456789"
+              }
+            },
+            "user": {
+              "buyeruid": "awesome-user"
+            },
+            "tmax": 1000
+          }
+        },
+        "mockResponse": {
+          "status": 200,
+          "body": {
+            "id": "awesome-resp-id",
+            "seatbid": [
+              {
+                "bid": [
+                  {
+                    "id": "a3ae1b4e2fc24a4fb45540082e98e162",
+                    "impid": "another-impression-id",
+                    "price": 3.5,
+                    "adm": "awesome-markup",
+                    "adomain": [
+                      "awesome.com"
+                    ],
+                    "crid": "21",
+                    "w":320,
+                    "h":480
+                  }
+                ],
+              "type": "banner",
+                "seat": "silvermob"
+              }
+            ],
+            "cur": "USD",
+            "ext": {
+              "responsetimemillis": {
+                "silvermob": 154
+              },
+              "tmaxrequest": 1000
+            }
+          }
+        }
+      }
+    ],
+    "expectedBidResponses": [ 
+        
+      {
+        "bids":[
+          {
+            "bid":{
+              "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+              "impid": "some-impression-id",
+              "price": 3.5,
+              "adm": "awesome-markup",
+              "adomain": [
+                "awesome.com"
+              ],
+              "crid": "20",
+              "w":320,
+              "h":50
+            },
+            "type": "banner"
+          }
+        ]
+      },
+      {
+        "bids": [
+            {
+                "bid":{
+                  "id": "a3ae1b4e2fc24a4fb45540082e98e162",
+                  "impid": "another-impression-id",
+                  "price": 3.5,
+                  "adm": "awesome-markup",
+                  "adomain": [
+                    "awesome.com"
+                  ],
+                  "crid": "21",
+                  "w":320,
+                  "h":480
+                },
+                "type": "banner"
+              }
+        ]
+    }
+    ]
+  }
+  
\ No newline at end of file
diff --git a/adapters/silvermob/silvermobtest/exemplary/native-app.json b/adapters/silvermob/silvermobtest/exemplary/native-app.json
new file mode 100644
index 00000000..49934bf7
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/exemplary/native-app.json
@@ -0,0 +1,159 @@
+{
+    "mockBidRequest": {
+      "id": "some-request-id",
+      "device": {
+        "ua": "test-user-agent",
+        "ip": "123.123.123.123",
+        "language": "en",
+        "dnt": 0
+      },
+      "tmax": 1000,
+      "user": {
+        "buyeruid": "awesome-user"
+      },
+      "app": {
+        "publisher": {
+          "id": "123456789"
+        },
+        "cat": [
+          "IAB22-1"
+        ],
+        "bundle": "com.app.awesome",
+        "name": "Awesome App",
+        "domain": "awesomeapp.com",
+        "id": "123456789"
+      },
+      "imp": [
+        {
+          "id": "some-impression-id",
+          "tagid": "ogTAGID",
+          "native": {
+            "ver":"1.1",
+            "request":"{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}"
+          },
+          "ext": {
+            "bidder": {
+              "host": "eu",
+              "zoneid": "0"
+            }
+          }
+        }
+      ]
+    },
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "headers": {
+            "Content-Type": [
+              "application/json;charset=utf-8"
+            ],
+            "Accept": [
+              "application/json"
+            ],
+            "X-Openrtb-Version": [
+              "2.5"
+            ],
+            "User-Agent": [
+              "test-user-agent"
+            ],
+            "X-Forwarded-For": [
+              "123.123.123.123"
+            ]
+          },
+          "uri": "http://eu.example.com/api/dsp/bid/0",
+          "body": {
+            "id": "some-request-id",
+            "device": {
+              "ua": "test-user-agent",
+              "ip": "123.123.123.123",
+              "language": "en",
+              "dnt": 0
+            },
+            "imp": [
+              {
+                "id": "some-impression-id",
+                "native": {
+                  "ver":"1.1",
+                  "request":"{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}"
+                },
+                "tagid": "ogTAGID",
+                "ext": {
+                  "bidder": {
+                    "host": "eu",
+                    "zoneid": "0"
+                  }
+                }
+              }
+            ],
+            "app": {
+              "id": "123456789",
+              "name": "Awesome App",
+              "bundle": "com.app.awesome",
+              "domain": "awesomeapp.com",
+              "cat": [
+                "IAB22-1"
+              ],
+              "publisher": {
+                "id": "123456789"
+              }
+            },
+            "user": {
+              "buyeruid": "awesome-user"
+            },
+            "tmax": 1000
+          }
+        },
+        "mockResponse": {
+          "status": 200,
+          "body": {
+            "id": "awesome-resp-id",
+            "seatbid": [
+              {
+                "bid": [
+                  {
+                    "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+                    "impid": "some-impression-id",
+                    "price": 3.5,
+                    "adm": "asesome-markup",
+                    "adomain": [
+                      "awesome.com"
+                    ],
+                    "crid": "20"
+                  }
+                ],
+                "type": "native",
+                "seat": "silvermob"
+              }
+            ],
+            "cur": "USD",
+            "ext": {
+              "responsetimemillis": {
+                "silvermob": 154
+              },
+              "tmaxrequest": 1000
+            }
+          }
+        }
+      }
+    ],
+    "expectedBidResponses": [
+      {
+        "bids":[
+          {
+            "bid":  {
+              "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+              "impid": "some-impression-id",
+              "price": 3.5,
+              "adm": "asesome-markup",
+              "crid": "20",
+              "adomain": [
+                "awesome.com"
+              ]
+            },
+            "type": "native"
+          }
+        ]
+      }
+    ]
+  }
+  
\ No newline at end of file
diff --git a/adapters/silvermob/silvermobtest/exemplary/video-app.json b/adapters/silvermob/silvermobtest/exemplary/video-app.json
new file mode 100644
index 00000000..c80d5ab9
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/exemplary/video-app.json
@@ -0,0 +1,171 @@
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "device": {
+      "ua": "test-user-agent",
+      "ip": "123.123.123.123",
+      "language": "en",
+      "dnt": 0
+    },
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "app": {
+      "publisher": {
+        "id": "123456789"
+      },
+      "cat": [
+        "IAB22-1"
+      ],
+      "bundle": "com.app.awesome",
+      "name": "Awesome App",
+      "domain": "awesomeapp.com",
+      "id": "123456789"
+    },
+    "imp": [
+      {
+        "id": "some-impression-id",
+        "tagid": "ogTAGID",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "w": 640,
+          "h": 480,
+          "minduration": 120,
+          "maxduration": 150
+        },
+        "ext": {
+          "bidder": {
+            "host": "eu",
+            "zoneid": "0"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "headers": {
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Accept": [
+            "application/json"
+          ],
+          "X-Openrtb-Version": [
+            "2.5"
+          ],
+          "User-Agent": [
+            "test-user-agent"
+          ],
+          "X-Forwarded-For": [
+            "123.123.123.123"
+          ]
+        },
+        "uri": "http://eu.example.com/api/dsp/bid/0",
+        "body": {
+          "id": "some-request-id",
+          "device": {
+            "ua": "test-user-agent",
+            "ip": "123.123.123.123",
+            "language": "en",
+            "dnt": 0
+          },
+          "imp": [
+            {
+              "id": "some-impression-id",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 120,
+                "maxduration": 150,
+                "w": 640,
+                "h": 480
+              },
+              "tagid": "ogTAGID",
+              "ext": {
+                "bidder": {
+                  "host": "eu",
+                  "zoneid": "0"
+                }
+              }
+            }
+          ],
+          "app": {
+            "id": "123456789",
+            "name": "Awesome App",
+            "bundle": "com.app.awesome",
+            "domain": "awesomeapp.com",
+            "cat": [
+              "IAB22-1"
+            ],
+            "publisher": {
+              "id": "123456789"
+            }
+          },
+          "user": {
+            "buyeruid": "awesome-user"
+          },
+          "tmax": 1000
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "awesome-resp-id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+                  "impid": "some-impression-id",
+                  "price": 3.5,
+                  "adm": "asesome-markup",
+                  "adomain": [
+                    "awesome.com"
+                  ],
+                  "crid": "20",
+                  "w": 1280,
+                  "h": 720
+                }
+              ],
+              "seat": "silvermob"
+            }
+          ],
+          "cur": "USD",
+          "ext": {
+            "responsetimemillis": {
+              "silvermob": 154
+            },
+            "tmaxrequest": 1000
+          }
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids":[
+        {
+          "bid":  {
+            "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+            "impid": "some-impression-id",
+            "price": 3.5,
+            "adm": "asesome-markup",
+            "crid": "20",
+            "adomain": [
+              "awesome.com"
+            ],
+            "w": 1280,
+            "h": 720
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/silvermob/silvermobtest/params/race/banner.json b/adapters/silvermob/silvermobtest/params/race/banner.json
new file mode 100644
index 00000000..9b6ca9d7
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/params/race/banner.json
@@ -0,0 +1,4 @@
+{
+  "zoneid": "0",
+  "host": "eu"
+}
diff --git a/adapters/silvermob/silvermobtest/params/race/native.json b/adapters/silvermob/silvermobtest/params/race/native.json
new file mode 100644
index 00000000..f63a4842
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/params/race/native.json
@@ -0,0 +1,4 @@
+{
+  "zoneid": "0",
+  "host": "eu"
+}
\ No newline at end of file
diff --git a/adapters/silvermob/silvermobtest/params/race/video.json b/adapters/silvermob/silvermobtest/params/race/video.json
new file mode 100644
index 00000000..f63a4842
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/params/race/video.json
@@ -0,0 +1,4 @@
+{
+  "zoneid": "0",
+  "host": "eu"
+}
\ No newline at end of file
diff --git a/adapters/silvermob/silvermobtest/supplemental/empty-seatbid-array.json b/adapters/silvermob/silvermobtest/supplemental/empty-seatbid-array.json
new file mode 100644
index 00000000..be95abea
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/supplemental/empty-seatbid-array.json
@@ -0,0 +1,139 @@
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "device": {
+      "ua": "test-user-agent",
+      "ip": "123.123.123.123",
+      "language": "en",
+      "dnt": 0
+    },
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "app": {
+      "publisher": {
+        "id": "123456789"
+      },
+      "cat": [
+        "IAB22-1"
+      ],
+      "bundle": "com.app.awesome",
+      "name": "Awesome App",
+      "domain": "awesomeapp.com",
+      "id": "123456789"
+    },
+    "imp": [
+      {
+        "id": "some-impression-id",
+        "tagid": "ogTAGID",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "w": 640,
+          "h": 480,
+          "minduration": 120,
+          "maxduration": 150
+        },
+        "ext": {
+          "bidder": {
+            "host": "eu",
+            "zoneid": "0"
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "headers": {
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Accept": [
+            "application/json"
+          ],
+          "X-Openrtb-Version": [
+            "2.5"
+          ],
+          "User-Agent": [
+            "test-user-agent"
+          ],
+          "X-Forwarded-For": [
+            "123.123.123.123"
+          ]
+        },
+        "uri": "http://eu.example.com/api/dsp/bid/0",
+        "body": {
+          "id": "some-request-id",
+          "device": {
+            "ua": "test-user-agent",
+            "ip": "123.123.123.123",
+            "language": "en",
+            "dnt": 0
+          },
+          "imp": [
+            {
+              "id": "some-impression-id",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "minduration": 120,
+                "maxduration": 150,
+                "w": 640,
+                "h": 480
+              },
+              "tagid": "ogTAGID",
+              "ext": {
+                "bidder": {
+                  "host": "eu",
+                  "zoneid": "0"
+                }
+              }
+            }
+          ],
+          "app": {
+            "id": "123456789",
+            "name": "Awesome App",
+            "bundle": "com.app.awesome",
+            "domain": "awesomeapp.com",
+            "cat": [
+              "IAB22-1"
+            ],
+            "publisher": {
+              "id": "123456789"
+            }
+          },
+          "user": {
+            "buyeruid": "awesome-user"
+          },
+          "tmax": 1000
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "awesome-resp-id",
+          "seatbid": [
+          ],
+          "cur": "USD",
+          "ext": {
+            "responsetimemillis": {
+              "silvermob": 154
+            },
+            "tmaxrequest": 1000
+          }
+        }
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Empty SeatBid array",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/silvermob/silvermobtest/supplemental/invalid-response.json b/adapters/silvermob/silvermobtest/supplemental/invalid-response.json
new file mode 100644
index 00000000..d2a1e890
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/supplemental/invalid-response.json
@@ -0,0 +1,118 @@
+
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "device": {
+      "ua": "test-user-agent",
+      "ip": "123.123.123.123",
+      "language": "en",
+      "dnt": 0
+    },
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "app": {
+      "publisher": {
+        "id": "123456789"
+      },
+      "cat": [
+        "IAB22-1"
+      ],
+      "bundle": "com.app.awesome",
+      "name": "Awesome App",
+      "domain": "awesomeapp.com",
+      "id": "123456789"
+    },
+    "imp": [
+      {
+        "id": "some-impression-id",
+        "tagid": "ogTAGID",
+        "banner": {
+          "w":320,
+          "h":50
+        },
+        "ext": {
+          "bidder": {
+            "host": "eu",
+            "zoneid": "0"
+          }
+        }
+      }
+    ]
+  },
+
+  "httpCalls": [{
+    "expectedRequest": {
+      "headers": {
+        "Content-Type": [
+          "application/json;charset=utf-8"
+        ],
+        "Accept": [
+          "application/json"
+        ],
+        "X-Openrtb-Version": [
+          "2.5"
+        ],
+        "User-Agent": [
+          "test-user-agent"
+        ],
+        "X-Forwarded-For": [
+          "123.123.123.123"
+        ]
+      },
+      "uri": "http://eu.example.com/api/dsp/bid/0",
+      "body": {
+        "id": "some-request-id",
+        "device": {
+          "ua": "test-user-agent",
+          "ip": "123.123.123.123",
+          "language": "en",
+          "dnt": 0
+        },
+        "imp": [
+          {
+            "id": "some-impression-id",
+            "banner": {
+                "w":320,
+                "h":50
+            },
+            "tagid": "ogTAGID",
+            "ext": {
+              "bidder": {
+                "host": "eu",
+                "zoneid": "0"
+              }
+            }
+          }
+        ],
+        "app": {
+          "id": "123456789",
+          "name": "Awesome App",
+          "bundle": "com.app.awesome",
+          "domain": "awesomeapp.com",
+          "cat": [
+            "IAB22-1"
+          ],
+          "publisher": {
+            "id": "123456789"
+          }
+        },
+        "user": {
+          "buyeruid": "awesome-user"
+        },
+        "tmax": 1000
+      }
+    },
+    "mockResponse": {
+      "status": 200,
+      "body": "invalid response"
+    }
+  }],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Error unmarshaling server Response: json: cannot unmarshal string into Go value of type openrtb.BidResponse",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/silvermob/silvermobtest/supplemental/invalid-silvermob-ext-object.json b/adapters/silvermob/silvermobtest/supplemental/invalid-silvermob-ext-object.json
new file mode 100644
index 00000000..090d7aff
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/supplemental/invalid-silvermob-ext-object.json
@@ -0,0 +1,28 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "some-impression-id",
+        "tagid": "my-adcode",
+        "video": {
+          "mimes": ["video/mp4"],
+          "w": 640,
+          "h": 480,
+          "minduration": 120,
+          "maxduration": 150
+        },
+        "ext": "Awesome"
+      }
+    ],
+    "site": {
+      "page": "test.com"
+    }
+  },
+  "expectedMakeRequestsErrors": [
+    {
+      "value":  "error unmarshaling imp.ext: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/silvermob/silvermobtest/supplemental/status-code-bad-request.json b/adapters/silvermob/silvermobtest/supplemental/status-code-bad-request.json
new file mode 100644
index 00000000..e93f2490
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/supplemental/status-code-bad-request.json
@@ -0,0 +1,99 @@
+
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "app": {
+      "publisher": {
+        "id": "123456789"
+      },
+      "cat": [
+        "IAB22-1"
+      ],
+      "bundle": "com.app.awesome",
+      "name": "Awesome App",
+      "domain": "awesomeapp.com",
+      "id": "123456789"
+    },
+    "imp": [
+      {
+        "id": "some-impression-id",
+        "tagid": "ogTAGID",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "w": 640,
+          "h": 480,
+          "minduration": 120,
+          "maxduration": 150
+        },
+        "ext": {
+          "bidder": {
+            "host": "eu",
+            "zoneid": "0"
+          }
+        }
+      }
+    ]
+  },
+
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "http://eu.example.com/api/dsp/bid/0",
+      "body": {
+        "id": "some-request-id",
+        "imp": [
+          {
+            "id": "some-impression-id",
+            "video": {
+              "mimes": [
+                "video/mp4"
+              ],
+              "minduration": 120,
+              "maxduration": 150,
+              "w": 640,
+              "h": 480
+            },
+            "tagid": "ogTAGID",
+            "ext": {
+              "bidder": {
+                "host": "eu",
+                "zoneid": "0"
+              }
+            }
+          }
+        ],
+        "app":  {
+          "publisher": {
+            "id": "123456789"
+          },
+          "cat": [
+            "IAB22-1"
+          ],
+          "bundle": "com.app.awesome",
+          "name": "Awesome App",
+          "domain": "awesomeapp.com",
+          "id": "123456789"
+        },
+        "user": {
+          "buyeruid": "awesome-user"
+        },
+        "tmax": 1000
+      }
+    },
+    "mockResponse": {
+      "status": 400
+    }
+  }],
+  "expectedBidResponses": [],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Bad Request status code: 400. Run with request.debug = 1 for more info",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/silvermob/silvermobtest/supplemental/status-code-no-content.json b/adapters/silvermob/silvermobtest/supplemental/status-code-no-content.json
new file mode 100644
index 00000000..a29710bf
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/supplemental/status-code-no-content.json
@@ -0,0 +1,83 @@
+
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "app": {
+      "id": "app_001",
+      "bundle": "com.awesome.app",
+      "publisher": {
+        "id": "2"
+      }
+    },
+    "imp": [
+      {
+        "id": "some-impression-id",
+        "tagid": "ogTAGID",
+        "video": {
+          "mimes": ["video/mp4"],
+          "w": 640,
+          "h": 480,
+          "minduration": 120,
+          "maxduration": 150
+        },
+        "ext": {
+          "bidder": {
+            "host": "eu",
+            "zoneid": "0"
+          }
+        }
+      }
+    ]
+  },
+
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "http://eu.example.com/api/dsp/bid/0",
+      "body": {
+        "id": "some-request-id",
+        "imp": [
+          {
+            "id": "some-impression-id",
+            "tagid": "ogTAGID",
+            "video": {
+              "mimes": [
+                "video/mp4"
+              ],
+              "minduration": 120,
+              "maxduration": 150,
+              "w": 640,
+              "h": 480
+            },
+            "ext": {
+              "bidder": {
+                "host": "eu",
+                "zoneid": "0"
+              }
+            }
+          }
+        ],
+        "app": {
+          "id": "app_001",
+          "bundle": "com.awesome.app",
+          "publisher": {
+            "id": "2"
+          }
+        },
+        "user": {
+          "buyeruid": "awesome-user"
+        },
+        "tmax": 1000
+      }
+    },
+    "mockResponse": {
+      "status": 204,
+      "body": {}
+    }
+  }],
+  "expectedBidResponses": [],
+  "expectedMakeBidsErrors": []
+}
diff --git a/adapters/silvermob/silvermobtest/supplemental/status-code-other-error.json b/adapters/silvermob/silvermobtest/supplemental/status-code-other-error.json
new file mode 100644
index 00000000..a32af01e
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/supplemental/status-code-other-error.json
@@ -0,0 +1,87 @@
+
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "app": {
+      "id": "app_001",
+      "bundle": "com.awesome.app",
+      "publisher": {
+        "id": "2"
+      }
+    },
+    "imp": [
+      {
+        "id": "some-impression-id",
+        "tagid": "ogTAGID",
+        "video": {
+          "mimes": ["video/mp4"],
+          "w": 640,
+          "h": 480,
+          "minduration": 120,
+          "maxduration": 150
+        },
+        "ext": {
+          "bidder": {
+            "host": "eu",
+            "zoneid": "0"
+          }
+        }
+      }
+    ]
+  },
+
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "http://eu.example.com/api/dsp/bid/0",
+      "body": {
+        "id": "some-request-id",
+        "imp": [
+          {
+            "id": "some-impression-id",
+            "tagid": "ogTAGID",
+            "video": {
+              "mimes": [
+                "video/mp4"
+              ],
+              "minduration": 120,
+              "maxduration": 150,
+              "w": 640,
+              "h": 480
+            },
+            "ext": {
+              "bidder": {
+                "host": "eu",
+                "zoneid": "0"
+              }
+            }
+          }
+        ],
+        "app": {
+          "id": "app_001",
+          "bundle": "com.awesome.app",
+          "publisher": {
+            "id": "2"
+          }
+        },
+        "user": {
+          "buyeruid": "awesome-user"
+        },
+        "tmax": 1000
+      }
+    },
+    "mockResponse": {
+      "status": 306
+    }
+  }],
+  "expectedBidResponses": [],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Unexpected status code: 306. Run with request.debug = 1 for more info",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/silvermob/silvermobtest/supplemental/status-code-service-unavailable.json b/adapters/silvermob/silvermobtest/supplemental/status-code-service-unavailable.json
new file mode 100644
index 00000000..5772a86e
--- /dev/null
+++ b/adapters/silvermob/silvermobtest/supplemental/status-code-service-unavailable.json
@@ -0,0 +1,87 @@
+
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "app": {
+      "id": "app_001",
+      "bundle": "com.awesome.app",
+      "publisher": {
+        "id": "2"
+      }
+    },
+    "imp": [
+      {
+        "id": "some-impression-id",
+        "tagid": "ogTAGID",
+        "video": {
+          "mimes": ["video/mp4"],
+          "w": 640,
+          "h": 480,
+          "minduration": 120,
+          "maxduration": 150
+        },
+        "ext": {
+          "bidder": {
+            "host": "eu",
+            "zoneid": "0"
+          }
+        }
+      }
+    ]
+  },
+
+  "httpCalls": [{
+    "expectedRequest": {
+      "uri": "http://eu.example.com/api/dsp/bid/0",
+      "body": {
+        "id": "some-request-id",
+        "imp": [
+          {
+            "id": "some-impression-id",
+            "tagid": "ogTAGID",
+            "video": {
+              "mimes": [
+                "video/mp4"
+              ],
+              "minduration": 120,
+              "maxduration": 150,
+              "w": 640,
+              "h": 480
+            },
+            "ext": {
+              "bidder": {
+                "host": "eu",
+                "zoneid": "0"
+              }
+            }
+          }
+        ],
+        "app": {
+          "id": "app_001",
+          "bundle": "com.awesome.app",
+          "publisher": {
+            "id": "2"
+          }
+        },
+        "user": {
+          "buyeruid": "awesome-user"
+        },
+        "tmax": 1000
+      }
+    },
+    "mockResponse": {
+      "status": 503
+    }
+  }],
+  "expectedBidResponses": [],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Unexpected status code: 503. Run with request.debug = 1 for more info",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/config/accounts_test.go b/config/accounts_test.go
new file mode 100644
index 00000000..ca7e8938
--- /dev/null
+++ b/config/accounts_test.go
@@ -0,0 +1,116 @@
+package config
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestAccountGDPREnabledForIntegrationType(t *testing.T) {
+	trueValue, falseValue := true, false
+
+	tests := []struct {
+		description          string
+		giveIntegrationType  IntegrationType
+		giveGDPREnabled      *bool
+		giveAMPGDPREnabled   *bool
+		giveAppGDPREnabled   *bool
+		giveVideoGDPREnabled *bool
+		giveWebGDPREnabled   *bool
+		wantEnabled          *bool
+	}{
+		{
+			description:         "GDPR AMP integration enabled, general GDPR disabled",
+			giveIntegrationType: IntegrationTypeAMP,
+			giveGDPREnabled:     &falseValue,
+			giveAMPGDPREnabled:  &trueValue,
+			wantEnabled:         &trueValue,
+		},
+		{
+			description:         "GDPR App integration enabled, general GDPR disabled",
+			giveIntegrationType: IntegrationTypeApp,
+			giveGDPREnabled:     &falseValue,
+			giveAppGDPREnabled:  &trueValue,
+			wantEnabled:         &trueValue,
+		},
+		{
+			description:          "GDPR Video integration enabled, general GDPR disabled",
+			giveIntegrationType:  IntegrationTypeVideo,
+			giveGDPREnabled:      &falseValue,
+			giveVideoGDPREnabled: &trueValue,
+			wantEnabled:          &trueValue,
+		},
+		{
+			description:         "GDPR Web integration enabled, general GDPR disabled",
+			giveIntegrationType: IntegrationTypeWeb,
+			giveGDPREnabled:     &falseValue,
+			giveWebGDPREnabled:  &trueValue,
+			wantEnabled:         &trueValue,
+		},
+		{
+			description:         "Web integration enabled, general GDPR unspecified",
+			giveIntegrationType: IntegrationTypeWeb,
+			giveGDPREnabled:     nil,
+			giveWebGDPREnabled:  &trueValue,
+			wantEnabled:         &trueValue,
+		},
+		{
+			description:         "GDPR Web integration disabled, general GDPR enabled",
+			giveIntegrationType: IntegrationTypeWeb,
+			giveGDPREnabled:     &trueValue,
+			giveWebGDPREnabled:  &falseValue,
+			wantEnabled:         &falseValue,
+		},
+		{
+			description:         "GDPR Web integration disabled, general GDPR unspecified",
+			giveIntegrationType: IntegrationTypeWeb,
+			giveGDPREnabled:     nil,
+			giveWebGDPREnabled:  &falseValue,
+			wantEnabled:         &falseValue,
+		},
+		{
+			description:         "GDPR Web integration unspecified, general GDPR disabled",
+			giveIntegrationType: IntegrationTypeWeb,
+			giveGDPREnabled:     &falseValue,
+			giveWebGDPREnabled:  nil,
+			wantEnabled:         &falseValue,
+		},
+		{
+			description:         "GDPR Web integration unspecified, general GDPR enabled",
+			giveIntegrationType: IntegrationTypeWeb,
+			giveGDPREnabled:     &trueValue,
+			giveWebGDPREnabled:  nil,
+			wantEnabled:         &trueValue,
+		},
+		{
+			description:         "GDPR Web integration unspecified, general GDPR unspecified",
+			giveIntegrationType: IntegrationTypeWeb,
+			giveGDPREnabled:     nil,
+			giveWebGDPREnabled:  nil,
+			wantEnabled:         nil,
+		},
+	}
+
+	for _, tt := range tests {
+		account := Account{
+			GDPR: AccountGDPR{
+				Enabled: tt.giveGDPREnabled,
+				IntegrationEnabled: AccountGDPRIntegration{
+					AMP:   tt.giveAMPGDPREnabled,
+					App:   tt.giveAppGDPREnabled,
+					Video: tt.giveVideoGDPREnabled,
+					Web:   tt.giveWebGDPREnabled,
+				},
+			},
+		}
+
+		enabled := account.GDPR.EnabledForIntegrationType(tt.giveIntegrationType)
+
+		if tt.wantEnabled == nil {
+			assert.Nil(t, enabled, tt.description)
+		} else {
+			assert.NotNil(t, enabled, tt.description)
+			assert.Equal(t, *tt.wantEnabled, *enabled, tt.description)
+		}
+	}
+}
diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go
index ae8bc3c8..bd2fa114 100644
--- a/exchange/exchange_test.go
+++ b/exchange/exchange_test.go
@@ -1305,6 +1305,7 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) {
 			Enforce: spec.EnforceLMT,
 		},
 		GDPR: config.GDPR{
+			Enabled:             spec.GDPREnabled,
 			UsersyncIfAmbiguous: !spec.AssumeGDPRApplies,
 			EEACountriesMap:     eeac,
 		},
@@ -2444,6 +2445,7 @@ func TestUpdateHbPbCatDur(t *testing.T) {
 }
 
 type exchangeSpec struct {
+	GDPREnabled       bool                   `json:"gdpr_enabled"`
 	IncomingRequest   exchangeRequest        `json:"incomingRequest"`
 	OutgoingRequests  map[string]*bidderSpec `json:"outgoingRequests"`
 	Response          exchangeResponse       `json:"response,omitempty"`
diff --git a/exchange/exchangetest/gdpr-geo-eu-off-device.json b/exchange/exchangetest/gdpr-geo-eu-off-device.json
index fc655de8..f704cdd5 100644
--- a/exchange/exchangetest/gdpr-geo-eu-off-device.json
+++ b/exchange/exchangetest/gdpr-geo-eu-off-device.json
@@ -1,5 +1,6 @@
 {
     "assume_gdpr_applies": false,
+    "gdpr_enabled": true,
     "incomingRequest": {
         "ortbRequest": {
             "id": "some-request-id",
diff --git a/exchange/exchangetest/gdpr-geo-eu-off.json b/exchange/exchangetest/gdpr-geo-eu-off.json
index 27a030f1..24357eb7 100644
--- a/exchange/exchangetest/gdpr-geo-eu-off.json
+++ b/exchange/exchangetest/gdpr-geo-eu-off.json
@@ -1,5 +1,6 @@
 {
     "assume_gdpr_applies": false,
+    "gdpr_enabled": true,
     "incomingRequest": {
         "ortbRequest": {
             "id": "some-request-id",
diff --git a/exchange/exchangetest/gdpr-geo-eu-on-featureflag-off.json b/exchange/exchangetest/gdpr-geo-eu-on-featureflag-off.json
new file mode 100644
index 00000000..6c6ca3ed
--- /dev/null
+++ b/exchange/exchangetest/gdpr-geo-eu-on-featureflag-off.json
@@ -0,0 +1,62 @@
+{
+    "assume_gdpr_applies": true,
+    "gdpr_enabled": false,
+    "incomingRequest": {
+        "ortbRequest": {
+            "id": "some-request-id",
+            "site": {
+                "page": "test.somepage.com"
+            },
+            "imp": [{
+                "id": "my-imp-id",
+                "video": {
+                    "mimes": ["video/mp4"]
+                },
+                "ext": {
+                    "appnexus": {
+                        "placementId": 1
+                    }
+                }
+            }],
+            "user": {
+                "buyeruid": "some-buyer-id",
+                "geo": {
+                    "country": "FRA"
+                }
+            }
+        }
+    },
+    "outgoingRequests": {
+        "appnexus": {
+            "expectRequest": {
+                "ortbRequest": {
+                    "id": "some-request-id",
+                    "site": {
+                        "page": "test.somepage.com"
+                    },
+                    "imp": [{
+                        "id": "my-imp-id",
+                        "video": {
+                            "mimes": ["video/mp4"]
+                        },
+                        "ext": {
+                            "bidder": {
+                                "placementId": 1
+                            }
+                        }
+                    }],
+                    "user": {
+                        "buyeruid": "some-buyer-id",
+                        "geo": {
+                            "country": "FRA"
+                        }
+                    }
+                },
+                "bidAdjustment": 1.0
+            },
+            "mockResponse": {
+                "errors": ["appnexus-error"]
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/exchange/exchangetest/gdpr-geo-eu-on.json b/exchange/exchangetest/gdpr-geo-eu-on.json
index 4ec42fc6..eb42a17c 100644
--- a/exchange/exchangetest/gdpr-geo-eu-on.json
+++ b/exchange/exchangetest/gdpr-geo-eu-on.json
@@ -1,5 +1,6 @@
 {
     "assume_gdpr_applies": true,
+    "gdpr_enabled": true,
     "incomingRequest": {
         "ortbRequest": {
             "id": "some-request-id",
diff --git a/exchange/utils_test.go b/exchange/utils_test.go
index 94975e82..14293ae2 100644
--- a/exchange/utils_test.go
+++ b/exchange/utils_test.go
@@ -82,7 +82,7 @@ func TestCleanOpenRTBRequests(t *testing.T) {
 	}
 
 	for _, test := range testCases {
-		reqByBidders, _, _, err := cleanOpenRTBRequests(context.Background(), test.req, nil, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{personalInfoAllowed: true}, true, privacyConfig)
+		reqByBidders, _, _, err := cleanOpenRTBRequests(context.Background(), test.req, nil, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{personalInfoAllowed: true}, true, privacyConfig, &config.Account{})
 		if test.hasError {
 			assert.NotNil(t, err, "Error shouldn't be nil")
 		} else {
@@ -179,7 +179,7 @@ func TestCleanOpenRTBRequestsCCPA(t *testing.T) {
 			},
 		}
 
-		results, _, privacyLabels, errs := cleanOpenRTBRequests(context.Background(), req, nil, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{personalInfoAllowed: true}, true, privacyConfig)
+		results, _, privacyLabels, errs := cleanOpenRTBRequests(context.Background(), req, nil, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{personalInfoAllowed: true}, true, privacyConfig, &config.Account{})
 		result := results["appnexus"]
 
 		assert.Nil(t, errs)
@@ -229,7 +229,7 @@ func TestCleanOpenRTBRequestsCCPAErrors(t *testing.T) {
 				Enforce: true,
 			},
 		}
-		_, _, _, errs := cleanOpenRTBRequests(context.Background(), req, &reqExtStruct, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{personalInfoAllowed: true}, true, privacyConfig)
+		_, _, _, errs := cleanOpenRTBRequests(context.Background(), req, &reqExtStruct, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{personalInfoAllowed: true}, true, privacyConfig, &config.Account{})
 
 		assert.ElementsMatch(t, []error{test.expectError}, errs, test.description)
 	}
@@ -264,7 +264,7 @@ func TestCleanOpenRTBRequestsCOPPA(t *testing.T) {
 		req := newBidRequest(t)
 		req.Regs = &openrtb.Regs{COPPA: test.coppa}
 
-		results, _, privacyLabels, errs := cleanOpenRTBRequests(context.Background(), req, nil, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{personalInfoAllowed: true}, true, config.Privacy{})
+		results, _, privacyLabels, errs := cleanOpenRTBRequests(context.Background(), req, nil, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{personalInfoAllowed: true}, true, config.Privacy{}, &config.Account{})
 		result := results["appnexus"]
 
 		assert.Nil(t, errs)
@@ -366,7 +366,7 @@ func TestCleanOpenRTBRequestsSChain(t *testing.T) {
 			extRequest = unmarshaledExt
 		}
 
-		results, _, _, errs := cleanOpenRTBRequests(context.Background(), req, extRequest, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{}, true, config.Privacy{})
+		results, _, _, errs := cleanOpenRTBRequests(context.Background(), req, extRequest, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{}, true, config.Privacy{}, &config.Account{})
 		result := results["appnexus"]
 
 		if test.hasError == true {
@@ -943,7 +943,7 @@ func TestCleanOpenRTBRequestsLMT(t *testing.T) {
 			},
 		}
 
-		results, _, privacyLabels, errs := cleanOpenRTBRequests(context.Background(), req, nil, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{personalInfoAllowed: true}, true, privacyConfig)
+		results, _, privacyLabels, errs := cleanOpenRTBRequests(context.Background(), req, nil, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{personalInfoAllowed: true}, true, privacyConfig, &config.Account{})
 		result := results["appnexus"]
 
 		assert.Nil(t, errs)
@@ -959,8 +959,12 @@ func TestCleanOpenRTBRequestsLMT(t *testing.T) {
 }
 
 func TestCleanOpenRTBRequestsGDPR(t *testing.T) {
+	trueValue, falseValue := true, false
+
 	testCases := []struct {
 		description         string
+		gdprAccountEnabled  *bool
+		gdprHostEnabled     bool
 		gdpr                string
 		gdprConsent         string
 		gdprScrub           bool
@@ -968,40 +972,96 @@ func TestCleanOpenRTBRequestsGDPR(t *testing.T) {
 		expectPrivacyLabels pbsmetrics.PrivacyLabels
 	}{
 		{
-			description: "Enforce - TCF Invalid",
-			gdpr:        "1",
-			gdprConsent: "malformed",
-			gdprScrub:   false,
+			description:        "Enforce - TCF Invalid",
+			gdprAccountEnabled: &trueValue,
+			gdprHostEnabled:    true,
+			gdpr:               "1",
+			gdprConsent:        "malformed",
+			gdprScrub:          false,
 			expectPrivacyLabels: pbsmetrics.PrivacyLabels{
 				GDPREnforced:   true,
 				GDPRTCFVersion: "",
 			},
 		},
 		{
-			description: "Enforce - TCF 1",
-			gdpr:        "1",
-			gdprConsent: "BONV8oqONXwgmADACHENAO7pqzAAppY",
-			gdprScrub:   true,
+			description:        "Enforce - TCF 1",
+			gdprAccountEnabled: &trueValue,
+			gdprHostEnabled:    true,
+			gdpr:               "1",
+			gdprConsent:        "BONV8oqONXwgmADACHENAO7pqzAAppY",
+			gdprScrub:          true,
 			expectPrivacyLabels: pbsmetrics.PrivacyLabels{
 				GDPREnforced:   true,
 				GDPRTCFVersion: pbsmetrics.TCFVersionV1,
 			},
 		},
 		{
-			description: "Enforce - TCF 2",
-			gdpr:        "1",
-			gdprConsent: "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA",
-			gdprScrub:   true,
+			description:        "Enforce - TCF 2",
+			gdprAccountEnabled: &trueValue,
+			gdprHostEnabled:    true,
+			gdpr:               "1",
+			gdprConsent:        "COzTVhaOzTVhaGvAAAENAiCIAP_AAH_AAAAAAEEUACCKAAA",
+			gdprScrub:          true,
 			expectPrivacyLabels: pbsmetrics.PrivacyLabels{
 				GDPREnforced:   true,
 				GDPRTCFVersion: pbsmetrics.TCFVersionV2,
 			},
 		},
 		{
-			description: "Not Enforce - TCF 1",
-			gdpr:        "0",
-			gdprConsent: "BONV8oqONXwgmADACHENAO7pqzAAppY",
-			gdprScrub:   false,
+			description:        "Not Enforce - TCF 1",
+			gdprAccountEnabled: &trueValue,
+			gdprHostEnabled:    true,
+			gdpr:               "0",
+			gdprConsent:        "BONV8oqONXwgmADACHENAO7pqzAAppY",
+			gdprScrub:          false,
+			expectPrivacyLabels: pbsmetrics.PrivacyLabels{
+				GDPREnforced:   false,
+				GDPRTCFVersion: "",
+			},
+		},
+		{
+			description:        "Enforce - TCF 1; account GDPR enabled, host GDPR setting disregarded",
+			gdprAccountEnabled: &trueValue,
+			gdprHostEnabled:    false,
+			gdpr:               "1",
+			gdprConsent:        "BONV8oqONXwgmADACHENAO7pqzAAppY",
+			gdprScrub:          true,
+			expectPrivacyLabels: pbsmetrics.PrivacyLabels{
+				GDPREnforced:   true,
+				GDPRTCFVersion: pbsmetrics.TCFVersionV1,
+			},
+		},
+		{
+			description:        "Not Enforce - TCF 1; account GDPR disabled, host GDPR setting disregarded",
+			gdprAccountEnabled: &falseValue,
+			gdprHostEnabled:    true,
+			gdpr:               "1",
+			gdprConsent:        "BONV8oqONXwgmADACHENAO7pqzAAppY",
+			gdprScrub:          false,
+			expectPrivacyLabels: pbsmetrics.PrivacyLabels{
+				GDPREnforced:   false,
+				GDPRTCFVersion: "",
+			},
+		},
+		{
+			description:        "Enforce - TCF 1; account GDPR not specified, host GDPR enabled",
+			gdprAccountEnabled: nil,
+			gdprHostEnabled:    true,
+			gdpr:               "1",
+			gdprConsent:        "BONV8oqONXwgmADACHENAO7pqzAAppY",
+			gdprScrub:          true,
+			expectPrivacyLabels: pbsmetrics.PrivacyLabels{
+				GDPREnforced:   true,
+				GDPRTCFVersion: pbsmetrics.TCFVersionV1,
+			},
+		},
+		{
+			description:        "Not Enforce - TCF 1; account GDPR not specified, host GDPR disabled",
+			gdprAccountEnabled: nil,
+			gdprHostEnabled:    false,
+			gdpr:               "1",
+			gdprConsent:        "BONV8oqONXwgmADACHENAO7pqzAAppY",
+			gdprScrub:          false,
 			expectPrivacyLabels: pbsmetrics.PrivacyLabels{
 				GDPREnforced:   false,
 				GDPRTCFVersion: "",
@@ -1018,13 +1078,30 @@ func TestCleanOpenRTBRequestsGDPR(t *testing.T) {
 
 		privacyConfig := config.Privacy{
 			GDPR: config.GDPR{
+				Enabled: test.gdprHostEnabled,
 				TCF2: config.TCF2{
 					Enabled: true,
 				},
 			},
 		}
 
-		results, _, privacyLabels, errs := cleanOpenRTBRequests(context.Background(), req, nil, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{personalInfoAllowed: !test.gdprScrub}, true, privacyConfig)
+		accountConfig := config.Account{
+			GDPR: config.AccountGDPR{
+				Enabled: test.gdprAccountEnabled,
+			},
+		}
+
+		results, _, privacyLabels, errs := cleanOpenRTBRequests(
+			context.Background(),
+			req,
+			nil,
+			&emptyUsersync{},
+			map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{},
+			pbsmetrics.Labels{},
+			&permissionsMock{personalInfoAllowed: !test.gdprScrub},
+			true,
+			privacyConfig,
+			&accountConfig)
 		result := results["appnexus"]
 
 		assert.Nil(t, errs)
diff --git a/usersync/usersyncers/syncer_test.go b/usersync/usersyncers/syncer_test.go
index 7582055f..a6e74966 100755
--- a/usersync/usersyncers/syncer_test.go
+++ b/usersync/usersyncers/syncer_test.go
@@ -102,6 +102,7 @@ func TestNewSyncerMap(t *testing.T) {
 		openrtb_ext.BidderMobileFuse:   true,
 		openrtb_ext.BidderOrbidder:     true,
 		openrtb_ext.BidderPubnative:    true,
+		openrtb_ext.BidderSilverMob:    true,
 		openrtb_ext.BidderSmaato:       true,
 		openrtb_ext.BidderTappx:        true,
 		openrtb_ext.BidderYeahmobi:     true,