---
layout: page_v2
title: Module - Prebid Server Adapter
display_name: Prebid Server Adapter
description: Server-to-Server header bidding
page_type: module
module_code : prebidServerBidAdapter
enable_download : true
vendor_specific: false
sidebarType : 1
---

# Prebid Server Adapter
{: .no_toc}

- TOC
{:toc }

## Overview

The Prebid Server Adapter is a meta-adapter. It's not an actual bidder, but
rather a way to get a batch of bids from other bidders with one request.
A request for the set of auctions is sent to Prebid Server, which performs
all the auctions server-to-server (S2S), responding in time for Prebid.js to
send the results to the ad server. This lightens the performance load on the user's device.

### Prebid Server Adapter Video Overview

<div style="padding:56.25% 0 0 0;margin: 1rem 0;position:relative;"><iframe src="https://player.vimeo.com/video/922780542?h=f7d8e81488&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="Server-Side Header Bidding with Prebid.js"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>

Video notes:

- [Prebid Server Overview](/prebid-server/overview/prebid-server-overview.html)
- [Prebid Managed Services](https://prebid.org/managed-services/)
- [Header Bidding with Prebid](/overview/intro.html)
- [Transcript of this video overview](/dev-docs/pbsBidAdapter-video-overview.html)

## Configuration

Here's a minimal example config:

```javascript
pbjs.setConfig({
    s2sConfig: {
        accountId : '12345',
        endpoint: 'https://prebid-server.example.com/openrtb2/auction',
        syncEndpoint: 'https://prebid-server.example.com/cookie_sync',
        bidders : ['msft','pubmatic', 'rubicon'],
        timeout: 300
    }
});
```

To use multiple prebid servers, just define `s2sConfig` as an array.
The same bidder cannot be set in both configs. For example:

```javascript
pbjs.setConfig({
  s2sConfig: {
    accountId: YOUR_SELLER_MEMBER_ID,
    bidders: ['msft'],
    enabled: true,
    allowUnknownBidderCodes: true,
    timeout: 1000,
    endpoint: {
      p1Consent:   'https://ib.adnxs.com/openrtb2/prebid',
      noP1Consent: 'https://ib.adnxs-simple.com/openrtb2/prebid'
    },
    syncEndpoint: {
      p1Consent:   'https://prebid.adnxs.com/pbs/v1/cookie_sync',
      noP1Consent: 'https://prebid.adnxs-simple.com/pbs/v1/cookie_sync'
    }
  }
});
```

There are many configuration options for s2sConfig:

{: .table .table-bordered .table-striped }
| Attribute | Scope | Type | Description                                                                                   |
|------------+---------+---------+---------------------------------------------------------------|
| `accountId` | Required | String | Your Prebid Server account ID. This is obtained from whoever's hosting your Prebid Server. |
| `name` | Optional | String | A handle for this configuration, used to reference a specific server (when multiple are present) from [ad unit configuration](/dev-docs/adunit-reference.html#stored-imp) |
| `bidders` | Optional | Array of Strings | Which bidders auctions should take place on the server side |
| `allowUnknownBidderCodes` | Optional | Boolean | Allow Prebid Server to bid on behalf of bidders that are not explicitly listed in the adUnit. See important [note](#allowUnknownBidderCodes) below. Defaults to `false`. |
| `enabled` | Optional | Boolean | Enables this s2sConfig block - defaults to `false` |
| `timeout` | Optional | Integer | Number of milliseconds allowed for the server-side auctions. This should be approximately 200ms-300ms less than your Prebid.js timeout to allow for all bids to be returned in a timely manner. Defaults to 75% of [`bidderTimeout`](/dev-docs/publisher-api-reference/setConfig.html#setConfig-Bidder-Timeouts) or 750ms, whichever is lesser. | 
| `adapter` | Required | String | Adapter to use to connect to Prebid Server. Defaults to 'prebidServer' |
| `endpoint` | Required | URL or Object | Defines the auction endpoint for the Prebid Server cluster.  See table below for object config properties. |
| `syncEndpoint` | Required | URL or Object | Defines the cookie_sync endpoint for the Prebid Server cluster. See table below for object config properties. |
| `userSyncLimit` | Optional | Integer | Max number of userSync URLs that can be executed by Prebid Server cookie_sync per request.  If not defined, PBS will execute all userSync URLs included in the request. |
| `syncTimeout` | Optional | Integer | Maximum number of milliseconds allowed for each server-side userSync to load. Default is 1000. |
| `syncUrlModifier` | Optional | Object | Function to modify a bidder's sync url before the actual call to the sync endpoint. Bidder must be enabled for s2sConfig. |
| `coopSync` | Optional | Boolean | Whether or not PBS is allowed to perform "cooperative syncing" for bidders not on this page. Publishers help each other improve match rates by allowing this. Default is true. |
| `defaultTtl` | Optional | Integer | Configures the default TTL in the Prebid Server adapter to use when Prebid Server does not return a bid TTL - 60 if not set |
| `adapterOptions` | Optional | Object | Arguments will be added to resulting OpenRTB payload to Prebid Server in every impression object at request.imp[].ext.BIDDER. See the example above. |
| `extPrebid` | Optional | Object | Arguments will be added to resulting OpenRTB payload to Prebid Server in request.ext.prebid. See the examples below. |
| `customHeaders` | Optional | Object | These custom headers will be included in the XHR call to the bidder's endpoint. This will allow you to send data specific to your use case. The format consists of an object where the keys represent the header names and the values correspond to the respective header values. Here is an example how a customHeader object might look like - `{"Header1": "Value1", "Header2": "Value2"}`|
| `endpointCompression` | Optional | Boolean | Gzip compress the auction request payload when supported and debug mode is off. Adds `gzip=1` to the request URL. |
| `filterBidderlessCalls` | Optional | Boolean | When `true`, ad units that have no bidders defined are excluded from Prebid Server requests. Defaults to `false`. |
| `alwaysHasCapacity` | Optional | Boolean | When `true`, this prebid server instance will be omitted in checking if origin has http capacity, defaults to `false` |
| `allowPriorityBids` | Optional | Array of Strings | Since Prebid.js 11.44. Bidder codes routed through this instance whose deal metadata is trusted when ranking: their bids take `meta.deal.priority` (lower wins) and are ranked on `meta.deal.priorityAdjustedCpm` instead of `cpm`, without changing the bid's price. Trusted bidders must be listed; there is no option to trust every bidder on the instance. The listed bidders in each request are sent to Prebid Server as `ext.prebid.as.apb`, along with `ext.prebid.as.ap: true` (priority bids allowed); `ext.prebid.as` is omitted when none of the requested bidders is listed. Prebid.js enforces this itself and doesn't rely on Prebid Server honoring those fields: it only trusts bids whose seat is one of those bidders, so bids under alternate or unknown seats are not trusted. Defaults to none. See [bidderSettings allowPriorityBids](/dev-docs/publisher-api-reference/bidderSettings.html#212-allowprioritybids). |

If `endpoint` and `syncEndpoint` are objects, these are the supported properties:

{: .table .table-bordered .table-striped }
| Attribute | Scope | Type | Description |
|------------+---------+---------+---------------------------------------------------------------|
| p1Consent | Required | String | Defines the auction endpoint or the cookie_sync endpoint for the Prebid Server cluster for non-consent requests or users who grant consent. |
| noP1Consent | Required | String | Defines the auction endpoint or the cookie_sync endpoint for the Prebid Server cluster for users who do not grant consent. (This is useful for a server configured to not accept any cookies to ensure compliance regulations.) |

**Notes on s2sConfig properties**

- If `bidders` is omitted, only adUnits that also omit bidders will be sent to Prebid Server. See the [stored impressions](#stored-imp) example below.
- If the `s2sConfig` timeout is not specified, Prebid Server will utilize a configured default for `tmax`.
- When using the `endpoint` or `syncEndpoint` object configs, you should define both properties.  If either property is not defined, Prebid Server requests for that type of user will not be made.  If you do not need to distinguish endpoints for consent reasons, you can simply define the same URL value in both fields or use the String version of the field (which is configured to use defined URL for all users).
- Since Prebid.js 11.20, the `cookie_sync` request to `syncEndpoint` is skipped in Safari, Firefox, and Chrome on iOS, or when cookies are disabled or denied, in line with the [user sync behavior]({{site.baseurl}}/dev-docs/publisher-api-reference/setConfig.html#setConfig-ConfigureUserSyncing-HowUserSyncingWorks) for bid adapters.
- When `endpointCompression` is enabled, Prebid.js compresses the request body sent to Prebid Server and appends `gzip=1` to the endpoint URL. This feature is skipped when debug mode is active or the browser lacks GZIP support. Do not use if your PBS Host does not yet support gzip request compression.
- <a name="allowUnknownBidderCodes" ></a> When `allowUnknownBidderCodes` is `true`, bidders that have not been explicitly requested in [`adUnit.bids`](../adunit-reference.html#adunitbids) may take part in the auction. This can break custom logic that relies on the availability of a bid request object for any given bid. Known scenarios where custom code won't get the request when there's an "unknown bidder":
  - There will not be a [`bidRequested`](/dev-docs/publisher-api-reference/getEvents.html) event.
  - In the [Price Floors module](/dev-docs/modules/floors.html), custom schema functions will see the bidRequest object as undefined.

Additional options for `s2sConfig` may be enabled by including the [Server-to-Server testing module]({{site.baseurl}}/dev-docs/modules/s2sTesting.html).

**Passing the Referrer to Server Side Adapters**

- Setting `extPrebid.origreferrer` will be recognized by some server-side adapters as the referring URL for the current page.

**Emitting SeatNonBid Data**

- Prebid Server can be instructed to return additional [SeatNonBid](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#seat-non-bid) information about why bidders might not have bid on certain adunits. You can get this extra information by setting `extPrebid.returnallbidstatus` equal to `true`. Note that client-side analytics adapters can receive this data by listening to the `pbsAnalytics` event (its `seatnonbid` field). The `seatNonBid` event was removed in Prebid.js 11.

## Server-Side Bidders Don't Need a Client-Side Adapter

A bidder listed in `s2sConfig.bidders` doesn't have to be in the Prebid.js build. Prebid.js forwards the bidder's ad unit params to Prebid Server without calling the bidder's Prebid.js adapter, so you can leave the adapter out and keep the bundle smaller. That includes bidders that only have a Prebid Server adapter. Prebid Server handles parameter validation and type conversion and runs user syncs through `/cookie_sync`. Prebid.js has no bidder-specific parameter transforms for server-side bidders.

If you leave the adapter out, keep these in mind:

- **GDPR / TCF:** the bidder's Global Vendor List ID is normally declared by its Prebid.js adapter. Without the adapter, Prebid.js doesn't know it. If the [TCF Control module](/dev-docs/modules/tcfControl.html) is enforcing vendor consent for `basicAds` (the default), the bidder is removed from the auction. Either declare its ID with [`gvlMapping`](/dev-docs/publisher-api-reference/setConfig.html#setConfig-gvlMapping), which also sends it to Prebid Server for aliases, or set `deferS2Sbidders: true` on the `basicAds` rule to let Prebid Server enforce vendor consent for bidders with unknown IDs.
- **Aliases:** an alias that's defined in the bidder's Prebid.js adapter isn't defined without it. Use an alias Prebid Server knows, or declare it in `extPrebid.aliases` as described in [Server-Side Aliases](#server-side-aliases).
- **Client-side fallback:** a bidder without an adapter can only bid server-side. Features that route a bidder to the client, such as the [s2sTesting module](/dev-docs/modules/s2sTesting.html), need the client-side adapter in the build.

## Bid Params

Bid params are sourced from the adapter configurations set for client side. These do not need to change for Prebid Server.

{: .alert.alert-warning :}
**Errors in bidder parameters will cause Prebid Server to reject the
entire request.** The Prebid Server philosophy is to avoid silent failures --
we assume you will test changes, and that it will be easier to notice a
4xx error coming from the server than a silent failure where it skips just
the bad parameter.

## Examples

### Defining endpoints

s2sConfig example with the endpoint attributes defined:

```javascript
pbjs.setConfig({
    s2sConfig: [{
        accountId: '1001',
        bidders: ['bidderA', 'bidderB'],
        endpoint: 'https://mypbs.example.com/path',
        syncEndpoint: 'https://mypbs.example.com/path',
        timeout: 300
    }]
})
```

A similar example with the endpoint attributes defined as objects:

```javascript
pbjs.setConfig({
    s2sConfig: [{
        accountId: '1001',
        bidders: ['bidderA', 'bidderB'],
        endpoint: {
            p1Consent: 'https://mypbs.example.com/path',
            noP1Consent: 'https://mypbs2.example.com/path'
        },
        syncEndpoint: {
            p1Consent: 'https://mypbs.example.com/path',
            noP1Consent: 'https://mypbs2.example.com/path'
        },
        timeout: 300
    }]
})
```

### Server-Side Aliases

You may want to run a particular bidder on the client for banner, but that same bidder on the
server for video. You would do this by setting a **server-side** alias. For example:

```javascript
pbjs.setConfig({
  s2sConfig: [{
    accountId: '1',
    bidders: ['tripleliftVideo'],
    endpoint: 'https://mypbs.example.com/path',
    syncEndpoint: 'https://mypbs.example.com/path',
    timeout: 500,
    extPrebid: {
      aliases: {
        tripleliftVideo: tripleLift
      }
    }
  }]
})
```

Here's how it works:

1. Video ad units are coded with the dynamic alias. e.g. tripleliftVideo
1. The s2sConfig.bidders array contains 'tripleliftVideo' telling Prebid.js to direct bids for that code to the server
1. Finally, the extPrebid.aliases line tells Prebid Server to route the 'tripleliftVideo' biddercode to the 'triplelift' server-side adapter.

Make sure to register your aliases' [`gvlMapping`](/dev-docs/publisher-api-reference/setConfig.html#setConfig-gvlMapping) via setConfig as well.

### Routing for Multiple PBS instances

Bids:

```javascript
[{
    bidder: 'foobar',
    params: {...},
},
{
    bidder: 'foobar',
    params: {...},
    pbsHost: 'foobar-2'
}]
```

s2sConfig:

```javascript
[{
    accountId: 1234,
    bidders: ['foobar'],
    enabled: true,
    endpoint: {
        noP1Consent : 'https://pbs.auction/openrtb2/auction',
        p1Consent : 'https://pbs.auction/openrtb2/auction'
    }
},
{
     accountId: 5678,
     bidders: ['foobar-2'],
     syncBidders: ['foobar'],
     enabled: true,
     endpoint: {
        noP1Consent : 'https://pbs.alt.auction/openrtb2/auction',
        p1Consent : 'https://pbs.alt.auction/openrtb2/auction'
     }
}]
```

The above would distribute `bid[0]` to s2s endpoint `https://pbs.auction/openrtb2/auction`, whereas `bid[1]` will be distributed to `https://pbs.alt.auction/openrtb2/auction`. The syncBidders is used to sync both with the original biddercode to as well as applying bidder specific FPD for pbs calls via bidderconfig.

### Video via s2sConfig

Supporting video through the Server-to-Server route can be done by providing a couple of extra arguments on the `extPrebid` object. e.g.

```javascript
pbjs.setConfig({
    s2sConfig: [{
        accountId: '1001',
        bidders: ['rubicon', 'pubmatic'],
        timeout: 250,
        extPrebid: {
            cache: {
                vastxml: {returnCreative: false}
            },
            targeting: {
                pricegranularity: {"ranges": [{"max": 40.00, "increment": 1.00}]}
            }
        }
    }]
})
```

<a name="stored-imp"></a>

### Stored impressions

Prebid Server stored [requests](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#stored-requests) can be requested through the adUnit `ortb2Imp` property. This is useful to move the list of bidders and parameters from the page to blocks of JSON stored on the server. For these cases, it's not necessary to specify `bids`:  

```javascript
pbjs.addAdUnits([{
  code: 'example-stored-request',
  mediaTypes: {
    banner: {
      sizes: [[300, 250]]
    }
  },
  ortb2Imp: {
    ext: {
      prebid: {
        storedrequest: {
          id: 'your-stored-request-id'
        }
      }
    }
  }
}])
```

### Stored responses

For debugging purposes, it can be useful to have a page that retrieves a static value rather than running an actual auction.
For this you can use PBS [stored responses](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#stored-responses).
Here's an example:

```javascript
pbjs.addAdUnits([{
  code: 'example-stored-response',
  mediaTypes: {
    banner: {
      sizes: [[300, 250]]
    }
  },
  ortb2Imp: {
    ext: {
      prebid: {
        storedauctionresponse: {
          id: 'your-stored-response-id'
        }
      }
    }
  }
}])
```

## Related Reading

- [Prebid Server Overview](/prebid-server/overview/prebid-server-overview.html)
