npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mixpeek/openrtb

v1.0.2

Published

OpenRTB 2.5/2.6/3.0 reference implementation for contextual content enrichment with IAB Taxonomy 3.0 mapping

Readme

@mixpeek/openrtb

OpenRTB 2.5/2.6/3.0 reference implementation for contextual content enrichment.

View all Mixpeek connectors →

npm version License: MIT

Scope & Intent

This package is a non-normative reference implementation intended to:

  • Demonstrate valid OpenRTB 2.5/2.6/3.0 enrichment patterns
  • Provide executable examples of site.content and imp.ext.data usage
  • Validate field mappings against the OpenRTB specification
  • Show compliant IAB Content Taxonomy 3.0 category assignment

It is not a required runtime dependency for OpenRTB implementations. Production systems may implement equivalent logic in any language.

Overview

This reference implementation extracts content from OpenRTB bid requests, processes it through Mixpeek's content analysis API, and returns enrichments formatted as spec-compliant OpenRTB fields. All output conforms to OpenRTB 2.5/2.6/3.0 field definitions.

Key Characteristics

  • Spec-Compliant Output: All enrichments map to standard OpenRTB fields
  • RTB-Safe Latency: Sub-200ms processing, never blocks bid flow
  • IAB Taxonomy 3.0: Category assignments use cattax: 7 per spec
  • Graceful Degradation: Fallback enrichments on API failure
  • Privacy-First: No user tracking or PII—pure contextual signals

Who This Is For

  • Engineers implementing or validating OpenRTB pipelines
  • SSP/DSP platform teams testing contextual enrichment patterns
  • Standards reviewers evaluating non-normative examples
  • Ad tech teams building spec-compliant RTB infrastructure

Installation

npm install @mixpeek/openrtb

Quick Start

import { createEnricher } from '@mixpeek/openrtb';

// Create enricher instance
const enricher = createEnricher({
  apiKey: 'your_mixpeek_api_key',
  collectionId: 'your_collection_id',
  namespace: 'your_namespace'
});

// Enrich an OpenRTB bid request
const bidRequest = {
  id: 'request-123',
  imp: [{ id: 'imp-1', banner: { w: 300, h: 250 } }],
  site: {
    domain: 'example.com',
    page: 'https://example.com/article/tech-news',
    content: {
      title: 'Latest Technology News',
      keywords: 'technology,software,ai'
    }
  }
};

// Get enriched bid request
const enrichedRequest = await enricher.enrichBidRequest(bidRequest);

// Or get enrichment data separately
const result = await enricher.enrich(bidRequest);
console.log(result.ortb2);      // OpenRTB site.content
console.log(result.targeting);  // Targeting key-values
console.log(result.enrichments); // Raw enrichment data

Configuration

| Option | Type | Default | Description | |--------|------|---------|-------------| | apiKey | string | required | Mixpeek API key | | collectionId | string | required | Collection ID for document storage | | namespace | string | required | Namespace for data isolation | | endpoint | string | https://api.mixpeek.com | API endpoint | | timeout | number | 200 | Request timeout in milliseconds | | cacheTTL | number | 300 | Cache TTL in seconds | | enableCache | boolean | true | Enable response caching | | enableFallback | boolean | true | Enable fallback enrichments on API failure | | debug | boolean | false | Enable debug logging |

Full Configuration Example

const enricher = createEnricher({
  apiKey: process.env.MIXPEEK_API_KEY,
  collectionId: process.env.MIXPEEK_COLLECTION_ID,
  namespace: process.env.MIXPEEK_NAMESPACE,
  endpoint: 'https://api.mixpeek.com',
  timeout: 200,
  cacheTTL: 300,
  enableCache: true,
  enableFallback: true,
  debug: false
});

API Reference

createEnricher(config)

Creates a new OpenRTB enricher instance.

const enricher = createEnricher(config);

enricher.enrich(bidRequest, options?)

Processes a bid request and returns enrichment data.

const result = await enricher.enrich(bidRequest);

// Result structure:
{
  success: true,
  enrichments: {
    keywords: ['technology', 'software', 'ai'],
    sentiment: { sentiment: 'positive', score: 0.7 },
    categories: { category: 'IAB19', categoryName: 'Technology', confidence: 0.9 },
    brandSafety: { level: 'safe', score: 1.0 },
    documentId: 'doc-123'
  },
  extractedContent: { /* extracted OpenRTB content */ },
  ortb2: {
    site: {
      content: { /* OpenRTB 2.6 site.content */ }
    }
  },
  targeting: {
    mixpeek_cat: 'IAB19',
    mixpeek_sentiment: 'positive',
    mixpeek_brand_safe: 'safe'
  },
  cached: false,
  latencyMs: 45
}

enricher.enrichBidRequest(bidRequest, options?)

Enriches a bid request in-place and returns the modified request.

const enrichedRequest = await enricher.enrichBidRequest(bidRequest);

// The returned request includes:
// - site.content with Mixpeek enrichments
// - imp[].ext.data.mixpeek for each impression
// - ext.mixpeek at request level

enricher.healthCheck()

Checks API health and returns status.

const health = await enricher.healthCheck();
// { status: 'healthy', latency: 50, timestamp: '...', cache: {...}, metrics: {...} }

enricher.getMetrics()

Returns processing metrics.

const metrics = enricher.getMetrics();
// { requests: 100, cacheHits: 40, cacheHitRate: 40, apiCalls: 60, avgLatencyMs: 45 }

enricher.clearCache()

Clears the enrichment cache.

enricher.destroy()

Cleans up resources (timers, cache).

OpenRTB Output Format

Site Content (OpenRTB 2.6)

{
  site: {
    content: {
      cat: ['IAB19', 'IAB19-18'],      // IAB categories
      keywords: 'technology,software,ai', // Keywords string
      cattax: 7,                        // IAB Tech Lab Content Taxonomy 3.0
      ext: {
        mixpeek: {
          sentiment: 'positive',        // positive/neutral/negative
          sentimentScore: 0.7,          // -1.0 to 1.0
          brandSafety: {
            level: 'safe',              // safe/low_risk/medium_risk/high_risk/blocked
            score: 1.0                  // 0.0 to 1.0
          },
          taxonomy: {
            category: 'IAB19',
            categoryName: 'Technology & Computing',
            confidence: 0.9
          },
          documentId: 'doc-123',
          embeddingId: 'emb-123',
          source: 'api',
          version: '1.0.0'
        }
      }
    }
  }
}

Impression Extension

{
  imp: [{
    id: 'imp-1',
    ext: {
      data: {
        mixpeek: {
          impId: 'imp-1',
          category: 'IAB19',
          categoryName: 'Technology & Computing',
          keywords: ['technology', 'software', 'ai'],
          sentiment: 'positive',
          brandSafetyLevel: 'safe',
          brandSafetyScore: 1.0,
          contentType: 'article',
          language: 'en'
        }
      }
    }
  }]
}

Targeting Keys

| Key | Description | Example | |-----|-------------|---------| | mixpeek_cat | Primary IAB category | IAB19 | | mixpeek_subcat | Category name | Technology & Computing | | mixpeek_kw | Top keywords | technology,software,ai | | mixpeek_sentiment | Sentiment | positive | | mixpeek_brand_safe | Brand safety level | safe | | mixpeek_content_type | Content type | article | | mixpeek_lang | Language | en | | mixpeek_emb_id | Embedding ID | emb-123 |

Supported Bid Request Types

Site Requests

{
  site: {
    domain: 'example.com',
    page: 'https://example.com/article',
    keywords: 'news,technology',
    cat: ['IAB19'],
    content: {
      title: 'Article Title',
      keywords: 'content,keywords'
    }
  }
}

App Requests

{
  app: {
    name: 'News App',
    bundle: 'com.example.newsapp',
    cat: ['IAB12'],
    content: {
      title: 'News Feed',
      keywords: 'news,breaking'
    }
  }
}

Video Requests

{
  imp: [{
    video: {
      mimes: ['video/mp4'],
      minduration: 5,
      maxduration: 30
    }
  }],
  site: {
    content: {
      title: 'Video Title',
      series: 'Series Name',
      len: 1800,
      livestream: 0
    }
  }
}

Caching

The connector includes built-in caching to minimize API calls and latency:

  • In-memory cache with configurable TTL
  • LRU eviction when max items reached
  • Automatic cache key generation from URL/title/content
  • Cache statistics available via getCacheStats()
// Check cache stats
const stats = enricher.getCacheStats();
console.log(stats);
// { size: 150, maxSize: 1000, hits: 500, misses: 200, hitRate: 71.43, ... }

Error Handling & Fallback

The connector never blocks bid processing:

  1. Timeout: Requests timeout after configurable duration (default 200ms)
  2. Fallback: On API failure, local enrichments are provided
  3. Graceful Degradation: Always returns a valid response structure
const result = await enricher.enrich(bidRequest);

if (!result.success) {
  console.log('API failed, using fallback:', result.error);
  // result.ortb2 still contains fallback data
}

Testing

# Run all tests
npm test

# Unit tests only
npm run test:unit

# Integration tests
npm run test:integration

# E2E tests
npm run test:e2e

# Live API tests (requires credentials)
export MIXPEEK_API_KEY="your_key"
export MIXPEEK_COLLECTION_ID="col_xxx"
export MIXPEEK_NAMESPACE="ns_xxx"
npm run test:live

# Coverage report
npm run test:coverage

Performance

| Metric | Target | Typical | |--------|--------|---------| | Processing latency | <100ms | 30-50ms | | API timeout | 200ms | - | | Cache hit rate | >50% | 60-80% | | Memory footprint | <50MB | 10-30MB |

Examples

Basic Enrichment

import { createEnricher } from '@mixpeek/openrtb';

const enricher = createEnricher({
  apiKey: process.env.MIXPEEK_API_KEY,
  collectionId: process.env.MIXPEEK_COLLECTION_ID,
  namespace: process.env.MIXPEEK_NAMESPACE,
  timeout: 150 // RTB-safe timeout
});

async function processBidRequest(bidRequest) {
  // Enrich and return spec-compliant output
  const enrichedRequest = await enricher.enrichBidRequest(bidRequest);
  return enrichedRequest;
}

Validating Output Fields

const result = await enricher.enrich(bidRequest);

// Verify IAB Taxonomy 3.0 compliance
console.log(result.ortb2.site.content.cattax); // 7 (IAB Tech Lab Content Taxonomy 3.0)
console.log(result.ortb2.site.content.cat);    // ['IAB19', 'IAB19-18']

// Check standard field mappings
console.log(result.ortb2.site.content.keywords); // 'technology,software,ai'

Changelog

v1.0.0

  • Initial release
  • OpenRTB 2.5/2.6/3.0 support
  • Site, app, and video bid request handling
  • IAB Content Taxonomy 3.0 mapping
  • Brand safety scoring
  • Sentiment analysis
  • In-memory caching with LRU eviction
  • Comprehensive test suite

License

MIT License - see LICENSE for details.


Appendix: Example Downstream Usage (Non-spec)

The following examples show how enriched data might be consumed by downstream systems. These patterns are not part of the OpenRTB specification and are provided for illustration only.

SSP: Enriching Before Auction

async function processBidRequest(bidRequest) {
  const enrichedRequest = await enricher.enrichBidRequest(bidRequest);

  // Send enriched request to DSPs
  const responses = await sendToDSPs(enrichedRequest);
  return responses;
}

DSP: Using Enrichments for Bid Decisions

async function evaluateBidRequest(bidRequest) {
  const result = await enricher.enrich(bidRequest);

  // Brand safety check
  if (result.enrichments.brandSafety.level === 'high_risk') {
    return null; // Don't bid
  }

  // Context-based bid adjustment
  let bidModifier = 1.0;
  if (result.enrichments.categories.category === 'IAB19') {
    bidModifier = 1.2; // Tech content premium
  }

  return calculateBid(bidRequest, bidModifier);
}

Support