diff --git a/modules/adspiritBidAdapter.js b/modules/adspiritBidAdapter.js
new file mode 100644
index 00000000000..da8676f6c9b
--- /dev/null
+++ b/modules/adspiritBidAdapter.js
@@ -0,0 +1,129 @@
+import * as utils from '../src/utils';
+import {registerBidder} from '../src/adapters/bidderFactory';
+import {BANNER, NATIVE} from '../src/mediaTypes.js';
+
+const RTB_URL = '/rtb/getbid.php?rtbprovider=prebid';
+const SCRIPT_URL = '/adasync.min.js';
+export const spec = {
+ code : 'adspirit',
+ aliases : ['xapadsmedia', 'connectad','twiago'],
+ supportedMediaTypes: [BANNER, NATIVE],
+
+ isBidRequestValid: function (bid)
+ {
+ let host = spec.getBidderHost(bid);
+ if(!host)
+ {
+ return false;
+ }
+ if(!bid.params.placementId)
+ {
+ return false;
+ }
+ return true;
+ },
+ buildRequests : function (validBidRequests, bidderRequest)
+ {
+ let requests = [];
+ let bidRequest;
+ let reqUrl;
+ let placementId;
+ for(let i = 0; i < validBidRequests.length; i++)
+ {
+ bidRequest = validBidRequests[i];
+ bidRequest.adspiritConId = spec.genAdConId(bidRequest);
+ reqUrl = spec.getBidderHost(bidRequest);
+ placementId = utils.getBidIdParameter('placementId', bidRequest.params);
+ reqUrl = '//' + reqUrl + RTB_URL + '&pid=' + placementId + '&ref=' + encodeURIComponent(bidderRequest.refererInfo.topmostLocation) + '&scx=' + (screen.width) + '&scy=' + (screen.height) + '&wcx=' + ('innerWidth' in window ? window.innerWidth : page.clientWidth) + '&wcy=' + ('innerHeight' in window ? window.innerHeight : page.clientHeight) + '&async=' + bidRequest.adspiritConId + '&t=' + Math.round(
+ Math.random() * 100000);
+ requests.push({
+ method : 'GET',
+ url : reqUrl,
+ data : {},
+ bidRequest: bidRequest
+ });
+ }
+ return requests;
+ },
+ interpretResponse: function (serverResponse, bidRequest)
+ {
+ const bidResponses = [];
+ let bidObj = bidRequest.bidRequest;
+
+ if(!serverResponse || !serverResponse.body || !bidObj)
+ {
+ utils.logWarn(`No valid bids from ${spec.code} bidder!`);
+ return [];
+ }
+ let adData = serverResponse.body;
+ let cpm = adData.cpm;
+ if(!cpm)
+ {
+ return [];
+ }
+
+ let host = spec.getBidderHost(bidObj);
+ if('mediaTypes' in bidObj && 'native' in bidObj.mediaTypes)
+ {
+ const bidResponse = {
+ requestId : bidObj.bidId,
+ cpm : cpm,
+ width : adData.w,
+ height : adData.h,
+ creativeId: bidObj.params.placementId,
+ currency : 'EUR',
+ netRevenue: true,
+ ttl : 300,
+ native : {
+ title : adData.title,
+ body : adData.body,
+ cta : adData.cta,
+ image : {url: adData.image},
+ clickUrl : adData.click,
+ impressionTrackers: [adData.view]
+ },
+ mediaType : NATIVE
+ };
+ }
+ else
+ {
+ let adm = 'window.inDapIF=false' + '' + adData.adm;
+
+ const bidResponse = {
+ requestId : bidObj.bidId,
+ cpm : cpm,
+ width : adData.w,
+ height : adData.h,
+ creativeId: bidObj.params.placementId,
+ currency : 'EUR',
+ netRevenue: true,
+ ttl : 300,
+ ad : adm,
+ mediaType : BANNER
+ };
+ }
+ bidResponses.push(bidResponse);
+ return bidResponses;
+ },
+ getBidderHost : function (bid)
+ {
+ if(bid.bidder === 'adspirit')
+ {
+ return utils.getBidIdParameter('host', bid.params);
+ }
+ if(bid.bidder === 'connectad')
+ {
+ return 'connected-by.connectad.io';
+ }
+ if(bid.bidder === 'xapadsmedia')
+ {
+ return 'dsp.xapads.com';
+ }
+ return null;
+ },
+ genAdConId : function (bid)
+ {
+ return bid.bidder + Math.round(Math.random() * 100000);
+ }
+};
+registerBidder(spec);
diff --git a/modules/adspiritBidAdapter.md b/modules/adspiritBidAdapter.md
new file mode 100644
index 00000000000..688d0814882
--- /dev/null
+++ b/modules/adspiritBidAdapter.md
@@ -0,0 +1,28 @@
+# Overview
+
+**Module Name**: AdSpirit Bidder Adapter
+**Module Type**: Bidder Adapter
+**Maintainer**: prebid@adspirit.de
+
+# Description
+
+Module that connects to an AdSpirit zone to fetch bids.
+
+# Test Parameters
+```
+ var adUnits = [
+ {
+ code: 'display-div',
+ sizes: [[300, 250]], // a display size
+ bids: [
+ {
+ bidder: "adspirit",
+ params: {
+ placementId: '5',
+ host: 'n1test.adspirit.de'
+ }
+ }
+ ]
+ }
+ ];
+```