Checkpoint Docs
Detect

Marketing Pixel

Lightweight, no-code AI agent detection for analytics and marketing teams

Overview

The Checkpoint Marketing Pixel is a lightweight, no-code detection snippet that identifies AI agents and bots visiting your website. It loads asynchronously, has minimal impact on page performance, and installs via a simple script tag or your tag manager.

The Pixel is ideal for:

  • Marketing teams who want bot traffic visibility without developer involvement
  • Analytics teams who need to separate real users from automated traffic
  • Content teams who want to monitor AI scraping activity

The pixel registers its JavaScript API on window.Checkpoint. The previous global window.AgentShield and the agentshield:* events remain as deprecated aliases (both resolve to the same object / both fire). The pixel writes two device-session cookies with identical contents — checkpoint_user (canonical) and agentshield_user (legacy) — and reads whichever it finds, so existing identities aren't lost. Read checkpoint_user; expect both on the wire.

Prerequisites

You'll need your Project ID before installing the Pixel — see Credentials for where to find it under Installations in your project dashboard.

Installation

Add the following script tag in your HTML <head> section:

<!-- Detect Pixel -->
<script>
  (function () {
    var as = document.createElement('script');
    as.type = 'text/javascript';
    as.async = true;
    as.src = 'https://kya.vouched.id/pixel.js';
    as.setAttribute('data-project-id', 'YOUR_PROJECT_ID');
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(as, s);
  })();
</script>
<!-- End Detect Pixel -->

Replace YOUR_PROJECT_ID with your Project ID (see Credentials). This is the exact snippet the dashboard generates for you.

Option A — Community Template (recommended). Install the official Checkpoint Pixel template once per container:

  1. Open the Checkpoint Pixel template in the GTM gallery (publisher: Know-That-Ai) — or in GTM go to Templates → Search Gallery and search Checkpoint (older gallery listings may still show the template's previous name, AgentShield, until Google syncs the rename)
  2. Click Add to Workspace, then Tags → New → Tag Configuration → Custom → Checkpoint Pixel, enter your Project ID, set Triggering to All Pages, and Save → Submit → Publish

Option B — Custom HTML tag. If your org disables community templates, use the same loader snippet the dashboard generates:

  1. Go to Tags → New → Tag Configuration → Custom HTML
  2. Paste the loader snippet:
<script>
  (function () {
    var as = document.createElement('script');
    as.type = 'text/javascript';
    as.async = true;
    as.src = 'https://kya.vouched.id/pixel.js';
    as.setAttribute('data-project-id', 'YOUR_PROJECT_ID');
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(as, s);
  })();
</script>
  1. Replace YOUR_PROJECT_ID, set Triggering to All Pages, then Save → Submit → Publish

Both options report into the same project. With the Custom HTML tag you can set any of the data-* options directly on the script tag; the Community Template exposes the same options as configurable fields (all except data-require-consent).

Add the pixel to your layout or page using the Script component:

// app/layout.tsx
import Script from 'next/script';

export default function Layout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Script
          src="https://kya.vouched.id/pixel.js"
          data-project-id={process.env.NEXT_PUBLIC_CHECKPOINT_PROJECT_ID}
          strategy="afterInteractive"
        />
      </body>
    </html>
  );
}

For server-side detection in Next.js, consider using the Middleware instead. The Pixel is client-side only.

How It Works

  1. The Pixel script loads asynchronously after your page renders
  2. It collects detection signals (user agent, headers, behavior, and — when enabled — a browser fingerprint)
  3. Signals are POSTed to the Checkpoint detection API (POST /api/v1/pixel)
  4. The result (classification + confidence) is logged to your project
  5. View results in the dashboard

The Pixel never blocks page rendering and adds no perceptible latency to the user experience.

Configuration

Project ID

Every Pixel installation requires a Project ID, set via data-project-id. See Credentials for where to find it.

Script attributes

All options are set as data-* attributes on the script tag:

AttributeDefaultDescription
data-project-idRequiredYour Checkpoint Project ID
data-debugfalse"true" enables verbose console logging
data-api-endpoint<origin>/api/v1/pixelOverride the ingestion endpoint
data-session-timeout1800000Session timeout in ms (30 minutes)
data-respect-dnttrueHonor the browser Do Not Track signal ("false" to disable)
data-batch-size10Events per batch
data-flush-interval5000Batch send interval (ms)
data-enable-fingerprintingtrueCollect a browser fingerprint ("false" to disable)
data-require-consentfalseGDPR: defer cookie storage until grantConsent() is called

Custom Events

Send custom events with the window.Checkpoint.track method:

<script>
  // Guard on the global — calls before pixel.js loads are lost (there is no queue)
  window.Checkpoint &&
    window.Checkpoint.track('form_submit', {
      form_id: 'contact',
      page: '/contact',
    });
</script>

JavaScript API

Once pixel.js loads, it exposes window.Checkpoint (and the deprecated alias window.AgentShield):

Method / propertyDescription
track(eventName, data?)Send a custom event
identify(userId, traits?)Associate a user id (traits are sent server-side only, never stored in the cookie; rate-limited)
getUser()Returns { id } for the identified user, or null
grantConsent()Enable cookie storage after obtaining GDPR consent (see data-require-consent)
reset()Clear identity + cookie and start a fresh anonymous session (logout / GDPR)
getSession()Returns { id, startTime, duration, userId }
getInitInfo()Returns version/init diagnostics (useful for duplicate-load debugging)
lastDetectionThe most recent agent detection object. Unset until an agent is detected — human traffic never populates it

identify() enforces a 1-second minimum interval between calls. A call inside that window is dropped (it returns without sending) and each successive violation doubles an internal backoff, up to 10 seconds; the counter decays as soon as an allowed call goes through. Rate limiting is skipped when data-debug="true" or on localhost, so a development run won't reproduce it.

The pixel also dispatches window CustomEvents you can listen for:

Eventdetail
checkpoint:detectionthe detection result (isAgent, confidence, …). Fires only when an agent is detected, not on every pageview
checkpoint:identify{ userId, traits, sessionId, deviceId }
checkpoint:reset{ previousUserId, newSessionId }

The legacy agentshield:detection / :identify / :reset events still fire as deprecated aliases.

What about bots and humans?

checkpoint:detection and lastDetection are gated on isAgent, which is true only for interactive AI assistants — ChatGPT, Claude, Perplexity. Bots (Googlebot, GPTBot, headless browsers) and humans classify with isAgent: false, so neither fires the event nor populates lastDetection. If you wire a GA4 forward off checkpoint:detection (as shown below), you are measuring AI-assistant traffic only, not all automation.

Every classification — agent, bot, and human alike — is still sent server-side and appears in the dashboard. Client-side, the pixel also records the last result to sessionStorage regardless of class:

// Written on every detection, not just agents.
const recent = JSON.parse(sessionStorage.getItem('checkpoint_recent_detection') || 'null');
// → { isAgent: boolean, isBot: boolean, confidence: number, timestamp: number }

Read isBot there to react to crawler traffic on the client. (A duplicate agentshield_recent_detection key is written with identical contents for back-compat.)

Associating pixel sessions with your own authenticated users — beyond the bare identify() / getUser() calls above — is covered in depth in User Identification, including framework-specific patterns for Next.js and React.

The pixel honors Do Not Track by default (data-respect-dnt) and auto-tracks SPA navigations (History pushState/popstate/hashchange). It stores a device/session id in the checkpoint_user cookie (deferred until grantConsent() when data-require-consent="true"). A visitor with an existing agentshield_user cookie keeps their identity — that cookie is still read.

Analytics Integration

Google Analytics 4

The pixel does not push to GA4 or the dataLayer on its own. Instead, listen for the checkpoint:detection event and forward it to GA4 yourself:

<script>
  window.addEventListener('checkpoint:detection', function (e) {
    var d = e.detail || {};
    // Forward to GA4 (gtag must already be installed)
    window.gtag &&
      window.gtag('event', 'checkpoint_detection', {
        is_agent: d.isAgent,
        confidence: d.confidence,
      });
  });
</script>

This lets you build GA4 audiences that exclude bot traffic and measure true conversion rates.

Pixel vs Beacon

FeaturePixelBeacon
InstallationScript tag / GTMnpm package
Code requiredNoneYes
Signal richnessBasic + fingerprintAdvanced
Event trackingtrack()trackEvent()
Web WorkerNoYes
Bundle size≈5 KB gzipped, plus ≈4.5 KB for the fingerprint detector it loads when data-enable-fingerprinting is on (the default)npm dependency
Best forMarketing, analyticsApplication integration

For more advanced client-side collection, see the JavaScript Beacon.

Troubleshooting

Pixel Not Loading

  • Check that the Project ID is correct
  • Verify no ad blockers or content security policies are blocking the script
  • Check the browser console for errors (set data-debug="true")

No Detections in Dashboard

  • Confirm the Pixel is loading (check the Network tab for pixel.js and a POST /api/v1/pixel)
  • Verify the Project ID matches your dashboard project
  • Check that GTM is published (if using GTM)
  • If the visitor's browser sends Do Not Track, the pixel collects nothing unless you set data-respect-dnt="false"

Content Security Policy

If your site uses CSP headers, add the Pixel domain to your script-src directive:

Content-Security-Policy: script-src 'self' https://kya.vouched.id;

Next Steps