Checkpoint Docs
Cookbooks

Detect: Beacon Integration

Add full-featured AI agent detection to your JavaScript application

Goal

Integrate the Checkpoint JavaScript Beacon into your web application for advanced client-side AI agent detection. By the end of this cookbook, you'll have:

  • Real-time detection with WebWorker offloading
  • Custom event tracking tied to detections
  • Automatic offline resilience with batched uploads
  • Full TypeScript support

Best for: React, Vue, Angular, and other SPAs where you need detection + custom event tracking.

Prerequisites

  • A Checkpoint account with a project created
  • A JavaScript/TypeScript application
  • Node.js 16+ and npm/yarn/pnpm

Time Estimate

15 minutes


Steps

Install the Beacon Package

npm install @kya-os/agentshield-beacon
yarn add @kya-os/agentshield-beacon
pnpm add @kya-os/agentshield-beacon

Get Your Project ID

  1. Log into your Checkpoint dashboard
  2. Select your project (or create one)
  3. Go to Settings → Deployment
  4. Copy your Project ID

Add it to your environment variables:

# .env.local (Next.js)
NEXT_PUBLIC_CHECKPOINT_PROJECT_ID=proj_abc123def456

# .env (Vite)
VITE_CHECKPOINT_PROJECT_ID=proj_abc123def456

# .env (Create React App)
REACT_APP_CHECKPOINT_PROJECT_ID=proj_abc123def456

Initialize the Beacon

Create a detection hook:

// hooks/useAgentDetection.ts
import { useEffect, useRef, useState } from 'react';
import { AgentShieldBeacon } from '@kya-os/agentshield-beacon';

interface DetectionResult {
  detectionClass: 'human' | 'ai_agent' | 'bot' | 'incomplete_data';
  confidence: number;
  agentName?: string;
}

export function useAgentDetection() {
  const beaconRef = useRef<AgentShieldBeacon | null>(null);
  const [detection, setDetection] = useState<DetectionResult | null>(null);
  const [isReady, setIsReady] = useState(false);

  useEffect(() => {
    const beacon = new AgentShieldBeacon({
      projectId: process.env.NEXT_PUBLIC_CHECKPOINT_PROJECT_ID!,
      endpoint: 'https://kya.vouched.id/api/v1',
      autoStart: true,
      debug: process.env.NODE_ENV === 'development',
    });

    beacon.on('detection', (result) => {
      setDetection(result);
      setIsReady(true);
    });

    beaconRef.current = beacon;

    return () => {
      beacon.destroy();
    };
  }, []);

  const track = (event: string, metadata?: Record<string, unknown>) => {
    beaconRef.current?.track({ type: event, metadata });
  };

  return { detection, isReady, track };
}

Use it in your app:

// app/layout.tsx or components/AgentDetectionProvider.tsx
'use client';

import { useAgentDetection } from '@/hooks/useAgentDetection';
import { createContext, useContext, ReactNode } from 'react';

const DetectionContext = createContext<ReturnType<typeof useAgentDetection> | null>(null);

export function AgentDetectionProvider({ children }: { children: ReactNode }) {
  const detection = useAgentDetection();

  return <DetectionContext.Provider value={detection}>{children}</DetectionContext.Provider>;
}

export function useDetection() {
  const context = useContext(DetectionContext);
  if (!context) throw new Error('useDetection must be used within AgentDetectionProvider');
  return context;
}
// composables/useAgentDetection.ts
import { onMounted, onUnmounted, ref } from 'vue';
import { AgentShieldBeacon } from '@kya-os/agentshield-beacon';

export function useAgentDetection() {
  const beacon = ref<AgentShieldBeacon | null>(null);
  const detection = ref<{
    detectionClass: string;
    confidence: number;
    agentName?: string;
  } | null>(null);
  const isReady = ref(false);

  onMounted(() => {
    beacon.value = new AgentShieldBeacon({
      projectId: import.meta.env.VITE_CHECKPOINT_PROJECT_ID,
      endpoint: 'https://kya.vouched.id/api/v1',
      autoStart: true,
    });

    beacon.value.on('detection', (result) => {
      detection.value = result;
      isReady.value = true;
    });
  });

  onUnmounted(() => {
    beacon.value?.destroy();
  });

  const track = (event: string, metadata?: Record<string, unknown>) => {
    beacon.value?.track({ type: event, metadata });
  };

  return { detection, isReady, track };
}

Use it in a component:

<script setup lang="ts">
import { useAgentDetection } from '@/composables/useAgentDetection';

const { detection, isReady, track } = useAgentDetection();

function handleFormSubmit() {
  track('form_submit', { formId: 'contact' });
}
</script>

<template>
  <div>
    <p v-if="isReady">Detected: {{ detection?.detectionClass }}</p>
    <button @click="handleFormSubmit">Submit</button>
  </div>
</template>
// detection.ts
import { AgentShieldBeacon } from '@kya-os/agentshield-beacon';

const beacon = new AgentShieldBeacon({
  projectId: 'YOUR_PROJECT_ID',
  endpoint: 'https://kya.vouched.id/api/v1',
  autoStart: true,
  debug: true,
});

// Listen for detection results
beacon.on('detection', (result) => {
  console.log('Detection:', result);

  // Example: Show warning for AI agents
  if (result.detectionClass === 'ai_agent') {
    console.warn(`AI Agent detected: ${result.agentName}`);
  }
});

// Track custom events
document.getElementById('checkout-btn')?.addEventListener('click', () => {
  beacon.track({
    type: 'checkout_started',
    metadata: {
      cartValue: 99.99,
      itemCount: 3,
    },
  });
});

// Cleanup on page unload
window.addEventListener('beforeunload', () => {
  beacon.destroy();
});

export { beacon };

Configure Advanced Options

Customize the Beacon for your use case:

const beacon = new AgentShieldBeacon({
  // Required
  projectId: process.env.NEXT_PUBLIC_CHECKPOINT_PROJECT_ID!,

  // Endpoint
  endpoint: 'https://kya.vouched.id/api/v1',

  // Detection
  autoStart: true, // Start immediately (default: true)

  // Batching — balance performance vs real-time
  batchSize: 10, // Events per batch (default: 10)
  batchInterval: 5000, // Send every 5 seconds (default: 5000ms)
  maxQueueSize: 100, // Max queued events (default: 100)

  // Performance
  useWorker: true, // Use WebWorker for detection (default: true)
  compression: true, // Compress payloads (default: true)

  // Reliability
  retryAttempts: 3, // Retry failed requests (default: 3)
  timeout: 10000, // Request timeout (default: 10000ms)

  // Development
  debug: process.env.NODE_ENV === 'development',
});

Add Event Tracking

Track custom events alongside detection data:

// Track page views
beacon.track({
  type: 'page_view',
  metadata: {
    path: window.location.pathname,
    referrer: document.referrer,
  },
});

// Track user actions
beacon.track({
  type: 'button_click',
  metadata: {
    buttonId: 'signup-cta',
    variant: 'hero',
  },
});

// Track form submissions
beacon.track({
  type: 'form_submit',
  metadata: {
    formId: 'contact-form',
    fields: ['name', 'email', 'message'],
  },
});

// Associate with a user (after login)
beacon.identify('user-123');

Verify Installation

  1. Start your development server
  2. Open the browser console
  3. Look for debug messages if debug: true is set
  4. Check the Network tab for requests to kya.vouched.id
  5. Visit your Checkpoint dashboard → Analytics

You should see detections flowing in within seconds.


Verify It's Working

Console Verification

With debug: true, you'll see:

[AgentShield Beacon] Initialized with project: proj_abc123
[AgentShield Beacon] Detection complete: human (confidence: 0)
[AgentShield Beacon] Batch sent: 3 events

Programmatic Check

// Get the current detection result
const result = beacon.getDetectionResult();

if (result) {
  console.log(`Class: ${result.detectionClass}`);
  console.log(`Confidence: ${result.confidence}%`);
  console.log(`Agent: ${result.agentName || 'N/A'}`);
}

Test with Different Agents

Simulate agent traffic using browser DevTools:

  1. Open DevTools → Network conditions
  2. Set a custom User-Agent: Mozilla/5.0 (compatible; GPTBot/1.0)
  3. Refresh the page
  4. Check your dashboard for an ai_agent detection

Troubleshooting

Beacon Not Initializing

SymptomCauseFix
"projectId is required" errorMissing env varCheck .env.local and restart server
No network requestsBeacon not startedSet autoStart: true or call beacon.start()
Worker errorCSP blocking workersAdd worker-src to CSP or set useWorker: false

Events Not Sending

  • Check batch settings — Events queue until batchSize or batchInterval triggers
  • Force flush — Call beacon.stop() to flush remaining events
  • Check offline status — Events queue when offline, send when reconnected

TypeScript Errors

Ensure you have the types installed:

npm install @types/node --save-dev

Add to tsconfig.json:

{
  "compilerOptions": {
    "types": ["@kya-os/agentshield-beacon"]
  }
}

What You Learned

  • How to install and configure the Beacon SDK
  • How to create a reusable detection hook (React) or composable (Vue)
  • How to track custom events alongside detections
  • How to handle WebWorker mode for optimal performance

Next Steps

GoalNext Cookbook
Block detected agentsMiddleware Enforcement
DNS-level enforcementGateway Setup
Server-side detectionMiddleware Detection