Network Inspector Guide
Verify NotPixel’s privacy claims yourself. This guide shows how to inspect network traffic and confirm that your users’ text never leaves their device when using privacy: true.
Trust, but verify. We believe privacy claims should be independently verifiable. Use your browser’s DevTools to see exactly what data is transmitted.
Quick Verification
Open DevTools
Press F12 or Cmd+Option+I (Mac) / Ctrl+Shift+I (Windows/Linux)
Go to Network Tab
Click on the Network tab in DevTools
Filter by “pick”
Type pick in the filter box to show only NotPixel API calls
Make a Request
Trigger an ad request in your app (e.g., send a message in chat)
Inspect the Payload
Click on the request → Payload tab → examine the request body
What You’ll See
With privacy: true (Local Embeddings)
{
"publisherId": "pub_abc123",
"mode": "embedding",
"embedding": [
0.0234, -0.0891, 0.1456, 0.0023, -0.0567, 0.0891, ...
// 384 floating-point numbers
],
"context": {
"lang": "en"
}
}What to notice:
modeis"embedding"— indicates local embedding modeembeddingcontains only numbers — mathematical vector representation- No
inputfield — your text was never sent - The 384 numbers are irreversible — cannot be converted back to text
Key verification: There should be NO input field in the request. If you see an input field with text, privacy mode is not active.
With privacy: false (Standard Mode)
{
"publisherId": "pub_abc123",
"mode": "standard",
"input": "help me optimize my SQL query for [email]",
"context": {
"lang": "en"
}
}What to notice:
modeis"standard"inputcontains sanitized text — PII like emails are replaced with[email]- Original email address is NOT visible
Step-by-Step: Chrome DevTools
Chrome/Edge
Chrome / Edge
-
Open DevTools: Right-click anywhere → “Inspect” or press
F12 -
Network Tab: Click “Network” in the top toolbar
-
Enable Preserve Log: Check “Preserve log” to keep requests after navigation
-
Filter Requests: Type
pickornotpixelin the filter box -
Make a Request: Use your app to trigger an ad fetch
-
Click the Request: Find the request to
/v1/pick -
View Payload:
- Click “Payload” tab
- Expand “Request Payload”
- Verify no
inputfield exists (for privacy mode)
-
View as Raw: Click “view source” to see the raw JSON
Verification Checklist
Use this checklist to verify privacy mode is working correctly:
For privacy: true
| Check | Expected | Status |
|---|---|---|
| Request URL | Contains /v1/pick | |
mode field | "embedding" | |
embedding field | Array of ~384 numbers | |
input field | Should NOT exist | |
| Numbers format | Floating point (e.g., 0.0234) |
For privacy: false (Standard)
| Check | Expected | Status |
|---|---|---|
| Request URL | Contains /v1/pick | |
mode field | "standard" | |
input field | Sanitized text | |
| Email addresses | Replaced with [email] | |
| Phone numbers | Replaced with [phone] | |
| Text length | Max 256 characters |
Common Issues
”I see input field with my text”
Problem: Privacy mode is not enabled.
Solution: Ensure you have privacy: true in your SDK configuration:
const ads = new Ads({
publisherId: 'pub_xxx',
privacy: true, // Must be explicitly set
});“I see mode: "standard" instead of "embedding"”
Problem: Either privacy mode is off, or local embedding failed and fell back to standard mode.
Solution:
- Check console for warnings about embedding failures
- Ensure
@huggingface/transformersis installed:npm install @huggingface/transformers - Preload the model to catch errors early:
await ads.embedding.preload(); console.log(ads.embedding.isReady()); // Should be true
“The embedding array has different length”
Problem: Different models produce different embedding dimensions.
Expected dimensions by model:
| Model | Dimensions |
|---|---|
Xenova/bge-small-en-v1.5 (default) | 384 |
Xenova/bge-base-en-v1.5 | 768 |
Xenova/all-MiniLM-L6-v2 | 384 |
Automated Verification
You can also verify programmatically in your tests:
import Ads from 'notpixel';
// Mock fetch to inspect the request
const originalFetch = global.fetch;
global.fetch = async (url, options) => {
if (url.includes('/v1/pick')) {
const body = JSON.parse(options.body);
// Verify privacy mode
console.assert(body.mode === 'embedding', 'Should be embedding mode');
console.assert(body.input === undefined, 'Should NOT have input field');
console.assert(Array.isArray(body.embedding), 'Should have embedding array');
console.assert(body.embedding.length === 384, 'Should have 384 dimensions');
console.log('✅ Privacy verification passed!');
}
return originalFetch(url, options);
};
const ads = new Ads({
publisherId: 'pub_xxx',
privacy: true,
});
await ads.getAd({ input: 'my sensitive query' });Understanding Embeddings
What is an embedding?
An embedding is a mathematical representation of text as a vector of numbers. It captures the semantic meaning without containing the actual words.
Text: "How do I optimize PostgreSQL queries?"
↓ (embedding model)
Vector: [0.023, -0.089, 0.145, 0.002, -0.056, ...]
(384 floating-point numbers)Why can’t embeddings be reversed?
- Information loss: 384 numbers cannot encode all possible sentences
- Many-to-one mapping: Different texts can produce similar embeddings
- No dictionary: The model doesn’t store a word↔number mapping
Think of it like a hash function — you can go from text → embedding, but not embedding → text. The mathematical properties guarantee this.
Visual Example
┌─────────────────────────────────────────┐
│ "I need help with my database" │
│ "Help me optimize my SQL" │ Similar
│ "Database performance issues" │ embeddings
└─────────────────────────────────────────┘
↓
[0.12, 0.34, -0.56, ...] ← Close vectors
[0.11, 0.35, -0.54, ...]
[0.13, 0.33, -0.55, ...]
┌─────────────────────────────────────────┐
│ "Best pizza recipes" │ Different
└─────────────────────────────────────────┘ embedding
↓
[-0.45, 0.78, 0.12, ...] ← Far vectorThe ad matching system finds ads with similar embeddings, without ever knowing what the user actually typed.
Summary
| Mode | What’s Sent | Verifiable |
|---|---|---|
privacy: true | Numbers only (embedding) | Check for no input field |
privacy: false | Sanitized text | Check for [email], [phone] |
Your privacy is verifiable. Every request can be inspected in your browser’s DevTools. We encourage you to verify our claims yourself.