Repository: prebid/prebid-server
Pull request #2283 (2022-06-28 09:33:23)

Read imp[].ext.tid, fix PBJS 7.3.0 compatibility
Added changes to read and mark `imp[].ext.tid` as special field and not a bidder code.


With https://github.com/prebid/Prebid.js/pull/8591 (https://github.com/prebid/Prebid.js/issues/8543) PBJS 7.3.0 sends `imp[].ext.tid` to PBS where PBS interprets `tid` as bidder code. Hence, blocking PBS adapter from using with PBJS 7.3.0.
Below is the error response from PBS.
```
Invalid request: request.imp[0].ext contains unknown bidder: tid. Did you forget an alias in request.ext.prebid.aliases?
```


Patch:
diff --git a/adapters/infytv/infytv.go b/adapters/infytv/infytv.go
new file mode 100644
index 00000000..af41958b
--- /dev/null
+++ b/adapters/infytv/infytv.go
@@ -0,0 +1,89 @@
+package infytv
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+
+	"github.com/mxmCherry/openrtb/v15/openrtb2"
+	"github.com/prebid/prebid-server/adapters"
+	"github.com/prebid/prebid-server/config"
+	"github.com/prebid/prebid-server/errortypes"
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+type adapter struct {
+	endpoint string
+}
+
+// Builder builds a new instance of the InfyTV adapter for the given bidder with the given config.
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
+	bidder := &adapter{
+		endpoint: config.Endpoint,
+	}
+	return bidder, nil
+}
+
+func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+	requestJSON, err := json.Marshal(request)
+	if err != nil {
+		return nil, []error{err}
+	}
+
+	requestData := &adapters.RequestData{
+		Method: "POST",
+		Uri:    a.endpoint,
+		Body:   requestJSON,
+	}
+
+	return []*adapters.RequestData{requestData}, nil
+}
+
+func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+
+	if responseData.StatusCode == http.StatusNoContent {
+		return nil, nil
+	}
+
+	if responseData.StatusCode == http.StatusBadRequest {
+		return nil, []error{&errortypes.BadInput{
+			Message: fmt.Sprintf("Bad Request. %s", string(responseData.Body)),
+		}}
+	}
+
+	if responseData.StatusCode == http.StatusServiceUnavailable {
+		return nil, nil
+	}
+
+	if responseData.StatusCode != http.StatusOK {
+		return nil, []error{&errortypes.BadServerResponse{
+			Message: fmt.Sprintf("Something went wrong, please contact your Account Manager. Status Code: [ %d ] ", responseData.StatusCode),
+		}}
+	}
+
+	var response openrtb2.BidResponse
+	if err := json.Unmarshal(responseData.Body, &response); err != nil {
+		return nil, []error{&errortypes.BadServerResponse{
+			Message: fmt.Sprintf("Bad response, %s", err),
+		}}
+	}
+
+	if len(response.SeatBid) == 0 {
+		return nil, []error{&errortypes.BadServerResponse{
+			Message: "Empty seatbid",
+		}}
+	}
+
+	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
+	bidResponse.Currency = response.Cur
+	for _, seatBid := range response.SeatBid {
+		for i := range seatBid.Bid {
+			b := &adapters.TypedBid{
+				Bid:     &seatBid.Bid[i],
+				BidType: openrtb_ext.BidTypeVideo,
+			}
+			bidResponse.Bids = append(bidResponse.Bids, b)
+		}
+	}
+	return bidResponse, nil
+}
diff --git a/adapters/kargo/kargo.go b/adapters/kargo/kargo.go
new file mode 100644
index 00000000..8525d771
--- /dev/null
+++ b/adapters/kargo/kargo.go
@@ -0,0 +1,89 @@
+package kargo
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+
+	"github.com/mxmCherry/openrtb/v15/openrtb2"
+	"github.com/prebid/prebid-server/adapters"
+	"github.com/prebid/prebid-server/config"
+	"github.com/prebid/prebid-server/errortypes"
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+type adapter struct {
+	URI string
+}
+type kargoExt struct {
+	MediaType string `json:"mediaType"`
+}
+
+// Builder builds a new instance of the Kargo adapter for the given bidder with the given config.
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
+	bidder := &adapter{
+		URI: config.Endpoint, // base url of bidding server
+	}
+	return bidder, nil
+}
+
+// MakeRequests creates outgoing requests to the Kargo bidding server.
+func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+	requestJSON, err := json.Marshal(request)
+	if err != nil {
+		return nil, []error{err}
+	}
+
+	requestData := &adapters.RequestData{
+		Method: "POST",
+		Uri:    a.URI,
+		Body:   requestJSON,
+	}
+
+	return []*adapters.RequestData{requestData}, nil
+}
+
+// MakeBids receives a bid response from the Kargo bidding server and creates bids for the publishers auction.
+func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+	if responseData.StatusCode == http.StatusNoContent {
+		return nil, nil
+	}
+
+	if responseData.StatusCode != http.StatusOK {
+		err := &errortypes.BadServerResponse{
+			Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info.", responseData.StatusCode),
+		}
+		return nil, []error{err}
+	}
+
+	var response openrtb2.BidResponse
+	if err := json.Unmarshal(responseData.Body, &response); err != nil {
+		return nil, []error{err}
+	}
+
+	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
+	bidResponse.Currency = response.Cur
+	for _, seatBid := range response.SeatBid {
+		for i, bid := range seatBid.Bid {
+			b := &adapters.TypedBid{
+				Bid:     &seatBid.Bid[i],
+				BidType: getMediaTypeForBid(bid.Ext),
+			}
+			bidResponse.Bids = append(bidResponse.Bids, b)
+		}
+	}
+	return bidResponse, nil
+}
+
+func getMediaTypeForBid(ext json.RawMessage) openrtb_ext.BidType {
+	var impExt kargoExt
+	if err := json.Unmarshal(ext, &impExt); err == nil {
+		switch impExt.MediaType {
+		case string(openrtb_ext.BidTypeVideo):
+			return openrtb_ext.BidTypeVideo
+		case string(openrtb_ext.BidTypeNative):
+			return openrtb_ext.BidTypeNative
+		}
+	}
+	return openrtb_ext.BidTypeBanner
+}
diff --git a/config/config.go b/config/config.go
index a7a1af14..01c677fd 100644
--- a/config/config.go
+++ b/config/config.go
@@ -982,6 +982,7 @@ func SetupViper(v *viper.Viper, filename string) {
 	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")
@@ -1052,7 +1053,7 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("adapters.videobyte.endpoint", "https://x.videobyte.com/ortbhb")
 	v.SetDefault("adapters.vidoomy.endpoint", "https://p.vidoomy.com/api/rtbserver/pbs")
 	v.SetDefault("adapters.viewdeos.endpoint", "http://ghb.sync.viewdeos.com/pbs/ortb")
-	v.SetDefault("adapters.visx.endpoint", "https://t.visx.net/s2s_bid?wrapperType=s2s_prebid_standard:0.1.0")
+	v.SetDefault("adapters.visx.endpoint", "https://t.visx.net/s2s_bid?wrapperType=s2s_prebid_standard:0.1.1")
 	v.SetDefault("adapters.vrtcal.endpoint", "http://rtb.vrtcal.com/bidder_prebid.vap?ssp=1804")
 	v.SetDefault("adapters.yahoossp.endpoint", "https://s2shb.ssp.yahoo.com/admax/bid/partners/PBS")
 	v.SetDefault("adapters.yeahmobi.endpoint", "https://{{.Host}}/prebid/bid")
@@ -1061,6 +1062,7 @@ 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/auction.go b/endpoints/openrtb2/auction.go
index ffbd358a..645c2505 100644
--- a/endpoints/openrtb2/auction.go
+++ b/endpoints/openrtb2/auction.go
@@ -1259,6 +1259,8 @@ func isBidderToValidate(bidder string) bool {
 		return false
 	case openrtb_ext.BidderReservedSKAdN:
 		return false
+	case openrtb_ext.BidderReservedTID:
+		return false
 	default:
 		return true
 	}
diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go
index 5c7e04d4..6e51b3bb 100755
--- a/exchange/adapter_builders.go
+++ b/exchange/adapter_builders.go
@@ -69,12 +69,14 @@ import (
 	"github.com/prebid/prebid-server/adapters/huaweiads"
 	"github.com/prebid/prebid-server/adapters/impactify"
 	"github.com/prebid/prebid-server/adapters/improvedigital"
+	"github.com/prebid/prebid-server/adapters/infytv"
 	"github.com/prebid/prebid-server/adapters/inmobi"
 	"github.com/prebid/prebid-server/adapters/interactiveoffers"
 	"github.com/prebid/prebid-server/adapters/invibes"
 	"github.com/prebid/prebid-server/adapters/iqzone"
 	"github.com/prebid/prebid-server/adapters/ix"
 	"github.com/prebid/prebid-server/adapters/jixie"
+	"github.com/prebid/prebid-server/adapters/kargo"
 	"github.com/prebid/prebid-server/adapters/kayzen"
 	"github.com/prebid/prebid-server/adapters/kidoz"
 	"github.com/prebid/prebid-server/adapters/krushmedia"
@@ -222,6 +224,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderIx:                ix.Builder,
 		openrtb_ext.BidderJANet:             adtelligent.Builder,
 		openrtb_ext.BidderJixie:             jixie.Builder,
+		openrtb_ext.BidderKargo:             kargo.Builder,
 		openrtb_ext.BidderKayzen:            kayzen.Builder,
 		openrtb_ext.BidderKidoz:             kidoz.Builder,
 		openrtb_ext.BidderKrushmedia:        krushmedia.Builder,
@@ -294,5 +297,6 @@ 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 610a1587..f5beac98 100644
--- a/exchange/utils.go
+++ b/exchange/utils.go
@@ -421,6 +421,10 @@ func createSanitizedImpExt(impExt, impExtPrebid map[string]json.RawMessage) (map
 		sanitizedImpExt[openrtb_ext.GPIDKey] = v
 	}
 
+	if v, exists := impExt[string(openrtb_ext.TIDKey)]; exists {
+		sanitizedImpExt[openrtb_ext.TIDKey] = v
+	}
+
 	return sanitizedImpExt, nil
 }
 
@@ -451,7 +455,8 @@ func isSpecialField(bidder string) bool {
 		bidder == openrtb_ext.FirstPartyDataExtKey ||
 		bidder == openrtb_ext.SKAdNExtKey ||
 		bidder == openrtb_ext.GPIDKey ||
-		bidder == openrtb_ext.PrebidExtKey
+		bidder == openrtb_ext.PrebidExtKey ||
+		bidder == openrtb_ext.TIDKey
 }
 
 // prepareUser changes req.User so that it's ready for the given bidder.
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index 0b044da9..9eaa81ca 100644
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -35,6 +35,7 @@ const (
 	BidderReservedGPID    BidderName = "gpid"    // Reserved for Global Placement ID (GPID).
 	BidderReservedPrebid  BidderName = "prebid"  // Reserved for Prebid Server configuration.
 	BidderReservedSKAdN   BidderName = "skadn"   // Reserved for Apple's SKAdNetwork OpenRTB extension.
+	BidderReservedTID     BidderName = "tid"     // Reserved for Per-Impression Transactions IDs for Multi-Impression Bid Requests.
 )
 
 // IsBidderNameReserved returns true if the specified name is a case insensitive match for a reserved bidder name.
@@ -67,6 +68,10 @@ func IsBidderNameReserved(name string) bool {
 		return true
 	}
 
+	if strings.EqualFold(name, string(BidderReservedTID)) {
+		return true
+	}
+
 	return false
 }
 
@@ -152,6 +157,7 @@ const (
 	BidderIx                BidderName = "ix"
 	BidderJANet             BidderName = "janet"
 	BidderJixie             BidderName = "jixie"
+	BidderKargo             BidderName = "kargo"
 	BidderKayzen            BidderName = "kayzen"
 	BidderKidoz             BidderName = "kidoz"
 	BidderKrushmedia        BidderName = "krushmedia"
@@ -224,6 +230,7 @@ const (
 	BidderYieldone          BidderName = "yieldone"
 	BidderYSSP              BidderName = "yssp"
 	BidderZeroClickFraud    BidderName = "zeroclickfraud"
+	BidderInfyTV            BidderName = "infytv"
 )
 
 // CoreBidderNames returns a slice of all core bidders.
@@ -305,6 +312,7 @@ func CoreBidderNames() []BidderName {
 		BidderIx,
 		BidderJANet,
 		BidderJixie,
+		BidderKargo,
 		BidderKayzen,
 		BidderKidoz,
 		BidderKrushmedia,
@@ -377,6 +385,7 @@ func CoreBidderNames() []BidderName {
 		BidderYieldone,
 		BidderYSSP,
 		BidderZeroClickFraud,
+		BidderInfyTV,
 	}
 }
 
diff --git a/openrtb_ext/imp_infytv.go b/openrtb_ext/imp_infytv.go
new file mode 100644
index 00000000..b7307c42
--- /dev/null
+++ b/openrtb_ext/imp_infytv.go
@@ -0,0 +1,6 @@
+package openrtb_ext
+
+type ImpExtInfytv struct {
+	PlacementID string `json:"placementId"`
+	PublisherID string `json:"publisherId"`
+}
diff --git a/openrtb_ext/imp_kargo.go b/openrtb_ext/imp_kargo.go
new file mode 100644
index 00000000..682561fb
--- /dev/null
+++ b/openrtb_ext/imp_kargo.go
@@ -0,0 +1,5 @@
+package openrtb_ext
+
+type ImpExtKargo struct {
+	AdSlotID string `json:"adSlotID"`
+}
diff --git a/openrtb_ext/request.go b/openrtb_ext/request.go
index 3abda32e..33d168f6 100644
--- a/openrtb_ext/request.go
+++ b/openrtb_ext/request.go
@@ -17,6 +17,9 @@ const SKAdNExtKey = "skadn"
 // GPIDKey defines the field name within request.ext reserved for the Global Placement ID (GPID),
 const GPIDKey = "gpid"
 
+// TIDKey reserved for Per-Impression Transactions IDs for Multi-Impression Bid Requests.
+const TIDKey = "tid"
+
 // NativeExchangeSpecificLowerBound defines the lower threshold of exchange specific types for native ads. There is no upper bound.
 const NativeExchangeSpecificLowerBound = 500
 
diff --git a/static/bidder-info/infytv.yaml b/static/bidder-info/infytv.yaml
new file mode 100644
index 00000000..02a045ee
--- /dev/null
+++ b/static/bidder-info/infytv.yaml
@@ -0,0 +1,9 @@
+maintainer:
+  email: "tech+hb@infy.tv"
+capabilities:
+  app:
+    mediaTypes:
+      - video
+  site:
+    mediaTypes:
+      - video
diff --git a/static/bidder-info/kargo.yaml b/static/bidder-info/kargo.yaml
new file mode 100644
index 00000000..4acfd254
--- /dev/null
+++ b/static/bidder-info/kargo.yaml
@@ -0,0 +1,13 @@
+maintainer:
+  email: "kraken@kargo.com"
+gvlVendorID: 972
+modifyingVastXmlAllowed: true
+capabilities:
+  site:
+    mediaTypes:
+      - banner
+      - video
+      - native
+userSync:
+  supports:
+    - redirect
diff --git a/static/bidder-params/infytv.json b/static/bidder-params/infytv.json
new file mode 100644
index 00000000..22f9b317
--- /dev/null
+++ b/static/bidder-params/infytv.json
@@ -0,0 +1,19 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "title": "InfyTV Adapter Params",
+  "description": "A schema which validates params accepted by the InfyTV adapter",
+  "type": "object",
+  "properties": {
+    "publisherId": {
+      "type": "string",
+      "description": "publisher ID"
+    },
+    "placementId": {
+      "type": "string",
+      "description": "Placement ID"
+    }
+  },
+  "required": [
+    "publisherId"
+  ]
+}
\ No newline at end of file
diff --git a/static/bidder-params/kargo.json b/static/bidder-params/kargo.json
new file mode 100644
index 00000000..15c11526
--- /dev/null
+++ b/static/bidder-params/kargo.json
@@ -0,0 +1,15 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Kargo Adapter Params",
+    "description": "A schema which validates params accepted by the Kargo adapter",
+    "type": "object",
+  
+    "properties": {
+        "adSlotID": {
+          "type": "string",
+          "description": "An ID which identifies the adslot placement. Equivalent to the id of target inventory, ad unit code, or placement id"
+        }
+      },
+    
+    "required": ["adSlotID"]
+  }


Test patch:
diff --git a/adapters/infytv/infytv_test.go b/adapters/infytv/infytv_test.go
new file mode 100644
index 00000000..8ee2fe0e
--- /dev/null
+++ b/adapters/infytv/infytv_test.go
@@ -0,0 +1,18 @@
+package infytv
+
+import (
+	"testing"
+
+	"github.com/prebid/prebid-server/adapters/adapterstest"
+	"github.com/prebid/prebid-server/config"
+	"github.com/prebid/prebid-server/openrtb_ext"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestJsonSamples(t *testing.T) {
+	bidder, buildErr := Builder(openrtb_ext.BidderEVolution, config.Adapter{
+		Endpoint: "https://test.infy.tv/pbs/openrtb"})
+
+	assert.NoError(t, buildErr)
+	adapterstest.RunJSONBidderTest(t, "infytvtest", bidder)
+}
diff --git a/adapters/infytv/infytvtest/exemplary/app.json b/adapters/infytv/infytvtest/exemplary/app.json
new file mode 100644
index 00000000..d4426bf7
--- /dev/null
+++ b/adapters/infytv/infytvtest/exemplary/app.json
@@ -0,0 +1,258 @@
+{
+  "mockBidRequest": {
+    "id": "6d773e60ab245243a04217d5f7e9e786",
+    "imp": [
+      {
+        "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+        "video": {
+          "mimes": [
+            "video/mp4",
+            "video/ogg",
+            "video/webm"
+          ],
+          "minduration": 3,
+          "maxduration": 3000,
+          "protocols": [
+            2,
+            3,
+            5,
+            6,
+            7,
+            8
+          ],
+          "w": 480,
+          "h": 320,
+          "linearity": 1,
+          "playbackmethod": [
+            2
+          ],
+          "pos": 0
+        },
+        "bidfloor": 0.40404,
+        "bidfloorcur": "USD",
+        "secure": 1,
+        "exp": 3600,
+        "ext": {
+          "bidder": {
+            "publisherId": "IY1014",
+            "placementId": "1999"
+          }
+        }
+      }
+    ],
+    "app": {
+      "id": "AA88S0101",
+      "name": "Crunchyroll",
+      "bundle": "com.adrise.crunchyroll",
+      "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+      "cat": [
+        "IAB1"
+      ],
+      "privacypolicy": 1,
+      "publisher": {
+        "id": "IY1002",
+        "name": "The View Point",
+        "domain": "krushmedia.com"
+      },
+      "content": {
+        "language": "en"
+      }
+    },
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+      "geo": {
+        "lat": 20.6668,
+        "lon": -103.3918,
+        "accuracy": 5,
+        "country": "MEX",
+        "region": "JAL",
+        "zip": "45186"
+      },
+      "dnt": 0,
+      "lmt": 0,
+      "ip": "187.152.119.145",
+      "devicetype": 2,
+      "os": "Windows",
+      "osv": "10",
+      "carrier": "Telmex"
+    },
+    "test": 1,
+    "at": 1,
+    "tmax": 500,
+    "cur": [
+      "USD"
+    ],
+    "source": {
+      "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://test.infy.tv/pbs/openrtb",
+        "body": {
+          "id": "6d773e60ab245243a04217d5f7e9e786",
+          "imp": [
+            {
+              "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+              "video": {
+                "mimes": [
+                  "video/mp4",
+                  "video/ogg",
+                  "video/webm"
+                ],
+                "minduration": 3,
+                "maxduration": 3000,
+                "protocols": [
+                  2,
+                  3,
+                  5,
+                  6,
+                  7,
+                  8
+                ],
+                "w": 480,
+                "h": 320,
+                "linearity": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "pos": 0
+              },
+              "bidfloor": 0.40404,
+              "bidfloorcur": "USD",
+              "secure": 1,
+              "exp": 3600,
+              "ext": {
+                "bidder": {
+                  "publisherId": "IY1014",
+                  "placementId": "1999"
+                }
+              }
+            }
+          ],
+          "app": {
+            "id": "AA88S0101",
+            "name": "Crunchyroll",
+            "bundle": "com.adrise.crunchyroll",
+            "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+            "cat": [
+              "IAB1"
+            ],
+            "privacypolicy": 1,
+            "publisher": {
+              "id": "IY1002",
+              "name": "The View Point",
+              "domain": "krushmedia.com"
+            },
+            "content": {
+              "language": "en"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+            "geo": {
+              "lat": 20.6668,
+              "lon": -103.3918,
+              "accuracy": 5,
+              "country": "MEX",
+              "region": "JAL",
+              "zip": "45186"
+            },
+            "dnt": 0,
+            "lmt": 0,
+            "ip": "187.152.119.145",
+            "devicetype": 2,
+            "os": "Windows",
+            "osv": "10",
+            "carrier": "Telmex"
+          },
+          "test": 1,
+          "at": 1,
+          "tmax": 500,
+          "cur": [
+            "USD"
+          ],
+          "source": {
+            "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "6d773e60ab245243a04217d5f7e9e786",
+          "bidid": "ccbd63285c0e7b69602d90319bda6be4",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "7f6c6d6ba432059a5305815a8d740283",
+                  "impid": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+                  "price": 0.1,
+                  "nurl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}",
+                  "burl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=burl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}",
+                  "adm": "<VAST version=\"2.0\"><Ad id=\"20001\" sequence=\"1\" conditionalAd=\"false\"><InLine><AdSystem version=\"4.0\"><![CDATA[iabtechlab]]></AdSystem><AdTitle><![CDATA[Inline Simple Ad]]></AdTitle><Impression><![CDATA[https://s.funnel.e-volution.ai/2/623416/analytics.gif?dt=6234161617121529371000&di=kiwilimon.com&ui=&ap=&sr=-1&pp=866d6b3a4a483ed4a454a1acaa588852&ti=6d773e60ab245243a04217d5f7e9e786&md=2&de=2&si=1c94d85ea1a55ebf3325a82935240614&dm=480x320&gt=MX&ac=&pc=&cr=&pv=56d8a5f0-3872-4fa9-9f03-85cd17df2f1f&c1=1&c2=-1&cb=16220688009256611]]></Impression><Impression><![CDATA[https://s.funnel.e-volution.ai/2/623416/analytics.js?dt=6234161607645611134000&di=kiwilimon.com&ui=&ap=&sr=-1&pp=866d6b3a4a483ed4a454a1acaa588852&ti=6d773e60ab245243a04217d5f7e9e786&md=2&de=2&si=1c94d85ea1a55ebf3325a82935240614&dm=480x320&gt=MX&ac=&pc=&cr=&pv=56d8a5f0-3872-4fa9-9f03-85cd17df2f1f&c1=1&c2=-1&cb=16220688009256611]]></Impression><Impression><![CDATA[https://adrta.com/i?clid=vrl&paid=bidlab&dvid=v&avid=&caid=&plid=&publisherId=866d6b3a4a483ed4a454a1acaa588852&siteId=1c94d85ea1a55ebf3325a82935240614&priceBid=10.01000&pricePaid=&lineItemId=1&kv1=0x0&kv2=https%3A%2F%2Fkiwilimon.com%2F&kv3=&kv4=187.152.119.145&kv5=1622068800924671&kv7=-1&kv9=00%3A00%3A16&kv11=&kv12=&kv15=MEX&kv16=20.6668&kv17=-103.3918&kv18=&kv19=&kv23=Telmex&kv24=&kv25=&kv26=windows&kv27=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F88.0.4324.190%20Safari%2F537.36&kv28=&cb=1622068800924671&kv29=[ERRORCODE]&kv30=[CONTENTPLAYHEAD]_[ADPLAYHEAD]&kv33=[ASSETURI]&kv34=[VASTVERSIONS]&kv35=[IFATYPE]&kv36=[IFA]&kv37=[CLIENTUA]&kv38=[SERVERUA]&kv39=[DEVICEUA]&kv40=[DEVICEIP]&kv41=[LATLONG]&kv42=[DOMAIN]&kv43=[PAGEURL]&kv44=[VIDEO_TYPE]&kv45=[PLAYERSIZE]&kv46=[REGULATIONS]&kv47=[ADTYPE]&kv48=[TRANSACTIONID]&kv49=[BREAKPOSITION]&kv50=[APPNAME]&kv51=[PLACEMENTTYPE]]]></Impression><Impression><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=sync&gdpr=0&gdpr_consent=&ccpa_consent=]]></Impression><Impression><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=i&key=ccbd63285c0e7b69602d90319bda6be4&cp=${AUCTION_PRICE}]]></Impression><Creatives><Creative id=\"5480\" sequence=\"1\" adId=\"2447226\"><UniversalAdId idRegistry=\"Ad-ID\" idValue=\"8465\">8465</UniversalAdId><Linear><TrackingEvents></TrackingEvents><Duration>00:00:16</Duration><MediaFiles><MediaFile id=\"5241\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"2000\" width=\"1280\" height=\"720\" minBitrate=\"1500\" maxBitrate=\"2500\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro.mp4]]></MediaFile><MediaFile id=\"5244\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"1000\" width=\"854\" height=\"480\" minBitrate=\"700\" maxBitrate=\"1500\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro-mid-resolution.mp4]]></MediaFile><MediaFile id=\"5246\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"600\" width=\"640\" height=\"360\" minBitrate=\"500\" maxBitrate=\"700\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro-low-resolution.mp4]]></MediaFile></MediaFiles><VideoClicks><ClickThrough id=\"blog\"><![CDATA[https://iabtechlab.com]]></ClickThrough></VideoClicks></Linear></Creative></Creatives><Error><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}&ecode=[ERRORCODE]]]></Error></InLine></Ad></VAST>",
+                  "adomain": [
+                    "test.com"
+                  ],
+                  "cat": [
+                    "IAB24"
+                  ],
+                  "cid": "1IP31",
+                  "crid": "1KS13",
+                  "w": 0,
+                  "h": 0,
+                  "ext": {
+                    "mediaType": "video"
+                  }
+                }
+              ],
+              "seat": "1"
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "7f6c6d6ba432059a5305815a8d740283",
+            "impid": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+            "price": 0.1,
+            "nurl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}",
+            "burl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=burl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}",
+            "adm": "<VAST version=\"2.0\"><Ad id=\"20001\" sequence=\"1\" conditionalAd=\"false\"><InLine><AdSystem version=\"4.0\"><![CDATA[iabtechlab]]></AdSystem><AdTitle><![CDATA[Inline Simple Ad]]></AdTitle><Impression><![CDATA[https://s.funnel.e-volution.ai/2/623416/analytics.gif?dt=6234161617121529371000&di=kiwilimon.com&ui=&ap=&sr=-1&pp=866d6b3a4a483ed4a454a1acaa588852&ti=6d773e60ab245243a04217d5f7e9e786&md=2&de=2&si=1c94d85ea1a55ebf3325a82935240614&dm=480x320&gt=MX&ac=&pc=&cr=&pv=56d8a5f0-3872-4fa9-9f03-85cd17df2f1f&c1=1&c2=-1&cb=16220688009256611]]></Impression><Impression><![CDATA[https://s.funnel.e-volution.ai/2/623416/analytics.js?dt=6234161607645611134000&di=kiwilimon.com&ui=&ap=&sr=-1&pp=866d6b3a4a483ed4a454a1acaa588852&ti=6d773e60ab245243a04217d5f7e9e786&md=2&de=2&si=1c94d85ea1a55ebf3325a82935240614&dm=480x320&gt=MX&ac=&pc=&cr=&pv=56d8a5f0-3872-4fa9-9f03-85cd17df2f1f&c1=1&c2=-1&cb=16220688009256611]]></Impression><Impression><![CDATA[https://adrta.com/i?clid=vrl&paid=bidlab&dvid=v&avid=&caid=&plid=&publisherId=866d6b3a4a483ed4a454a1acaa588852&siteId=1c94d85ea1a55ebf3325a82935240614&priceBid=10.01000&pricePaid=&lineItemId=1&kv1=0x0&kv2=https%3A%2F%2Fkiwilimon.com%2F&kv3=&kv4=187.152.119.145&kv5=1622068800924671&kv7=-1&kv9=00%3A00%3A16&kv11=&kv12=&kv15=MEX&kv16=20.6668&kv17=-103.3918&kv18=&kv19=&kv23=Telmex&kv24=&kv25=&kv26=windows&kv27=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F88.0.4324.190%20Safari%2F537.36&kv28=&cb=1622068800924671&kv29=[ERRORCODE]&kv30=[CONTENTPLAYHEAD]_[ADPLAYHEAD]&kv33=[ASSETURI]&kv34=[VASTVERSIONS]&kv35=[IFATYPE]&kv36=[IFA]&kv37=[CLIENTUA]&kv38=[SERVERUA]&kv39=[DEVICEUA]&kv40=[DEVICEIP]&kv41=[LATLONG]&kv42=[DOMAIN]&kv43=[PAGEURL]&kv44=[VIDEO_TYPE]&kv45=[PLAYERSIZE]&kv46=[REGULATIONS]&kv47=[ADTYPE]&kv48=[TRANSACTIONID]&kv49=[BREAKPOSITION]&kv50=[APPNAME]&kv51=[PLACEMENTTYPE]]]></Impression><Impression><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=sync&gdpr=0&gdpr_consent=&ccpa_consent=]]></Impression><Impression><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=i&key=ccbd63285c0e7b69602d90319bda6be4&cp=${AUCTION_PRICE}]]></Impression><Creatives><Creative id=\"5480\" sequence=\"1\" adId=\"2447226\"><UniversalAdId idRegistry=\"Ad-ID\" idValue=\"8465\">8465</UniversalAdId><Linear><TrackingEvents></TrackingEvents><Duration>00:00:16</Duration><MediaFiles><MediaFile id=\"5241\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"2000\" width=\"1280\" height=\"720\" minBitrate=\"1500\" maxBitrate=\"2500\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro.mp4]]></MediaFile><MediaFile id=\"5244\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"1000\" width=\"854\" height=\"480\" minBitrate=\"700\" maxBitrate=\"1500\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro-mid-resolution.mp4]]></MediaFile><MediaFile id=\"5246\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"600\" width=\"640\" height=\"360\" minBitrate=\"500\" maxBitrate=\"700\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro-low-resolution.mp4]]></MediaFile></MediaFiles><VideoClicks><ClickThrough id=\"blog\"><![CDATA[https://iabtechlab.com]]></ClickThrough></VideoClicks></Linear></Creative></Creatives><Error><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}&ecode=[ERRORCODE]]]></Error></InLine></Ad></VAST>",
+            "adomain": [
+              "test.com"
+            ],
+            "cat": [
+              "IAB24"
+            ],
+            "cid": "1IP31",
+            "crid": "1KS13",
+            "ext": {
+              "mediaType": "video"
+            }
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/infytv/infytvtest/exemplary/video.json b/adapters/infytv/infytvtest/exemplary/video.json
new file mode 100644
index 00000000..7eb9c800
--- /dev/null
+++ b/adapters/infytv/infytvtest/exemplary/video.json
@@ -0,0 +1,280 @@
+{
+  "mockBidRequest": {
+    "id": "6d773e60ab245243a04217d5f7e9e786",
+    "imp": [
+      {
+        "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+        "video": {
+          "mimes": [
+            "video/mp4",
+            "video/ogg",
+            "video/webm"
+          ],
+          "minduration": 3,
+          "maxduration": 3000,
+          "protocols": [
+            2,
+            3,
+            5,
+            6,
+            7,
+            8
+          ],
+          "w": 480,
+          "h": 320,
+          "linearity": 1,
+          "playbackmethod": [
+            2
+          ],
+          "pos": 0
+        },
+        "bidfloor": 0.40404,
+        "bidfloorcur": "USD",
+        "secure": 1,
+        "exp": 3600,
+        "ext": {
+          "bidder": {
+            "publisherId": "IY1014",
+            "placementId": "1999"
+          }
+        }
+      }
+    ],
+    "site": {
+      "id": "1c94d85ea1a55ebf3325a82935240614",
+      "domain": "kiwilimon.com",
+      "cat": [
+        "IAB1",
+        "IAB2",
+        "IAB3",
+        "IAB4",
+        "IAB5",
+        "IAB6",
+        "IAB7",
+        "IAB8",
+        "IAB9",
+        "IAB10",
+        "IAB11",
+        "IAB13",
+        "IAB14",
+        "IAB15",
+        "IAB17",
+        "IAB18"
+      ],
+      "page": "https://kiwilimon.com/",
+      "publisher": {
+        "id": "866d6b3a4a483ed4a454a1acaa588852"
+      },
+      "ext": {
+        "amp": 0
+      }
+    },
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+      "geo": {
+        "lat": 20.6668,
+        "lon": -103.3918,
+        "accuracy": 5,
+        "country": "MEX",
+        "region": "JAL",
+        "zip": "45186"
+      },
+      "dnt": 0,
+      "lmt": 0,
+      "ip": "187.152.119.145",
+      "devicetype": 2,
+      "os": "Windows",
+      "osv": "10",
+      "carrier": "Telmex"
+    },
+    "test": 1,
+    "at": 1,
+    "tmax": 500,
+    "cur": [
+      "USD"
+    ],
+    "source": {
+      "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://test.infy.tv/pbs/openrtb",
+        "body": {
+          "id": "6d773e60ab245243a04217d5f7e9e786",
+          "imp": [
+            {
+              "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+              "video": {
+                "mimes": [
+                  "video/mp4",
+                  "video/ogg",
+                  "video/webm"
+                ],
+                "minduration": 3,
+                "maxduration": 3000,
+                "protocols": [
+                  2,
+                  3,
+                  5,
+                  6,
+                  7,
+                  8
+                ],
+                "w": 480,
+                "h": 320,
+                "linearity": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "pos": 0
+              },
+              "bidfloor": 0.40404,
+              "bidfloorcur": "USD",
+              "secure": 1,
+              "exp": 3600,
+              "ext": {
+                "bidder": {
+                  "publisherId": "IY1014",
+                  "placementId": "1999"
+                }
+              }
+            }
+          ],
+          "site": {
+            "id": "1c94d85ea1a55ebf3325a82935240614",
+            "domain": "kiwilimon.com",
+            "cat": [
+              "IAB1",
+              "IAB2",
+              "IAB3",
+              "IAB4",
+              "IAB5",
+              "IAB6",
+              "IAB7",
+              "IAB8",
+              "IAB9",
+              "IAB10",
+              "IAB11",
+              "IAB13",
+              "IAB14",
+              "IAB15",
+              "IAB17",
+              "IAB18"
+            ],
+            "page": "https://kiwilimon.com/",
+            "publisher": {
+              "id": "866d6b3a4a483ed4a454a1acaa588852"
+            },
+            "ext": {
+              "amp": 0
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+            "geo": {
+              "lat": 20.6668,
+              "lon": -103.3918,
+              "accuracy": 5,
+              "country": "MEX",
+              "region": "JAL",
+              "zip": "45186"
+            },
+            "dnt": 0,
+            "lmt": 0,
+            "ip": "187.152.119.145",
+            "devicetype": 2,
+            "os": "Windows",
+            "osv": "10",
+            "carrier": "Telmex"
+          },
+          "test": 1,
+          "at": 1,
+          "tmax": 500,
+          "cur": [
+            "USD"
+          ],
+          "source": {
+            "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "6d773e60ab245243a04217d5f7e9e786",
+          "bidid": "ccbd63285c0e7b69602d90319bda6be4",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "7f6c6d6ba432059a5305815a8d740283",
+                  "impid": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+                  "price": 0.1,
+                  "nurl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}",
+                  "burl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=burl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}",
+                  "adm": "<VAST version=\"2.0\"><Ad id=\"20001\" sequence=\"1\" conditionalAd=\"false\"><InLine><AdSystem version=\"4.0\"><![CDATA[iabtechlab]]></AdSystem><AdTitle><![CDATA[Inline Simple Ad]]></AdTitle><Impression><![CDATA[https://s.funnel.e-volution.ai/2/623416/analytics.gif?dt=6234161617121529371000&di=kiwilimon.com&ui=&ap=&sr=-1&pp=866d6b3a4a483ed4a454a1acaa588852&ti=6d773e60ab245243a04217d5f7e9e786&md=2&de=2&si=1c94d85ea1a55ebf3325a82935240614&dm=480x320&gt=MX&ac=&pc=&cr=&pv=56d8a5f0-3872-4fa9-9f03-85cd17df2f1f&c1=1&c2=-1&cb=16220688009256611]]></Impression><Impression><![CDATA[https://s.funnel.e-volution.ai/2/623416/analytics.js?dt=6234161607645611134000&di=kiwilimon.com&ui=&ap=&sr=-1&pp=866d6b3a4a483ed4a454a1acaa588852&ti=6d773e60ab245243a04217d5f7e9e786&md=2&de=2&si=1c94d85ea1a55ebf3325a82935240614&dm=480x320&gt=MX&ac=&pc=&cr=&pv=56d8a5f0-3872-4fa9-9f03-85cd17df2f1f&c1=1&c2=-1&cb=16220688009256611]]></Impression><Impression><![CDATA[https://adrta.com/i?clid=vrl&paid=bidlab&dvid=v&avid=&caid=&plid=&publisherId=866d6b3a4a483ed4a454a1acaa588852&siteId=1c94d85ea1a55ebf3325a82935240614&priceBid=10.01000&pricePaid=&lineItemId=1&kv1=0x0&kv2=https%3A%2F%2Fkiwilimon.com%2F&kv3=&kv4=187.152.119.145&kv5=1622068800924671&kv7=-1&kv9=00%3A00%3A16&kv11=&kv12=&kv15=MEX&kv16=20.6668&kv17=-103.3918&kv18=&kv19=&kv23=Telmex&kv24=&kv25=&kv26=windows&kv27=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F88.0.4324.190%20Safari%2F537.36&kv28=&cb=1622068800924671&kv29=[ERRORCODE]&kv30=[CONTENTPLAYHEAD]_[ADPLAYHEAD]&kv33=[ASSETURI]&kv34=[VASTVERSIONS]&kv35=[IFATYPE]&kv36=[IFA]&kv37=[CLIENTUA]&kv38=[SERVERUA]&kv39=[DEVICEUA]&kv40=[DEVICEIP]&kv41=[LATLONG]&kv42=[DOMAIN]&kv43=[PAGEURL]&kv44=[VIDEO_TYPE]&kv45=[PLAYERSIZE]&kv46=[REGULATIONS]&kv47=[ADTYPE]&kv48=[TRANSACTIONID]&kv49=[BREAKPOSITION]&kv50=[APPNAME]&kv51=[PLACEMENTTYPE]]]></Impression><Impression><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=sync&gdpr=0&gdpr_consent=&ccpa_consent=]]></Impression><Impression><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=i&key=ccbd63285c0e7b69602d90319bda6be4&cp=${AUCTION_PRICE}]]></Impression><Creatives><Creative id=\"5480\" sequence=\"1\" adId=\"2447226\"><UniversalAdId idRegistry=\"Ad-ID\" idValue=\"8465\">8465</UniversalAdId><Linear><TrackingEvents></TrackingEvents><Duration>00:00:16</Duration><MediaFiles><MediaFile id=\"5241\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"2000\" width=\"1280\" height=\"720\" minBitrate=\"1500\" maxBitrate=\"2500\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro.mp4]]></MediaFile><MediaFile id=\"5244\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"1000\" width=\"854\" height=\"480\" minBitrate=\"700\" maxBitrate=\"1500\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro-mid-resolution.mp4]]></MediaFile><MediaFile id=\"5246\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"600\" width=\"640\" height=\"360\" minBitrate=\"500\" maxBitrate=\"700\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro-low-resolution.mp4]]></MediaFile></MediaFiles><VideoClicks><ClickThrough id=\"blog\"><![CDATA[https://iabtechlab.com]]></ClickThrough></VideoClicks></Linear></Creative></Creatives><Error><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}&ecode=[ERRORCODE]]]></Error></InLine></Ad></VAST>",
+                  "adomain": [
+                    "test.com"
+                  ],
+                  "cat": [
+                    "IAB24"
+                  ],
+                  "cid": "1IP31",
+                  "crid": "1KS13",
+                  "w": 0,
+                  "h": 0,
+                  "ext": {
+                    "mediaType": "video"
+                  }
+                }
+              ],
+              "seat": "1"
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "7f6c6d6ba432059a5305815a8d740283",
+            "impid": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+            "price": 0.1,
+            "nurl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}",
+            "burl": "http://us-east-edge1.e-volution.ai/?c=rtb&m=burl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}",
+            "adm": "<VAST version=\"2.0\"><Ad id=\"20001\" sequence=\"1\" conditionalAd=\"false\"><InLine><AdSystem version=\"4.0\"><![CDATA[iabtechlab]]></AdSystem><AdTitle><![CDATA[Inline Simple Ad]]></AdTitle><Impression><![CDATA[https://s.funnel.e-volution.ai/2/623416/analytics.gif?dt=6234161617121529371000&di=kiwilimon.com&ui=&ap=&sr=-1&pp=866d6b3a4a483ed4a454a1acaa588852&ti=6d773e60ab245243a04217d5f7e9e786&md=2&de=2&si=1c94d85ea1a55ebf3325a82935240614&dm=480x320&gt=MX&ac=&pc=&cr=&pv=56d8a5f0-3872-4fa9-9f03-85cd17df2f1f&c1=1&c2=-1&cb=16220688009256611]]></Impression><Impression><![CDATA[https://s.funnel.e-volution.ai/2/623416/analytics.js?dt=6234161607645611134000&di=kiwilimon.com&ui=&ap=&sr=-1&pp=866d6b3a4a483ed4a454a1acaa588852&ti=6d773e60ab245243a04217d5f7e9e786&md=2&de=2&si=1c94d85ea1a55ebf3325a82935240614&dm=480x320&gt=MX&ac=&pc=&cr=&pv=56d8a5f0-3872-4fa9-9f03-85cd17df2f1f&c1=1&c2=-1&cb=16220688009256611]]></Impression><Impression><![CDATA[https://adrta.com/i?clid=vrl&paid=bidlab&dvid=v&avid=&caid=&plid=&publisherId=866d6b3a4a483ed4a454a1acaa588852&siteId=1c94d85ea1a55ebf3325a82935240614&priceBid=10.01000&pricePaid=&lineItemId=1&kv1=0x0&kv2=https%3A%2F%2Fkiwilimon.com%2F&kv3=&kv4=187.152.119.145&kv5=1622068800924671&kv7=-1&kv9=00%3A00%3A16&kv11=&kv12=&kv15=MEX&kv16=20.6668&kv17=-103.3918&kv18=&kv19=&kv23=Telmex&kv24=&kv25=&kv26=windows&kv27=Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F88.0.4324.190%20Safari%2F537.36&kv28=&cb=1622068800924671&kv29=[ERRORCODE]&kv30=[CONTENTPLAYHEAD]_[ADPLAYHEAD]&kv33=[ASSETURI]&kv34=[VASTVERSIONS]&kv35=[IFATYPE]&kv36=[IFA]&kv37=[CLIENTUA]&kv38=[SERVERUA]&kv39=[DEVICEUA]&kv40=[DEVICEIP]&kv41=[LATLONG]&kv42=[DOMAIN]&kv43=[PAGEURL]&kv44=[VIDEO_TYPE]&kv45=[PLAYERSIZE]&kv46=[REGULATIONS]&kv47=[ADTYPE]&kv48=[TRANSACTIONID]&kv49=[BREAKPOSITION]&kv50=[APPNAME]&kv51=[PLACEMENTTYPE]]]></Impression><Impression><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=sync&gdpr=0&gdpr_consent=&ccpa_consent=]]></Impression><Impression><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=i&key=ccbd63285c0e7b69602d90319bda6be4&cp=${AUCTION_PRICE}]]></Impression><Creatives><Creative id=\"5480\" sequence=\"1\" adId=\"2447226\"><UniversalAdId idRegistry=\"Ad-ID\" idValue=\"8465\">8465</UniversalAdId><Linear><TrackingEvents></TrackingEvents><Duration>00:00:16</Duration><MediaFiles><MediaFile id=\"5241\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"2000\" width=\"1280\" height=\"720\" minBitrate=\"1500\" maxBitrate=\"2500\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro.mp4]]></MediaFile><MediaFile id=\"5244\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"1000\" width=\"854\" height=\"480\" minBitrate=\"700\" maxBitrate=\"1500\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro-mid-resolution.mp4]]></MediaFile><MediaFile id=\"5246\" delivery=\"progressive\" type=\"video/mp4\" bitrate=\"600\" width=\"640\" height=\"360\" minBitrate=\"500\" maxBitrate=\"700\" scalable=\"1\" maintainAspectRatio=\"1\" codec=\"0\"><![CDATA[https://iab-publicfiles.s3.amazonaws.com/vast/VAST-4.0-Short-Intro-low-resolution.mp4]]></MediaFile></MediaFiles><VideoClicks><ClickThrough id=\"blog\"><![CDATA[https://iabtechlab.com]]></ClickThrough></VideoClicks></Linear></Creative></Creatives><Error><![CDATA[https://us-east-edge1.e-volution.ai/?c=rtb&m=nurl&auctionId=ccbd63285c0e7b69602d90319bda6be4&price=${AUCTION_PRICE}&ecode=[ERRORCODE]]]></Error></InLine></Ad></VAST>",
+            "adomain": [
+              "test.com"
+            ],
+            "cat": [
+              "IAB24"
+            ],
+            "cid": "1IP31",
+            "crid": "1KS13",
+            "ext": {
+              "mediaType": "video"
+            }
+          },
+          "type": "video"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/infytv/infytvtest/supplemental/bad-response.json b/adapters/infytv/infytvtest/supplemental/bad-response.json
new file mode 100644
index 00000000..5141cdca
--- /dev/null
+++ b/adapters/infytv/infytvtest/supplemental/bad-response.json
@@ -0,0 +1,202 @@
+{
+  "mockBidRequest": {
+    "id": "6d773e60ab245243a04217d5f7e9e786",
+    "imp": [
+      {
+        "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+        "video": {
+          "mimes": [
+            "video/mp4",
+            "video/ogg",
+            "video/webm"
+          ],
+          "minduration": 3,
+          "maxduration": 3000,
+          "protocols": [
+            2,
+            3,
+            5,
+            6,
+            7,
+            8
+          ],
+          "w": 480,
+          "h": 320,
+          "linearity": 1,
+          "playbackmethod": [
+            2
+          ],
+          "pos": 0
+        },
+        "bidfloor": 0.40404,
+        "bidfloorcur": "USD",
+        "secure": 1,
+        "exp": 3600,
+        "ext": {
+          "bidder": {
+            "key": "test_video"
+          }
+        }
+      }
+    ],
+    "app": {
+      "id": "AA88S0101",
+      "name": "Crunchyroll",
+      "bundle": "com.adrise.crunchyroll",
+      "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+      "cat": [
+        "IAB1"
+      ],
+      "privacypolicy": 1,
+      "publisher": {
+        "id": "IY1002",
+        "name": "The View Point",
+        "domain": "krushmedia.com"
+      },
+      "content": {
+        "language": "en"
+      }
+    },
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+      "geo": {
+        "lat": 20.6668,
+        "lon": -103.3918,
+        "accuracy": 5,
+        "country": "MEX",
+        "region": "JAL",
+        "zip": "45186"
+      },
+      "dnt": 0,
+      "lmt": 0,
+      "ip": "187.152.119.145",
+      "devicetype": 2,
+      "os": "Windows",
+      "osv": "10",
+      "carrier": "Telmex"
+    },
+    "test": 1,
+    "at": 1,
+    "tmax": 500,
+    "cur": [
+      "USD"
+    ],
+    "source": {
+      "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://test.infy.tv/pbs/openrtb",
+        "body": {
+          "id": "6d773e60ab245243a04217d5f7e9e786",
+          "imp": [
+            {
+              "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+              "video": {
+                "mimes": [
+                  "video/mp4",
+                  "video/ogg",
+                  "video/webm"
+                ],
+                "minduration": 3,
+                "maxduration": 3000,
+                "protocols": [
+                  2,
+                  3,
+                  5,
+                  6,
+                  7,
+                  8
+                ],
+                "w": 480,
+                "h": 320,
+                "linearity": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "pos": 0
+              },
+              "bidfloor": 0.40404,
+              "bidfloorcur": "USD",
+              "secure": 1,
+              "exp": 3600,
+              "ext": {
+                "bidder": {
+                  "key": "test_video"
+                }
+              }
+            }
+          ],
+          "app": {
+            "id": "AA88S0101",
+            "name": "Crunchyroll",
+            "bundle": "com.adrise.crunchyroll",
+            "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+            "cat": [
+              "IAB1"
+            ],
+            "privacypolicy": 1,
+            "publisher": {
+              "id": "IY1002",
+              "name": "The View Point",
+              "domain": "krushmedia.com"
+            },
+            "content": {
+              "language": "en"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+            "geo": {
+              "lat": 20.6668,
+              "lon": -103.3918,
+              "accuracy": 5,
+              "country": "MEX",
+              "region": "JAL",
+              "zip": "45186"
+            },
+            "dnt": 0,
+            "lmt": 0,
+            "ip": "187.152.119.145",
+            "devicetype": 2,
+            "os": "Windows",
+            "osv": "10",
+            "carrier": "Telmex"
+          },
+          "test": 1,
+          "at": 1,
+          "tmax": 500,
+          "cur": [
+            "USD"
+          ],
+          "source": {
+            "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": ""
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Bad response, json: cannot unmarshal string into Go value of type openrtb2.BidResponse",
+      "comparison": "literal"
+    }
+  ],
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/infytv/infytvtest/supplemental/empty-seatbid.json b/adapters/infytv/infytvtest/supplemental/empty-seatbid.json
new file mode 100644
index 00000000..0db426fc
--- /dev/null
+++ b/adapters/infytv/infytvtest/supplemental/empty-seatbid.json
@@ -0,0 +1,207 @@
+{
+  "mockBidRequest": {
+    "id": "6d773e60ab245243a04217d5f7e9e786",
+    "imp": [
+      {
+        "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+        "video": {
+          "mimes": [
+            "video/mp4",
+            "video/ogg",
+            "video/webm"
+          ],
+          "minduration": 3,
+          "maxduration": 3000,
+          "protocols": [
+            2,
+            3,
+            5,
+            6,
+            7,
+            8
+          ],
+          "w": 480,
+          "h": 320,
+          "linearity": 1,
+          "playbackmethod": [
+            2
+          ],
+          "pos": 0
+        },
+        "bidfloor": 0.40404,
+        "bidfloorcur": "USD",
+        "secure": 1,
+        "exp": 3600,
+        "ext": {
+          "bidder": {
+            "key": "test_video"
+          }
+        }
+      }
+    ],
+    "app": {
+      "id": "AA88S0101",
+      "name": "Crunchyroll",
+      "bundle": "com.adrise.crunchyroll",
+      "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+      "cat": [
+        "IAB1"
+      ],
+      "privacypolicy": 1,
+      "publisher": {
+        "id": "IY1002",
+        "name": "The View Point",
+        "domain": "krushmedia.com"
+      },
+      "content": {
+        "language": "en"
+      }
+    },
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+      "geo": {
+        "lat": 20.6668,
+        "lon": -103.3918,
+        "accuracy": 5,
+        "country": "MEX",
+        "region": "JAL",
+        "zip": "45186"
+      },
+      "dnt": 0,
+      "lmt": 0,
+      "ip": "187.152.119.145",
+      "devicetype": 2,
+      "os": "Windows",
+      "osv": "10",
+      "carrier": "Telmex"
+    },
+    "test": 1,
+    "at": 1,
+    "tmax": 500,
+    "cur": [
+      "USD"
+    ],
+    "source": {
+      "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://test.infy.tv/pbs/openrtb",
+        "body": {
+          "id": "6d773e60ab245243a04217d5f7e9e786",
+          "imp": [
+            {
+              "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+              "video": {
+                "mimes": [
+                  "video/mp4",
+                  "video/ogg",
+                  "video/webm"
+                ],
+                "minduration": 3,
+                "maxduration": 3000,
+                "protocols": [
+                  2,
+                  3,
+                  5,
+                  6,
+                  7,
+                  8
+                ],
+                "w": 480,
+                "h": 320,
+                "linearity": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "pos": 0
+              },
+              "bidfloor": 0.40404,
+              "bidfloorcur": "USD",
+              "secure": 1,
+              "exp": 3600,
+              "ext": {
+                "bidder": {
+                  "key": "test_video"
+                }
+              }
+            }
+          ],
+          "app": {
+            "id": "AA88S0101",
+            "name": "Crunchyroll",
+            "bundle": "com.adrise.crunchyroll",
+            "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+            "cat": [
+              "IAB1"
+            ],
+            "privacypolicy": 1,
+            "publisher": {
+              "id": "IY1002",
+              "name": "The View Point",
+              "domain": "krushmedia.com"
+            },
+            "content": {
+              "language": "en"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+            "geo": {
+              "lat": 20.6668,
+              "lon": -103.3918,
+              "accuracy": 5,
+              "country": "MEX",
+              "region": "JAL",
+              "zip": "45186"
+            },
+            "dnt": 0,
+            "lmt": 0,
+            "ip": "187.152.119.145",
+            "devicetype": 2,
+            "os": "Windows",
+            "osv": "10",
+            "carrier": "Telmex"
+          },
+          "test": 1,
+          "at": 1,
+          "tmax": 500,
+          "cur": [
+            "USD"
+          ],
+          "source": {
+            "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "a1580f2f-be6d-11eb-a150-d094662c1c35",
+          "bidid": "359da97d0384d8a14767029c18fd840d",
+          "seatbid": [],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Empty seatbid",
+      "comparison": "literal"
+    }
+  ],
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/infytv/infytvtest/supplemental/status-204.json b/adapters/infytv/infytvtest/supplemental/status-204.json
new file mode 100644
index 00000000..f432e241
--- /dev/null
+++ b/adapters/infytv/infytvtest/supplemental/status-204.json
@@ -0,0 +1,196 @@
+{
+  "mockBidRequest": {
+    "id": "6d773e60ab245243a04217d5f7e9e786",
+    "imp": [
+      {
+        "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+        "video": {
+          "mimes": [
+            "video/mp4",
+            "video/ogg",
+            "video/webm"
+          ],
+          "minduration": 3,
+          "maxduration": 3000,
+          "protocols": [
+            2,
+            3,
+            5,
+            6,
+            7,
+            8
+          ],
+          "w": 480,
+          "h": 320,
+          "linearity": 1,
+          "playbackmethod": [
+            2
+          ],
+          "pos": 0
+        },
+        "bidfloor": 0.40404,
+        "bidfloorcur": "USD",
+        "secure": 1,
+        "exp": 3600,
+        "ext": {
+          "bidder": {
+            "key": "test_video"
+          }
+        }
+      }
+    ],
+    "app": {
+      "id": "AA88S0101",
+      "name": "Crunchyroll",
+      "bundle": "com.adrise.crunchyroll",
+      "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+      "cat": [
+        "IAB1"
+      ],
+      "privacypolicy": 1,
+      "publisher": {
+        "id": "IY1002",
+        "name": "The View Point",
+        "domain": "krushmedia.com"
+      },
+      "content": {
+        "language": "en"
+      }
+    },
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+      "geo": {
+        "lat": 20.6668,
+        "lon": -103.3918,
+        "accuracy": 5,
+        "country": "MEX",
+        "region": "JAL",
+        "zip": "45186"
+      },
+      "dnt": 0,
+      "lmt": 0,
+      "ip": "187.152.119.145",
+      "devicetype": 2,
+      "os": "Windows",
+      "osv": "10",
+      "carrier": "Telmex"
+    },
+    "test": 1,
+    "at": 1,
+    "tmax": 500,
+    "cur": [
+      "USD"
+    ],
+    "source": {
+      "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://test.infy.tv/pbs/openrtb",
+        "body": {
+          "id": "6d773e60ab245243a04217d5f7e9e786",
+          "imp": [
+            {
+              "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+              "video": {
+                "mimes": [
+                  "video/mp4",
+                  "video/ogg",
+                  "video/webm"
+                ],
+                "minduration": 3,
+                "maxduration": 3000,
+                "protocols": [
+                  2,
+                  3,
+                  5,
+                  6,
+                  7,
+                  8
+                ],
+                "w": 480,
+                "h": 320,
+                "linearity": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "pos": 0
+              },
+              "bidfloor": 0.40404,
+              "bidfloorcur": "USD",
+              "secure": 1,
+              "exp": 3600,
+              "ext": {
+                "bidder": {
+                  "key": "test_video"
+                }
+              }
+            }
+          ],
+          "app": {
+            "id": "AA88S0101",
+            "name": "Crunchyroll",
+            "bundle": "com.adrise.crunchyroll",
+            "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+            "cat": [
+              "IAB1"
+            ],
+            "privacypolicy": 1,
+            "publisher": {
+              "id": "IY1002",
+              "name": "The View Point",
+              "domain": "krushmedia.com"
+            },
+            "content": {
+              "language": "en"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+            "geo": {
+              "lat": 20.6668,
+              "lon": -103.3918,
+              "accuracy": 5,
+              "country": "MEX",
+              "region": "JAL",
+              "zip": "45186"
+            },
+            "dnt": 0,
+            "lmt": 0,
+            "ip": "187.152.119.145",
+            "devicetype": 2,
+            "os": "Windows",
+            "osv": "10",
+            "carrier": "Telmex"
+          },
+          "test": 1,
+          "at": 1,
+          "tmax": 500,
+          "cur": [
+            "USD"
+          ],
+          "source": {
+            "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 204,
+        "body": {}
+      }
+    }
+  ],
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/infytv/infytvtest/supplemental/status-400.json b/adapters/infytv/infytvtest/supplemental/status-400.json
new file mode 100644
index 00000000..44d55575
--- /dev/null
+++ b/adapters/infytv/infytvtest/supplemental/status-400.json
@@ -0,0 +1,202 @@
+{
+  "mockBidRequest": {
+    "id": "6d773e60ab245243a04217d5f7e9e786",
+    "imp": [
+      {
+        "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+        "video": {
+          "mimes": [
+            "video/mp4",
+            "video/ogg",
+            "video/webm"
+          ],
+          "minduration": 3,
+          "maxduration": 3000,
+          "protocols": [
+            2,
+            3,
+            5,
+            6,
+            7,
+            8
+          ],
+          "w": 480,
+          "h": 320,
+          "linearity": 1,
+          "playbackmethod": [
+            2
+          ],
+          "pos": 0
+        },
+        "bidfloor": 0.40404,
+        "bidfloorcur": "USD",
+        "secure": 1,
+        "exp": 3600,
+        "ext": {
+          "bidder": {
+            "key": "test_video"
+          }
+        }
+      }
+    ],
+    "app": {
+      "id": "AA88S0101",
+      "name": "Crunchyroll",
+      "bundle": "com.adrise.crunchyroll",
+      "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+      "cat": [
+        "IAB1"
+      ],
+      "privacypolicy": 1,
+      "publisher": {
+        "id": "IY1002",
+        "name": "The View Point",
+        "domain": "krushmedia.com"
+      },
+      "content": {
+        "language": "en"
+      }
+    },
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+      "geo": {
+        "lat": 20.6668,
+        "lon": -103.3918,
+        "accuracy": 5,
+        "country": "MEX",
+        "region": "JAL",
+        "zip": "45186"
+      },
+      "dnt": 0,
+      "lmt": 0,
+      "ip": "187.152.119.145",
+      "devicetype": 2,
+      "os": "Windows",
+      "osv": "10",
+      "carrier": "Telmex"
+    },
+    "test": 1,
+    "at": 1,
+    "tmax": 500,
+    "cur": [
+      "USD"
+    ],
+    "source": {
+      "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://test.infy.tv/pbs/openrtb",
+        "body": {
+          "id": "6d773e60ab245243a04217d5f7e9e786",
+          "imp": [
+            {
+              "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+              "video": {
+                "mimes": [
+                  "video/mp4",
+                  "video/ogg",
+                  "video/webm"
+                ],
+                "minduration": 3,
+                "maxduration": 3000,
+                "protocols": [
+                  2,
+                  3,
+                  5,
+                  6,
+                  7,
+                  8
+                ],
+                "w": 480,
+                "h": 320,
+                "linearity": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "pos": 0
+              },
+              "bidfloor": 0.40404,
+              "bidfloorcur": "USD",
+              "secure": 1,
+              "exp": 3600,
+              "ext": {
+                "bidder": {
+                  "key": "test_video"
+                }
+              }
+            }
+          ],
+          "app": {
+            "id": "AA88S0101",
+            "name": "Crunchyroll",
+            "bundle": "com.adrise.crunchyroll",
+            "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+            "cat": [
+              "IAB1"
+            ],
+            "privacypolicy": 1,
+            "publisher": {
+              "id": "IY1002",
+              "name": "The View Point",
+              "domain": "krushmedia.com"
+            },
+            "content": {
+              "language": "en"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+            "geo": {
+              "lat": 20.6668,
+              "lon": -103.3918,
+              "accuracy": 5,
+              "country": "MEX",
+              "region": "JAL",
+              "zip": "45186"
+            },
+            "dnt": 0,
+            "lmt": 0,
+            "ip": "187.152.119.145",
+            "devicetype": 2,
+            "os": "Windows",
+            "osv": "10",
+            "carrier": "Telmex"
+          },
+          "test": 1,
+          "at": 1,
+          "tmax": 500,
+          "cur": [
+            "USD"
+          ],
+          "source": {
+            "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 400,
+        "body": "The Key has a different ad format"
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Bad Request. \"The Key has a different ad format\"",
+      "comparison": "literal"
+    }
+  ],
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/infytv/infytvtest/supplemental/status-503.json b/adapters/infytv/infytvtest/supplemental/status-503.json
new file mode 100644
index 00000000..310ad85e
--- /dev/null
+++ b/adapters/infytv/infytvtest/supplemental/status-503.json
@@ -0,0 +1,195 @@
+{
+  "mockBidRequest": {
+    "id": "6d773e60ab245243a04217d5f7e9e786",
+    "imp": [
+      {
+        "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+        "video": {
+          "mimes": [
+            "video/mp4",
+            "video/ogg",
+            "video/webm"
+          ],
+          "minduration": 3,
+          "maxduration": 3000,
+          "protocols": [
+            2,
+            3,
+            5,
+            6,
+            7,
+            8
+          ],
+          "w": 480,
+          "h": 320,
+          "linearity": 1,
+          "playbackmethod": [
+            2
+          ],
+          "pos": 0
+        },
+        "bidfloor": 0.40404,
+        "bidfloorcur": "USD",
+        "secure": 1,
+        "exp": 3600,
+        "ext": {
+          "bidder": {
+            "key": "test_video"
+          }
+        }
+      }
+    ],
+    "app": {
+      "id": "AA88S0101",
+      "name": "Crunchyroll",
+      "bundle": "com.adrise.crunchyroll",
+      "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+      "cat": [
+        "IAB1"
+      ],
+      "privacypolicy": 1,
+      "publisher": {
+        "id": "IY1002",
+        "name": "The View Point",
+        "domain": "krushmedia.com"
+      },
+      "content": {
+        "language": "en"
+      }
+    },
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+      "geo": {
+        "lat": 20.6668,
+        "lon": -103.3918,
+        "accuracy": 5,
+        "country": "MEX",
+        "region": "JAL",
+        "zip": "45186"
+      },
+      "dnt": 0,
+      "lmt": 0,
+      "ip": "187.152.119.145",
+      "devicetype": 2,
+      "os": "Windows",
+      "osv": "10",
+      "carrier": "Telmex"
+    },
+    "test": 1,
+    "at": 1,
+    "tmax": 500,
+    "cur": [
+      "USD"
+    ],
+    "source": {
+      "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://test.infy.tv/pbs/openrtb",
+        "body": {
+          "id": "6d773e60ab245243a04217d5f7e9e786",
+          "imp": [
+            {
+              "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+              "video": {
+                "mimes": [
+                  "video/mp4",
+                  "video/ogg",
+                  "video/webm"
+                ],
+                "minduration": 3,
+                "maxduration": 3000,
+                "protocols": [
+                  2,
+                  3,
+                  5,
+                  6,
+                  7,
+                  8
+                ],
+                "w": 480,
+                "h": 320,
+                "linearity": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "pos": 0
+              },
+              "bidfloor": 0.40404,
+              "bidfloorcur": "USD",
+              "secure": 1,
+              "exp": 3600,
+              "ext": {
+                "bidder": {
+                  "key": "test_video"
+                }
+              }
+            }
+          ],
+          "app": {
+            "id": "AA88S0101",
+            "name": "Crunchyroll",
+            "bundle": "com.adrise.crunchyroll",
+            "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+            "cat": [
+              "IAB1"
+            ],
+            "privacypolicy": 1,
+            "publisher": {
+              "id": "IY1002",
+              "name": "The View Point",
+              "domain": "krushmedia.com"
+            },
+            "content": {
+              "language": "en"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+            "geo": {
+              "lat": 20.6668,
+              "lon": -103.3918,
+              "accuracy": 5,
+              "country": "MEX",
+              "region": "JAL",
+              "zip": "45186"
+            },
+            "dnt": 0,
+            "lmt": 0,
+            "ip": "187.152.119.145",
+            "devicetype": 2,
+            "os": "Windows",
+            "osv": "10",
+            "carrier": "Telmex"
+          },
+          "test": 1,
+          "at": 1,
+          "tmax": 500,
+          "cur": [
+            "USD"
+          ],
+          "source": {
+            "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 503
+      }
+    }
+  ],
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/infytv/infytvtest/supplemental/unexpected-status.json b/adapters/infytv/infytvtest/supplemental/unexpected-status.json
new file mode 100644
index 00000000..bfb4b3f9
--- /dev/null
+++ b/adapters/infytv/infytvtest/supplemental/unexpected-status.json
@@ -0,0 +1,201 @@
+{
+  "mockBidRequest": {
+    "id": "6d773e60ab245243a04217d5f7e9e786",
+    "imp": [
+      {
+        "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+        "video": {
+          "mimes": [
+            "video/mp4",
+            "video/ogg",
+            "video/webm"
+          ],
+          "minduration": 3,
+          "maxduration": 3000,
+          "protocols": [
+            2,
+            3,
+            5,
+            6,
+            7,
+            8
+          ],
+          "w": 480,
+          "h": 320,
+          "linearity": 1,
+          "playbackmethod": [
+            2
+          ],
+          "pos": 0
+        },
+        "bidfloor": 0.40404,
+        "bidfloorcur": "USD",
+        "secure": 1,
+        "exp": 3600,
+        "ext": {
+          "bidder": {
+            "key": "test_video"
+          }
+        }
+      }
+    ],
+    "app": {
+      "id": "AA88S0101",
+      "name": "Crunchyroll",
+      "bundle": "com.adrise.crunchyroll",
+      "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+      "cat": [
+        "IAB1"
+      ],
+      "privacypolicy": 1,
+      "publisher": {
+        "id": "IY1002",
+        "name": "The View Point",
+        "domain": "krushmedia.com"
+      },
+      "content": {
+        "language": "en"
+      }
+    },
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+      "geo": {
+        "lat": 20.6668,
+        "lon": -103.3918,
+        "accuracy": 5,
+        "country": "MEX",
+        "region": "JAL",
+        "zip": "45186"
+      },
+      "dnt": 0,
+      "lmt": 0,
+      "ip": "187.152.119.145",
+      "devicetype": 2,
+      "os": "Windows",
+      "osv": "10",
+      "carrier": "Telmex"
+    },
+    "test": 1,
+    "at": 1,
+    "tmax": 500,
+    "cur": [
+      "USD"
+    ],
+    "source": {
+      "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+    },
+    "regs": {
+      "ext": {
+        "gdpr": 0
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://test.infy.tv/pbs/openrtb",
+        "body": {
+          "id": "6d773e60ab245243a04217d5f7e9e786",
+          "imp": [
+            {
+              "id": "bfb2dd46a5e63a0a84711c20fd8ce9e1",
+              "video": {
+                "mimes": [
+                  "video/mp4",
+                  "video/ogg",
+                  "video/webm"
+                ],
+                "minduration": 3,
+                "maxduration": 3000,
+                "protocols": [
+                  2,
+                  3,
+                  5,
+                  6,
+                  7,
+                  8
+                ],
+                "w": 480,
+                "h": 320,
+                "linearity": 1,
+                "playbackmethod": [
+                  2
+                ],
+                "pos": 0
+              },
+              "bidfloor": 0.40404,
+              "bidfloorcur": "USD",
+              "secure": 1,
+              "exp": 3600,
+              "ext": {
+                "bidder": {
+                  "key": "test_video"
+                }
+              }
+            }
+          ],
+          "app": {
+            "id": "AA88S0101",
+            "name": "Crunchyroll",
+            "bundle": "com.adrise.crunchyroll",
+            "storeurl": "https://channelstore.roku.com/details/d11368f0934f695ff350af56600d8ccb",
+            "cat": [
+              "IAB1"
+            ],
+            "privacypolicy": 1,
+            "publisher": {
+              "id": "IY1002",
+              "name": "The View Point",
+              "domain": "krushmedia.com"
+            },
+            "content": {
+              "language": "en"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36",
+            "geo": {
+              "lat": 20.6668,
+              "lon": -103.3918,
+              "accuracy": 5,
+              "country": "MEX",
+              "region": "JAL",
+              "zip": "45186"
+            },
+            "dnt": 0,
+            "lmt": 0,
+            "ip": "187.152.119.145",
+            "devicetype": 2,
+            "os": "Windows",
+            "osv": "10",
+            "carrier": "Telmex"
+          },
+          "test": 1,
+          "at": 1,
+          "tmax": 500,
+          "cur": [
+            "USD"
+          ],
+          "source": {
+            "tid": "42da74bc-88c5-40ea-8187-9070a34e8e10"
+          },
+          "regs": {
+            "ext": {
+              "gdpr": 0
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 401
+      }
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "Something went wrong, please contact your Account Manager. Status Code: [ 401 ] ",
+      "comparison": "literal"
+    }
+  ],
+  "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/infytv/params_test.go b/adapters/infytv/params_test.go
new file mode 100644
index 00000000..6719b102
--- /dev/null
+++ b/adapters/infytv/params_test.go
@@ -0,0 +1,44 @@
+package infytv
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+func TestValidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json schema. %v", err)
+	}
+
+	for _, p := range validParams {
+		if err := validator.Validate(openrtb_ext.BidderInfyTV, json.RawMessage(p)); err != nil {
+			t.Errorf("Schema rejected valid params: %s", p)
+		}
+	}
+}
+
+func TestInvalidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json schema. %v", err)
+	}
+
+	for _, p := range invalidParams {
+		if err := validator.Validate(openrtb_ext.BidderInfyTV, json.RawMessage(p)); err == nil {
+			t.Errorf("Schema allowed invalid params: %s", p)
+		}
+	}
+}
+
+var validParams = []string{
+	`{"publisherId": "1598991608990"}`,
+	`{"publisherId": "1598991608990", "placementId": "9999"}`,
+}
+
+var invalidParams = []string{
+	`{"publisherId": 42}`,
+	`{"publisherId": 42, "placementId":9898}`,
+}
diff --git a/adapters/kargo/kargo_test.go b/adapters/kargo/kargo_test.go
new file mode 100644
index 00000000..0936cfa4
--- /dev/null
+++ b/adapters/kargo/kargo_test.go
@@ -0,0 +1,20 @@
+package kargo
+
+import (
+	"testing"
+
+	"github.com/prebid/prebid-server/adapters/adapterstest"
+	"github.com/prebid/prebid-server/config"
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+func TestJsonSamples(t *testing.T) {
+	bidder, buildErr := Builder(openrtb_ext.BidderKargo, config.Adapter{
+		Endpoint: "http://example.com/bid"})
+
+	if buildErr != nil {
+		t.Fatalf("Builder returned unexpected error %v", buildErr)
+	}
+
+	adapterstest.RunJSONBidderTest(t, "kargotest", bidder)
+}
diff --git a/adapters/kargo/kargotest/exemplary/banner.json b/adapters/kargo/kargotest/exemplary/banner.json
new file mode 100644
index 00000000..db14ee8b
--- /dev/null
+++ b/adapters/kargo/kargotest/exemplary/banner.json
@@ -0,0 +1,207 @@
+{
+  "mockBidRequest": {
+    "id": "5f4d1e01",
+    "at": 1,
+    "imp": [
+      {
+        "id": "8b1bdcca",
+        "banner": {
+          "w": 300,
+          "h": 300,
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ],
+          "pos": 0,
+          "expdir": [1, 2, 3, 4, 5]
+        },
+        "tagid": "73",
+        "secure": 1,
+        "iframebuster": ["ALL"],
+        "ext": {
+          "adSlotID": "11523"
+        }
+      }
+    ],
+    "site": {
+      "id": "123",
+      "domain": "www.dailymail.co.uk",
+      "cat": ["IAB7"],
+      "page": "https://www.dailymail.co.uk/",
+      "ref": "https://www.dailymail.co.uk/",
+      "mobile": 1,
+      "publisher": {
+        "id": "1"
+      }
+    },
+    "device": {
+      "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.1 Safari/537",
+      "geo": {
+        "ipservice": 4,
+        "country": "US",
+        "region": "CO",
+        "metro": "751",
+        "city": "SomeCityInCo",
+        "zip": "11223"
+      },
+      "ip": "127.0.0.1",
+      "devicetype": 2,
+      "make": "Apple",
+      "model": "iPhone",
+      "os": "Windows",
+      "osv": "10.0",
+      "carrier": "none",
+      "language": "en",
+      "connectiontype": 2,
+      "dnt": 0
+    },
+    "user": {
+      "id": "07fb48ed",
+      "ext": {
+      },
+      "buyeruid": "345"
+    },
+    "regs": {
+      "ext": {
+        "us_privacy": "1"
+      }
+    },
+    "tmax": 200,
+    "ext": {
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://example.com/bid",
+        "body": {
+          "id": "5f4d1e01",
+          "at": 1,
+          "imp": [
+            {
+              "id": "8b1bdcca",
+              "banner": {
+                "w": 300,
+                "h": 300,
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 250
+                  }
+                ],
+                "pos": 0,
+                "expdir": [1, 2, 3, 4, 5]
+              },
+              "tagid": "73",
+              "secure": 1,
+              "iframebuster": ["ALL"],
+              "ext": {
+                "adSlotID": "11523"
+              }
+            }
+          ],
+          "site": {
+            "id": "123",
+            "domain": "www.dailymail.co.uk",
+            "cat": ["IAB7"],
+            "page": "https://www.dailymail.co.uk/",
+            "ref": "https://www.dailymail.co.uk/",
+            "mobile": 1,
+            "publisher": {
+              "id": "1"
+            }
+          },
+          "device": {
+            "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.1 Safari/537",
+            "geo": {
+              "ipservice": 4,
+              "country": "US",
+              "region": "CO",
+              "metro": "751",
+              "city": "SomeCityInCo",
+              "zip": "11223"
+            },
+            "ip": "127.0.0.1",
+            "devicetype": 2,
+            "make": "Apple",
+            "model": "iPhone",
+            "os": "Windows",
+            "osv": "10.0",
+            "carrier": "none",
+            "language": "en",
+            "connectiontype": 2,
+            "dnt": 0
+          },
+          "user": {
+            "id": "07fb48ed",
+            "ext": {
+            },
+            "buyeruid": "345"
+          },
+          "regs": {
+            "ext": {
+              "us_privacy": "1"
+            }
+          },
+          "tmax": 200,
+          "ext": {
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "5f4d1e01",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "67sadsac",
+                  "impid": "8b1bdcca",
+                  "price": 10,
+                  "nurl": "http://example.com/win/10",
+                  "adm": "<div>ad</div>",
+                  "adomain": ["example.com"],
+                  "cid": "test-cid",
+                  "crid": "test-crid",
+                  "cat": ["IAB13"],
+                  "w": 300,
+                  "h": 300,
+                  "ext": {"mediaType": "banner"}
+                }
+              ],
+              "seat": "_b345"
+            }
+          ],
+          "bidid": "67sadsac",
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "bids": [
+        {
+          "bid": {
+            "id": "67sadsac",
+            "impid": "8b1bdcca",
+            "price": 10,
+            "nurl": "http://example.com/win/10",
+            "adm": "<div>ad</div>",
+            "adomain": ["example.com"],
+            "cid": "test-cid",
+            "crid": "test-crid",
+            "cat": ["IAB13"],
+            "w": 300,
+            "h": 300,
+            "ext": {"mediaType": "banner"}
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/kargo/kargotest/exemplary/native.json b/adapters/kargo/kargotest/exemplary/native.json
new file mode 100644
index 00000000..d0f03d61
--- /dev/null
+++ b/adapters/kargo/kargotest/exemplary/native.json
@@ -0,0 +1,220 @@
+{
+    "mockBidRequest": {
+      "id": "5f4d1e01",
+      "at": 1,
+      "imp": [
+          {
+              "id": "8b1bdcca",
+              "banner": {
+                  "w": 300,
+                  "h": 300,
+                  "format": [
+                      {
+                          "w": 300,
+                          "h": 250
+                      }
+                  ],
+                  "pos": 0,
+                  "expdir": [1,2,3,4,5]
+              },
+              "native": {
+                  "request" : "{\"plcmttype\":2,\"privacy\":0,\"assets\":[{\"id\":5,\"required\":0,\"title\":{\"len\":90}},{\"id\":6,\"required\":0,\"img\":{\"wmin\":620,\"hmin\":300,\"type\":3}},{\"id\":10,\"required\":0,\"data\":{\"len\":90,\"type\":1}},{\"id\":8,\"required\":0,\"data\":{\"len\":14,\"type\":12}},{\"id\":7,\"required\":0,\"img\":{\"wmin\":80,\"hmin\":80,\"type\":1}},{\"id\":11,\"required\":0,\"data\":{\"len\":140,\"type\":2}}]}"
+              },
+              "tagid": "73",
+              "secure": 1,
+              "iframebuster": [
+                  "ALL"
+              ],
+              "ext": {
+                "adSlotID": "11523"
+              }
+          }
+      ],
+      "site": {
+          "id": "123",
+          "domain": "www.dailymail.co.uk",
+          "cat": ["IAB7"],
+          "page": "https://www.dailymail.co.uk/",
+          "ref": "https://www.dailymail.co.uk/",
+          "mobile": 1,
+          "publisher": {
+              "id": "1"
+          }
+      },
+      "device": {
+          "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.1 Safari/537",
+          "geo": {
+              "ipservice": 4,
+              "country": "US",
+              "region": "CO",
+              "metro": "751",
+              "city": "Ft Collins",
+              "zip": "80524"
+          },
+          "ip": "127.0.0.1",
+          "devicetype": 2,
+          "make": "Apple",
+          "model": "iPhone",
+          "os": "Windows",
+          "osv": "10.0",
+          "carrier": "none",
+          "language": "en",
+          "connectiontype": 2,
+          "dnt": 0
+      },
+      "user": {
+          "id": "07fb48ed",
+          "ext": {
+          },
+          "buyeruid": "345"
+      },
+      "regs": {
+          "ext": {
+              "us_privacy": "1"
+          }
+      },
+      "tmax": 200,
+      "ext": {
+      }
+  }
+  ,
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "uri": "http://example.com/bid",
+          "body": {
+            "id": "5f4d1e01",
+            "at": 1,
+            "imp": [
+                {
+                    "id": "8b1bdcca",
+                    "banner": {
+                        "w": 300,
+                        "h": 300,
+                        "format": [
+                            {
+                                "w": 300,
+                                "h": 250
+                            }
+                        ],
+                        "pos": 0,
+                        "expdir": [1,2,3,4,5]
+                    },
+                    "native": {
+                        "request" : "{\"plcmttype\":2,\"privacy\":0,\"assets\":[{\"id\":5,\"required\":0,\"title\":{\"len\":90}},{\"id\":6,\"required\":0,\"img\":{\"wmin\":620,\"hmin\":300,\"type\":3}},{\"id\":10,\"required\":0,\"data\":{\"len\":90,\"type\":1}},{\"id\":8,\"required\":0,\"data\":{\"len\":14,\"type\":12}},{\"id\":7,\"required\":0,\"img\":{\"wmin\":80,\"hmin\":80,\"type\":1}},{\"id\":11,\"required\":0,\"data\":{\"len\":140,\"type\":2}}]}"
+                    },
+                    "tagid": "73",
+                    "secure": 1,
+                    "iframebuster": [
+                        "ALL"
+                    ],
+                    "ext": {
+                      "adSlotID": "11523"
+                    }
+                }
+            ],
+            "site": {
+                "id": "123",
+                "domain": "www.dailymail.co.uk",
+                "cat": ["IAB7"],
+                "page": "https://www.dailymail.co.uk/",
+                "ref": "https://www.dailymail.co.uk/",
+                "mobile": 1,
+                "publisher": {
+                    "id": "1"
+                }
+            },
+            "device": {
+                "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.1 Safari/537",
+                "geo": {
+                    "ipservice": 4,
+                    "country": "US",
+                    "region": "CO",
+                    "metro": "751",
+                    "city": "Ft Collins",
+                    "zip": "80524"
+                },
+                "ip": "127.0.0.1",
+                "devicetype": 2,
+                "make": "Apple",
+                "model": "iPhone",
+                "os": "Windows",
+                "osv": "10.0",
+                "carrier": "none",
+                "language": "en",
+                "connectiontype": 2,
+                "dnt": 0
+            },
+            "user": {
+                "id": "07fb48ed",
+                "ext": {
+                },
+                "buyeruid": "345"
+            },
+            "regs": {
+                "ext": {
+                    "us_privacy": "1"
+                }
+            },
+            "tmax": 200,
+            "ext": {
+            }
+          }
+        },
+        "mockResponse": {
+            "status": 200,
+            "body": {
+              "id": "5f4d1e01",
+              "seatbid": [
+                {
+                  "bid": [
+                    {
+                      "id": "67sadsac",
+                      "impid": "8b1bdcca",
+                      "price": 10,
+                      "nurl": "http://example.com/win/10",
+                      "adm": "<div>ad</div>",
+                      "adomain": ["example.com"],
+                      "cid": "test-cid",
+                      "crid": "test-crid",
+                      "cat": ["IAB13"],
+                      "w": 300,
+                      "h": 300,
+                      "ext": {"mediaType": "native"}
+                    }
+                  ],
+                  "seat": "_b345"
+                }
+              ],
+              "bidid": "67sadsac",
+              "cur": "USD"
+            }
+          }
+        }
+      ],
+      "expectedBidResponses": [
+        {
+          "currency": "USD",
+          "bids": [
+            {
+              "bid": {
+                "id": "67sadsac",
+                "impid": "8b1bdcca",
+                "price": 10,
+                "nurl": "http://example.com/win/10",
+                "adm": "<div>ad</div>",
+                "adomain": ["example.com"],
+                "cid": "test-cid",
+                "crid": "test-crid",
+                "cat": ["IAB13"],
+                "w": 300,
+                "h": 300,
+                "ext": {"mediaType": "native"}
+              },
+              "type": "native"
+            }
+          ]
+        }
+      ]
+    }
+    
\ No newline at end of file
diff --git a/adapters/kargo/kargotest/exemplary/video.json b/adapters/kargo/kargotest/exemplary/video.json
new file mode 100644
index 00000000..92a21249
--- /dev/null
+++ b/adapters/kargo/kargotest/exemplary/video.json
@@ -0,0 +1,224 @@
+{
+    "mockBidRequest": {
+      "id": "5f4d1e01",
+      "at": 1,
+      "imp": [
+          {
+              "id": "8b1bdcca",
+              "banner": {
+                  "w": 300,
+                  "h": 300,
+                  "format": [
+                      {
+                          "w": 300,
+                          "h": 250
+                      }
+                  ],
+                  "pos": 0,
+                  "expdir": [1,2,3,4,5]
+              },
+              "video": {
+                 "mimes": null, 
+                  "skip":0,
+                  "playbackmethod":[2]
+              },
+              "tagid": "73",
+              "secure": 1,
+              "iframebuster": [
+                  "ALL"
+              ],
+              "ext": {
+                "adSlotID": "11523"
+              }
+          }
+      ],
+      "site": {
+          "id": "123",
+          "domain": "www.dailymail.co.uk",
+          "cat": ["IAB7"],
+          "page": "https://www.dailymail.co.uk/",
+          "ref": "https://www.dailymail.co.uk/",
+          "mobile": 1,
+          "publisher": {
+              "id": "1"
+          }
+      },
+      "device": {
+          "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.1 Safari/537",
+          "geo": {
+              "ipservice": 4,
+              "country": "US",
+              "region": "CO",
+              "metro": "751",
+              "city": "Ft Collins",
+              "zip": "80524"
+          },
+          "ip": "127.0.0.1",
+          "devicetype": 2,
+          "make": "Apple",
+          "model": "iPhone",
+          "os": "Windows",
+          "osv": "10.0",
+          "carrier": "none",
+          "language": "en",
+          "connectiontype": 2,
+          "dnt": 0
+      },
+      "user": {
+          "id": "07fb48ed",
+          "ext": {
+          },
+          "buyeruid": "345"
+      },
+      "regs": {
+          "ext": {
+              "us_privacy": "1"
+          }
+      },
+      "tmax": 200,
+      "ext": {
+      }
+  }
+  ,
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "uri": "http://example.com/bid",
+          "body": {
+            "id": "5f4d1e01",
+      "at": 1,
+      "imp": [
+          {
+              "id": "8b1bdcca",
+              "banner": {
+                  "w": 300,
+                  "h": 300,
+                  "format": [
+                      {
+                          "w": 300,
+                          "h": 250
+                      }
+                  ],
+                  "pos": 0,
+                  "expdir": [1,2,3,4,5]
+              },
+              "video": {
+                 "mimes": null, 
+                  "skip":0,
+                  "playbackmethod":[2]
+              },
+              "tagid": "73",
+              "secure": 1,
+              "iframebuster": [
+                  "ALL"
+              ],
+              "ext": {
+                "adSlotID": "11523"
+              }
+          }
+      ],
+      "site": {
+          "id": "123",
+          "domain": "www.dailymail.co.uk",
+          "cat": ["IAB7"],
+          "page": "https://www.dailymail.co.uk/",
+          "ref": "https://www.dailymail.co.uk/",
+          "mobile": 1,
+          "publisher": {
+              "id": "1"
+          }
+      },
+      "device": {
+          "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.1 Safari/537",
+          "geo": {
+              "ipservice": 4,
+              "country": "US",
+              "region": "CO",
+              "metro": "751",
+              "city": "Ft Collins",
+              "zip": "80524"
+          },
+          "ip": "127.0.0.1",
+          "devicetype": 2,
+          "make": "Apple",
+          "model": "iPhone",
+          "os": "Windows",
+          "osv": "10.0",
+          "carrier": "none",
+          "language": "en",
+          "connectiontype": 2,
+          "dnt": 0
+      },
+      "user": {
+          "id": "07fb48ed",
+          "ext": {
+          },
+          "buyeruid": "345"
+      },
+      "regs": {
+          "ext": {
+              "us_privacy": "1"
+          }
+      },
+      "tmax": 200,
+      "ext": {
+      }
+          }
+        },
+        "mockResponse": {
+            "status": 200,
+            "body": {
+              "id": "5f4d1e01",
+              "seatbid": [
+                {
+                  "bid": [
+                    {
+                      "id": "67sadsac",
+                      "impid": "8b1bdcca",
+                      "price": 10,
+                      "nurl": "http://example.com/win/10",
+                      "adm": "<div>ad</div>",
+                      "adomain": ["example.com"],
+                      "cid": "test-cid",
+                      "crid": "test-crid",
+                      "cat": ["IAB13"],
+                      "w": 300,
+                      "h": 300,
+                      "ext": {"mediaType": "video"}
+                    }
+                  ],
+                  "seat": "_b345"
+                }
+              ],
+              "bidid": "67sadsac",
+              "cur": "USD"
+            }
+          }
+        }
+      ],
+      "expectedBidResponses": [
+        {
+          "currency": "USD",
+          "bids": [
+            {
+              "bid": {
+                "id": "67sadsac",
+                "impid": "8b1bdcca",
+                "price": 10,
+                "nurl": "http://example.com/win/10",
+                "adm": "<div>ad</div>",
+                "adomain": ["example.com"],
+                "cid": "test-cid",
+                "crid": "test-crid",
+                "cat": ["IAB13"],
+                "w": 300,
+                "h": 300,
+                "ext": {"mediaType": "video"}
+              },
+              "type": "video"
+            }
+          ]
+        }
+      ]
+    }
+    
\ No newline at end of file
diff --git a/adapters/kargo/kargotest/supplemental/status-bad-request.json b/adapters/kargo/kargotest/supplemental/status-bad-request.json
new file mode 100644
index 00000000..3cb98431
--- /dev/null
+++ b/adapters/kargo/kargotest/supplemental/status-bad-request.json
@@ -0,0 +1,36 @@
+{
+    "mockBidRequest": {
+      "id": "5f4d1e01",
+      "at": 1,
+      "imp": [
+      ],
+      "tmax": 200
+    },
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "uri": "http://example.com/bid",
+          "body": {
+            "id": "5f4d1e01",
+            "at": 1,
+            "imp": [
+            ],
+            "tmax": 200
+          }
+        },
+        "mockResponse": {
+          "status": 400,
+          "body": {
+          }
+        }
+      }
+    ],
+    "expectedBidResponses": [],
+    "expectedMakeBidsErrors": [
+      {
+        "value": "Unexpected status code: 400. Run with request.debug = 1 for more info.",
+        "comparison": "literal"
+      }
+    ]
+  }
+  
\ No newline at end of file
diff --git a/adapters/kargo/kargotest/supplemental/status-no-content.json b/adapters/kargo/kargotest/supplemental/status-no-content.json
new file mode 100644
index 00000000..8c6e0544
--- /dev/null
+++ b/adapters/kargo/kargotest/supplemental/status-no-content.json
@@ -0,0 +1,130 @@
+{
+  "mockBidRequest": {
+    "id": "5f4d1e01",
+    "at": 1,
+    "imp": [
+      {
+        "id": "8b1bdcca",
+        "banner": {
+          "w": 300,
+          "h": 300,
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ],
+          "pos": 0,
+          "expdir": [1, 2, 3, 4, 5]
+        },
+        "video": {
+          "mimes": null
+        },
+        "native": {
+          "request": ""
+        },
+        "pmp": {
+        },
+        "tagid": "73",
+        "secure": 1,
+        "iframebuster": ["ALL"],
+        "ext": {}
+      }
+    ],
+    "site": {
+      "id": "123",
+      "domain": "www.dailymail.co.uk",
+      "cat": ["IAB7"],
+      "page": "https://www.dailymail.co.uk/",
+      "ref": "https://www.dailymail.co.uk/",
+      "mobile": 1,
+      "publisher": {
+        "id": "1"
+      }
+    },
+    "user": {
+      "id": "07fb48ed",
+      "ext": {
+        "consent": "consent opt-out"
+      },
+      "buyeruid": "345"
+    },
+    "regs": {
+      "ext": {
+        "us_privacy": "1"
+      }
+    },
+    "tmax": 200,
+    "ext": {}
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://example.com/bid",
+        "body": {
+          "id": "5f4d1e01",
+          "at": 1,
+          "imp": [
+            {
+              "id": "8b1bdcca",
+              "banner": {
+                "w": 300,
+                "h": 300,
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 250
+                  }
+                ],
+                "pos": 0,
+                "expdir": [1, 2, 3, 4, 5]
+              },
+              "video": {
+                "mimes": null
+              },
+              "native": {
+                "request": ""
+              },
+              "pmp": {
+              },
+              "tagid": "73",
+              "secure": 1,
+              "iframebuster": ["ALL"],
+              "ext": {}
+            }
+          ],
+          "site": {
+            "id": "123",
+            "domain": "www.dailymail.co.uk",
+            "cat": ["IAB7"],
+            "page": "https://www.dailymail.co.uk/",
+            "ref": "https://www.dailymail.co.uk/",
+            "mobile": 1,
+            "publisher": {
+              "id": "1"
+            }
+          },
+          "user": {
+            "id": "07fb48ed",
+            "ext": {
+              "consent": "consent opt-out"
+            },
+            "buyeruid": "345"
+          },
+          "regs": {
+            "ext": {
+              "us_privacy": "1"
+            }
+          },
+          "tmax": 200,
+          "ext": {}
+        }
+      },
+      "mockResponse": {
+        "status": 204,
+        "body": {}
+      }
+    }
+  ],
+  "expectedBidResponses": []
+}
diff --git a/adapters/kargo/params_test.go b/adapters/kargo/params_test.go
new file mode 100644
index 00000000..44937637
--- /dev/null
+++ b/adapters/kargo/params_test.go
@@ -0,0 +1,47 @@
+package kargo
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+func TestValidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json schema. %v", err)
+	}
+
+	for _, p := range validParams {
+		if err := validator.Validate(openrtb_ext.BidderKargo, json.RawMessage(p)); err != nil {
+			t.Errorf("Schema rejected valid params: %s", p)
+		}
+	}
+}
+
+func TestInvalidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json schema. %v", err)
+	}
+
+	for _, p := range invalidParams {
+		if err := validator.Validate(openrtb_ext.BidderKargo, json.RawMessage(p)); err == nil {
+			t.Errorf("Schema allowed invalid params: %s", p)
+		}
+	}
+}
+
+var validParams = []string{
+	`{"adSlotID": ""}`,
+	`{"adSlotID": "11523"}`,
+}
+
+var invalidParams = []string{
+	`{"adSlotID": 42}`,
+	`{"adSlotID": }`,
+	`{"adSlotId": "32321"}`,
+	`{"id": }`,
+	`{}`,
+}
diff --git a/exchange/utils_test.go b/exchange/utils_test.go
index dd51b3b3..629f0369 100644
--- a/exchange/utils_test.go
+++ b/exchange/utils_test.go
@@ -354,6 +354,7 @@ func TestCreateSanitizedImpExt(t *testing.T) {
 				"context":   json.RawMessage(`"anyContext"`),
 				"skadn":     json.RawMessage(`"anySKAdNetwork"`),
 				"gpid":      json.RawMessage(`"anyGPID"`),
+				"tid":       json.RawMessage(`"anyTID"`),
 			},
 			givenImpExtPrebid: map[string]json.RawMessage{
 				"bidder":    json.RawMessage(`"anyBidder"`),
@@ -365,6 +366,7 @@ func TestCreateSanitizedImpExt(t *testing.T) {
 				"context": json.RawMessage(`"anyContext"`),
 				"skadn":   json.RawMessage(`"anySKAdNetwork"`),
 				"gpid":    json.RawMessage(`"anyGPID"`),
+				"tid":     json.RawMessage(`"anyTID"`),
 			},
 			expectedError: "",
 		},
@@ -434,7 +436,7 @@ func TestExtractBidderExts(t *testing.T) {
 		},
 		{
 			description:              "Special Names Ignored - imp.ext.BIDDER",
-			givenImpExt:              map[string]json.RawMessage{"prebid": json.RawMessage(`{"prebid":"value1"}}`), "context": json.RawMessage(`{"firstPartyData":"value2"}}`), "skadn": json.RawMessage(`{"skAdNetwork":"value3"}}`), "gpid": json.RawMessage(`{"gpid":"value4"}}`)},
+			givenImpExt:              map[string]json.RawMessage{"prebid": json.RawMessage(`{"prebid":"value1"}}`), "context": json.RawMessage(`{"firstPartyData":"value2"}}`), "skadn": json.RawMessage(`{"skAdNetwork":"value3"}}`), "gpid": json.RawMessage(`{"gpid":"value4"}}`), "tid": json.RawMessage("6e927474-4c83-40ac-8180-16858314b7c5")},
 			givenImpExtPrebidBidders: map[string]json.RawMessage{},
 			expected:                 map[string]json.RawMessage{},
 		},
diff --git a/openrtb_ext/bidders_test.go b/openrtb_ext/bidders_test.go
index 056223e2..f95d4a36 100644
--- a/openrtb_ext/bidders_test.go
+++ b/openrtb_ext/bidders_test.go
@@ -113,6 +113,10 @@ func TestIsBidderNameReserved(t *testing.T) {
 		{"skadn", true},
 		{"skADN", true},
 		{"SKADN", true},
+		{"tid", true},
+		{"TId", true},
+		{"Tid", true},
+		{"TiD", true},
 		{"notreserved", false},
 	}