diff --git a/adapters/adelerate/adelerate.go b/adapters/adelerate/adelerate.go
new file mode 100644
index 00000000000..f9198464eac
--- /dev/null
+++ b/adapters/adelerate/adelerate.go
@@ -0,0 +1,138 @@
+package adelerate
+
+import (
+ "fmt"
+ "net/http"
+
+ "github.com/prebid/openrtb/v20/openrtb2"
+ "github.com/prebid/prebid-server/v4/adapters"
+ "github.com/prebid/prebid-server/v4/config"
+ "github.com/prebid/prebid-server/v4/errortypes"
+ "github.com/prebid/prebid-server/v4/openrtb_ext"
+ "github.com/prebid/prebid-server/v4/util/jsonutil"
+)
+
+type adapter struct {
+ endpoint string
+}
+
+type reqBidderExt struct {
+ Bidder openrtb_ext.ImpExtAdelerate `json:"bidder"`
+}
+
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
+ bidder := &adapter{
+ endpoint: config.Endpoint,
+ }
+ return bidder, nil
+}
+
+func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+ var errs []error
+ validImps := make([]openrtb2.Imp, 0, len(request.Imp))
+
+ for i := range request.Imp {
+ currImp := request.Imp[i]
+
+ var bidderExt reqBidderExt
+ if err := jsonutil.Unmarshal(currImp.Ext, &bidderExt); err != nil {
+ errs = append(errs, &errortypes.BadInput{
+ Message: fmt.Sprintf("Invalid imp.ext for impression index %d. err: %s", i, err.Error()),
+ })
+ continue
+ }
+
+ if bidderExt.Bidder.Floor > 0 && currImp.BidFloor == 0 {
+ currImp.BidFloor = bidderExt.Bidder.Floor
+ if bidderExt.Bidder.FloorCurrency != "" {
+ currImp.BidFloorCur = bidderExt.Bidder.FloorCurrency
+ } else {
+ currImp.BidFloorCur = "USD"
+ }
+ }
+
+ currImp.Secure = openrtb2.Int8Ptr(1)
+
+ validImps = append(validImps, currImp)
+ }
+
+ if len(validImps) == 0 {
+ return nil, errs
+ }
+
+ reqCopy := *request
+ reqCopy.Imp = validImps
+
+ adapterReq, err := a.buildRequest(&reqCopy)
+ if err != nil {
+ return nil, append(errs, err)
+ }
+
+ return []*adapters.RequestData{adapterReq}, errs
+}
+
+func (a *adapter) buildRequest(request *openrtb2.BidRequest) (*adapters.RequestData, error) {
+ reqJSON, err := jsonutil.Marshal(request)
+ if err != nil {
+ return nil, err
+ }
+
+ headers := http.Header{}
+ headers.Add("Content-Type", "application/json;charset=utf-8")
+ headers.Add("Accept", "application/json")
+
+ return &adapters.RequestData{
+ Method: http.MethodPost,
+ Uri: a.endpoint,
+ Body: reqJSON,
+ Headers: headers,
+ ImpIDs: openrtb_ext.GetImpIDs(request.Imp),
+ }, nil
+}
+
+func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+ if adapters.IsResponseStatusCodeNoContent(responseData) {
+ return nil, nil
+ }
+
+ if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil {
+ return nil, []error{err}
+ }
+
+ var response openrtb2.BidResponse
+ if err := jsonutil.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 := range seatBid.Bid {
+ bidType, err := getMediaTypeForBid(seatBid.Bid[i])
+ if err != nil {
+ return nil, []error{err}
+ }
+
+ b := &adapters.TypedBid{
+ Bid: &seatBid.Bid[i],
+ BidType: bidType,
+ }
+ bidResponse.Bids = append(bidResponse.Bids, b)
+ }
+ }
+ return bidResponse, nil
+}
+
+func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
+ switch bid.MType {
+ case openrtb2.MarkupBanner:
+ return openrtb_ext.BidTypeBanner, nil
+ case openrtb2.MarkupVideo:
+ return openrtb_ext.BidTypeVideo, nil
+ case openrtb2.MarkupNative:
+ return openrtb_ext.BidTypeNative, nil
+ default:
+ return "", fmt.Errorf("unsupported MType %d for bid %s", bid.MType, bid.ID)
+ }
+}
\ No newline at end of file
diff --git a/adapters/adelerate/adelerate_test.go b/adapters/adelerate/adelerate_test.go
new file mode 100644
index 00000000000..d9451814c9a
--- /dev/null
+++ b/adapters/adelerate/adelerate_test.go
@@ -0,0 +1,20 @@
+package adelerate
+
+import (
+ "testing"
+
+ "github.com/prebid/prebid-server/v4/adapters/adapterstest"
+ "github.com/prebid/prebid-server/v4/config"
+ "github.com/prebid/prebid-server/v4/openrtb_ext"
+)
+
+func TestJsonSamples(t *testing.T) {
+ bidder, buildErr := Builder(openrtb_ext.BidderAdelerate, config.Adapter{
+ Endpoint: "https://pbs.bidelerate.com/openrtb2/auction"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
+
+ if buildErr != nil {
+ t.Fatalf("Builder returned unexpected error %v", buildErr)
+ }
+
+ adapterstest.RunJSONBidderTest(t, "adeleratetest", bidder)
+}
\ No newline at end of file
diff --git a/adapters/adelerate/adeleratetest/exemplary/banner-with-existing-bidfloor.json b/adapters/adelerate/adeleratetest/exemplary/banner-with-existing-bidfloor.json
new file mode 100644
index 00000000000..a5f8a38772a
--- /dev/null
+++ b/adapters/adelerate/adeleratetest/exemplary/banner-with-existing-bidfloor.json
@@ -0,0 +1,109 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "bidfloor": 3.0,
+ "bidfloorcur": "GBP",
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1",
+ "floor": 1.5,
+ "floorCurrency": "EUR"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://pbs.bidelerate.com/openrtb2/auction",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "bidfloor": 3.0,
+ "bidfloorcur": "GBP",
+ "secure": 1,
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1",
+ "floor": 1.5,
+ "floorCurrency": "EUR"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test-bid-id",
+ "impid": "test-imp-id",
+ "price": 4.0,
+ "adm": "
test ad
",
+ "crid": "creative-123",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ }
+ ],
+ "seat": "adelerate"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "currency": "USD",
+ "bids": [
+ {
+ "bid": {
+ "id": "test-bid-id",
+ "impid": "test-imp-id",
+ "price": 4.0,
+ "adm": "test ad
",
+ "crid": "creative-123",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapters/adelerate/adeleratetest/exemplary/banner-with-floor-default-currency.json b/adapters/adelerate/adeleratetest/exemplary/banner-with-floor-default-currency.json
new file mode 100644
index 00000000000..9da9bbb8847
--- /dev/null
+++ b/adapters/adelerate/adeleratetest/exemplary/banner-with-floor-default-currency.json
@@ -0,0 +1,105 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1",
+ "floor": 2.0
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://pbs.bidelerate.com/openrtb2/auction",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "bidfloor": 2.0,
+ "bidfloorcur": "USD",
+ "secure": 1,
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1",
+ "floor": 2.0
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test-bid-id",
+ "impid": "test-imp-id",
+ "price": 3.0,
+ "adm": "test ad
",
+ "crid": "creative-123",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ }
+ ],
+ "seat": "adelerate"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "currency": "USD",
+ "bids": [
+ {
+ "bid": {
+ "id": "test-bid-id",
+ "impid": "test-imp-id",
+ "price": 3.0,
+ "adm": "test ad
",
+ "crid": "creative-123",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapters/adelerate/adeleratetest/exemplary/banner-with-floor.json b/adapters/adelerate/adeleratetest/exemplary/banner-with-floor.json
new file mode 100644
index 00000000000..62eb7bc343b
--- /dev/null
+++ b/adapters/adelerate/adeleratetest/exemplary/banner-with-floor.json
@@ -0,0 +1,107 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1",
+ "floor": 1.5,
+ "floorCurrency": "EUR"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://pbs.bidelerate.com/openrtb2/auction",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "bidfloor": 1.5,
+ "bidfloorcur": "EUR",
+ "secure": 1,
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1",
+ "floor": 1.5,
+ "floorCurrency": "EUR"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test-bid-id",
+ "impid": "test-imp-id",
+ "price": 2.0,
+ "adm": "test ad
",
+ "crid": "creative-123",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ }
+ ],
+ "seat": "adelerate"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "currency": "USD",
+ "bids": [
+ {
+ "bid": {
+ "id": "test-bid-id",
+ "impid": "test-imp-id",
+ "price": 2.0,
+ "adm": "test ad
",
+ "crid": "creative-123",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/adelerate/adeleratetest/exemplary/multi-imp.json b/adapters/adelerate/adeleratetest/exemplary/multi-imp.json
new file mode 100644
index 00000000000..da47509c922
--- /dev/null
+++ b/adapters/adelerate/adeleratetest/exemplary/multi-imp.json
@@ -0,0 +1,153 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id-1",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "placement-1",
+ "publisherId": "publisher-1"
+ }
+ }
+ },
+ {
+ "id": "test-imp-id-2",
+ "banner": {
+ "format": [
+ {"w": 728, "h": 90}
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "placement-2",
+ "publisherId": "publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://pbs.bidelerate.com/openrtb2/auction",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id-1",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "secure": 1,
+ "ext": {
+ "bidder": {
+ "placementId": "placement-1",
+ "publisherId": "publisher-1"
+ }
+ }
+ },
+ {
+ "id": "test-imp-id-2",
+ "banner": {
+ "format": [
+ {"w": 728, "h": 90}
+ ]
+ },
+ "secure": 1,
+ "ext": {
+ "bidder": {
+ "placementId": "placement-2",
+ "publisherId": "publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "impIDs": ["test-imp-id-1", "test-imp-id-2"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "bid-1",
+ "impid": "test-imp-id-1",
+ "price": 1.5,
+ "adm": "ad 1
",
+ "crid": "creative-1",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ },
+ {
+ "id": "bid-2",
+ "impid": "test-imp-id-2",
+ "price": 2.0,
+ "adm": "ad 2
",
+ "crid": "creative-2",
+ "w": 728,
+ "h": 90,
+ "mtype": 1
+ }
+ ],
+ "seat": "adelerate"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "currency": "USD",
+ "bids": [
+ {
+ "bid": {
+ "id": "bid-1",
+ "impid": "test-imp-id-1",
+ "price": 1.5,
+ "adm": "ad 1
",
+ "crid": "creative-1",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ },
+ "type": "banner"
+ },
+ {
+ "bid": {
+ "id": "bid-2",
+ "impid": "test-imp-id-2",
+ "price": 2.0,
+ "adm": "ad 2
",
+ "crid": "creative-2",
+ "w": 728,
+ "h": 90,
+ "mtype": 1
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapters/adelerate/adeleratetest/exemplary/simple-banner.json b/adapters/adelerate/adeleratetest/exemplary/simple-banner.json
new file mode 100644
index 00000000000..e1012a5fec1
--- /dev/null
+++ b/adapters/adelerate/adeleratetest/exemplary/simple-banner.json
@@ -0,0 +1,103 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250},
+ {"w": 728, "h": 90}
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://pbs.bidelerate.com/openrtb2/auction",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250},
+ {"w": 728, "h": 90}
+ ]
+ },
+ "secure": 1,
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test-bid-id",
+ "impid": "test-imp-id",
+ "price": 1.5,
+ "adm": "test ad
",
+ "crid": "creative-123",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ }
+ ],
+ "seat": "adelerate"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "currency": "USD",
+ "bids": [
+ {
+ "bid": {
+ "id": "test-bid-id",
+ "impid": "test-imp-id",
+ "price": 1.5,
+ "adm": "test ad
",
+ "crid": "creative-123",
+ "w": 300,
+ "h": 250,
+ "mtype": 1
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/adelerate/adeleratetest/exemplary/simple-native.json b/adapters/adelerate/adeleratetest/exemplary/simple-native.json
new file mode 100644
index 00000000000..362bdca64b8
--- /dev/null
+++ b/adapters/adelerate/adeleratetest/exemplary/simple-native.json
@@ -0,0 +1,95 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "native": {
+ "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":90}}]}",
+ "ver": "1.2"
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://pbs.bidelerate.com/openrtb2/auction",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "native": {
+ "request": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":90}}]}",
+ "ver": "1.2"
+ },
+ "secure": 1,
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test-bid-id",
+ "impid": "test-imp-id",
+ "price": 3.0,
+ "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Test Title\"}}],\"link\":{\"url\":\"https://click.example.com\"}}",
+ "crid": "native-creative-101",
+ "mtype": 4
+ }
+ ],
+ "seat": "adelerate"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "currency": "USD",
+ "bids": [
+ {
+ "bid": {
+ "id": "test-bid-id",
+ "impid": "test-imp-id",
+ "price": 3.0,
+ "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"Test Title\"}}],\"link\":{\"url\":\"https://click.example.com\"}}",
+ "crid": "native-creative-101",
+ "mtype": 4
+ },
+ "type": "native"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/adelerate/adeleratetest/exemplary/simple-video.json b/adapters/adelerate/adeleratetest/exemplary/simple-video.json
new file mode 100644
index 00000000000..14bad1d5deb
--- /dev/null
+++ b/adapters/adelerate/adeleratetest/exemplary/simple-video.json
@@ -0,0 +1,103 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "video": {
+ "mimes": ["video/mp4"],
+ "protocols": [1, 2, 3],
+ "w": 640,
+ "h": 480
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://pbs.bidelerate.com/openrtb2/auction",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "video": {
+ "mimes": ["video/mp4"],
+ "protocols": [1, 2, 3],
+ "w": 640,
+ "h": 480
+ },
+ "secure": 1,
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com",
+ "page": "https://example.com/page"
+ }
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test-bid-id",
+ "impid": "test-imp-id",
+ "price": 5.0,
+ "adm": "",
+ "crid": "video-creative-789",
+ "w": 640,
+ "h": 480,
+ "mtype": 2
+ }
+ ],
+ "seat": "adelerate"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "currency": "USD",
+ "bids": [
+ {
+ "bid": {
+ "id": "test-bid-id",
+ "impid": "test-imp-id",
+ "price": 5.0,
+ "adm": "",
+ "crid": "video-creative-789",
+ "w": 640,
+ "h": 480,
+ "mtype": 2
+ },
+ "type": "video"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/adelerate/adeleratetest/supplemental/bad-request.json b/adapters/adelerate/adeleratetest/supplemental/bad-request.json
new file mode 100644
index 00000000000..e83d3eab466
--- /dev/null
+++ b/adapters/adelerate/adeleratetest/supplemental/bad-request.json
@@ -0,0 +1,65 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://pbs.bidelerate.com/openrtb2/auction",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "secure": 1,
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com"
+ }
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 400,
+ "body": {}
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Unexpected status code: 400. Run with request.debug = 1 for more info",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/adelerate/adeleratetest/supplemental/bad-server-response.json b/adapters/adelerate/adeleratetest/supplemental/bad-server-response.json
new file mode 100644
index 00000000000..201856618f7
--- /dev/null
+++ b/adapters/adelerate/adeleratetest/supplemental/bad-server-response.json
@@ -0,0 +1,65 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://pbs.bidelerate.com/openrtb2/auction",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "secure": 1,
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com"
+ }
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": "invalid json"
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "expect { or n, but found .*",
+ "comparison": "regex"
+ }
+ ]
+}
diff --git a/adapters/adelerate/adeleratetest/supplemental/invalid-ext.json b/adapters/adelerate/adeleratetest/supplemental/invalid-ext.json
new file mode 100644
index 00000000000..05fdd0bb48c
--- /dev/null
+++ b/adapters/adelerate/adeleratetest/supplemental/invalid-ext.json
@@ -0,0 +1,27 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "ext": {
+ "bidder": "invalid"
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com"
+ }
+ },
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "Invalid imp.ext for impression index 0. err: .*",
+ "comparison": "regex"
+ }
+ ]
+}
diff --git a/adapters/adelerate/adeleratetest/supplemental/no-content.json b/adapters/adelerate/adeleratetest/supplemental/no-content.json
new file mode 100644
index 00000000000..c68c047fef9
--- /dev/null
+++ b/adapters/adelerate/adeleratetest/supplemental/no-content.json
@@ -0,0 +1,60 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://pbs.bidelerate.com/openrtb2/auction",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "secure": 1,
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com"
+ }
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 204,
+ "body": {}
+ }
+ }
+ ],
+ "expectedBidResponses": []
+}
\ No newline at end of file
diff --git a/adapters/adelerate/adeleratetest/supplemental/server-error.json b/adapters/adelerate/adeleratetest/supplemental/server-error.json
new file mode 100644
index 00000000000..b569b88579e
--- /dev/null
+++ b/adapters/adelerate/adeleratetest/supplemental/server-error.json
@@ -0,0 +1,65 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://pbs.bidelerate.com/openrtb2/auction",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "secure": 1,
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com"
+ }
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 503,
+ "body": {}
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Unexpected status code: 503. Run with request.debug = 1 for more info",
+ "comparison": "literal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/adelerate/adeleratetest/supplemental/unknown-media-type.json b/adapters/adelerate/adeleratetest/supplemental/unknown-media-type.json
new file mode 100644
index 00000000000..00c392088db
--- /dev/null
+++ b/adapters/adelerate/adeleratetest/supplemental/unknown-media-type.json
@@ -0,0 +1,85 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://pbs.bidelerate.com/openrtb2/auction",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {"w": 300, "h": 250}
+ ]
+ },
+ "secure": 1,
+ "ext": {
+ "bidder": {
+ "placementId": "test-placement-1",
+ "publisherId": "test-publisher-1"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "example.com"
+ }
+ },
+ "impIDs": ["test-imp-id"]
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test-bid-id",
+ "impid": "test-imp-id",
+ "price": 1.5,
+ "adm": "test ad
",
+ "crid": "creative-123",
+ "w": 300,
+ "h": 250,
+ "mtype": 0
+ }
+ ],
+ "seat": "adelerate"
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "unsupported MType 0 for bid test-bid-id",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/adelerate/params_test.go b/adapters/adelerate/params_test.go
new file mode 100644
index 00000000000..015b9fd1aee
--- /dev/null
+++ b/adapters/adelerate/params_test.go
@@ -0,0 +1,54 @@
+package adelerate
+
+import (
+ "encoding/json"
+ "testing"
+
+ "github.com/prebid/prebid-server/v4/openrtb_ext"
+)
+
+var validParams = []string{
+ `{"placementId":"123", "publisherId":"456"}`,
+ `{"placementId":"abc", "publisherId":"def", "floor": 1.5, "floorCurrency": "EUR"}`,
+ `{"placementId":"abc", "publisherId":"def", "floor": 0.5}`,
+}
+
+var invalidParams = []string{
+ ``,
+ `null`,
+ `true`,
+ `5`,
+ `[]`,
+ `{}`,
+ `{"placementId":"123"}`,
+ `{"publisherId":"456"}`,
+ `{"placementId":"", "publisherId":"456"}`,
+ `{"placementId":"123", "publisherId":""}`,
+ `{"some": "param"}`,
+}
+
+func TestValidParams(t *testing.T) {
+ validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+ if err != nil {
+ t.Fatalf("Failed to fetch the json-schemas. %v", err)
+ }
+
+ for _, validParam := range validParams {
+ if err := validator.Validate(openrtb_ext.BidderAdelerate, json.RawMessage(validParam)); err != nil {
+ t.Errorf("Schema rejected adelerate params: %s", validParam)
+ }
+ }
+}
+
+func TestInvalidParams(t *testing.T) {
+ validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+ if err != nil {
+ t.Fatalf("Failed to fetch the json-schemas. %v", err)
+ }
+
+ for _, invalidParam := range invalidParams {
+ if err := validator.Validate(openrtb_ext.BidderAdelerate, json.RawMessage(invalidParam)); err == nil {
+ t.Errorf("Schema allowed unexpected params: %s", invalidParam)
+ }
+ }
+}
diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go
index 630fbe348b9..318f1a9bc96 100755
--- a/exchange/adapter_builders.go
+++ b/exchange/adapter_builders.go
@@ -8,6 +8,7 @@ import (
"github.com/prebid/prebid-server/v4/adapters/acuityads"
"github.com/prebid/prebid-server/v4/adapters/adagio"
"github.com/prebid/prebid-server/v4/adapters/adelement"
+ "github.com/prebid/prebid-server/v4/adapters/adelerate"
"github.com/prebid/prebid-server/v4/adapters/adf"
"github.com/prebid/prebid-server/v4/adapters/adgeneration"
"github.com/prebid/prebid-server/v4/adapters/adhese"
@@ -275,6 +276,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
openrtb_ext.BidderAcuityAds: acuityads.Builder,
openrtb_ext.BidderAdagio: adagio.Builder,
openrtb_ext.BidderAdelement: adelement.Builder,
+ openrtb_ext.BidderAdelerate: adelerate.Builder,
openrtb_ext.BidderAdf: adf.Builder,
openrtb_ext.BidderAdgeneration: adgeneration.Builder,
openrtb_ext.BidderAdhese: adhese.Builder,
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index 1b61ff724e2..9828ab9992e 100644
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -24,6 +24,7 @@ var coreBidderNames []BidderName = []BidderName{
BidderAcuityAds,
BidderAdagio,
BidderAdelement,
+ BidderAdelerate,
BidderAdf,
BidderAdgeneration,
BidderAdhese,
@@ -398,6 +399,7 @@ const (
BidderAcuityAds BidderName = "acuityads"
BidderAdagio BidderName = "adagio"
BidderAdelement BidderName = "adelement"
+ BidderAdelerate BidderName = "adelerate"
BidderAdf BidderName = "adf"
BidderAdgeneration BidderName = "adgeneration"
BidderAdhese BidderName = "adhese"
diff --git a/openrtb_ext/imp_adelerate.go b/openrtb_ext/imp_adelerate.go
new file mode 100644
index 00000000000..af6d06625b7
--- /dev/null
+++ b/openrtb_ext/imp_adelerate.go
@@ -0,0 +1,8 @@
+package openrtb_ext
+
+type ImpExtAdelerate struct {
+ PlacementId string `json:"placementId"`
+ PublisherId string `json:"publisherId"`
+ Floor float64 `json:"floor,omitempty"`
+ FloorCurrency string `json:"floorCurrency,omitempty"`
+}
\ No newline at end of file
diff --git a/static/bidder-info/adelerate.yaml b/static/bidder-info/adelerate.yaml
new file mode 100644
index 00000000000..bba4f0ff872
--- /dev/null
+++ b/static/bidder-info/adelerate.yaml
@@ -0,0 +1,21 @@
+endpoint: "https://pbs.bidelerate.com/openrtb2/auction"
+maintainer:
+ email: "support@adelerate.com"
+capabilities:
+ app:
+ mediaTypes:
+ - banner
+ - video
+ - native
+ site:
+ mediaTypes:
+ - banner
+ - video
+ - native
+userSync:
+ iframe:
+ url: "https://pbs.bidelerate.com/cookie_sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}"
+ userMacro: "[UID]"
+ redirect:
+ url: "https://pbs.bidelerate.com/cookie_sync/pixel?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&redir={{.RedirectURL}}"
+ userMacro: "[UID]"
\ No newline at end of file
diff --git a/static/bidder-params/adelerate.json b/static/bidder-params/adelerate.json
new file mode 100644
index 00000000000..0ae85b2baaa
--- /dev/null
+++ b/static/bidder-params/adelerate.json
@@ -0,0 +1,30 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "Adelerate Adapter Params",
+ "description": "A schema which validates params accepted by the Adelerate adapter",
+ "type": "object",
+ "properties": {
+ "placementId": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The placement ID provided by Adelerate"
+ },
+ "publisherId": {
+ "type": "string",
+ "minLength": 1,
+ "description": "The publisher ID provided by Adelerate"
+ },
+ "floor": {
+ "type": "number",
+ "description": "Minimum CPM price. Use of Prebid Floors module is preferred."
+ },
+ "floorCurrency": {
+ "type": "string",
+ "description": "Currency for the floor param. Defaults to USD."
+ }
+ },
+ "required": [
+ "placementId",
+ "publisherId"
+ ]
+}
\ No newline at end of file