Repository: prebid/prebid-server
Pull request #2298 (2022-07-12 09:30:55)

bliink: fix multi-seatbid handling
Instead of handling first SeatBid we now handling all SeatBids


Patch:
diff --git a/adapters/bliink/bliink.go b/adapters/bliink/bliink.go
index dd6ebcf1..1326d6a3 100644
--- a/adapters/bliink/bliink.go
+++ b/adapters/bliink/bliink.go
@@ -75,15 +75,16 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData
 		}}
 	}
 
-	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(response.SeatBid[0].Bid))
+	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
 	bidResponse.Currency = response.Cur
-	seatBid := response.SeatBid[0]
 	var errs []error
-	for i, bid := range seatBid.Bid {
-		mediaType, err := getMediaTypeForImp(bid.ImpID, request.Imp)
-		if err != nil {
-			errs = append(errs, err)
-		} else {
+	for _, seatBid := range response.SeatBid {
+		for i, bid := range seatBid.Bid {
+			mediaType, err := getMediaTypeForImp(bid.ImpID, request.Imp)
+			if err != nil {
+				errs = append(errs, err)
+				continue
+			}
 			bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
 				Bid:     &seatBid.Bid[i],
 				BidType: mediaType,
diff --git a/adapters/smartadserver/smartadserver.go b/adapters/smartadserver/smartadserver.go
index 92dc95ad..43ff361c 100644
--- a/adapters/smartadserver/smartadserver.go
+++ b/adapters/smartadserver/smartadserver.go
@@ -174,6 +174,8 @@ func getMediaTypeForImp(impID string, imps []openrtb2.Imp) openrtb_ext.BidType {
 		if imp.ID == impID {
 			if imp.Video != nil {
 				return openrtb_ext.BidTypeVideo
+			} else if imp.Native != nil {
+				return openrtb_ext.BidTypeNative
 			}
 			return openrtb_ext.BidTypeBanner
 		}
diff --git a/amp/parse.go b/amp/parse.go
index c0b7b8b2..478ce84f 100644
--- a/amp/parse.go
+++ b/amp/parse.go
@@ -20,6 +20,7 @@ type Params struct {
 	Slot            string
 	StoredRequestID string
 	Timeout         *uint64
+	Targeting       string
 }
 
 // Size defines size information of an AMP request.
@@ -56,6 +57,7 @@ func ParseParams(httpRequest *http.Request) (Params, error) {
 		Slot:            query.Get("slot"),
 		StoredRequestID: tagID,
 		Timeout:         parseIntPtr(query.Get("timeout")),
+		Targeting:       query.Get("targeting"),
 	}
 	return params, nil
 }
diff --git a/config/config.go b/config/config.go
index 304c92ad..0733e6c9 100644
--- a/config/config.go
+++ b/config/config.go
@@ -922,8 +922,8 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("adapters.adkerneladn.endpoint", "https://pbs2.adksrv.com/rtbpub?account={{.PublisherID}}")
 	v.SetDefault("adapters.adman.endpoint", "http://pub.admanmedia.com/?c=o&m=ortb")
 	v.SetDefault("adapters.admixer.endpoint", "http://inv-nets.admixer.net/pbs.aspx")
-	v.SetDefault("adapters.adocean.endpoint", "https://{{.Host}}")
 	v.SetDefault("adapters.adnuntius.endpoint", "https://ads.adnuntius.delivery/i")
+	v.SetDefault("adapters.adocean.endpoint", "https://{{.Host}}")
 	v.SetDefault("adapters.adoppler.endpoint", "http://{{.AccountID}}.trustedmarketplace.io/ads/processHeaderBid/{{.AdUnit}}")
 	v.SetDefault("adapters.adot.endpoint", "https://dsp.adotmob.com/headerbidding{PUBLISHER_PATH}/bidrequest")
 	v.SetDefault("adapters.adpone.endpoint", "http://rtb.adpone.com/bid-request?src=prebid_server")
@@ -969,45 +969,45 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("adapters.decenterads.endpoint", "http://supply.decenterads.com/?c=o&m=rtb")
 	v.SetDefault("adapters.deepintent.endpoint", "https://prebid.deepintent.com/prebid")
 	v.SetDefault("adapters.dmx.endpoint", "https://dmx-direct.districtm.io/b/v2")
+	v.SetDefault("adapters.e_volution.endpoint", "http://service.e-volution.ai/pbserver")
 	v.SetDefault("adapters.emx_digital.endpoint", "https://hb.emxdgt.com")
 	v.SetDefault("adapters.engagebdr.endpoint", "http://dsp.bnmla.com/hb")
 	v.SetDefault("adapters.eplanning.endpoint", "http://rtb.e-planning.net/pbs/1")
-	v.SetDefault("adapters.epom.endpoint", "https://an.epom.com/ortb")
 	v.SetDefault("adapters.epom.disabled", true)
-	v.SetDefault("adapters.e_volution.endpoint", "http://service.e-volution.ai/pbserver")
+	v.SetDefault("adapters.epom.endpoint", "https://an.epom.com/ortb")
 	v.SetDefault("adapters.gamma.endpoint", "https://hb.gammaplatform.com/adx/request/")
 	v.SetDefault("adapters.gamoshi.endpoint", "https://rtb.gamoshi.io")
 	v.SetDefault("adapters.grid.endpoint", "https://grid.bidswitch.net/sp_bid?sp=prebid")
 	v.SetDefault("adapters.groupm.endpoint", "https://hbopenbid.pubmatic.com/translator?source=prebid-server")
 	v.SetDefault("adapters.gumgum.endpoint", "https://g2.gumgum.com/providers/prbds2s/bid")
-	v.SetDefault("adapters.huaweiads.endpoint", "https://acd.op.hicloud.com/ppsadx/getResult")
 	v.SetDefault("adapters.huaweiads.disabled", true)
+	v.SetDefault("adapters.huaweiads.endpoint", "https://acd.op.hicloud.com/ppsadx/getResult")
 	v.SetDefault("adapters.impactify.endpoint", "https://sonic.impactify.media/bidder")
 	v.SetDefault("adapters.improvedigital.endpoint", "http://ad.360yield.com/pbs")
+	v.SetDefault("adapters.infytv.endpoint", "https://nxs.infy.tv/pbs/openrtb")
 	v.SetDefault("adapters.inmobi.endpoint", "https://api.w.inmobi.com/showad/openrtb/bidder/prebid")
 	v.SetDefault("adapters.interactiveoffers.endpoint", "https://prebid-server.ioadx.com/bidRequest/?partnerId={{.AccountID}}")
+	v.SetDefault("adapters.invibes.endpoint", "https://{{.ZoneID}}.videostep.com/bid/ServerBidAdContent")
+	v.SetDefault("adapters.iqzone.endpoint", "http://smartssp-us-east.iqzone.com/pserver")
 	v.SetDefault("adapters.ix.disabled", true)
 	v.SetDefault("adapters.janet.endpoint", "http://ghb.bidder.jmgads.com/pbs/ortb")
 	v.SetDefault("adapters.jixie.endpoint", "https://hb.jixie.io/v2/hbsvrpost")
 	v.SetDefault("adapters.kargo.endpoint", "https://krk.kargo.com/api/v1/openrtb")
 	v.SetDefault("adapters.kayzen.endpoint", "https://bids-{{.ZoneID}}.bidder.kayzen.io/?exchange={{.AccountID}}")
-	v.SetDefault("adapters.krushmedia.endpoint", "http://ads4.krushmedia.com/?c=rtb&m=req&key={{.AccountID}}")
-	v.SetDefault("adapters.invibes.endpoint", "https://{{.ZoneID}}.videostep.com/bid/ServerBidAdContent")
-	v.SetDefault("adapters.iqzone.endpoint", "http://smartssp-us-east.iqzone.com/pserver")
 	v.SetDefault("adapters.kidoz.endpoint", "http://prebid-adapter.kidoz.net/openrtb2/auction?src=prebid-server")
+	v.SetDefault("adapters.krushmedia.endpoint", "http://ads4.krushmedia.com/?c=rtb&m=req&key={{.AccountID}}")
 	v.SetDefault("adapters.kubient.endpoint", "https://kssp.kbntx.ch/prebid")
 	v.SetDefault("adapters.lockerdome.endpoint", "https://lockerdome.com/ladbid/prebidserver/openrtb2")
 	v.SetDefault("adapters.logicad.endpoint", "https://pbs.ladsp.com/adrequest/prebidserver")
 	v.SetDefault("adapters.lunamedia.endpoint", "http://api.lunamedia.io/xp/get?pubid={{.PublisherID}}")
-	v.SetDefault("adapters.sa_lunamedia.endpoint", "http://balancer.lmgssp.com/pserver")
 	v.SetDefault("adapters.madvertise.endpoint", "https://mobile.mng-ads.com/bidrequest{{.ZoneID}}")
 	v.SetDefault("adapters.marsmedia.endpoint", "https://bid306.rtbsrv.com/bidder/?bid=f3xtet")
 	v.SetDefault("adapters.mediafuse.endpoint", "http://ib.adnxs.com/openrtb2")
 	v.SetDefault("adapters.medianet.endpoint", "https://prebid-adapter.media.net/rtb/pb/prebids2s")
 	v.SetDefault("adapters.medianet.extra_info", "https://medianet.golang.pbs.com")
 	v.SetDefault("adapters.mgid.endpoint", "https://prebid.mgid.com/prebid/")
-	v.SetDefault("adapters.mobilefuse.endpoint", "http://mfx.mobilefuse.com/openrtb?pub_id={{.PublisherID}}")
 	v.SetDefault("adapters.mobfoxpb.endpoint", "http://bes.mobfox.com/?c=__route__&m=__method__&key=__key__")
+	v.SetDefault("adapters.mobilefuse.endpoint", "http://mfx.mobilefuse.com/openrtb?pub_id={{.PublisherID}}")
 	v.SetDefault("adapters.nanointeractive.endpoint", "https://ad.audiencemanager.de/hbs")
 	v.SetDefault("adapters.nextmillennium.endpoint", "https://pbs.nextmillmedia.com/openrtb2/auction")
 	v.SetDefault("adapters.ninthdecimal.endpoint", "http://rtb.ninthdecimal.com/xp/get?pubid={{.PublisherID}}")
@@ -1031,6 +1031,7 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("adapters.rtbhouse.endpoint", "http://prebidserver-s2s-ams.creativecdn.com/bidder/prebidserver/bids")
 	v.SetDefault("adapters.rubicon.disabled", true)
 	v.SetDefault("adapters.rubicon.endpoint", "http://exapi-us-east.rubiconproject.com/a/api/exchange.json")
+	v.SetDefault("adapters.sa_lunamedia.endpoint", "http://balancer.lmgssp.com/pserver")
 	v.SetDefault("adapters.sharethrough.endpoint", "https://btlr.sharethrough.com/universal/v1?supply_id=FGMrCMMc")
 	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")
@@ -1040,7 +1041,7 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("adapters.smartyads.endpoint", "http://{{.Host}}.smartyads.com/bid?rtb_seat_id={{.SourceId}}&secret_key={{.AccountID}}")
 	v.SetDefault("adapters.smilewanted.endpoint", "http://prebid-server.smilewanted.com")
 	v.SetDefault("adapters.sonobi.endpoint", "https://apex.go.sonobi.com/prebid?partnerid=71d9d3d8af")
-	v.SetDefault("adapters.sovrn.endpoint", "http://ap.lijit.com/rtb/bid?src=prebid_server")
+	v.SetDefault("adapters.sovrn.endpoint", "http://pbs.lijit.com/rtb/bid?src=prebid_server")
 	v.SetDefault("adapters.streamkey.endpoint", "http://ghb.hb.streamkey.net/pbs/ortb")
 	v.SetDefault("adapters.stroeercore.disabled", true)
 	v.SetDefault("adapters.stroeercore.endpoint", "http://mhb.adscale.de/s2sdsh")
@@ -1069,7 +1070,6 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("adapters.yieldone.endpoint", "https://y.one.impact-ad.jp/hbs_imp")
 	v.SetDefault("adapters.yssp.disabled", true)
 	v.SetDefault("adapters.zeroclickfraud.endpoint", "http://{{.Host}}/openrtb2?sid={{.SourceId}}")
-	v.SetDefault("adapters.infytv.endpoint", "https://nxs.infy.tv/pbs/openrtb")
 
 	v.SetDefault("max_request_size", 1024*256)
 	v.SetDefault("analytics.file.filename", "")
diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go
index 6910efb1..c8e80682 100644
--- a/endpoints/openrtb2/amp_auction.go
+++ b/endpoints/openrtb2/amp_auction.go
@@ -6,6 +6,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	jsonpatch "gopkg.in/evanphx/json-patch.v4"
 	"net/http"
 	"net/url"
 	"strings"
@@ -453,6 +454,31 @@ func (deps *endpointDeps) overrideWithParams(ampParams amp.Params, req *openrtb2
 		req.TMax = int64(*ampParams.Timeout) - deps.cfg.AMPTimeoutAdjustment
 	}
 
+	if err := setTargeting(req, ampParams.Targeting); err != nil {
+		return []error{err}
+	}
+
+	return nil
+}
+
+// setTargeting merges "targeting" to imp[0].ext.data
+func setTargeting(req *openrtb2.BidRequest, targeting string) error {
+	if len(targeting) == 0 {
+		return nil
+	}
+
+	targetingData := exchange.WrapJSONInData([]byte(targeting))
+
+	if len(req.Imp[0].Ext) > 0 {
+		newImpExt, err := jsonpatch.MergePatch(req.Imp[0].Ext, targetingData)
+		if err != nil {
+			return fmt.Errorf("unable to merge imp.ext with targeting data, check targeting data is correct: %s", err.Error())
+		}
+		req.Imp[0].Ext = newImpExt
+		return nil
+	}
+
+	req.Imp[0].Ext = targetingData
 	return nil
 }
 
diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go
index 6e51b3bb..ed1ac43e 100755
--- a/exchange/adapter_builders.go
+++ b/exchange/adapter_builders.go
@@ -163,8 +163,8 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderAdnuntius:         adnuntius.Builder,
 		openrtb_ext.BidderAdOcean:           adocean.Builder,
 		openrtb_ext.BidderAdoppler:          adoppler.Builder,
-		openrtb_ext.BidderAdpone:            adpone.Builder,
 		openrtb_ext.BidderAdot:              adot.Builder,
+		openrtb_ext.BidderAdpone:            adpone.Builder,
 		openrtb_ext.BidderAdprime:           adprime.Builder,
 		openrtb_ext.BidderAdtarget:          adtarget.Builder,
 		openrtb_ext.BidderAdtelligent:       adtelligent.Builder,
@@ -217,6 +217,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderHuaweiAds:         huaweiads.Builder,
 		openrtb_ext.BidderImpactify:         impactify.Builder,
 		openrtb_ext.BidderImprovedigital:    improvedigital.Builder,
+		openrtb_ext.BidderInfyTV:            infytv.Builder,
 		openrtb_ext.BidderInMobi:            inmobi.Builder,
 		openrtb_ext.BidderInteractiveoffers: interactiveoffers.Builder,
 		openrtb_ext.BidderInvibes:           invibes.Builder,
@@ -232,7 +233,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderLockerDome:        lockerdome.Builder,
 		openrtb_ext.BidderLogicad:           logicad.Builder,
 		openrtb_ext.BidderLunaMedia:         lunamedia.Builder,
-		openrtb_ext.BidderSaLunaMedia:       salunamedia.Builder,
 		openrtb_ext.BidderMadvertise:        madvertise.Builder,
 		openrtb_ext.BidderMarsmedia:         marsmedia.Builder,
 		openrtb_ext.BidderMediafuse:         appnexus.Builder,
@@ -261,6 +261,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderRichaudience:      richaudience.Builder,
 		openrtb_ext.BidderRTBHouse:          rtbhouse.Builder,
 		openrtb_ext.BidderRubicon:           rubicon.Builder,
+		openrtb_ext.BidderSaLunaMedia:       salunamedia.Builder,
 		openrtb_ext.BidderSharethrough:      sharethrough.Builder,
 		openrtb_ext.BidderSilverMob:         silvermob.Builder,
 		openrtb_ext.BidderSmaato:            smaato.Builder,
@@ -271,8 +272,8 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderSmileWanted:       smilewanted.Builder,
 		openrtb_ext.BidderSonobi:            sonobi.Builder,
 		openrtb_ext.BidderSovrn:             sovrn.Builder,
-		openrtb_ext.BidderStroeerCore:       stroeerCore.Builder,
 		openrtb_ext.BidderStreamkey:         adtelligent.Builder,
+		openrtb_ext.BidderStroeerCore:       stroeerCore.Builder,
 		openrtb_ext.BidderSynacormedia:      synacormedia.Builder,
 		openrtb_ext.BidderTappx:             tappx.Builder,
 		openrtb_ext.BidderTelaria:           telaria.Builder,
@@ -297,6 +298,5 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderYieldone:          yieldone.Builder,
 		openrtb_ext.BidderYSSP:              yahoossp.Builder,
 		openrtb_ext.BidderZeroClickFraud:    zeroclickfraud.Builder,
-		openrtb_ext.BidderInfyTV:            infytv.Builder,
 	}
 }
diff --git a/exchange/utils.go b/exchange/utils.go
index 22cfa85e..62fa210e 100644
--- a/exchange/utils.go
+++ b/exchange/utils.go
@@ -805,3 +805,11 @@ func mergeBidderRequests(allBidderRequests []BidderRequest, bidderNameToBidderRe
 	}
 	return allBidderRequests
 }
+
+func WrapJSONInData(data []byte) []byte {
+	res := make([]byte, 0, len(data))
+	res = append(res, []byte(`{"data":`)...)
+	res = append(res, data...)
+	res = append(res, []byte(`}`)...)
+	return res
+}
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index 9eaa81ca..a9830d27 100644
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -134,9 +134,9 @@ const (
 	BidderCpmstar           BidderName = "cpmstar"
 	BidderCriteo            BidderName = "criteo"
 	BidderDatablocks        BidderName = "datablocks"
-	BidderDmx               BidderName = "dmx"
 	BidderDecenterAds       BidderName = "decenterads"
 	BidderDeepintent        BidderName = "deepintent"
+	BidderDmx               BidderName = "dmx"
 	BidderEmxDigital        BidderName = "emx_digital"
 	BidderEngageBDR         BidderName = "engagebdr"
 	BidderEPlanning         BidderName = "eplanning"
@@ -150,6 +150,7 @@ const (
 	BidderHuaweiAds         BidderName = "huaweiads"
 	BidderImpactify         BidderName = "impactify"
 	BidderImprovedigital    BidderName = "improvedigital"
+	BidderInfyTV            BidderName = "infytv"
 	BidderInMobi            BidderName = "inmobi"
 	BidderInteractiveoffers BidderName = "interactiveoffers"
 	BidderInvibes           BidderName = "invibes"
@@ -165,14 +166,13 @@ const (
 	BidderLockerDome        BidderName = "lockerdome"
 	BidderLogicad           BidderName = "logicad"
 	BidderLunaMedia         BidderName = "lunamedia"
-	BidderSaLunaMedia       BidderName = "sa_lunamedia"
 	BidderMadvertise        BidderName = "madvertise"
 	BidderMarsmedia         BidderName = "marsmedia"
 	BidderMediafuse         BidderName = "mediafuse"
+	BidderMedianet          BidderName = "medianet"
 	BidderMgid              BidderName = "mgid"
 	BidderMobfoxpb          BidderName = "mobfoxpb"
 	BidderMobileFuse        BidderName = "mobilefuse"
-	BidderMedianet          BidderName = "medianet"
 	BidderNanoInteractive   BidderName = "nanointeractive"
 	BidderNextMillennium    BidderName = "nextmillennium"
 	BidderNinthDecimal      BidderName = "ninthdecimal"
@@ -194,6 +194,7 @@ const (
 	BidderRichaudience      BidderName = "richaudience"
 	BidderRTBHouse          BidderName = "rtbhouse"
 	BidderRubicon           BidderName = "rubicon"
+	BidderSaLunaMedia       BidderName = "sa_lunamedia"
 	BidderSharethrough      BidderName = "sharethrough"
 	BidderSilverMob         BidderName = "silvermob"
 	BidderSmaato            BidderName = "smaato"
@@ -220,8 +221,8 @@ const (
 	BidderVerizonMedia      BidderName = "verizonmedia"
 	BidderVideoByte         BidderName = "videobyte"
 	BidderVidoomy           BidderName = "vidoomy"
-	BidderVisx              BidderName = "visx"
 	BidderViewdeos          BidderName = "viewdeos"
+	BidderVisx              BidderName = "visx"
 	BidderVrtcal            BidderName = "vrtcal"
 	BidderYahooSSP          BidderName = "yahoossp"
 	BidderYeahmobi          BidderName = "yeahmobi"
@@ -230,7 +231,6 @@ const (
 	BidderYieldone          BidderName = "yieldone"
 	BidderYSSP              BidderName = "yssp"
 	BidderZeroClickFraud    BidderName = "zeroclickfraud"
-	BidderInfyTV            BidderName = "infytv"
 )
 
 // CoreBidderNames returns a slice of all core bidders.
@@ -305,6 +305,7 @@ func CoreBidderNames() []BidderName {
 		BidderHuaweiAds,
 		BidderImpactify,
 		BidderImprovedigital,
+		BidderInfyTV,
 		BidderInMobi,
 		BidderInteractiveoffers,
 		BidderInvibes,
@@ -320,7 +321,6 @@ func CoreBidderNames() []BidderName {
 		BidderLockerDome,
 		BidderLogicad,
 		BidderLunaMedia,
-		BidderSaLunaMedia,
 		BidderMadvertise,
 		BidderMarsmedia,
 		BidderMediafuse,
@@ -338,8 +338,8 @@ func CoreBidderNames() []BidderName {
 		BidderOperaads,
 		BidderOrbidder,
 		BidderOutbrain,
-		BidderPGAM,
 		BidderPangle,
+		BidderPGAM,
 		BidderPubmatic,
 		BidderPubnative,
 		BidderPulsepoint,
@@ -349,6 +349,7 @@ func CoreBidderNames() []BidderName {
 		BidderRichaudience,
 		BidderRTBHouse,
 		BidderRubicon,
+		BidderSaLunaMedia,
 		BidderSharethrough,
 		BidderSilverMob,
 		BidderSmaato,
@@ -385,7 +386,6 @@ func CoreBidderNames() []BidderName {
 		BidderYieldone,
 		BidderYSSP,
 		BidderZeroClickFraud,
-		BidderInfyTV,
 	}
 }
 
diff --git a/openrtb_ext/device.go b/openrtb_ext/device.go
index 1e860556..8c5b3673 100644
--- a/openrtb_ext/device.go
+++ b/openrtb_ext/device.go
@@ -70,7 +70,7 @@ type ExtDevicePrebid struct {
 
 // ExtDeviceInt defines the contract for bidrequest.device.ext.prebid.interstitial
 type ExtDeviceInt struct {
-	MinWidthPerc  int64 `json:"minwidtheperc"`
+	MinWidthPerc  int64 `json:"minwidthperc"`
 	MinHeightPerc int64 `json:"minheightperc"`
 }
 
diff --git a/static/bidder-info/kargo.yaml b/static/bidder-info/kargo.yaml
index 4acfd254..689d9b5d 100644
--- a/static/bidder-info/kargo.yaml
+++ b/static/bidder-info/kargo.yaml
@@ -9,5 +9,6 @@ capabilities:
       - video
       - native
 userSync:
-  supports:
-    - redirect
+  redirect:
+    url: "https://crb.kargo.com/api/v1/dsync/PrebidServer?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}"
+    userMacro: "$UID"
diff --git a/static/bidder-info/smartadserver.yaml b/static/bidder-info/smartadserver.yaml
index a6b06d95..ba36e551 100644
--- a/static/bidder-info/smartadserver.yaml
+++ b/static/bidder-info/smartadserver.yaml
@@ -6,10 +6,12 @@ capabilities:
     mediaTypes:
       - banner
       - video
+      - native
   site:
     mediaTypes:
       - banner
       - video
+      - native
 userSync:
   redirect:
     url: "https://ssbsync-global.smartadserver.com/api/sync?callerId=5&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirectUri={{.RedirectURL}}"


Test patch:
diff --git a/adapters/bliink/bliinktest/exemplary/banner_native_video.json b/adapters/bliink/bliinktest/exemplary/banner_native_video.json
new file mode 100644
index 00000000..cb652749
--- /dev/null
+++ b/adapters/bliink/bliinktest/exemplary/banner_native_video.json
@@ -0,0 +1,222 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "device": {
+      "ua": "test-user-agent",
+      "ip": "123.123.123.123"
+    },
+    "user": {
+      "buyeruid": "awesome-user",
+      "ext": {
+        "consent": "gdprConsentString"
+      }
+    },
+    "site": {
+      "page": "test.com",
+      "publisher": {
+        "id": "123456789"
+      }
+    },
+    "imp": [
+      {
+        "id": "test-banner-id",
+        "tagid": "TAGID",
+        "banner": {
+          "w": 320,
+          "h": 50
+        }
+      },
+      {
+        "id": "test-native-id",
+        "tagid": "TAGID",
+        "native": {
+          "request": "{test json string}",
+          "ver": "1.2"
+        }
+      },
+      {
+        "id": "test-video-id",
+        "tagid": "TAGID",
+        "video": {
+          "mimes": [
+            "video/mp4"
+          ],
+          "w": 500,
+          "h": 300,
+          "minduration": 120,
+          "maxduration": 150
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "headers": {
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Accept": [
+            "application/json"
+          ],
+          "X-Openrtb-Version": [
+            "2.5"
+          ]
+        },
+        "uri": "http://biddertest.url/bid",
+        "body": {
+          "id": "test-request-id",
+          "device": {
+            "ua": "test-user-agent",
+            "ip": "123.123.123.123"
+          },
+          "imp": [
+            {
+              "id": "test-banner-id",
+              "tagid": "TAGID",
+              "banner": {
+                "w": 320,
+                "h": 50
+              }
+            },
+            {
+              "id": "test-native-id",
+              "tagid": "TAGID",
+              "native": {
+                "request": "{test json string}",
+                "ver": "1.2"
+              }
+            },
+            {
+              "id": "test-video-id",
+              "tagid": "TAGID",
+              "video": {
+                "mimes": [
+                  "video/mp4"
+                ],
+                "w": 500,
+                "h": 300,
+                "minduration": 120,
+                "maxduration": 150
+              }
+            }
+          ],
+          "site": {
+            "page": "test.com",
+            "publisher": {
+              "id": "123456789"
+            }
+          },
+          "user": {
+            "buyeruid": "awesome-user",
+            "ext": {
+              "consent": "gdprConsentString"
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "awesome-resp-id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+                  "impid": "test-banner-id",
+                  "price": 0.9,
+                  "adm": "awesome-markup",
+                  "adomain": [
+                    "awesome.com"
+                  ],
+                  "crid": "20",
+                  "w": 320,
+                  "h": 50
+                },
+                {
+                  "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+                  "impid": "test-native-id",
+                  "price": 0.9,
+                  "adm": "awesome-markup",
+                  "adomain": [
+                    "awesome.com"
+                  ],
+                  "crid": "20"
+                }
+              ],
+              "seat": "bliink"
+            },
+            {
+              "bid": [
+                {
+                  "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+                  "impid": "test-video-id",
+                  "price": 0.9,
+                  "adm": "awesome-markup",
+                  "adomain": [
+                    "awesome.com"
+                  ],
+                  "crid": "20",
+                  "w": 320,
+                  "h": 50
+                }
+              ],
+              "seat": "bliink2"
+            }
+          ],
+          "cur": "EUR"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+            "impid": "test-banner-id",
+            "price": 0.9,
+            "adm": "awesome-markup",
+            "adomain": [
+              "awesome.com"
+            ],
+            "crid": "20",
+            "w": 320,
+            "h": 50
+          },
+          "type": "banner"
+        },
+        {
+          "bid": {
+            "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+            "impid": "test-native-id",
+            "price": 0.9,
+            "adm": "awesome-markup",
+            "adomain": [
+              "awesome.com"
+            ],
+            "crid": "20"
+          },
+          "type": "native"
+        },
+        {
+          "bid": {
+            "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+            "impid": "test-video-id",
+            "price": 0.9,
+            "adm": "awesome-markup",
+            "adomain": [
+              "awesome.com"
+            ],
+            "crid": "20",
+            "w": 320,
+            "h": 50
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/smartadserver/smartadservertest/exemplary/native-app.json b/adapters/smartadserver/smartadservertest/exemplary/native-app.json
new file mode 100644
index 00000000..86c41e43
--- /dev/null
+++ b/adapters/smartadserver/smartadservertest/exemplary/native-app.json
@@ -0,0 +1,270 @@
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "device": {
+      "ua": "test-user-agent",
+      "ip": "123.123.123.123",
+      "language": "en",
+      "dnt": 0,
+      "make": "samsung",
+      "model": "sm-a505u",
+      "devicetype": 4,
+      "lmt": 0,
+      "w": 412,
+      "h": 812,
+      "pxratio": 2.625
+    },
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "app": {
+      "name": "SmartNews: Local Breaking News",
+      "bundle": "jp.gocro.smartnews.android",
+      "publisher": {
+        "id": "pub-2647321473134964",
+        "ext": {
+          "country": "JP"
+        }
+      },
+      "content": {
+        "url": "https://play.google.com/store/apps/details?id\u003djp.gocro.smartnews.android",
+        "userrating": "4.2",
+        "livestream": 0,
+        "language": "en"
+      },
+      "storeurl": "https://play.google.com/store/apps/details?id\u003djp.gocro.smartnews.android",
+      "ext": {
+        "inventorypartnerdomain": ""
+      }
+    },
+    "imp": [
+      {
+        "id": "1",
+        "tagid": "1",
+        "bidfloor": 0.16,
+        "bidfloorcur": "EUR",
+        "secure": 1,
+        "native": {
+          "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":25}},{\"id\":2,\"required\":1,\"data\":{\"type\":2,\"len\":90}},{\"id\":3,\"data\":{\"type\":12,\"len\":15}},{\"id\":4,\"required\":1,\"img\":{\"type\":3,\"wmin\":1200,\"hmin\":627}},{\"id\":5,\"required\":1,\"img\":{\"type\":1,\"wmin\":100,\"hmin\":100}},{\"id\":6,\"data\":{\"type\":3,\"len\":5}},{\"id\":7,\"data\":{\"type\":6}}],\"eventtrackers\":[{\"event\":1,\"methods\":[1]}]}",
+          "ver": "1.2",
+          "api": [
+            3,
+            5,
+            6
+          ]
+        },
+        "metric": [
+          {
+            "type": "viewability",
+            "value": 0.94,
+            "vendor": "EXCHANGE"
+          },
+          {
+            "type": "session_depth",
+            "value": 2.0,
+            "vendor": "EXCHANGE"
+          }
+        ],
+        "ext": {
+          "billing_id": [
+            "48566531714"
+          ],
+          "dfp_ad_unit_code": "/22455324824/US/Android/ChannelView/NonFirst/us_android_channelview_nonfirst_native_v",
+          "ampad": 2,
+          "open_bidding": {
+            "is_open_bidding": 1
+          },
+          "creative_enforcement_settings": {
+            "policy_enforcement": 1,
+            "scan_enforcement": 3,
+            "publisher_blocks_enforcement": 2,
+            "is_default": 1
+          },
+          "auction_environment": 0,
+          "bidder": {
+            "siteId": 1,
+            "pageId": 2,
+            "formatId": 3,
+            "networkId": 73
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "headers": {
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Accept": [
+            "application/json"
+          ]
+        },
+        "uri": "https://ssb.smartadserver.com/api/bid?callerId=5",
+        "body": {
+          "id": "some-request-id",
+          "device": {
+            "ua": "test-user-agent",
+            "ip": "123.123.123.123",
+            "language": "en",
+            "dnt": 0,
+            "make": "samsung",
+            "model": "sm-a505u",
+            "devicetype": 4,
+            "lmt": 0,
+            "w": 412,
+            "h": 812,
+            "pxratio": 2.625
+          },
+          "tmax": 1000,
+          "user": {
+            "buyeruid": "awesome-user"
+          },
+          "app": {
+            "name": "SmartNews: Local Breaking News",
+            "bundle": "jp.gocro.smartnews.android",
+            "publisher": {
+              "id": "pub-2647321473134964",
+              "ext": {
+                "country": "JP"
+              }
+            },
+            "content": {
+              "url": "https://play.google.com/store/apps/details?id\u003djp.gocro.smartnews.android",
+              "userrating": "4.2",
+              "language": "en"
+            },
+            "storeurl": "https://play.google.com/store/apps/details?id\u003djp.gocro.smartnews.android",
+            "ext": {
+              "inventorypartnerdomain": ""
+            }
+          },
+          "imp": [
+            {
+              "id": "1",
+              "tagid": "1",
+              "bidfloor": 0.16,
+              "bidfloorcur": "EUR",
+              "secure": 1,
+              "native": {
+                "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":25}},{\"id\":2,\"required\":1,\"data\":{\"type\":2,\"len\":90}},{\"id\":3,\"data\":{\"type\":12,\"len\":15}},{\"id\":4,\"required\":1,\"img\":{\"type\":3,\"wmin\":1200,\"hmin\":627}},{\"id\":5,\"required\":1,\"img\":{\"type\":1,\"wmin\":100,\"hmin\":100}},{\"id\":6,\"data\":{\"type\":3,\"len\":5}},{\"id\":7,\"data\":{\"type\":6}}],\"eventtrackers\":[{\"event\":1,\"methods\":[1]}]}",
+                "ver": "1.2",
+                "api": [
+                  3,
+                  5,
+                  6
+                ]
+              },
+              "metric": [
+                {
+                  "type": "viewability",
+                  "value": 0.94,
+                  "vendor": "EXCHANGE"
+                },
+                {
+                  "type": "session_depth",
+                  "value": 2.0,
+                  "vendor": "EXCHANGE"
+                }
+              ],
+              "ext": {
+                "billing_id": [
+                  "48566531714"
+                ],
+                "dfp_ad_unit_code": "/22455324824/US/Android/ChannelView/NonFirst/us_android_channelview_nonfirst_native_v",
+                "ampad": 2,
+                "open_bidding": {
+                  "is_open_bidding": 1
+                },
+                "creative_enforcement_settings": {
+                  "policy_enforcement": 1,
+                  "scan_enforcement": 3,
+                  "publisher_blocks_enforcement": 2,
+                  "is_default": 1
+                },
+                "auction_environment": 0,
+                "bidder": {
+                  "siteId": 1,
+                  "pageId": 2,
+                  "formatId": 3,
+                  "networkId": 73
+                }
+              }
+            }
+          ],
+          "site": {
+            "publisher": {
+              "id": "73"
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "awesome-resp-id",
+          "seatbid": [
+            {
+              "seat": "13936",
+              "bid": [
+                {
+                  "id": "905895002584918328",
+                  "impid": "1",
+                  "price": 0.86403,
+                  "adm": "{\"native\":{\"ver\":\"1.2\",\"privacy\":\"https://privacy.us.criteo.com/adchoices?cppv\u003d3\u0026cpp\u003ddA0RezzRiApl49U79WS4eSofHI9xp0QYBojK_np3IC3bUxP--nXz3YJ9Knp3lffIaxxkyWjwHWw6E-om3O1QPVKQzRogO7TA1mZgFFS7oTrn5BAmxej9Ibf_f3nLqCMlvyUb0uBGRRY8e6F_4mMTsPfi0gfvHMHt9p9cMMz7_EMMB2a2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Hotel Katla\"}},{\"id\":2,\"data\":{\"value\":\"Vik\"}},{\"id\":3,\"data\":{\"value\":\"Book Now\"}},{\"id\":4,\"img\":{\"url\":\"https://pix.us.criteo.net/img/img?c\u003d3\u0026cq\u003d256\u0026h\u003d800\u0026m\u003d0\u0026partner\u003d4653\u0026q\u003d80\u0026r\u003d2\u0026u\u003dhttps%3A%2F%2Fmedia-cdn.tripadvisor.com%2Fmedia%2Fphoto-s%2F1c%2Fe0%2Fd1%2F28%2Fb86401-exterior.jpg\u0026ups\u003d1\u0026v\u003d3\u0026w\u003d800\u0026s\u003dmfVfgFTxkIyJE1l8uEIH0kjY\",\"w\":800,\"h\":800,\"ext\":{\"imagemode\":1}}},{\"id\":5,\"img\":{\"url\":\"https://pix.us.criteo.net/img/img?h\u003d200\u0026m\u003d0\u0026partner\u003d4653\u0026q\u003d80\u0026r\u003d0\u0026u\u003dhttp%3A%2F%2Fstatic.va.us.criteo.net%2Fdesign%2Fdt%2F4653%2F220310%2Fa8c95dab6f4048a3a93333bb2df35394_logo_colorset_1_square.png\u0026v\u003d3\u0026w\u003d200\u0026s\u003dS_tJonEVlXbjJYH3qQhRMmmr\",\"w\":200,\"h\":200}},{\"id\":7,\"data\":{\"value\":\"from $212\"}}],\"link\":{\"url\":\"https://cat.va.us.criteo.com/delivery/ckn.php?cppv\u003d3\u0026cpp\u003d_Hp3ShHYhT6VGVf27R7phNvxu2hpEMhI-_juBZvPRzA-urYvy54GTjaheHPJy7u8s523QQV0dFM_3EsVBAkZLqLOmHSlm5FjpMn_-sQY_Fpu1m4uZi9T5i2t49tP2csthrSlyhHQHD55kOCkG2gTV5GV4gbBTeDun61HYB0ztXzScWk0jO9iEy-6YGY_6nZCB5LpUKuaiZ4ApBhNuHx6rQkJkdbBmKFnS0sY3Dvri6AigvbUsZiku6v_VGqTKlER65Z1UzFx-mGSn5yZjsjbO-Zf0l7xRNzZFb7dW_EZjZufLLL47fyT5uMcbVypmMYcu6Htxb5Z_wj3eL7gz_zThJxYi60PzBoI4F3dYznFPgl6NY_Nazp1nAryiPGiCDbpM4yGF_9Sh8pEg2Ev94beM_ymWaqEdYTuCor6_grea5K0GIXeKSv5c4FsGSrTflQmIE_nLrJuvI8wMGQC8JtuNdC43wwWnQj5tOhHcOANVvZBkE_M\u0026maxdest\u003dhttps%3A%2F%2Fwww.tripadvisor.com%2FHotel_Review-s1-d5030264%3Fm%3D66738%26supcm%3D288696%26supai%3D307147\"},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"https://cat.va.us.criteo.com/delivery/lgn.php?cppv\u003d3\u0026cpp\u003dOYXXGxHYhT6VGVf27R7phNvxu2hpEMhI-_juBZvPRzA-urYvy54GTjaheHPJy7u8s523QQV0dFM_3EsVBAkZLqLOmHSlm5FjpMn_-sQY_Fpu1m4uZi9T5i2t49tP2csthrSlygJccxue8pR1zYveG3Rhcmzgt7JGjWy2WOHS5y42tNQvzbafDza85vKl66AQJCfeqdM_A6tUxZe2WFlSDw1s6sokf8fdldJ0aZucyWwh1Wx_tJbdzbyaD-j9TcpnAVsI2npiXJPI-_9xnE4pG3SAJiGZ2K4hWT34PkEC0g_9C9s1Hf6jQ6X1Wv0a8wa5IWLoMldXqnZ3W7jr9nPKXngjEy6n2-_WId8D9q9LkwXFcIR9LGovLfQ3U9XT9j1oJLzqgmyIVB9Z7VPF-NxHUDh1-fcjDMRMCPTKAOI4CcI8akLDN9M6XyaM7KLtHCHOpi1k-HT_gI70veWC4koE-UouUwM\u0026z\u003dsj0HnHF3bINdeGYjfRPFUEztMyUWhruGkElSEg\"}],\"assetsurl\":\"https://rdi.va.us.criteo.com/delivery/r/native?u\u003d%7CQ4DwbCv1DLCf%2FRGbTXtJ1gp584IIyg2Xyl6hmWNuvP4%3D%7C\u0026zn\u003dsj0HnHF3bINdeGYjfRPFUEztMyUWhruGkElSEg\u0026callback\u003d\u0026c1\u003dSEEq4vz4aLDKSl7f6j97sw4tGcTvFLx-G7HAXpahtNFbKhTsLPbfhYclWUAr1fpRrS5FKjKJDCrsY5WICFwCPtxotN6aDFevt17x9oLdclOk5qh_QOZ3AhwsnBXMPNEsxS6CR_ZPGwG6JmcbFms24fl9H5zHw7NWKcPTb_xtLsHLuKy3X2iAgHZ8QIT_87DNLHhfjmcEfnPnLr-669VrrQc4GLrjhWW8qFUaOfru2DjSZdBJjgxjTbuEbVI4NJ38zG7hgs13DDu9i7b9gidNjSJVg492IBN50JmS0p07mKQzgD2ELoa8cbdPnr9kwXwH3C6N_esaNHo87pj8DPHXQqVV6XvvZAeoQpUgo6Src_tX1eSo6ZHzH2mWXFCo6kP9BBf9HOdB8H5n1oL_rNxqfCthXOYzAlbAGeCvyc0GCeCuzwiCkq53bqcssz3E4Scul6ZDYUZltsbEeYLJPwkdMSviPH4Po-j9mUQaHW5lMABl2nam2q6lDoEFulNR8kz3R2BbrlMEoDHfcAtDf9gHKNndrYVRhfRtEMu0RW1SVdJ6fKuPvU1_zodMaXEpGmJ6dEwz04eBm22yN7nAaqJQYdEiiLuvrYyQZPzp6M8nXt66I8hzO9WfYk40EvQzg-fZMmr7NMke0_YPCm7oRyFZChAnbq3LE_jpjAuygA_S-Yq8y1d4RVhfRgTUdAdJaYne\"}}",
+                  "adomain": [
+                    "tripadvisor.com"
+                  ],
+                  "crid": "11116594",
+                  "w": 0,
+                  "h": 0,
+                  "exp": 0,
+                  "qagmediarating": 0,
+                  "ext": {
+                    "event_notification_token": {
+                      "payload": "4323.905895002584918328.1655998688532"
+                    },
+                    "impression_tracking_url": [
+                      "https://ssb-use1.smartadserver.com:443/api/imp?callerid\u003d3\u0026rtb\u003d1\u0026rtbnid\u003d4323\u0026rtbbid\u003d905895002584918328\u0026rtbh\u003d5aa204f3c4aca84cb52ea307bbff41e44571485c\u0026rtblt\u003d637915954885316448\u0026rtbet\u003d2\u0026rtbptnid\u003d361\u0026cftgid\u003d4a496db2aade"
+                    ]
+                  }
+                }
+              ]
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "905895002584918328",
+            "impid": "1",
+            "price": 0.86403,
+            "adm": "{\"native\":{\"ver\":\"1.2\",\"privacy\":\"https://privacy.us.criteo.com/adchoices?cppv\u003d3\u0026cpp\u003ddA0RezzRiApl49U79WS4eSofHI9xp0QYBojK_np3IC3bUxP--nXz3YJ9Knp3lffIaxxkyWjwHWw6E-om3O1QPVKQzRogO7TA1mZgFFS7oTrn5BAmxej9Ibf_f3nLqCMlvyUb0uBGRRY8e6F_4mMTsPfi0gfvHMHt9p9cMMz7_EMMB2a2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Hotel Katla\"}},{\"id\":2,\"data\":{\"value\":\"Vik\"}},{\"id\":3,\"data\":{\"value\":\"Book Now\"}},{\"id\":4,\"img\":{\"url\":\"https://pix.us.criteo.net/img/img?c\u003d3\u0026cq\u003d256\u0026h\u003d800\u0026m\u003d0\u0026partner\u003d4653\u0026q\u003d80\u0026r\u003d2\u0026u\u003dhttps%3A%2F%2Fmedia-cdn.tripadvisor.com%2Fmedia%2Fphoto-s%2F1c%2Fe0%2Fd1%2F28%2Fb86401-exterior.jpg\u0026ups\u003d1\u0026v\u003d3\u0026w\u003d800\u0026s\u003dmfVfgFTxkIyJE1l8uEIH0kjY\",\"w\":800,\"h\":800,\"ext\":{\"imagemode\":1}}},{\"id\":5,\"img\":{\"url\":\"https://pix.us.criteo.net/img/img?h\u003d200\u0026m\u003d0\u0026partner\u003d4653\u0026q\u003d80\u0026r\u003d0\u0026u\u003dhttp%3A%2F%2Fstatic.va.us.criteo.net%2Fdesign%2Fdt%2F4653%2F220310%2Fa8c95dab6f4048a3a93333bb2df35394_logo_colorset_1_square.png\u0026v\u003d3\u0026w\u003d200\u0026s\u003dS_tJonEVlXbjJYH3qQhRMmmr\",\"w\":200,\"h\":200}},{\"id\":7,\"data\":{\"value\":\"from $212\"}}],\"link\":{\"url\":\"https://cat.va.us.criteo.com/delivery/ckn.php?cppv\u003d3\u0026cpp\u003d_Hp3ShHYhT6VGVf27R7phNvxu2hpEMhI-_juBZvPRzA-urYvy54GTjaheHPJy7u8s523QQV0dFM_3EsVBAkZLqLOmHSlm5FjpMn_-sQY_Fpu1m4uZi9T5i2t49tP2csthrSlyhHQHD55kOCkG2gTV5GV4gbBTeDun61HYB0ztXzScWk0jO9iEy-6YGY_6nZCB5LpUKuaiZ4ApBhNuHx6rQkJkdbBmKFnS0sY3Dvri6AigvbUsZiku6v_VGqTKlER65Z1UzFx-mGSn5yZjsjbO-Zf0l7xRNzZFb7dW_EZjZufLLL47fyT5uMcbVypmMYcu6Htxb5Z_wj3eL7gz_zThJxYi60PzBoI4F3dYznFPgl6NY_Nazp1nAryiPGiCDbpM4yGF_9Sh8pEg2Ev94beM_ymWaqEdYTuCor6_grea5K0GIXeKSv5c4FsGSrTflQmIE_nLrJuvI8wMGQC8JtuNdC43wwWnQj5tOhHcOANVvZBkE_M\u0026maxdest\u003dhttps%3A%2F%2Fwww.tripadvisor.com%2FHotel_Review-s1-d5030264%3Fm%3D66738%26supcm%3D288696%26supai%3D307147\"},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"https://cat.va.us.criteo.com/delivery/lgn.php?cppv\u003d3\u0026cpp\u003dOYXXGxHYhT6VGVf27R7phNvxu2hpEMhI-_juBZvPRzA-urYvy54GTjaheHPJy7u8s523QQV0dFM_3EsVBAkZLqLOmHSlm5FjpMn_-sQY_Fpu1m4uZi9T5i2t49tP2csthrSlygJccxue8pR1zYveG3Rhcmzgt7JGjWy2WOHS5y42tNQvzbafDza85vKl66AQJCfeqdM_A6tUxZe2WFlSDw1s6sokf8fdldJ0aZucyWwh1Wx_tJbdzbyaD-j9TcpnAVsI2npiXJPI-_9xnE4pG3SAJiGZ2K4hWT34PkEC0g_9C9s1Hf6jQ6X1Wv0a8wa5IWLoMldXqnZ3W7jr9nPKXngjEy6n2-_WId8D9q9LkwXFcIR9LGovLfQ3U9XT9j1oJLzqgmyIVB9Z7VPF-NxHUDh1-fcjDMRMCPTKAOI4CcI8akLDN9M6XyaM7KLtHCHOpi1k-HT_gI70veWC4koE-UouUwM\u0026z\u003dsj0HnHF3bINdeGYjfRPFUEztMyUWhruGkElSEg\"}],\"assetsurl\":\"https://rdi.va.us.criteo.com/delivery/r/native?u\u003d%7CQ4DwbCv1DLCf%2FRGbTXtJ1gp584IIyg2Xyl6hmWNuvP4%3D%7C\u0026zn\u003dsj0HnHF3bINdeGYjfRPFUEztMyUWhruGkElSEg\u0026callback\u003d\u0026c1\u003dSEEq4vz4aLDKSl7f6j97sw4tGcTvFLx-G7HAXpahtNFbKhTsLPbfhYclWUAr1fpRrS5FKjKJDCrsY5WICFwCPtxotN6aDFevt17x9oLdclOk5qh_QOZ3AhwsnBXMPNEsxS6CR_ZPGwG6JmcbFms24fl9H5zHw7NWKcPTb_xtLsHLuKy3X2iAgHZ8QIT_87DNLHhfjmcEfnPnLr-669VrrQc4GLrjhWW8qFUaOfru2DjSZdBJjgxjTbuEbVI4NJ38zG7hgs13DDu9i7b9gidNjSJVg492IBN50JmS0p07mKQzgD2ELoa8cbdPnr9kwXwH3C6N_esaNHo87pj8DPHXQqVV6XvvZAeoQpUgo6Src_tX1eSo6ZHzH2mWXFCo6kP9BBf9HOdB8H5n1oL_rNxqfCthXOYzAlbAGeCvyc0GCeCuzwiCkq53bqcssz3E4Scul6ZDYUZltsbEeYLJPwkdMSviPH4Po-j9mUQaHW5lMABl2nam2q6lDoEFulNR8kz3R2BbrlMEoDHfcAtDf9gHKNndrYVRhfRtEMu0RW1SVdJ6fKuPvU1_zodMaXEpGmJ6dEwz04eBm22yN7nAaqJQYdEiiLuvrYyQZPzp6M8nXt66I8hzO9WfYk40EvQzg-fZMmr7NMke0_YPCm7oRyFZChAnbq3LE_jpjAuygA_S-Yq8y1d4RVhfRgTUdAdJaYne\"}}",
+            "adomain": [
+              "tripadvisor.com"
+            ],
+            "crid": "11116594",
+            "ext": {
+              "event_notification_token": {
+                "payload": "4323.905895002584918328.1655998688532"
+              },
+              "impression_tracking_url": [
+                "https://ssb-use1.smartadserver.com:443/api/imp?callerid\u003d3\u0026rtb\u003d1\u0026rtbnid\u003d4323\u0026rtbbid\u003d905895002584918328\u0026rtbh\u003d5aa204f3c4aca84cb52ea307bbff41e44571485c\u0026rtblt\u003d637915954885316448\u0026rtbet\u003d2\u0026rtbptnid\u003d361\u0026cftgid\u003d4a496db2aade"
+              ]
+            }
+          },
+          "type": "native"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/smartadserver/smartadservertest/exemplary/native-web.json b/adapters/smartadserver/smartadservertest/exemplary/native-web.json
new file mode 100644
index 00000000..a5fcb172
--- /dev/null
+++ b/adapters/smartadserver/smartadservertest/exemplary/native-web.json
@@ -0,0 +1,273 @@
+{
+  "mockBidRequest": {
+    "id": "some-request-id",
+    "device": {
+      "ua": "test-user-agent",
+      "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245",
+      "language": "en",
+      "dnt": 0,
+      "geo": {
+        "lat": 123.0,
+        "lon": 123.0,
+        "country": "BEL",
+        "region": "BE-VWV",
+        "city": "Ieper"
+      }
+    },
+    "tmax": 1000,
+    "user": {
+      "buyeruid": "awesome-user"
+    },
+    "site": {
+      "page": "https://www.redactie24.be/shopping/colruyt-moet-ingrijpen-3-producten-onmiddellijk-uit-de-rekken-gehaald-140289",
+      "publisher": {
+        "id": "pub-9936969251765866",
+        "ext": {
+          "country": "NL"
+        }
+      },
+      "content": {
+        "language": "nl"
+      },
+      "mobile": 1,
+      "ext": {
+        "amp": 0,
+        "page_visibility": 1,
+        "inventorypartnerdomain": ""
+      }
+    },
+    "imp": [
+      {
+        "id": "1",
+        "displaymanager": "GOOGLE",
+        "tagid": "1349892507",
+        "bidfloor": 0.75,
+        "bidfloorcur": "EUR",
+        "secure": 1,
+        "native": {
+          "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":25}},{\"id\":2,\"required\":1,\"data\":{\"type\":2,\"len\":90}},{\"id\":3,\"data\":{\"type\":12,\"len\":15}},{\"id\":4,\"required\":1,\"img\":{\"type\":3,\"wmin\":1200,\"hmin\":627}},{\"id\":5,\"required\":1,\"img\":{\"type\":1,\"wmin\":100,\"hmin\":100}},{\"id\":6,\"data\":{\"type\":3,\"len\":5}}],\"eventtrackers\":[{\"event\":1,\"methods\":[1]}],\"ext\":{\"style_id\":188304,\"style_height\":1,\"style_width\":1,\"style_layout_type\":1}}",
+          "ver": "1.2"
+        },
+        "metric": [
+          {
+            "type": "click_through_rate",
+            "value": 0.0016456807497888803,
+            "vendor": "EXCHANGE"
+          },
+          {
+            "type": "viewability",
+            "value": 0.84,
+            "vendor": "EXCHANGE"
+          },
+          {
+            "type": "session_depth",
+            "value": 1.0,
+            "vendor": "EXCHANGE"
+          }
+        ],
+        "ext": {
+          "billing_id": [
+            "48566531714"
+          ],
+          "dfp_ad_unit_code": "/15748617/Redactie24.be/Redactie24.be-Mobile-Rectangle-Mid",
+          "ampad": 3,
+          "open_bidding": {
+            "is_open_bidding": 1
+          },
+          "creative_enforcement_settings": {
+            "policy_enforcement": 1,
+            "scan_enforcement": 3,
+            "publisher_blocks_enforcement": 2,
+            "is_default": 1
+          },
+          "auction_environment": 0,
+          "bidder": {
+            "siteId": 1,
+            "pageId": 2,
+            "formatId": 3,
+            "networkId": 73
+          }
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "headers": {
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "Accept": [
+            "application/json"
+          ]
+        },
+        "uri": "https://ssb.smartadserver.com/api/bid?callerId=5",
+        "body": {
+          "id": "some-request-id",
+          "device": {
+            "ua": "test-user-agent",
+            "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245",
+            "language": "en",
+            "dnt": 0,
+            "geo": {
+              "lat": 123.0,
+              "lon": 123.0,
+              "country": "BEL",
+              "region": "BE-VWV",
+              "city": "Ieper"
+            }
+          },
+          "tmax": 1000,
+          "user": {
+            "buyeruid": "awesome-user"
+          },
+          "site": {
+            "page": "https://www.redactie24.be/shopping/colruyt-moet-ingrijpen-3-producten-onmiddellijk-uit-de-rekken-gehaald-140289",
+            "publisher": {
+              "id": "73",
+              "ext": {
+                "country": "NL"
+              }
+            },
+            "content": {
+              "language": "nl"
+            },
+            "mobile": 1,
+            "ext": {
+              "amp": 0,
+              "page_visibility": 1,
+              "inventorypartnerdomain": ""
+            }
+          },
+          "imp": [
+            {
+              "id": "1",
+              "displaymanager": "GOOGLE",
+              "tagid": "1349892507",
+              "bidfloor": 0.75,
+              "bidfloorcur": "EUR",
+              "secure": 1,
+              "native": {
+                "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":25}},{\"id\":2,\"required\":1,\"data\":{\"type\":2,\"len\":90}},{\"id\":3,\"data\":{\"type\":12,\"len\":15}},{\"id\":4,\"required\":1,\"img\":{\"type\":3,\"wmin\":1200,\"hmin\":627}},{\"id\":5,\"required\":1,\"img\":{\"type\":1,\"wmin\":100,\"hmin\":100}},{\"id\":6,\"data\":{\"type\":3,\"len\":5}}],\"eventtrackers\":[{\"event\":1,\"methods\":[1]}],\"ext\":{\"style_id\":188304,\"style_height\":1,\"style_width\":1,\"style_layout_type\":1}}",
+                "ver": "1.2"
+              },
+              "metric": [
+                {
+                  "type": "click_through_rate",
+                  "value": 0.0016456807497888803,
+                  "vendor": "EXCHANGE"
+                },
+                {
+                  "type": "viewability",
+                  "value": 0.84,
+                  "vendor": "EXCHANGE"
+                },
+                {
+                  "type": "session_depth",
+                  "value": 1.0,
+                  "vendor": "EXCHANGE"
+                }
+              ],
+              "ext": {
+                "billing_id": [
+                  "48566531714"
+                ],
+                "dfp_ad_unit_code": "/15748617/Redactie24.be/Redactie24.be-Mobile-Rectangle-Mid",
+                "ampad": 3,
+                "open_bidding": {
+                  "is_open_bidding": 1
+                },
+                "creative_enforcement_settings": {
+                  "policy_enforcement": 1,
+                  "scan_enforcement": 3,
+                  "publisher_blocks_enforcement": 2,
+                  "is_default": 1
+                },
+                "auction_environment": 0,
+                "bidder": {
+                  "siteId": 1,
+                  "pageId": 2,
+                  "formatId": 3,
+                  "networkId": 73
+                }
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "awesome-resp-id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "295938731865870037",
+                  "impid": "1",
+                  "price": 1.54925,
+                  "adm": "{\"native\":{\"ver\":\"1.2\",\"privacy\":\"https://www.google.com/url?ct\u003dabg\u0026q\u003dhttps://www.google.com/adsense/support/bin/request.py%3Fcontact%3Dabg_afc%26url%3Dhttps://www.redactie24.be/shopping/colruyt-moet-ingrijpen-3-producten-onmiddellijk-uit-de-rekken-gehaald-140289%26gl%3DBE%26hl%3Dnl%26client%3Dca-pub-6068497455919343%26ai0%3DCMWU2JWy1YsCyELKtzAbL7bvgCburseVqyIHkmrwQpC8QASDyoukmYDnIAQapAjPWmVA1qrE-qAMBqgTyAU_Q8o1C6ubbCv5vk2HM3fs8wHZka2sgzJZ-ydmQV3eXB3NIsBx4KgRQHdARGZjklQkHnxyL7qcXt6CNK_VP-USVsgKVRLy4TZDA-KqA9So2DlO5_spLZUkXDRJcuzdsl3jErSYVMoiXBrz0o8wkoCropIrEdyguIXj7mdUa0jzOqYI7PGmVI1GQFGlxvHl0vHKqTcvJvXuL10Rb3tBTgTn11m3vvbjv-0Gr7wEXMQHIMxwRw348dNQFgNpFh_uQaTDXulE_2cYB5eIAL3OSzp3-NImnXi5BReLIz2S-O27cYQCDQFn0vanM1ZBl0h-s1F8TwASDw7itjATgBAOIBbOq9pJBkAYBoAY32AYCgAfrp8o7qAeOzhuoB5PYG6gH7paxAqgH_p6xAqgHpKOxAqgH1ckbqAemvhuoB_PRG6gHltgbqAeqm7ECqAffn7EC2AcBoAjTx6kEsAgC0ggSCIDhgBAQARgfMgKqAjoDgMAD8ggRYmlkZGVyLTEyMjQxNjY3NDGxCQJEVu77f8u_gAoEmAsByAsBsBPP7cUP0BMA2BMKghQTGhF3d3cucmVkYWN0aWUyNC5iZdgUAdAVAfgWAYAXAQ\u0026usg\u003dAOvVaw19w649NdpH5fOLqrJv5iKn\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Merkenfestival!\"}},{\"id\":2,\"data\":{\"value\":\"Merkenfestival bij Colruyt met heel wat kortingen op grote merken. Van 15/6 t.e.m. 28/6\"}},{\"id\":3,\"data\":{\"value\":\"Profiteer ervan\"}},{\"id\":4,\"img\":{\"url\":\"https://s0.2mdn.net/simgad/13451259496958298280\",\"w\":1200,\"h\":627}},{\"id\":5,\"img\":{\"url\":\"https://s0.2mdn.net/simgad/2036458828863222275\",\"w\":200,\"h\":200}}],\"link\":{\"url\":\"https://googleads.g.doubleclick.net/dbm/clk?sa\u003dL\u0026ai\u003dCMWU2JWy1YsCyELKtzAbL7bvgCburseVqyIHkmrwQpC8QASDyoukmYDnIAQapAjPWmVA1qrE-qAMBqgTyAU_Q8o1C6ubbCv5vk2HM3fs8wHZka2sgzJZ-ydmQV3eXB3NIsBx4KgRQHdARGZjklQkHnxyL7qcXt6CNK_VP-USVsgKVRLy4TZDA-KqA9So2DlO5_spLZUkXDRJcuzdsl3jErSYVMoiXBrz0o8wkoCropIrEdyguIXj7mdUa0jzOqYI7PGmVI1GQFGlxvHl0vHKqTcvJvXuL10Rb3tBTgTn11m3vvbjv-0Gr7wEXMQHIMxwRw348dNQFgNpFh_uQaTDXulE_2cYB5eIAL3OSzp3-NImnXi5BReLIz2S-O27cYQCDQFn0vanM1ZBl0h-s1F8TwASDw7itjATgBAOIBbOq9pJBkAYBoAY32AYCgAfrp8o7qAeOzhuoB5PYG6gH7paxAqgH_p6xAqgHpKOxAqgH1ckbqAemvhuoB_PRG6gHltgbqAeqm7ECqAffn7EC2AcBoAjTx6kEsAgC0ggSCIDhgBAQARgfMgKqAjoDgMAD8ggRYmlkZGVyLTEyMjQxNjY3NDGxCQJEVu77f8u_gAoEmAsByAsBsBPP7cUP0BMA2BMKghQTGhF3d3cucmVkYWN0aWUyNC5iZdgUAdAVAfgWAYAXAQ\u0026num\u003d1\u0026cid\u003dCAASEuRoVZGmAOtO71YvotJoZFcAsA\u0026sig\u003dAOD64_1hNRa4SE5uXyxwr67sFVdttkXPMw\u0026client\u003dca-pub-6068497455919343\u0026dbm_c\u003dAKAmf-DXV5GMQ1DDDLVJesOQet1BLLRN_F07dwWiFKq6MqCPa-5AOEBQ_NDUHJd3Y7ZvHAC0fPA8yvkbeGzxb22Xfcn61EBbTw\u0026dbm_d\u003dAKAmf-C7GnCTqLdVsHVmHm0th-M3KSzxsgdBt0CfU5p-ZewkMHZUp9MuXuFB3lu9eNAZk4HDQ4bcasljiO2TWzUK4FX1F9kodnzxAz8-58dvtZ_35H3RZti6IayNy2JmlX77vA-4i-MDo1y_xGmVmgYlW8htjrrh38P7oiCkk1Eeqp4GT8b5NPXJ6owKBjP-f-4j3Br85EEUqlDm8XhSeKayoEmRGSAWwyLJWPfSWMU8AYCGMoCbz3d1qdYAM7vMMAubD38vdNkIzeScpaP97fO_Rcyn_N1SdyWJ2tWSJgjEw0zMU4n7d_v1BB0L7c8dXeMey9y62DX9lkhYKc6IGSi7lzs1b3N3xg\u0026dc_exteid\u003d3253483843301142955\u0026dc_pubid\u003d4\u0026adurl\u003dhttps://www.colruyt.be/nl/acties/merkenfestival?utm_medium\u003ddisplay\u0026utm_source\u003dmatterkind\u0026utm_campaign\u003dclp_merkenfestival__2022_sa_a3___vi13_\u0026utm_content\u003dnative___2j_nl___prog_20220615\"},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"https://googleads.g.doubleclick.net/dbm/ad?dbm_c\u003dAKAmf-ALROcN7i4iCF4_lIWdwE1RqHrg-hXY1YlIcMdhjf0y_Vq8xKKuLNx44WcLwmLtsgQuH-YjpoA5jssSSfE8YFwd2OIM6A\u0026dbm_d\u003dAKAmf-DYOlYXzDGNy1AWHuljIkbVGdy-3XkSQC4_DLFN7K4j3Xydgq5hqeOlKV2G3tZA0Qx7-_Q-vOikIfQ9xwfiMdyVPW8AaWknZ0G6Yh1bqlj_uRORqDWnPJDfCUs-3qRBuJGtQUzy8QiIsxVZxHL7BocEBcky55fsbVOGVAfImlSS3r_H5m4bp8L1UTtLKrL4RghtDpElRkOgcVLofR53DiYEGqDjkdFFIMCpypmUMxVsmzQJjF0bwXiqNPMe7cRv2KxToY88NAXkvM3X1kfnApXp2lIQubljbN-mvcljPppQhLHWqXlqA-mhafhbat0yllG0riHO1frZYgnqW9-a3ot-ra-Z1NVZTgs4JTab1RlBqmVm87GyEYUG8_8z85upY54zDqeNhkOBt_yU6-aJH3TVJ8n3sm4gLKXpvTP8sfTKjgKEqc2FVwWHShT1wOdgDBOyiv4W8J7tfelvhsJphT83a7exKdNAf0tJTZ-l_oo0iWveHCMz_R8KKv4lMT8HtlHZ77c1-5jx2FtyEMJiSRdiANiy8E6Syb9l8HsamiugkLmsBaLbMlOEmGsd9Qz34Pn5SUmNoKhGmQJVJuKoD5UDbL-PoWBf-7PfVgCsoSM2AeM6-0ENasMZ5Ij95_icGTJD2k5hiAtB4A2tnXdkVR1xGcxmq61Oxz4F_VQIPeTosvqXwhBfvw8jpyc4rvQqVKfqpHg-1LktGXQ9KWocMto_ddVCJHqv9SEn09SwhNqWvbunWoZNelsHLGjexpcYXIyeDAZSv4x53yxmctjkI6J5Dx_-cLcDseueVX5mUYCnC_XUegJsJqUwAY9OeaZMf05ItZmARQF30o-4VMuzqzUc6nF7BHwVi1mK8ZCm1LI-CuMZmIrrR92Iecu8nw6zObCxsP9PbNStz76qv6l1pYSxxp5AcSRuDWUgDG-D4Pwj3CuV3Tr--jNlqDIVzEyRfg9nbkRa6EPogb1CG2-jJgg7SpSMrbs4mDaZT-OOZyCEY12-PtT8_Dt-eD3HxI2-C2EZSY11Faii3qRiIlObXjuAmghElecenOQXqK_rqHoOowdRxnkNdLdiaReXKY5iErMx-wq2Q6gw3PM-oyNTbE3lOPhLbFlCVnVdPKM2InjTkOpsT32Gd-aa0Or09_IxB89Ww1JnHAxzcN9JMXSv5gbCiE04IbdcDooWncPsVmuFoYP_xIVP17kugYPA7oVvSJ4cTNiuZHLJxHvRk_kdKrM2bP0sXTSUpzRl76QORln7m2plu6uMDuFneLRt_mwpotp88ziQdDEezOrOH4GcQF8Hy4hUV5stN4XL9wUF8Bid3Rj1MDCK0fcVJ5zqx4nfqkvXmGvjfw0B172YsbXVrwnyLN3L40u4clQ0CMApqRx7xUzMEJfkh791EnVQCmPrKDuhxgUTrI0UE02HRypReiZnTKKleotRsaVAtpWik-aguBZW_CApcL0vnrDER0z1m6xFakB3tIw9uXJhuZnWIaRxzBvW_cXNWopkS7-g0pNTMnbo6mFqYRh38u0voIvHzm7KliItR10fxX_KZUF6K9YUaDPGDZ9r_zMl4YWX4VQ0d5ZP1ATgDcpQa_M7sEsTBRCodltxE4mVLYF89w3SNXU-Th7WQWWix37mbL3iA6JffljlwiXqxe8NnSsHLYaNgk1rjAGKpRw4pbyNMePymohg3k26tdRqwS8HG5Wt4uxby-RPIdOnqesZ-y-WuBpzwvGqgJIi5ckjjM12p5mT28FdQkVOR7kSIkzM7gBoUvSBdcLwr9DcUUV8obqakZ9dL_cjVxRuUmQ5lJBoSLLMdwE9tT6Um5FyhR51HfK43oN85GyR4srHjE_jHM2LWEPdB4MUG69V7bAUCGCsh3hl2rcNiTP7aWVrDBIgj5XPBmhxWudPJjNY8zHbycpV-BjSIxwQ9kRI8ykxBYLG8fjJZHmoXFM0t0mOhtJogp2yaKXDLsQCnU_X0SkpS9KPCDE1Bf7Npw6K_kvLuvVZR3NYRYvCu6pxGKhBLB83ZcM4-Lo2ij2NDTLDTl2XAYOCKCrSIwTN2mMa35srI20IXP2PBnhCVPVncJfoWaGzG_MKrQFj4jWqpNo0gFVvJfwx2nPdYJ6sMSQsy50vB-NJEvz9W80H7yoann5M4KjrRftg40AAUQeknwqCBuLlxqN7zISUXm1i0dlzEeMBtqY0d1HSUCdoPr2sJL3rKlrw5Ap1zChcVV_HE5RtQzFgcGy0yXFcTtf1DNJ5A1SQYG4JHwQrI-qKxdSBLSQ-dg_CO-Zy-EmvN4Ys0S82zzU2-kmkR-yj4xAQ4lqLUxw2ux4fsyHayADQPSJgC1ACKE2wd0-6kyOPDVXBAZECWK13tStxR5XR27kSgkvx6Ve3RKPa9P4x07GO5ih6K67i5y9kIaGVokNHtkmsR2m0AzMrkW1VcK81YI_800Bm_MHgk93uDrCoPpPfk4lCVMh6VGiS9YgxXCui74V4Kq6CY-N-U34siIT3iLgxIND3jrGcN2NabVPz7sshPYGrPez6SDJtExdVPom-SCHxvtVWTDCnq5eud_mIIOT44uoK7XbQZ6ae7AVYdhbvvKDhGarm-V4txmfHqkF9_sZYQ1NI2DD1sI1RU-N8DriBqMTT56kwrwifCp1Y8Qe-Q7sr_K3nNdE5nBJABRiTKdpHQ-ZpvJTLslTJmjrXDMlgjkcx3F06KQLvQ4kyrO9PeCIyya79Clay0yJ7IbMNtQ5H_R84AOMS0-DrnZBsW0-y1Z21h7UjHvEYkIPAvmMi8uA2Jz_LROi8munwwcdyFGg3U5uX-5hW9YbV3NYANWcajk0QsOJfrO5kQr4EQ7ulzXPTOavnfnYlEzXEz6LF2g_wpT3uVh2IZK9opwtAwD3MDrbukKstwVOQAM4WbUp8_DRGJP4XTmrqpAZZ70dLm9CrxjS55fmCA9LjmBPGLA4A97pNTfjziXL6RwWCISDfaPb3YBeF7ILmLuuLpXweIf3e1R61FBg8x8vIbC_CgwSOhLrAQmsgAVv_o-9aFFL38mTmOj1z1wpkjX4WDzebnqClSsfHfZXTnea9skm7oHMnmUN2BH4brF5e8Zyi1DmdrizQ8A\u0026pr\u003d60:2.532574\u0026cid\u003dCAASEuRoVZGmAOtO71YvotJoZFcAsA\u0026dc_exteid\u003d3253483843301142955\u0026dc_pubid\u003d4\"}]}}",
+                  "adomain": [
+                    "colruyt.be"
+                  ],
+                  "crid": "431321529",
+                  "w": 0,
+                  "h": 0,
+                  "exp": 0,
+                  "qagmediarating": 0,
+                  "ext": {
+                    "event_notification_token": {
+                      "payload": "3305.295938731865870037.1656056869251"
+                    },
+                    "impression_tracking_url": [
+                      "https://ssb-itx5.smartadserver.com:443/api/imp?callerid\u003d3\u0026rtb\u003d1\u0026rtbnid\u003d3305\u0026rtbbid\u003d295938731865870037\u0026rtbh\u003ddc4394811e91fdf08152b776f92c56d8e579c439\u0026rtblt\u003d637916536692508131\u0026rtbet\u003d1\u0026rtbptnid\u003d76\u0026cftgid\u003d16747b4b6788"
+                    ],
+                    "third_party_buyer_token": "AKAmf-DVv2DRJUgEPOajfj9Fo42XjLuHvqfOu6JQ5cpX6aEWvjp3c9AG1996IBT-ikYiT6HWItxrqDB6T66XtyhccpqLug1SOwKH9uyZQtUmVFpnRPVwRaCtZJs_c1Gl_ZEAvvUvIHvd"
+                  }
+                }
+              ],
+              "seat": "118133"
+            }
+          ],
+          "cur": "EUR",
+          "statuscode": 0,
+          "ext": {
+            "responsetimemillis": {
+              "acuityads": 154
+            },
+            "tmaxrequest": 1000
+          }
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "295938731865870037",
+            "impid": "1",
+            "price": 1.54925,
+            "adm": "{\"native\":{\"ver\":\"1.2\",\"privacy\":\"https://www.google.com/url?ct\u003dabg\u0026q\u003dhttps://www.google.com/adsense/support/bin/request.py%3Fcontact%3Dabg_afc%26url%3Dhttps://www.redactie24.be/shopping/colruyt-moet-ingrijpen-3-producten-onmiddellijk-uit-de-rekken-gehaald-140289%26gl%3DBE%26hl%3Dnl%26client%3Dca-pub-6068497455919343%26ai0%3DCMWU2JWy1YsCyELKtzAbL7bvgCburseVqyIHkmrwQpC8QASDyoukmYDnIAQapAjPWmVA1qrE-qAMBqgTyAU_Q8o1C6ubbCv5vk2HM3fs8wHZka2sgzJZ-ydmQV3eXB3NIsBx4KgRQHdARGZjklQkHnxyL7qcXt6CNK_VP-USVsgKVRLy4TZDA-KqA9So2DlO5_spLZUkXDRJcuzdsl3jErSYVMoiXBrz0o8wkoCropIrEdyguIXj7mdUa0jzOqYI7PGmVI1GQFGlxvHl0vHKqTcvJvXuL10Rb3tBTgTn11m3vvbjv-0Gr7wEXMQHIMxwRw348dNQFgNpFh_uQaTDXulE_2cYB5eIAL3OSzp3-NImnXi5BReLIz2S-O27cYQCDQFn0vanM1ZBl0h-s1F8TwASDw7itjATgBAOIBbOq9pJBkAYBoAY32AYCgAfrp8o7qAeOzhuoB5PYG6gH7paxAqgH_p6xAqgHpKOxAqgH1ckbqAemvhuoB_PRG6gHltgbqAeqm7ECqAffn7EC2AcBoAjTx6kEsAgC0ggSCIDhgBAQARgfMgKqAjoDgMAD8ggRYmlkZGVyLTEyMjQxNjY3NDGxCQJEVu77f8u_gAoEmAsByAsBsBPP7cUP0BMA2BMKghQTGhF3d3cucmVkYWN0aWUyNC5iZdgUAdAVAfgWAYAXAQ\u0026usg\u003dAOvVaw19w649NdpH5fOLqrJv5iKn\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Merkenfestival!\"}},{\"id\":2,\"data\":{\"value\":\"Merkenfestival bij Colruyt met heel wat kortingen op grote merken. Van 15/6 t.e.m. 28/6\"}},{\"id\":3,\"data\":{\"value\":\"Profiteer ervan\"}},{\"id\":4,\"img\":{\"url\":\"https://s0.2mdn.net/simgad/13451259496958298280\",\"w\":1200,\"h\":627}},{\"id\":5,\"img\":{\"url\":\"https://s0.2mdn.net/simgad/2036458828863222275\",\"w\":200,\"h\":200}}],\"link\":{\"url\":\"https://googleads.g.doubleclick.net/dbm/clk?sa\u003dL\u0026ai\u003dCMWU2JWy1YsCyELKtzAbL7bvgCburseVqyIHkmrwQpC8QASDyoukmYDnIAQapAjPWmVA1qrE-qAMBqgTyAU_Q8o1C6ubbCv5vk2HM3fs8wHZka2sgzJZ-ydmQV3eXB3NIsBx4KgRQHdARGZjklQkHnxyL7qcXt6CNK_VP-USVsgKVRLy4TZDA-KqA9So2DlO5_spLZUkXDRJcuzdsl3jErSYVMoiXBrz0o8wkoCropIrEdyguIXj7mdUa0jzOqYI7PGmVI1GQFGlxvHl0vHKqTcvJvXuL10Rb3tBTgTn11m3vvbjv-0Gr7wEXMQHIMxwRw348dNQFgNpFh_uQaTDXulE_2cYB5eIAL3OSzp3-NImnXi5BReLIz2S-O27cYQCDQFn0vanM1ZBl0h-s1F8TwASDw7itjATgBAOIBbOq9pJBkAYBoAY32AYCgAfrp8o7qAeOzhuoB5PYG6gH7paxAqgH_p6xAqgHpKOxAqgH1ckbqAemvhuoB_PRG6gHltgbqAeqm7ECqAffn7EC2AcBoAjTx6kEsAgC0ggSCIDhgBAQARgfMgKqAjoDgMAD8ggRYmlkZGVyLTEyMjQxNjY3NDGxCQJEVu77f8u_gAoEmAsByAsBsBPP7cUP0BMA2BMKghQTGhF3d3cucmVkYWN0aWUyNC5iZdgUAdAVAfgWAYAXAQ\u0026num\u003d1\u0026cid\u003dCAASEuRoVZGmAOtO71YvotJoZFcAsA\u0026sig\u003dAOD64_1hNRa4SE5uXyxwr67sFVdttkXPMw\u0026client\u003dca-pub-6068497455919343\u0026dbm_c\u003dAKAmf-DXV5GMQ1DDDLVJesOQet1BLLRN_F07dwWiFKq6MqCPa-5AOEBQ_NDUHJd3Y7ZvHAC0fPA8yvkbeGzxb22Xfcn61EBbTw\u0026dbm_d\u003dAKAmf-C7GnCTqLdVsHVmHm0th-M3KSzxsgdBt0CfU5p-ZewkMHZUp9MuXuFB3lu9eNAZk4HDQ4bcasljiO2TWzUK4FX1F9kodnzxAz8-58dvtZ_35H3RZti6IayNy2JmlX77vA-4i-MDo1y_xGmVmgYlW8htjrrh38P7oiCkk1Eeqp4GT8b5NPXJ6owKBjP-f-4j3Br85EEUqlDm8XhSeKayoEmRGSAWwyLJWPfSWMU8AYCGMoCbz3d1qdYAM7vMMAubD38vdNkIzeScpaP97fO_Rcyn_N1SdyWJ2tWSJgjEw0zMU4n7d_v1BB0L7c8dXeMey9y62DX9lkhYKc6IGSi7lzs1b3N3xg\u0026dc_exteid\u003d3253483843301142955\u0026dc_pubid\u003d4\u0026adurl\u003dhttps://www.colruyt.be/nl/acties/merkenfestival?utm_medium\u003ddisplay\u0026utm_source\u003dmatterkind\u0026utm_campaign\u003dclp_merkenfestival__2022_sa_a3___vi13_\u0026utm_content\u003dnative___2j_nl___prog_20220615\"},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"https://googleads.g.doubleclick.net/dbm/ad?dbm_c\u003dAKAmf-ALROcN7i4iCF4_lIWdwE1RqHrg-hXY1YlIcMdhjf0y_Vq8xKKuLNx44WcLwmLtsgQuH-YjpoA5jssSSfE8YFwd2OIM6A\u0026dbm_d\u003dAKAmf-DYOlYXzDGNy1AWHuljIkbVGdy-3XkSQC4_DLFN7K4j3Xydgq5hqeOlKV2G3tZA0Qx7-_Q-vOikIfQ9xwfiMdyVPW8AaWknZ0G6Yh1bqlj_uRORqDWnPJDfCUs-3qRBuJGtQUzy8QiIsxVZxHL7BocEBcky55fsbVOGVAfImlSS3r_H5m4bp8L1UTtLKrL4RghtDpElRkOgcVLofR53DiYEGqDjkdFFIMCpypmUMxVsmzQJjF0bwXiqNPMe7cRv2KxToY88NAXkvM3X1kfnApXp2lIQubljbN-mvcljPppQhLHWqXlqA-mhafhbat0yllG0riHO1frZYgnqW9-a3ot-ra-Z1NVZTgs4JTab1RlBqmVm87GyEYUG8_8z85upY54zDqeNhkOBt_yU6-aJH3TVJ8n3sm4gLKXpvTP8sfTKjgKEqc2FVwWHShT1wOdgDBOyiv4W8J7tfelvhsJphT83a7exKdNAf0tJTZ-l_oo0iWveHCMz_R8KKv4lMT8HtlHZ77c1-5jx2FtyEMJiSRdiANiy8E6Syb9l8HsamiugkLmsBaLbMlOEmGsd9Qz34Pn5SUmNoKhGmQJVJuKoD5UDbL-PoWBf-7PfVgCsoSM2AeM6-0ENasMZ5Ij95_icGTJD2k5hiAtB4A2tnXdkVR1xGcxmq61Oxz4F_VQIPeTosvqXwhBfvw8jpyc4rvQqVKfqpHg-1LktGXQ9KWocMto_ddVCJHqv9SEn09SwhNqWvbunWoZNelsHLGjexpcYXIyeDAZSv4x53yxmctjkI6J5Dx_-cLcDseueVX5mUYCnC_XUegJsJqUwAY9OeaZMf05ItZmARQF30o-4VMuzqzUc6nF7BHwVi1mK8ZCm1LI-CuMZmIrrR92Iecu8nw6zObCxsP9PbNStz76qv6l1pYSxxp5AcSRuDWUgDG-D4Pwj3CuV3Tr--jNlqDIVzEyRfg9nbkRa6EPogb1CG2-jJgg7SpSMrbs4mDaZT-OOZyCEY12-PtT8_Dt-eD3HxI2-C2EZSY11Faii3qRiIlObXjuAmghElecenOQXqK_rqHoOowdRxnkNdLdiaReXKY5iErMx-wq2Q6gw3PM-oyNTbE3lOPhLbFlCVnVdPKM2InjTkOpsT32Gd-aa0Or09_IxB89Ww1JnHAxzcN9JMXSv5gbCiE04IbdcDooWncPsVmuFoYP_xIVP17kugYPA7oVvSJ4cTNiuZHLJxHvRk_kdKrM2bP0sXTSUpzRl76QORln7m2plu6uMDuFneLRt_mwpotp88ziQdDEezOrOH4GcQF8Hy4hUV5stN4XL9wUF8Bid3Rj1MDCK0fcVJ5zqx4nfqkvXmGvjfw0B172YsbXVrwnyLN3L40u4clQ0CMApqRx7xUzMEJfkh791EnVQCmPrKDuhxgUTrI0UE02HRypReiZnTKKleotRsaVAtpWik-aguBZW_CApcL0vnrDER0z1m6xFakB3tIw9uXJhuZnWIaRxzBvW_cXNWopkS7-g0pNTMnbo6mFqYRh38u0voIvHzm7KliItR10fxX_KZUF6K9YUaDPGDZ9r_zMl4YWX4VQ0d5ZP1ATgDcpQa_M7sEsTBRCodltxE4mVLYF89w3SNXU-Th7WQWWix37mbL3iA6JffljlwiXqxe8NnSsHLYaNgk1rjAGKpRw4pbyNMePymohg3k26tdRqwS8HG5Wt4uxby-RPIdOnqesZ-y-WuBpzwvGqgJIi5ckjjM12p5mT28FdQkVOR7kSIkzM7gBoUvSBdcLwr9DcUUV8obqakZ9dL_cjVxRuUmQ5lJBoSLLMdwE9tT6Um5FyhR51HfK43oN85GyR4srHjE_jHM2LWEPdB4MUG69V7bAUCGCsh3hl2rcNiTP7aWVrDBIgj5XPBmhxWudPJjNY8zHbycpV-BjSIxwQ9kRI8ykxBYLG8fjJZHmoXFM0t0mOhtJogp2yaKXDLsQCnU_X0SkpS9KPCDE1Bf7Npw6K_kvLuvVZR3NYRYvCu6pxGKhBLB83ZcM4-Lo2ij2NDTLDTl2XAYOCKCrSIwTN2mMa35srI20IXP2PBnhCVPVncJfoWaGzG_MKrQFj4jWqpNo0gFVvJfwx2nPdYJ6sMSQsy50vB-NJEvz9W80H7yoann5M4KjrRftg40AAUQeknwqCBuLlxqN7zISUXm1i0dlzEeMBtqY0d1HSUCdoPr2sJL3rKlrw5Ap1zChcVV_HE5RtQzFgcGy0yXFcTtf1DNJ5A1SQYG4JHwQrI-qKxdSBLSQ-dg_CO-Zy-EmvN4Ys0S82zzU2-kmkR-yj4xAQ4lqLUxw2ux4fsyHayADQPSJgC1ACKE2wd0-6kyOPDVXBAZECWK13tStxR5XR27kSgkvx6Ve3RKPa9P4x07GO5ih6K67i5y9kIaGVokNHtkmsR2m0AzMrkW1VcK81YI_800Bm_MHgk93uDrCoPpPfk4lCVMh6VGiS9YgxXCui74V4Kq6CY-N-U34siIT3iLgxIND3jrGcN2NabVPz7sshPYGrPez6SDJtExdVPom-SCHxvtVWTDCnq5eud_mIIOT44uoK7XbQZ6ae7AVYdhbvvKDhGarm-V4txmfHqkF9_sZYQ1NI2DD1sI1RU-N8DriBqMTT56kwrwifCp1Y8Qe-Q7sr_K3nNdE5nBJABRiTKdpHQ-ZpvJTLslTJmjrXDMlgjkcx3F06KQLvQ4kyrO9PeCIyya79Clay0yJ7IbMNtQ5H_R84AOMS0-DrnZBsW0-y1Z21h7UjHvEYkIPAvmMi8uA2Jz_LROi8munwwcdyFGg3U5uX-5hW9YbV3NYANWcajk0QsOJfrO5kQr4EQ7ulzXPTOavnfnYlEzXEz6LF2g_wpT3uVh2IZK9opwtAwD3MDrbukKstwVOQAM4WbUp8_DRGJP4XTmrqpAZZ70dLm9CrxjS55fmCA9LjmBPGLA4A97pNTfjziXL6RwWCISDfaPb3YBeF7ILmLuuLpXweIf3e1R61FBg8x8vIbC_CgwSOhLrAQmsgAVv_o-9aFFL38mTmOj1z1wpkjX4WDzebnqClSsfHfZXTnea9skm7oHMnmUN2BH4brF5e8Zyi1DmdrizQ8A\u0026pr\u003d60:2.532574\u0026cid\u003dCAASEuRoVZGmAOtO71YvotJoZFcAsA\u0026dc_exteid\u003d3253483843301142955\u0026dc_pubid\u003d4\"}]}}",
+            "adomain": [
+              "colruyt.be"
+            ],
+            "crid": "431321529",
+            "ext": {
+              "event_notification_token": {
+                "payload": "3305.295938731865870037.1656056869251"
+              },
+              "impression_tracking_url": [
+                "https://ssb-itx5.smartadserver.com:443/api/imp?callerid\u003d3\u0026rtb\u003d1\u0026rtbnid\u003d3305\u0026rtbbid\u003d295938731865870037\u0026rtbh\u003ddc4394811e91fdf08152b776f92c56d8e579c439\u0026rtblt\u003d637916536692508131\u0026rtbet\u003d1\u0026rtbptnid\u003d76\u0026cftgid\u003d16747b4b6788"
+              ],
+              "third_party_buyer_token": "AKAmf-DVv2DRJUgEPOajfj9Fo42XjLuHvqfOu6JQ5cpX6aEWvjp3c9AG1996IBT-ikYiT6HWItxrqDB6T66XtyhccpqLug1SOwKH9uyZQtUmVFpnRPVwRaCtZJs_c1Gl_ZEAvvUvIHvd"
+            }
+          },
+          "type": "native"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/amp/parse_test.go b/amp/parse_test.go
index deacff6b..7a589bb4 100644
--- a/amp/parse_test.go
+++ b/amp/parse_test.go
@@ -24,8 +24,9 @@ func TestParseParams(t *testing.T) {
 		},
 		{
 			description: "All Fields",
+			// targeting data is encoded string that looks like this: {"gam-key1":"val1","gam-key2":"val2"}
 			query: "tag_id=anyTagID&account=anyAccount&curl=anyCurl&consent_string=anyConsent&debug=1&__amp_source_origin=anyOrigin" +
-				"&slot=anySlot&timeout=42&h=1&w=2&oh=3&ow=4&ms=10x11,12x13",
+				"&slot=anySlot&timeout=42&h=1&w=2&oh=3&ow=4&ms=10x11,12x13&targeting=%7B%22gam-key1%22%3A%22val1%22%2C%22gam-key2%22%3A%22val2%22%7D",
 			expectedParams: Params{
 				Account:         "anyAccount",
 				CanonicalURL:    "anyCurl",
@@ -44,6 +45,7 @@ func TestParseParams(t *testing.T) {
 						{W: 10, H: 11}, {W: 12, H: 13},
 					},
 				},
+				Targeting: `{"gam-key1":"val1","gam-key2":"val2"}`,
 			},
 		},
 		{
diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go
index f585c4ea..65b736d1 100644
--- a/endpoints/openrtb2/amp_auction_test.go
+++ b/endpoints/openrtb2/amp_auction_test.go
@@ -1449,3 +1449,130 @@ func TestAmpAuctionResponseHeaders(t *testing.T) {
 		assert.Equal(t, expectedHeaders, recorder.Result().Header, test.description+":statuscode")
 	}
 }
+
+func TestRequestWithTargeting(t *testing.T) {
+	stored := map[string]json.RawMessage{
+		"1": json.RawMessage(validRequest(t, "site.json")),
+	}
+	exchange := &mockAmpExchange{}
+	endpoint, _ := NewAmpEndpoint(
+		fakeUUIDGenerator{},
+		exchange,
+		newParamsValidator(t),
+		&mockAmpStoredReqFetcher{stored},
+		empty_fetcher.EmptyFetcher{},
+		&config.Configuration{MaxRequestSize: maxSize},
+		&metricsConfig.NilMetricsEngine{},
+		analyticsConf.NewPBSAnalytics(&config.Analytics{}),
+		nil,
+		nil,
+		openrtb_ext.BuildBidderMap(),
+		empty_fetcher.EmptyFetcher{},
+	)
+	url, err := url.Parse("/openrtb2/auction/amp")
+	assert.NoError(t, err, "unexpected error received while parsing url")
+	values := url.Query()
+	values.Add("targeting", `{"gam-key1":"val1", "gam-key2":"val2"}`)
+	values.Add("tag_id", "1")
+	url.RawQuery = values.Encode()
+
+	request, err := http.NewRequest("GET", url.String(), nil)
+	if !assert.NoError(t, err) {
+		return
+	}
+	recorder := httptest.NewRecorder()
+	endpoint(recorder, request, nil)
+
+	if !assert.NotNil(t, exchange.lastRequest, "Endpoint responded with %d: %s", recorder.Code, recorder.Body.String()) {
+		return
+	}
+	assert.JSONEq(t, `{"appnexus":{"placementId":12883451}, "data":{"gam-key1":"val1", "gam-key2":"val2"}}`, string(exchange.lastRequest.Imp[0].Ext))
+}
+
+func TestSetTargeting(t *testing.T) {
+	tests := []struct {
+		description    string
+		bidRequest     openrtb2.BidRequest
+		targeting      string
+		expectedImpExt string
+		wantError      bool
+		errorMessage   string
+	}{
+		{
+			description:    "valid imp ext, valid targeting data",
+			bidRequest:     openrtb2.BidRequest{Imp: []openrtb2.Imp{{Ext: []byte(`{"appnexus":{"placementId":123}}`)}}},
+			targeting:      `{"gam-key1":"val1", "gam-key2":"val2"}`,
+			expectedImpExt: `{"appnexus":{"placementId":123}, "data": {"gam-key1":"val1", "gam-key2":"val2"}}`,
+			wantError:      false,
+			errorMessage:   "",
+		},
+		{
+			description:    "valid imp ext, empty targeting data",
+			bidRequest:     openrtb2.BidRequest{Imp: []openrtb2.Imp{{Ext: []byte(`{"appnexus":{"placementId":123}}`)}}},
+			targeting:      ``,
+			expectedImpExt: `{"appnexus":{"placementId":123}}`,
+			wantError:      false,
+			errorMessage:   "",
+		},
+		{
+			description:    "empty imp ext, valid targeting data",
+			bidRequest:     openrtb2.BidRequest{Imp: []openrtb2.Imp{{Ext: []byte(`{}`)}}},
+			targeting:      `{"gam-key1":"val1", "gam-key2":"val2"}`,
+			expectedImpExt: `{"data": {"gam-key1":"val1", "gam-key2":"val2"}}`,
+			wantError:      false,
+			errorMessage:   "",
+		},
+		{
+			description:    "nil imp ext, valid targeting data",
+			bidRequest:     openrtb2.BidRequest{Imp: []openrtb2.Imp{{Ext: nil}}},
+			targeting:      `{"gam-key1":"val1", "gam-key2":"val2"}`,
+			expectedImpExt: `{"data": {"gam-key1":"val1", "gam-key2":"val2"}}`,
+			wantError:      false,
+			errorMessage:   "",
+		},
+		{
+			description:    "imp ext has data, valid targeting data",
+			bidRequest:     openrtb2.BidRequest{Imp: []openrtb2.Imp{{Ext: []byte(`{"data":{"placementId":123}}`)}}},
+			targeting:      `{"gam-key1":"val1", "gam-key2":"val2"}`,
+			expectedImpExt: `{"data": {"gam-key1":"val1", "gam-key2":"val2", "placementId":123}}`,
+			wantError:      false,
+			errorMessage:   "",
+		},
+		{
+			description:    "imp ext has data and other fields, valid targeting data",
+			bidRequest:     openrtb2.BidRequest{Imp: []openrtb2.Imp{{Ext: []byte(`{"data":{"placementId":123}, "prebid": 123}`)}}},
+			targeting:      `{"gam-key1":"val1", "gam-key2":"val2"}`,
+			expectedImpExt: `{"data": {"gam-key1":"val1", "gam-key2":"val2", "placementId":123}, "prebid":123}`,
+			wantError:      false,
+			errorMessage:   "",
+		},
+		{
+			description:    "imp ext has invalid format, valid targeting data",
+			bidRequest:     openrtb2.BidRequest{Imp: []openrtb2.Imp{{Ext: []byte(`{123:{}`)}}},
+			targeting:      `{"gam-key1":"val1", "gam-key2":"val2"}`,
+			expectedImpExt: ``,
+			wantError:      true,
+			errorMessage:   "unable to merge imp.ext with targeting data, check targeting data is correct: Invalid JSON Document",
+		},
+		{
+			description:    "valid imp ext, invalid targeting data",
+			bidRequest:     openrtb2.BidRequest{Imp: []openrtb2.Imp{{Ext: []byte(`{"appnexus":{"placementId":123}}`)}}},
+			targeting:      `{123,}`,
+			expectedImpExt: ``,
+			wantError:      true,
+			errorMessage:   "unable to merge imp.ext with targeting data, check targeting data is correct: Invalid JSON Patch",
+		},
+	}
+
+	for _, test := range tests {
+		req := &test.bidRequest
+		err := setTargeting(req, test.targeting)
+		if test.wantError {
+			assert.EqualErrorf(t, err, test.errorMessage, "error is incorrect for test case: %s", test.description)
+		} else {
+			assert.NoError(t, err, "error should be nil for test case: %s", test.description)
+			assert.JSONEq(t, test.expectedImpExt, string(req.Imp[0].Ext), "incorrect impression extension returned for test %s", test.description)
+		}
+
+	}
+}
diff --git a/exchange/utils_test.go b/exchange/utils_test.go
index b4241329..600d0721 100644
--- a/exchange/utils_test.go
+++ b/exchange/utils_test.go
@@ -3082,3 +3082,42 @@ func Test_parseAliasesGVLIDs(t *testing.T) {
 		})
 	}
 }
+
+func TestBuildExtData(t *testing.T) {
+	testCases := []struct {
+		description string
+		input       []byte
+		expectedRes string
+	}{
+		{
+			description: "Input object with int value",
+			input:       []byte(`{"someData": 123}`),
+			expectedRes: `{"data": {"someData": 123}}`,
+		},
+		{
+			description: "Input object with bool value",
+			input:       []byte(`{"someData": true}`),
+			expectedRes: `{"data": {"someData": true}}`,
+		},
+		{
+			description: "Input object with string value",
+			input:       []byte(`{"someData": "true"}`),
+			expectedRes: `{"data": {"someData": "true"}}`,
+		},
+		{
+			description: "No input object",
+			input:       []byte(`{}`),
+			expectedRes: `{"data": {}}`,
+		},
+		{
+			description: "Input object with object value",
+			input:       []byte(`{"someData": {"moreFpdData": "fpddata"}}`),
+			expectedRes: `{"data": {"someData": {"moreFpdData": "fpddata"}}}`,
+		},
+	}
+
+	for _, test := range testCases {
+		actualRes := WrapJSONInData(test.input)
+		assert.JSONEq(t, test.expectedRes, string(actualRes), "Incorrect result data")
+	}
+}