Your own IVT server. Every flag explained.
Invalid traffic detection at ad-tech scale: 125 detectors, a Go engine built for 500M+ scans per day, on a dedicated server that scans nothing but your traffic.
- Detectors
- 125 in total: 98 high risk, 18 medium, 9 low. Each one open, documented, and inspectable.
- Ships
- Browser snippet, Go detection server, React dashboard, Kafka and ClickHouse data pipeline.
- Runs on
- A dedicated server rented for you alone. Your signals, your database, your rules.
- Billing
- No per-scan billing. No black boxes.
Dedicated OpenIVT servers are being made available in stages. Leave a work email and the team will contact you directly.
The black-box problem
The IVT industry runs on closed, proprietary scoring engines that don't talk to each other. One vendor routinely flags another's clean traffic as invalid, and vice versa, with no shared methodology.
Publishers get penalized twice. Advertisers lose trust. Legitimate traffic gets caught in the crossfire.
OpenIVT's stance: every detector is open, documented, and inspectable. When traffic is flagged, you can see exactly which signal fired and why.
Four components, one pipeline
A full-stack platform that catches bots, click farms, spoofed devices, and cookie-fraud rings that drain digital advertising budgets. Everything below ships together on a dedicated server that runs only your scans.
| Component | Stack | Role |
|---|---|---|
| Browser Snippet | TypeScript | A ~500 byte loader plus a ~12 KB probe bundle that collects client-side signals. |
| Detection Server | Go | Runs all 125 detectors concurrently against every signal. |
| Dashboard | React, Vite | Manage threats, inspect events, browse the catalog, view analytics. |
| Data Pipeline | Kafka, ClickHouse, Redis | High-throughput ingest, storage, and caching. |
How a beacon becomes a verdict
The browser snippet sends beacons to a Go ingest API, which publishes them to Kafka. A worker pool consumes the topic, runs the 125 detectors, and writes results to ClickHouse. Redis provides caching and the cookie-collision aggregation.
The dashboard talks to the same Go API, backed by PostgreSQL for configuration and ClickHouse for analytics.
Four beacons per page view
| Beacon | Carries | Timing |
|---|---|---|
| Main | Page-load signals | sent immediately |
| Auction | Prebid and SSP signals | delayed ~500 ms, polls up to 6 s |
| NSFW | On-device image classification with TF.js MobileNetV2 | fires after 5 s idle |
| Session summary | Dwell and interaction totals | sent when the page is left |
125 detectors in three risk tiers
| Range | Category | Examples |
|---|---|---|
| High risk, 98 detectorsHeadless and WebDriver bots, click and impression fraud, canvas and WebGL spoofing, ad injection, proxy and VPN, session replay, cookie-jar injection, honeypot traps. | ||
| H001-H010 | Bot and automation | WebDriver, headless Chrome, Selenium, Puppeteer, Playwright |
| H011-H020 | Click fraud | Click farms, rapid clicks, click injection, invisible clicks |
| H021-H030 | Impression fraud | Pixel stuffing, ad stacking, background tabs, pop-unders |
| H031-H040 | Datacenter, proxy and spoofing | DC IPs, VPN, Tor, domain and referrer spoofing |
| H041-H050 | Device and hardware spoofing | Canvas, WebGL, timezone, platform mismatch |
| H051-H060 | Malware and injection | Ad injection, DOM tampering, script injection, form jacking |
| H063-H070 | Session and network anomalies | Session replay, IP rotation, geo mismatch, DNS anomalies |
| H071-H080 | Behavioral anomalies | Robotic mouse paths, no-interaction sessions, instant form fill |
| H081-H094 | AI crawlers, farms and timing | GPTBot, human farms, botnets, impossible timing |
| H096-H109 | Measurement tampering and environment | SDK spoofing, IP, ASN and device blocklists, VM and container detection |
| H112-H124 | Advanced signals, audience and cookie fraud | Worker abuse, cookie injection, TLS fingerprinting, click-coordinate replay, honeypot traps |
| Medium risk, 18 detectorsSuspicious referrers, viewability spoofing, floor manipulation, adult-content misrepresentation. | ||
| M001 | SuspiciousReferer | Known traffic brokers, high-risk TLDs, NXDOMAIN referrers |
| M010 | AbnormalErrorRate | Abnormal error rates |
| M023 | AudienceInjection | Prebid RTD fake segments, inflated ORTB2 floors, DMP script stacking |
| M024 | AdultContentMisrepresentation | RTA label, adult-only ad network scripts, IAB25 categories, age gates, on-device ML image classification |
| Low risk, 9 detectorsOld browsers, deprecated OSes, missing headers, incomplete signals. | ||
L001OldBrowser
L002DeprecatedOS
L003UncommonScreenResolution
L004MissingExpectedHeaders
L005NoJavaScript
L007HighLatencyClient
L008IncompleteSignalPayload
L009FirstTimeVisitor
L014UnusualFontList
| ||
Code numbering is sparse: retired detectors keep their codes reserved.
From the catalog
Five entries, as they appear in the Threat Catalog. Every detector in the dashboard is documented at this level: what signal it reads, what it correlates against, and what a hit means.
| Code | Name | What it catches |
|---|---|---|
| H116 | AudienceCookieInjection | DMP and identity-graph cookies (BlueKai, LiveRamp, TradeDesk UID2, Lotame, Adobe AAM) present without the data-provider script ever having loaded. These orphan cookies are the fingerprint of tools like Humanex, MultiLogin and AdsPower that pre-load premium audience cookie jars to inflate CPMs. |
| H117 | CookieValueCollision | Audience-cookie replay: the same DMP cookie value hash seen across many distinct IPs in a 30-minute rolling window. A ClickHouse aggregation job runs every 5 minutes and writes collision counts to Redis. Only a djb2 fingerprint of the cookie ever leaves the browser. |
| H123 | AdClickPointCollision | Coordinate-replay click bots: the same 2 px-quantized ad-click coordinate hash correlated across distinct IPs and across different sites in a 30-minute window. |
| H124 | Honeypot | The snippet plants an off-screen decoy ad and a visually hidden trap link no human can see or reach. Any click on them is programmatic by construction. Server-side corroboration keeps link prefetchers and preview crawlers clean. |
| M024 | AdultContentMisrepresentation | RTA label, adult-only ad network scripts, explicit meta declarations, IAB25 categories, age gates, URL and title keywords, and on-device ML image classification. |
Your signals, your database, your rules
Nothing is shared. Your server scans your traffic and nobody else's. There is no vendor-side scoring, no per-scan billing, and no black box between a flagged event and the signal that fired.
| Item | Detail |
|---|---|
| Cookie values | Never leave the browser in plaintext. Only a lightweight fingerprint is emitted. |
| Retention | Raw signal events and detection results live in ClickHouse, partitioned by day, with a 90-day TTL. |
| GeoIP | Optional MaxMind GeoLite2 databases enable the IP and ASN detectors. |
| Provisioning | A dedicated server with the full stack ready to go: Go detection server, snippet, dashboard, PostgreSQL, Redis, ClickHouse and Kafka. Single tenant, so no other customer's scans ever run on it. Optional GeoIP and your admin account are set up in the dashboard. |
| API | POST /api/v1/signals for ingest, plus threat toggles, analytics stats, top threats, cookie collisions, an events log, and API keys. |
Two script tags to integrate
The loader is about 500 bytes. It pulls in the ~12 KB probe bundle, which collects client-side signals and posts them to the ingest endpoint on your server.
From there the dashboard takes over: Threats, Threat Catalog, Reports, Events, Inventory Quality, Cookie Collisions, Implementation, and Settings.
<script src="https://your-cdn.com/ivt-loader.min.js"></script>
<script>
window.__ivt = window.__ivt || { q: [], t: Date.now(), v: '1.0.0' };
window.__ivt.q.push(['config', {
endpoint: 'https://your-server.com/api/v1/signals',
apiKey: 'YOUR_API_KEY',
probesUrl: 'https://your-cdn.com/ivt-probes.min.js'
}]);
</script>