Skip to main content
The ShieldLabs client is a single ES module you load by dynamic import() from cdn.shieldlabs.ai. There is no npm package and no native mobile SDK. It runs in the browser only. The module collects 100+ browser, device, and network signals and posts them to ShieldLabs automatically. It does not compute a VisitorID, DeviceID, or Risk Score in the browser. Those are derived on the server and delivered by webhook and the Management API. You correlate the browser call to the server result using the requestID from the optional callback.

Install (HTML)

Add this near the top of <body>. Use type="module" (the snippet relies on import.meta.url and top-level dynamic import, so it cannot run as a classic script).
<script type="module">
  const mod = await import('https://cdn.shieldlabs.ai/snippet.js?publicKey=YOUR_PUBLIC_KEY');
  mod.checkAnonymous();
</script>
publicKey is your site’s public key, one per registered domain. It is safe to expose in page source. Grab yours from API Keys.
The call is fully async and non-blocking. Incognito detection, local-signal probing, and the WebRTC real-IP check run in parallel and never block page render. The Promise resolves when the snapshot POST completes; the identification result arrives separately (see below).

The four exports

The module exports four functions. checkAuthenticatedUser and checkAnonymous are the same underlying call. The only difference is whether you pass a user id.
ExportWhen it runsUse it for
checkAnonymous(callback?)Only when the visit session changes (10-minute window)A visitor you cannot identify yet (logged-out traffic)
checkAuthenticatedUser(hashedUserId, callback?)When the session changes or a new user id is seenA logged-in user. Pass a hashed/pseudonymous id
forceCheckAnonymous(callback?)Immediately, every call (clears the session first)Before a sensitive action when you need a fresh anonymous check
forceCheckAuthenticatedUser(hashedUserId, callback?)Immediately, every call (clears the session first)Right after login, or before a high-risk action
Always pass a hashed or pseudonymous id to checkAuthenticatedUser and forceCheckAuthenticatedUser. Never pass a raw email or a real account id. ShieldLabs stores this value as your UserHID to correlate activity. It should not be reversible to a real identity.

forceCheck*: clear the session and run now

checkAnonymous and checkAuthenticatedUser are session-gated: within a 10-minute visit window they skip the work and reuse the existing session. That is the right default for most page views. forceCheckAnonymous and forceCheckAuthenticatedUser ignore that gate. They clear the session and run a full identification immediately. Reach for them when the moment matters:
  • Right after login. Re-run the check now that you know who the user is, so the server links this session to the account.
  • Before a sensitive action (checkout, withdrawal, password change, a new device approval). Get a fresh score keyed to a requestID you can act on.
// after a successful login
mod.forceCheckAuthenticatedUser(hashedUserId, (serverResponse, requestID) => {
  // store requestID, then read the score server-side via webhook or History API
});

The optional callback

Each export accepts an optional callback that fires once, after the snapshot POST resolves:
mod.checkAnonymous((serverResponse, requestID) => {
  // serverResponse: the server's snapshot acknowledgment (JSON)
  // requestID: the UUID for this call. Your join key to the server result.
});
The browser does not return the VisitorID, DeviceID, or Risk Score. Those are computed on the server. Send the requestID to your backend, then read the result from the webhook payload or the History API (query by request_id). Do not try to read the score from serverResponse.
The flow:
  1. The snippet collects signals and POSTs them to rest.shieldlabs.ai.
  2. Your callback fires with (serverResponse, requestID).
  3. The server scores asynchronously (~1s) and delivers the initial webhook, then an update webhook after the WebRTC real-IP check.
  4. Your backend matches the webhook (or History API row) to the browser call by requestID.

Framework integrations

The HTML method above works anywhere. In a framework, put the same dynamic import() inside a lifecycle hook so it runs once on mount. Pass your public key in from config or props.
<script type="module">
  const PUBLIC_KEY = 'YOUR_PUBLIC_KEY';
  const mod = await import(`https://cdn.shieldlabs.ai/snippet.js?publicKey=${PUBLIC_KEY}`);

  // anonymous visitor:
  mod.checkAnonymous();

  // or a logged-in user (hashed id only):
  // mod.checkAuthenticatedUser('user_hashed_id_here');

  // force an immediate check (clears session), e.g. right after login:
  // mod.forceCheckAuthenticatedUser('user_hashed_id_here');
</script>
Memoize the import (the Angular example caches modulePromise) so the module loads once even if you mount the wrapper in several places. The framework wrappers are thin: they call the same CDN module as the HTML method, just from your app code instead of an inline script.

Capturing the result with a callback

Pass a callback in any framework to grab the requestID and hand it to your backend:
useEffect(() => {
  let cancelled = false;

  async function run() {
    const mod = await import(
      `https://cdn.shieldlabs.ai/snippet.js?publicKey=${publicKey}`
    );
    if (cancelled) return;

    mod.checkAuthenticatedUser(hashedUserId, async (serverResponse, requestID) => {
      // forward requestID to your server, which reads the score from the
      // webhook or the History API and decides allow / challenge / review / block.
      await fetch('/api/shieldlabs/checked', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ requestID }),
      });
    });
  }

  run();
  return () => { cancelled = true; };
}, [publicKey, hashedUserId]);
ShieldLabs surfaces the score and signals. Your own code owns the decision. See Acting on the Risk Score for how to turn the score and its Details into an allow / challenge / review / block path in your application.

Next steps

Content Security Policy

Allowlist the CDN, REST, and WebRTC hosts if your site sends a strict CSP header.

API Keys

Find your domain’s public key for the snippet and the secret key for the server.

Webhooks

Receive the scored result keyed by requestID, with the initial and update phases.

How it works

Follow a single identify call from the browser snapshot to the server score.