DEV Community

Cover image for How to Add Adjacency-Aware Contextual Targeting to Prebid in 15 Minutes
Ethan Steininger for Mixpeek

Posted on

How to Add Adjacency-Aware Contextual Targeting to Prebid in 15 Minutes

Replace cookie-based targeting with privacy-first contextual signals — without blocking your auctions.


The Problem

Cookie deprecation is here. Third-party targeting signals are disappearing, and publishers need alternatives that:

  1. Don't rely on user identifiers
  2. Don't add latency to header bidding
  3. Work with existing SSP/DSP infrastructure

The Mixpeek RTD module solves this by enriching Prebid bid requests with contextual + adjacency signals via standard OpenRTB fields.


What You'll Get

After this 15-minute setup, your bid requests will include:

Signal Type Data
Contextual IAB v3.0 categories, keywords, sentiment, brand safety score
Adjacency Previous creative ID, bidder, ad categories

SSPs and DSPs consume these via ortb2.site.content and ortb2Imp.ext.data — no custom integration required on their end.


Step 1: Install the Module

npm install @mixpeek/prebid
Enter fullscreen mode Exit fullscreen mode

Or add via CDN:

<script src="https://unpkg.com/@mixpeek/prebid@latest/dist/mixpeek-rtd.min.js"></script>
Enter fullscreen mode Exit fullscreen mode

Step 2: Get Your Credentials

  1. Sign up at mixpeek.com
  2. Generate an API key in your dashboard
  3. Create a collection with feature extractors
  4. Note your namespace ID (format: ns_xxxxx)

Step 3: Configure Prebid

Add the RTD provider to your Prebid config:

import '@mixpeek/prebid'pbjs.setConfig({  realTimeData: {
    auctionDelay: 250,  // Max wait time (ms)
    dataProviders: [{
      name: 'mixpeek',
      waitForIt: true,
      params: {
        apiKey: 'YOUR_API_KEY',
        collectionId: 'YOUR_COLLECTION_ID',
        namespace: 'YOUR_NAMESPACE'
      }
    }]
  }
})
Enter fullscreen mode Exit fullscreen mode

That's it. Bid requests are now enriched automatically.


Step 4: Verify the Output

Check that contextual data is being injected:

pbjs.onEvent('mixpeekContextReady', function(context) {
  console.log('Category:', context.taxonomy?.label)
  console.log('Keywords:', context.keywords)
  console.log('Brand Safety:', context.brandSafety)
})
Enter fullscreen mode Exit fullscreen mode

Your ortb2 object will now include:

{
  "site": {
    "content": {
      "cat": ["IAB19-11"],
      "cattax": 6,
      "genre": "Technology",
      "keywords": "ai,technology,ml",
      "ext": {
        "data": {
          "mixpeek": {
            "score": 0.94,
            "brandSafety": 0.98,
            "sentiment": "positive"
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

How DSPs Consume the Signals

DSPs can use the enriched data for:

Contextual Targeting

// Target technology content
if (ortb2.site.content.cat.includes('IAB19-11')) {
  // Bid on tech inventory
}
Enter fullscreen mode Exit fullscreen mode

Competitive Separation

// Avoid back-to-back competing ads
const prevCat = ortb2Imp.ext.data.hb_mixpeek_prev_cat
if (prevCat === 'IAB18-1' && currentAd.category === 'IAB18-1') {
  // Skip this impression
}
Enter fullscreen mode Exit fullscreen mode

Brand Safety

// Only bid on safe inventory
if (ortb2.site.content.ext.data.mixpeek.brandSafety > 0.9) {
  // Safe to bid
}
Enter fullscreen mode Exit fullscreen mode

Shadow Mode: Risk-Free Testing

Want to test without affecting live auctions? Use shadow mode:

pbjs.setConfig({
  realTimeData: {
    auctionDelay: 0,  // No delay
    dataProviders: [{
      name: 'mixpeek',
      waitForIt: false,  // Don't wait for response
      params: {
        apiKey: 'YOUR_API_KEY',
        collectionId: 'YOUR_COLLECTION_ID',
        namespace: 'YOUR_NAMESPACE'
      }
    }]
  }
})
Enter fullscreen mode Exit fullscreen mode

This logs contextual data without blocking auctions. Perfect for validating the integration before going

Top comments (0)