Prebid Server Configuration Guide
This document covers the Sellwild managed Prebid Server instance at prebid.sellwild.com, including how server-side auctions work, configuration reference, SSP onboarding, GDPR enforcement, telemetry, and testing.
Table of Contents
- Overview
- How Server-Side Auctions Work
- Configuration Reference
- SSP Onboarding
- Supported Bidders
- GDPR Enforcement
- Auction Telemetry
- Testing
- House Ads and No-Fill Handling
- Troubleshooting
Overview
prebid.sellwild.com is a managed Prebid Server instance that runs OpenRTB 2.6 server-side auctions on behalf of Sellwild SDK integrations. Instead of loading individual bidder adapters in the client-side WebView (where cookie sync, IDFA access, and third-party storage are all restricted), the SDK sends a single HTTP request to Prebid Server, which fans out to all configured SSPs server-side.
Key benefits:
- Eliminates client-side cookie sync failures inherent to native WebViews (WKWebView, Android WebView).
- Reduces client-side JavaScript payload -- no individual bidder adapter scripts.
- Centralizes bidder timeout enforcement on the server.
- Enables server-side GDPR and consent enforcement via
regs.ext.gdpr. - Provides deterministic auction telemetry (response times, bid prices) via response extensions.
Endpoint:
https://prebid.sellwild.com/openrtb2/auctionHow Server-Side Auctions Work
The following diagram illustrates the OpenRTB request flow when the SDK is configured with PrebidServerConfig:
+------------------+ +-------------------+ +------------------+
| | | | | |
| Mobile App | | prebid.sellwild | | SSP Endpoints |
| (Flutter SDK) | | .com | | (AppNexus, |
| | | Prebid Server | | Pubmatic, etc) |
+--------+---------+ +---------+---------+ +--------+---------+
| | |
| 1. WebView loads | |
| Prebid.js with | |
| s2sConfig set | |
| | |
| 2. POST /openrtb2/auction| |
| (single request with | |
| imp[], app{}, regs{})| |
+-------------------------->| |
| | |
| | 3. Fan out: parallel |
| | OpenRTB bid requests |
| | to each configured |
| | SSP |
| +------------------------->|
| | |
| | 4. SSPs return bids |
| | (or no-bid) within |
| | timeout window |
| |<-------------------------+
| | |
| | 5. Server runs auction: |
| | - Applies floors |
| | - Enforces GDPR |
| | - Selects winner(s) |
| | |
| 6. Response with | |
| seatbid[] array, | |
| ext.responsetimemillis| |
|<--------------------------+ |
| | |
| 7. Prebid.js renders | |
| winning creative | |
| in ad slot | |
| | |Step-by-step:
The SDK builds the WebView HTML with
s2sConfiginjected intopbjs.setConfig(). This tells Prebid.js to route all bidder calls through Prebid Server instead of loading client-side adapters.Prebid.js constructs an OpenRTB 2.6 bid request and POSTs it to
prebid.sellwild.com/openrtb2/auction. The request includes:imp[]-- impression objects with ad unit sizes and floor prices.app{}-- in-app traffic declaration with bundle ID and store URL.regs.ext.gdpr-- GDPR consent signal.source.ext.prebid.bidders-- the list of SSPs to query.
Prebid Server parses the request and fans out parallel OpenRTB bid requests to each configured SSP endpoint.
SSPs return bid responses (or no-bid) within the configured timeout window (default: 1500ms).
Prebid Server runs the auction logic: applies bid floors, enforces GDPR vendor consent, deduplicates bids, and selects the winning bid(s) per impression.
The consolidated response is returned to the client with
seatbid[]containing winning bids andext.responsetimemilliscontaining per-bidder latency data.Prebid.js in the WebView receives the response, sets targeting keys on the ad server (GAM or zone-based), and renders the winning creative.
Configuration Reference
PrebidServerConfig (SDK)
Configure Prebid Server in the SDK by setting the prebidServer field on SellwildConfig:
prebidServer: PrebidServerConfig(
accountId: 'weatherbug',
endpoint: 'https://prebid.sellwild.com/openrtb2/auction',
bidders: ['appnexus', 'pubmatic', 'ix', 'rubicon', 'openx'],
timeout: 1500,
),| Field | Type | Required | Default | Description |
|---|---|---|---|---|
accountId | String | Yes | -- | Your Prebid Server account ID. This is your Sellwild partner code. |
endpoint | String | Yes | -- | Full URL: https://prebid.sellwild.com/openrtb2/auction |
bidders | List<String> | Yes | -- | Bidder codes to include in the server-side auction. Must match server config. |
timeout | int | No | 1500 | Maximum time (ms) the server waits for SSP responses before closing auction. |
syncEndpoint | String? | No | null | Cookie sync endpoint. Derived from endpoint if omitted. |
Server-Side Configuration
The following settings are managed on the Prebid Server instance at prebid.sellwild.com. They are documented here for transparency and to aid debugging. Changes to server-side configuration are made by the Sellwild ad operations team.
| Setting | Value / Description |
|---|---|
gdpr.default-value | 1 -- GDPR enforcement is on by default. See GDPR Enforcement. |
auction.timeout-ms | 1500 -- server-side default. Overridden by the client timeout field. |
auction.truncate-target-attr | 20 -- targeting key values are truncated to 20 characters. |
adapters.<bidder>.enabled | Per-bidder enable/disable. See Supported Bidders. |
cache.scheme / cache.host | Prebid Cache configuration for video/native creative caching. |
metrics.type | prometheus -- auction telemetry exported via Prometheus. |
SSP Onboarding
Adding a new SSP to your Prebid Server auction requires only your seat ID for that SSP. No server-side code changes or adapter development is needed -- Prebid Server ships with adapters for all major SSPs.
Steps
Obtain your seat ID from the SSP. This is typically called a "publisher ID", "account ID", or "seat ID" depending on the SSP. Examples:
- AppNexus:
placementId(numeric, e.g.,12345678) - Pubmatic:
publisherId(string, e.g.,"156209") - Index Exchange:
siteId(string, e.g.,"123456") - Rubicon:
accountId,siteId,zoneId(all numeric)
- AppNexus:
Provide the seat ID to the Sellwild ad operations team. Include:
- SSP name and bidder code (e.g.,
appnexus,pubmatic) - Your seat/account ID for that SSP
- Any size restrictions or geo-targeting requirements
- SSP name and bidder code (e.g.,
Add the bidder code to your SDK configuration:
dartprebidServer: PrebidServerConfig( accountId: 'weatherbug', endpoint: 'https://prebid.sellwild.com/openrtb2/auction', bidders: ['appnexus', 'pubmatic', 'ix', 'rubicon', 'openx', 'new_ssp'], timeout: 1500, ),Test the integration using the curl commands in the Testing section. Verify the new bidder appears in
ext.responsetimemillisin the response.
What Sellwild Configures Server-Side
Once you provide your seat ID, the Sellwild team adds the bidder configuration to the Prebid Server account config:
adapters:
new_ssp:
enabled: true
endpoint: "https://ssp-endpoint.example.com/openrtb2"
params:
publisherId: "YOUR_SEAT_ID"No SDK update or app release is required for server-side SSP changes.
Supported Bidders
The following SSPs are available on prebid.sellwild.com. Use the Bidder Code value in your PrebidServerConfig.bidders list.
| SSP | Bidder Code | Required Params | Notes |
|---|---|---|---|
| AppNexus (Xandr) | appnexus | placementId | Supports banner, video, native |
| Pubmatic | pubmatic | publisherId, adSlot | Supports banner, video |
| Index Exchange | ix | siteId | Banner and video |
| Rubicon (Magnite) | rubicon | accountId, siteId, zoneId | Full-stack SSP |
| OpenX | openx | unit, delDomain | Banner, video |
| TripleLift | triplelift | inventoryCode | Native and display |
| Sharethrough | sharethrough | pkey | Native in-feed and display |
| InMobi | inmobi | plc | Mobile-first; strong in-app demand |
| Smaato | smaato | publisherId, adspaceId | Mobile banner, interstitial, rewarded |
| Yieldmo | yieldmo | placementId | High-impact mobile formats |
| Amazon TAM | amazontam | slotId | Requires Amazon Publisher Services setup |
| 33Across | 33across | siteId, productId | Viewable impression model |
| Sovrn | sovrn | tagid | Banner, video |
| GumGum | gumgum | zone | In-image and in-screen formats |
| Unruly | unruly | siteId | Outstream video |
| Rise (Emerse) | rise | org | Display and video |
| Criteo | criteo | zoneId | Retargeting demand |
| MediaNet | medianet | cid, crid | Contextual demand |
To request a bidder not listed here, contact the Sellwild ad operations team with the bidder code from the Prebid Server bidder list.
GDPR Enforcement
How It Works
prebid.sellwild.com is configured with gdpr.default-value: 1. This means:
- When
regs.ext.gdpris absent from the bid request: GDPR enforcement is applied by default. The server treats the request as if it originated from a GDPR-regulated region. - When
regs.ext.gdpris set to1: GDPR enforcement is explicitly enabled. The server checksuser.ext.consentfor a valid TCF v2 consent string and suppresses bidders that do not have vendor consent. - When
regs.ext.gdpris set to0: GDPR enforcement is explicitly disabled. All configured bidders receive the bid request.
How the SDK Passes Consent
When Prebid.js in the WebView constructs the OpenRTB request for Prebid Server, it includes GDPR signals in two locations:
{
"regs": {
"ext": {
"gdpr": 1
}
},
"user": {
"ext": {
"consent": "BOJ/P2HOJ/P2HABABMAAAAAZ+A=="
}
}
}regs.ext.gdpr-- integer flag (0 or 1) indicating whether GDPR applies.user.ext.consent-- the IAB TCF v2 consent string. Prebid.js reads this fromwindow.__tcfapiif a CMP is present in the WebView.
Implications for Mobile Apps
In a native mobile WebView, there is typically no CMP running inside the WebView. This means:
- Prebid.js will not find
window.__tcfapiand will send the request without a consent string. - Because
gdpr.default-valueis1, Prebid Server treats the request as subject to GDPR. - Without a valid consent string, bidders that require TCF consent will not receive the bid request.
Result: In GDPR regions, auctions may return no bids unless consent is properly configured.
Mitigation strategies:
- Prebid Server S2S mode -- Configure
tcfVersion: 2andgppEnabled: trueinSellwildConfig. The web widget may handle consent through its own in-widget CMP flow. - Native CMP bridging -- Inject the TC string from your native CMP into the WebView before Prebid.js loads (see the Flutter Integration Guide).
- Non-GDPR regions -- If your app serves only non-GDPR regions, you can verify that Prebid.js sends
regs.ext.gdpr: 0by testing with the curl commands below.
Auction Telemetry
Response Extensions
Every auction response from prebid.sellwild.com includes telemetry data in the ext object:
{
"seatbid": [...],
"ext": {
"responsetimemillis": {
"appnexus": 120,
"pubmatic": 85,
"ix": 210,
"rubicon": 0,
"openx": 145
},
"tmaxrequest": 1500,
"prebid": {
"auctiontimestamp": 1714400000000
}
}
}| Field | Description |
|---|---|
ext.responsetimemillis.<bidder> | Time in ms each bidder took to respond. 0 = timed out or error. |
ext.tmaxrequest | The effective timeout used for this auction. |
ext.prebid.auctiontimestamp | Unix timestamp (ms) of when the auction was processed. |
Monitoring Bid Prices
Winning bid prices are returned in seatbid[].bid[].price (CPM in USD):
{
"seatbid": [
{
"seat": "appnexus",
"bid": [
{
"id": "1",
"impid": "imp-1",
"price": 2.50,
"adm": "<creative markup>",
"w": 300,
"h": 250
}
]
}
]
}Key Metrics to Track
| Metric | How to Derive | Healthy Range |
|---|---|---|
| Auction fill rate | Requests with at least one seatbid / total requests | 60--90% (varies) |
| Average winning CPM | Mean of seatbid[].bid[].price across filled auctions | $0.50--$5.00 |
| Bidder timeout rate | Count of responsetimemillis values = 0 / total bidder calls | < 5% |
| P95 server response time | 95th percentile of total auction response latency | < 500ms |
| Average bidder response time | Mean of responsetimemillis per bidder | < 200ms |
Prometheus Metrics
prebid.sellwild.com exports Prometheus metrics. Contact the Sellwild team for access to the metrics endpoint or Grafana dashboards if you require real-time monitoring.
Testing
Verify the Endpoint
Confirm the Prebid Server endpoint is reachable:
curl -s -o /dev/null -w "%{http_code}" https://prebid.sellwild.com/openrtb2/auctionExpected output: 400 (the server rejects empty requests but confirms it is running).
Send a Test Auction Request
The following curl command sends a minimal OpenRTB bid request to prebid.sellwild.com with a 300x250 banner impression:
curl -s -X POST https://prebid.sellwild.com/openrtb2/auction \
-H "Content-Type: application/json" \
-d '{
"id": "test-request-001",
"imp": [
{
"id": "imp-1",
"banner": {
"w": 300,
"h": 250
},
"ext": {
"prebid": {
"bidder": {
"appnexus": {
"placementId": 13144370
}
}
}
}
}
],
"app": {
"bundle": "com.aws.android",
"storeurl": "https://play.google.com/store/apps/details?id=com.aws.android",
"publisher": {
"id": "weatherbug"
}
},
"device": {
"ua": "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36",
"ip": "203.0.113.1",
"os": "android",
"osv": "13"
},
"tmax": 1500
}' | python3 -m json.toolExpected Response Structure
A successful auction returns HTTP 200 with a JSON body:
{
"id": "test-request-001",
"seatbid": [
{
"seat": "appnexus",
"bid": [
{
"id": "bid-abc123",
"impid": "imp-1",
"price": 1.85,
"adm": "<div><!-- creative markup --></div>",
"w": 300,
"h": 250,
"crid": "98765"
}
]
}
],
"cur": "USD",
"ext": {
"responsetimemillis": {
"appnexus": 95
},
"tmaxrequest": 1500
}
}If no bidders return a bid, seatbid will be an empty array or absent from the response.
Test Multiple Bidders
Include multiple bidders in a single request:
curl -s -X POST https://prebid.sellwild.com/openrtb2/auction \
-H "Content-Type: application/json" \
-d '{
"id": "test-multi-bidder-001",
"imp": [
{
"id": "imp-1",
"banner": {
"w": 300,
"h": 250
},
"ext": {
"prebid": {
"bidder": {
"appnexus": { "placementId": 13144370 },
"pubmatic": { "publisherId": "156209", "adSlot": "slot1" },
"ix": { "siteId": "123456" }
}
}
}
}
],
"app": {
"bundle": "com.aws.android",
"storeurl": "https://play.google.com/store/apps/details?id=com.aws.android",
"publisher": {
"id": "weatherbug"
}
},
"device": {
"ua": "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36",
"ip": "203.0.113.1",
"os": "android",
"osv": "13"
},
"tmax": 1500
}' | python3 -m json.toolCheck ext.responsetimemillis in the response to verify each bidder was reached.
Test with GDPR Consent
Verify that GDPR enforcement works correctly by sending a request with explicit consent signals:
curl -s -X POST https://prebid.sellwild.com/openrtb2/auction \
-H "Content-Type: application/json" \
-d '{
"id": "test-gdpr-001",
"imp": [
{
"id": "imp-1",
"banner": { "w": 320, "h": 50 },
"ext": {
"prebid": {
"bidder": {
"appnexus": { "placementId": 13144370 }
}
}
}
}
],
"app": {
"bundle": "com.aws.android",
"publisher": { "id": "weatherbug" }
},
"regs": {
"ext": {
"gdpr": 1
}
},
"user": {
"ext": {
"consent": "BOJ/P2HOJ/P2HABABMAAAAAZ+A=="
}
},
"tmax": 1500
}' | python3 -m json.toolTo test GDPR blocking, send "gdpr": 1 without a consent string. Bidders requiring consent should return no bids.
Test with a Mobile Banner Size
Verify a 320x50 mobile banner auction:
curl -s -X POST https://prebid.sellwild.com/openrtb2/auction \
-H "Content-Type: application/json" \
-d '{
"id": "test-mobile-banner-001",
"imp": [
{
"id": "imp-1",
"banner": {
"w": 320,
"h": 50,
"format": [
{ "w": 320, "h": 50 }
]
},
"ext": {
"prebid": {
"bidder": {
"appnexus": { "placementId": 13144370 }
}
}
}
}
],
"app": {
"bundle": "com.aws.android",
"storeurl": "https://play.google.com/store/apps/details?id=com.aws.android",
"publisher": { "id": "weatherbug" }
},
"device": {
"ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)",
"os": "ios",
"osv": "17.0"
},
"tmax": 1500
}' | python3 -m json.toolHouse Ads and No-Fill Handling
When no SSP returns a bid (a "no-fill"), the SDK falls back through the following chain:
Prebid Server auction -- if configured via
PrebidServerConfig, Prebid.js sends the S2S request. Ifseatbidis empty, Prebid.js reports no demand.GAM passback -- if
gamTagis set inSellwildConfig, GPT requests the GAM ad unit. GAM can be configured with house ad line items that fill at a $0.00 CPM floor.Zone-based fallback -- if
bannerZidorzoneIdis set, the SDK loads a creative frombidstream.sellwild.com. This can serve a house ad or a direct-sold campaign.Blank slot -- if all of the above return empty, the ad slot renders as transparent. The
SellwildBannerwidget will display an emptySizedBoxat the specified dimensions.
Configuring House Ads
To ensure a house ad always fills when programmatic demand is unavailable:
- In GAM: Create a "House" line item with priority 16, $0.00 CPM, and assign a house creative. Target it to the same ad unit path used in
gamTag. - Via Sellwild zones: Contact the Sellwild ad operations team to configure a house creative on your zone ID. The zone ad server at
bidstream.sellwild.comwill return the house creative when no programmatic fill is available.
Controlling Refresh on No-Fill
The SDK respects maxFailedAuctions in SellwildConfig (default: 3). After three consecutive no-fill auctions on an ad slot, the SDK stops refreshing that slot to conserve bandwidth and battery.
SellwildConfig(
partnerCode: 'weatherbug',
listingsUrl: '...',
maxFailedAuctions: 5, // Allow more retries before stopping
adRefreshInterval: Duration(seconds: 45), // Slow down refresh rate
)Troubleshooting
GDPR Blocking -- No Bids in European Regions
Symptom: Auctions return empty seatbid for users in EU/EEA countries, but fill normally in the US.
Cause: prebid.sellwild.com has gdpr.default-value: 1. Without a TCF consent string in the request, bidders that require consent will not bid.
Resolution:
- Verify your request includes
regs.ext.gdpranduser.ext.consentby testing with curl (see Testing). - If using a native CMP, bridge the consent string to the WebView before the auction runs.
- For testing, send
"regs": { "ext": { "gdpr": 0 } }to confirm bids return when GDPR is not enforced. Do not ship this override to production for EU traffic.
DNS Errors on Rubicon or Index Exchange with Test IDs
Symptom: ext.responsetimemillis shows 0 for rubicon or ix, and server logs show DNS resolution failures.
Cause: Rubicon and Index Exchange use account-specific endpoints derived from your seat IDs (e.g., {accountId}-ssp.rubiconproject.com). When using placeholder or test seat IDs, the derived hostname does not exist in DNS.
Resolution:
- Replace test seat IDs with your production IDs from Rubicon/IX.
- Verify the bidder endpoint resolves:
dig +short {accountId}-ssp.rubiconproject.com - If you do not have a production account with these SSPs, remove them from the
bidderslist until onboarding is complete.
No Fill -- All Bidders Time Out
Symptom: ext.responsetimemillis shows 0 for all bidders. seatbid is empty.
Possible causes:
- Network connectivity: The Prebid Server instance cannot reach SSP endpoints. This is a server-side issue -- contact the Sellwild team.
- Invalid seat IDs: Bidders reject requests with unrecognized account IDs. They may return HTTP 204 (no content) or an error before the timeout.
- Timeout too low: If
timeoutis set below 500ms, slow bidders will be cut off. Increase to 1500ms. - Request validation failure: The OpenRTB request may be missing required fields. Check that
app.bundleandapp.publisher.idare set.
Debugging steps:
- Test with a known-good bidder and placement ID (e.g., AppNexus test placement
13144370). - Increase timeout to 3000ms temporarily.
- Add
"test": 1to the OpenRTB request root to enable test mode (bidders return synthetic bids).
No Fill -- Bidders Respond but Do Not Bid
Symptom: ext.responsetimemillis shows non-zero values (bidders were reached), but seatbid is empty.
Possible causes:
- Floor prices too high: Your
floorMultiplierinSellwildConfigor ad unit floors may be above the market clearing price. - Geo-targeting mismatch: The
device.ipordevice.geoin the request maps to a region the SSP does not serve. - Ad size not supported: Some SSPs do not support all IAB sizes. Verify the
banner.wandbanner.hvalues are standard sizes. - App bundle not recognized: Some SSPs have allowlists. Confirm your
app.bundleis registered with the SSP.
SDK Reports "Prebid Server Unreachable"
Symptom: The onError callback fires with a network error when PrebidServerConfig is set.
Steps:
- Verify the endpoint URL is correct:
https://prebid.sellwild.com/openrtb2/auction - Test reachability from the device: open
https://prebid.sellwild.comin the device browser. - Check for corporate firewalls or VPNs that may block the domain.
- Verify the device has an active internet connection.
High Bidder Latency
Symptom: ext.responsetimemillis shows values above 500ms for certain bidders, causing slow ad load times.
Resolution:
- Review which bidders are slow. If a bidder consistently exceeds 300ms, consider removing it to improve user experience.
- Reduce the
timeoutvalue to cap auction duration (e.g., 1000ms instead of 1500ms). Bidders that do not respond within the timeout are excluded. - Reduce the number of bidders. Each additional bidder adds marginal latency to the server-side fan-out.
WebView Console Shows "pbjs.setConfig is not a function"
Cause: Prebid.js has not loaded yet when the pre-configuration script runs.
Resolution: This should not occur with the SDK's default HTML template, which uses pbjs.que.push() to defer configuration until Prebid.js is ready. If you are using a custom prebidSrc, verify the script URL is correct and loads successfully.