Skip to Content
NotPixel SDK v1.0.1 — Now with caching, hooks, and browser tracking!
FeaturesNetwork Inspector

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:

  • mode is "embedding" — indicates local embedding mode
  • embedding contains only numbers — mathematical vector representation
  • No input field — 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:

  • mode is "standard"
  • input contains sanitized text — PII like emails are replaced with [email]
  • Original email address is NOT visible

Step-by-Step: Chrome DevTools

Chrome / Edge

  1. Open DevTools: Right-click anywhere → “Inspect” or press F12

  2. Network Tab: Click “Network” in the top toolbar

  3. Enable Preserve Log: Check “Preserve log” to keep requests after navigation

  4. Filter Requests: Type pick or notpixel in the filter box

  5. Make a Request: Use your app to trigger an ad fetch

  6. Click the Request: Find the request to /v1/pick

  7. View Payload:

    • Click “Payload” tab
    • Expand “Request Payload”
    • Verify no input field exists (for privacy mode)
  8. 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

CheckExpectedStatus
Request URLContains /v1/pick
mode field"embedding"
embedding fieldArray of ~384 numbers
input fieldShould NOT exist
Numbers formatFloating point (e.g., 0.0234)

For privacy: false (Standard)

CheckExpectedStatus
Request URLContains /v1/pick
mode field"standard"
input fieldSanitized text
Email addressesReplaced with [email]
Phone numbersReplaced with [phone]
Text lengthMax 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:

  1. Check console for warnings about embedding failures
  2. Ensure @huggingface/transformers is installed:
    npm install @huggingface/transformers
  3. 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:

ModelDimensions
Xenova/bge-small-en-v1.5 (default)384
Xenova/bge-base-en-v1.5768
Xenova/all-MiniLM-L6-v2384

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?

  1. Information loss: 384 numbers cannot encode all possible sentences
  2. Many-to-one mapping: Different texts can produce similar embeddings
  3. 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 vector

The ad matching system finds ads with similar embeddings, without ever knowing what the user actually typed.


Summary

ModeWhat’s SentVerifiable
privacy: trueNumbers only (embedding)Check for no input field
privacy: falseSanitized textCheck 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.