@mixpeek/prebid 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +153 -0
- package/ENDPOINTS.md +308 -0
- package/LICENSE +68 -0
- package/QUICKSTART.md +234 -0
- package/README.md +439 -0
- package/TESTING.md +341 -0
- package/dist/mixpeekContextAdapter.js +3 -0
- package/dist/mixpeekContextAdapter.js.LICENSE.txt +1 -0
- package/dist/mixpeekContextAdapter.js.map +1 -0
- package/docs/MIGRATION_V2.md +519 -0
- package/docs/api-reference.md +455 -0
- package/docs/health-check.md +348 -0
- package/docs/integration-guide.md +577 -0
- package/examples/publisher-demo/README.md +65 -0
- package/examples/publisher-demo/index.html +331 -0
- package/examples/publisher-demo/package.json +11 -0
- package/package.json +82 -0
- package/src/api/mixpeekClient.js +303 -0
- package/src/cache/cacheManager.js +245 -0
- package/src/config/constants.js +125 -0
- package/src/extractors/imageExtractor.js +142 -0
- package/src/extractors/pageExtractor.js +196 -0
- package/src/extractors/videoExtractor.js +228 -0
- package/src/modules/mixpeekContextAdapter.js +833 -0
- package/src/modules/mixpeekRtdProvider.js +305 -0
- package/src/prebid/prebidIntegration.js +117 -0
- package/src/utils/helpers.js +261 -0
- package/src/utils/iabMapping.js +367 -0
- package/src/utils/logger.js +64 -0
- package/src/utils/previousAdTracker.js +95 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
Complete API documentation for the Mixpeek Context Adapter.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Configuration](#configuration)
|
|
8
|
+
- [Adapter Methods](#adapter-methods)
|
|
9
|
+
- [Events](#events)
|
|
10
|
+
- [Data Structures](#data-structures)
|
|
11
|
+
- [Error Codes](#error-codes)
|
|
12
|
+
|
|
13
|
+
## Configuration
|
|
14
|
+
|
|
15
|
+
### `pbjs.setConfig({ mixpeek: {...} })`
|
|
16
|
+
|
|
17
|
+
Configure the Mixpeek Context Adapter.
|
|
18
|
+
|
|
19
|
+
#### Required Parameters
|
|
20
|
+
|
|
21
|
+
| Parameter | Type | Description |
|
|
22
|
+
|-----------|------|-------------|
|
|
23
|
+
| `apiKey` | string | Your Mixpeek API key (starts with `sk_`) |
|
|
24
|
+
| `collectionId` | string | Mixpeek collection ID (starts with `col_`) |
|
|
25
|
+
|
|
26
|
+
#### Optional Parameters
|
|
27
|
+
|
|
28
|
+
| Parameter | Type | Default | Description |
|
|
29
|
+
|-----------|------|---------|-------------|
|
|
30
|
+
| `endpoint` | string | `https://api.mixpeek.com` | Mixpeek API endpoint |
|
|
31
|
+
| `namespace` | string | `null` | Optional namespace for data isolation |
|
|
32
|
+
| `mode` | string | `auto` | Content mode: `auto`, `page`, `video`, or `image` |
|
|
33
|
+
| `videoSelector` | string | `video` | CSS selector for video elements |
|
|
34
|
+
| `maxImages` | number | `5` | Maximum number of images to analyze |
|
|
35
|
+
| `featureExtractors` | array | `['taxonomy']` | Feature extractors to use |
|
|
36
|
+
| `customExtractors` | array | `[]` | Custom feature extractor configurations |
|
|
37
|
+
| `timeout` | number | `250` | API request timeout in milliseconds |
|
|
38
|
+
| `retryAttempts` | number | `2` | Number of retry attempts on failure |
|
|
39
|
+
| `enableCache` | boolean | `true` | Enable local caching |
|
|
40
|
+
| `cacheTTL` | number | `300` | Cache time-to-live in seconds |
|
|
41
|
+
| `debug` | boolean | `false` | Enable debug logging |
|
|
42
|
+
| `batchSize` | number | `1` | Number of concurrent requests |
|
|
43
|
+
|
|
44
|
+
#### Example
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
pbjs.setConfig({
|
|
48
|
+
mixpeek: {
|
|
49
|
+
apiKey: 'sk_1234567890abcdef',
|
|
50
|
+
collectionId: 'col_abc123xyz',
|
|
51
|
+
namespace: 'production',
|
|
52
|
+
mode: 'auto',
|
|
53
|
+
featureExtractors: ['taxonomy', 'brand-safety', 'keywords'],
|
|
54
|
+
timeout: 250,
|
|
55
|
+
cacheTTL: 300,
|
|
56
|
+
enableCache: true,
|
|
57
|
+
debug: false
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Adapter Methods
|
|
63
|
+
|
|
64
|
+
### Direct Access
|
|
65
|
+
|
|
66
|
+
The adapter is available globally as `window.MixpeekContextAdapter`.
|
|
67
|
+
|
|
68
|
+
### `init(config)`
|
|
69
|
+
|
|
70
|
+
Initialize the adapter with configuration.
|
|
71
|
+
|
|
72
|
+
**Parameters:**
|
|
73
|
+
- `config` (object): Configuration object (same as setConfig)
|
|
74
|
+
|
|
75
|
+
**Returns:** `boolean` - Success status
|
|
76
|
+
|
|
77
|
+
**Example:**
|
|
78
|
+
```javascript
|
|
79
|
+
const success = window.MixpeekContextAdapter.init({
|
|
80
|
+
apiKey: 'sk_...',
|
|
81
|
+
collectionId: 'col_...'
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### `enrichAdUnits(adUnits)`
|
|
86
|
+
|
|
87
|
+
Enrich ad units with contextual data.
|
|
88
|
+
|
|
89
|
+
**Parameters:**
|
|
90
|
+
- `adUnits` (array): Array of Prebid ad unit objects
|
|
91
|
+
|
|
92
|
+
**Returns:** `Promise<array>` - Enriched ad units
|
|
93
|
+
|
|
94
|
+
**Example:**
|
|
95
|
+
```javascript
|
|
96
|
+
const enriched = await window.MixpeekContextAdapter.enrichAdUnits(adUnits);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### `getContext()`
|
|
100
|
+
|
|
101
|
+
Get contextual data for the current page.
|
|
102
|
+
|
|
103
|
+
**Returns:** `Promise<object>` - Context data object
|
|
104
|
+
|
|
105
|
+
**Example:**
|
|
106
|
+
```javascript
|
|
107
|
+
const context = await window.MixpeekContextAdapter.getContext();
|
|
108
|
+
console.log(context.taxonomy.label); // "IAB12-6: Mobile Phones"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### `getContextData()`
|
|
112
|
+
|
|
113
|
+
Get the most recent context data (synchronous).
|
|
114
|
+
|
|
115
|
+
**Returns:** `object|null` - Context data or null
|
|
116
|
+
|
|
117
|
+
**Example:**
|
|
118
|
+
```javascript
|
|
119
|
+
const context = window.MixpeekContextAdapter.getContextData();
|
|
120
|
+
if (context) {
|
|
121
|
+
console.log(context.taxonomy);
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### `clearCache()`
|
|
126
|
+
|
|
127
|
+
Clear all cached context data.
|
|
128
|
+
|
|
129
|
+
**Example:**
|
|
130
|
+
```javascript
|
|
131
|
+
window.MixpeekContextAdapter.clearCache();
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### `getCacheStats()`
|
|
135
|
+
|
|
136
|
+
Get cache statistics.
|
|
137
|
+
|
|
138
|
+
**Returns:** `object` - Cache statistics
|
|
139
|
+
|
|
140
|
+
**Example:**
|
|
141
|
+
```javascript
|
|
142
|
+
const stats = window.MixpeekContextAdapter.getCacheStats();
|
|
143
|
+
console.log(stats);
|
|
144
|
+
// {
|
|
145
|
+
// memoryCount: 5,
|
|
146
|
+
// localStorageCount: 3,
|
|
147
|
+
// localStorageSize: 12450,
|
|
148
|
+
// ttl: 300
|
|
149
|
+
// }
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### `healthCheck()`
|
|
153
|
+
|
|
154
|
+
Perform a health check on the Mixpeek API.
|
|
155
|
+
|
|
156
|
+
**Returns:** `Promise<object>` - Health status
|
|
157
|
+
|
|
158
|
+
**Example:**
|
|
159
|
+
```javascript
|
|
160
|
+
const health = await window.MixpeekContextAdapter.healthCheck();
|
|
161
|
+
console.log(health.status); // "ok"
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### `on(event, callback)`
|
|
165
|
+
|
|
166
|
+
Register an event listener.
|
|
167
|
+
|
|
168
|
+
**Parameters:**
|
|
169
|
+
- `event` (string): Event name
|
|
170
|
+
- `callback` (function): Callback function
|
|
171
|
+
|
|
172
|
+
**Example:**
|
|
173
|
+
```javascript
|
|
174
|
+
window.MixpeekContextAdapter.on('mixpeekContextReady', function(context) {
|
|
175
|
+
console.log('Context ready:', context);
|
|
176
|
+
});
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Events
|
|
180
|
+
|
|
181
|
+
All events are emitted through Prebid's event system and can be listened to via `pbjs.onEvent()` or `adapter.on()`.
|
|
182
|
+
|
|
183
|
+
### `mixpeekContextReady`
|
|
184
|
+
|
|
185
|
+
Fired when context data is successfully loaded.
|
|
186
|
+
|
|
187
|
+
**Callback Parameters:**
|
|
188
|
+
- `context` (object): Context data object
|
|
189
|
+
|
|
190
|
+
**Example:**
|
|
191
|
+
```javascript
|
|
192
|
+
pbjs.onEvent('mixpeekContextReady', function(context) {
|
|
193
|
+
console.log('Taxonomy:', context.taxonomy.label);
|
|
194
|
+
console.log('Score:', context.taxonomy.score);
|
|
195
|
+
console.log('Brand Safety:', context.brandSafety);
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### `mixpeekContextError`
|
|
200
|
+
|
|
201
|
+
Fired when an error occurs during context enrichment.
|
|
202
|
+
|
|
203
|
+
**Callback Parameters:**
|
|
204
|
+
- `error` (object): Error object
|
|
205
|
+
|
|
206
|
+
**Example:**
|
|
207
|
+
```javascript
|
|
208
|
+
pbjs.onEvent('mixpeekContextError', function(error) {
|
|
209
|
+
console.error('Error:', error.message);
|
|
210
|
+
console.error('Code:', error.code);
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### `mixpeekContextCached`
|
|
215
|
+
|
|
216
|
+
Fired when cached context data is used.
|
|
217
|
+
|
|
218
|
+
**Callback Parameters:**
|
|
219
|
+
- `context` (object): Cached context data
|
|
220
|
+
|
|
221
|
+
**Example:**
|
|
222
|
+
```javascript
|
|
223
|
+
pbjs.onEvent('mixpeekContextCached', function(context) {
|
|
224
|
+
console.log('Using cached context');
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### `mixpeekApiRequest`
|
|
229
|
+
|
|
230
|
+
Fired when an API request is made.
|
|
231
|
+
|
|
232
|
+
**Callback Parameters:**
|
|
233
|
+
- `data` (object): Request data
|
|
234
|
+
|
|
235
|
+
**Example:**
|
|
236
|
+
```javascript
|
|
237
|
+
pbjs.onEvent('mixpeekApiRequest', function(data) {
|
|
238
|
+
console.log('API request:', data.content, data.mode);
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### `mixpeekApiResponse`
|
|
243
|
+
|
|
244
|
+
Fired when an API response is received.
|
|
245
|
+
|
|
246
|
+
**Callback Parameters:**
|
|
247
|
+
- `data` (object): Response data
|
|
248
|
+
|
|
249
|
+
**Example:**
|
|
250
|
+
```javascript
|
|
251
|
+
pbjs.onEvent('mixpeekApiResponse', function(data) {
|
|
252
|
+
console.log('Document ID:', data.document_id);
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Data Structures
|
|
257
|
+
|
|
258
|
+
### Context Object
|
|
259
|
+
|
|
260
|
+
The context object returned by `getContext()` and `mixpeekContextReady` event:
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
{
|
|
264
|
+
documentId: string, // Mixpeek document ID
|
|
265
|
+
mode: string, // Content mode: 'page', 'video', or 'image'
|
|
266
|
+
content: {
|
|
267
|
+
url: string, // Content URL
|
|
268
|
+
title: string, // Content title
|
|
269
|
+
type: string // Content type
|
|
270
|
+
},
|
|
271
|
+
taxonomy?: {
|
|
272
|
+
label: string, // Taxonomy label (e.g., "IAB12-6: Mobile Phones")
|
|
273
|
+
nodeId: string, // Taxonomy node ID
|
|
274
|
+
path: string[], // Hierarchical path
|
|
275
|
+
score: number, // Confidence score (0-1)
|
|
276
|
+
all: array // All taxonomy results
|
|
277
|
+
},
|
|
278
|
+
brandSafety?: number | object, // Brand safety score or object
|
|
279
|
+
keywords?: string[], // Extracted keywords
|
|
280
|
+
sentiment?: string | object, // Sentiment analysis
|
|
281
|
+
embeddingId?: string // Embedding ID for retrieval
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Ad Unit Object
|
|
286
|
+
|
|
287
|
+
Ad units are enriched with Mixpeek targeting keys:
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
{
|
|
291
|
+
code: string,
|
|
292
|
+
mediaTypes: {...},
|
|
293
|
+
ortb2Imp: {
|
|
294
|
+
ext: {
|
|
295
|
+
data: {
|
|
296
|
+
// Current page context
|
|
297
|
+
hb_mixpeek_taxonomy: string, // IAB taxonomy code
|
|
298
|
+
hb_mixpeek_category: string, // Category label
|
|
299
|
+
hb_mixpeek_node: string, // Taxonomy node ID
|
|
300
|
+
hb_mixpeek_path: string, // Category path
|
|
301
|
+
hb_mixpeek_score: string, // Confidence score
|
|
302
|
+
hb_mixpeek_safety: string, // Brand safety score
|
|
303
|
+
hb_mixpeek_keywords: string, // Comma-separated keywords
|
|
304
|
+
hb_mixpeek_sentiment: string, // Sentiment label
|
|
305
|
+
hb_mixpeek_embed: string, // Embedding ID
|
|
306
|
+
|
|
307
|
+
// Previous ad context (adjacency awareness)
|
|
308
|
+
hb_mixpeek_prev_creative: string, // Last creative ID
|
|
309
|
+
hb_mixpeek_prev_bidder: string, // Last winning bidder
|
|
310
|
+
hb_mixpeek_prev_adunit: string, // Last ad unit code
|
|
311
|
+
hb_mixpeek_prev_cat: string // Last ad categories (comma-separated)
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
bids: [
|
|
316
|
+
{
|
|
317
|
+
bidder: string,
|
|
318
|
+
params: {
|
|
319
|
+
keywords: {
|
|
320
|
+
// Same targeting keys as above
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
]
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Feature Extractor Configuration
|
|
329
|
+
|
|
330
|
+
Custom feature extractor configuration:
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
{
|
|
334
|
+
feature_extractor_id: string, // Feature extractor ID
|
|
335
|
+
payload?: { // Optional payload
|
|
336
|
+
[key: string]: any
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
**Example:**
|
|
342
|
+
```javascript
|
|
343
|
+
{
|
|
344
|
+
feature_extractor_id: 'taxonomy',
|
|
345
|
+
payload: {
|
|
346
|
+
version: '3.0',
|
|
347
|
+
threshold: 0.7,
|
|
348
|
+
top_k: 5
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## Error Codes
|
|
354
|
+
|
|
355
|
+
### `INVALID_CONFIG`
|
|
356
|
+
|
|
357
|
+
Configuration validation failed.
|
|
358
|
+
|
|
359
|
+
**Common Causes:**
|
|
360
|
+
- Missing `apiKey` or `collectionId`
|
|
361
|
+
- Invalid data types
|
|
362
|
+
- Negative timeout or cacheTTL
|
|
363
|
+
|
|
364
|
+
### `API_TIMEOUT`
|
|
365
|
+
|
|
366
|
+
API request exceeded timeout limit.
|
|
367
|
+
|
|
368
|
+
**Common Causes:**
|
|
369
|
+
- Network latency
|
|
370
|
+
- Timeout set too low
|
|
371
|
+
- Mixpeek API performance issues
|
|
372
|
+
|
|
373
|
+
### `API_ERROR`
|
|
374
|
+
|
|
375
|
+
API returned an error response.
|
|
376
|
+
|
|
377
|
+
**Common Causes:**
|
|
378
|
+
- Invalid API key
|
|
379
|
+
- Collection not found
|
|
380
|
+
- Rate limit exceeded
|
|
381
|
+
- Server error
|
|
382
|
+
|
|
383
|
+
### `NETWORK_ERROR`
|
|
384
|
+
|
|
385
|
+
Network request failed.
|
|
386
|
+
|
|
387
|
+
**Common Causes:**
|
|
388
|
+
- No internet connection
|
|
389
|
+
- CORS issues
|
|
390
|
+
- Firewall blocking requests
|
|
391
|
+
|
|
392
|
+
### `INVALID_RESPONSE`
|
|
393
|
+
|
|
394
|
+
API response could not be parsed.
|
|
395
|
+
|
|
396
|
+
**Common Causes:**
|
|
397
|
+
- Malformed JSON
|
|
398
|
+
- Unexpected response structure
|
|
399
|
+
|
|
400
|
+
### `MISSING_CONTENT`
|
|
401
|
+
|
|
402
|
+
No content could be extracted from the page.
|
|
403
|
+
|
|
404
|
+
**Common Causes:**
|
|
405
|
+
- Empty page
|
|
406
|
+
- Content blocked by scripts
|
|
407
|
+
- Incorrect content mode
|
|
408
|
+
|
|
409
|
+
### `CACHE_ERROR`
|
|
410
|
+
|
|
411
|
+
Cache operation failed.
|
|
412
|
+
|
|
413
|
+
**Common Causes:**
|
|
414
|
+
- localStorage unavailable
|
|
415
|
+
- Storage quota exceeded
|
|
416
|
+
|
|
417
|
+
## HTTP Status Codes
|
|
418
|
+
|
|
419
|
+
| Code | Meaning | Action |
|
|
420
|
+
|------|---------|--------|
|
|
421
|
+
| 200 | Success | Process response |
|
|
422
|
+
| 400 | Bad Request | Check request payload |
|
|
423
|
+
| 401 | Unauthorized | Verify API key |
|
|
424
|
+
| 403 | Forbidden | Check API permissions |
|
|
425
|
+
| 404 | Not Found | Verify collection ID |
|
|
426
|
+
| 429 | Rate Limited | Implement backoff |
|
|
427
|
+
| 500 | Server Error | Retry request |
|
|
428
|
+
|
|
429
|
+
## Rate Limits
|
|
430
|
+
|
|
431
|
+
Default Mixpeek API rate limits:
|
|
432
|
+
|
|
433
|
+
- **Requests per minute**: 100
|
|
434
|
+
- **Requests per hour**: 5,000
|
|
435
|
+
- **Burst**: 10 concurrent
|
|
436
|
+
|
|
437
|
+
Contact Mixpeek to increase limits for production use.
|
|
438
|
+
|
|
439
|
+
## Best Practices
|
|
440
|
+
|
|
441
|
+
1. **Cache Effectively**: Set `cacheTTL` based on content update frequency
|
|
442
|
+
2. **Handle Errors**: Always listen to `mixpeekContextError` events
|
|
443
|
+
3. **Optimize Timeout**: Balance between speed and reliability (250ms recommended)
|
|
444
|
+
4. **Monitor Performance**: Track API latency and cache hit rate
|
|
445
|
+
5. **Test Thoroughly**: Verify targeting keys reach all bidders
|
|
446
|
+
6. **Debug Locally**: Use `debug: true` during development only
|
|
447
|
+
|
|
448
|
+
## Support
|
|
449
|
+
|
|
450
|
+
For questions or issues:
|
|
451
|
+
|
|
452
|
+
- **Documentation**: [docs.mixpeek.com](https://docs.mixpeek.com)
|
|
453
|
+
- **Email**: support@mixpeek.com
|
|
454
|
+
- **GitHub**: [github.com/mixpeek/prebid-contextual-adapter](https://github.com/mixpeek/prebid-contextual-adapter)
|
|
455
|
+
|