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 Server API. You correlate the browser call to the server result using the requestID from the optional callback.
The snippet stores a long-lived first-party id under the key cookieID in both localStorage and a first-party cookie. That value is sent to ShieldLabs as cookieID and stored server-side as CookieID. VisitorID is computed on the server from the DeviceID and CookieID and is not written to browser storage.

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).
publicKey is your site’s public key, one per registered domain. It is safe to expose in page source. Grab yours from the Snippet tab (see Keys).
The call is fully async and non-blocking. Several checks 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. They all run a full identification and bill one request per call; they differ only in whether you tag a user id and whether they reset the visit session first.
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.
The account-based Patterns (Many Accounts on One Device, Many Devices on One Account, and the rest keyed on accounts) only populate when you pass a UserHID through checkAuthenticatedUser. If you only ever call checkAnonymous, the device, visitor, and Local IP patterns still work, but the account-keyed ones cannot form.

forceCheck*: clear the session and run now

For checkAnonymous and checkAuthenticatedUser, the short-lived visit window only governs the SessionID: calls inside the same window share one SessionID, while a call after it expires gets a fresh one. The work itself (collecting signals and posting the snapshot for scoring) always runs. forceCheckAnonymous and forceCheckAuthenticatedUser do the same full identification, but they reset the visit session first so this call starts a new SessionID. 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.

The optional callback

Each export accepts an optional callback as its last argument. It fires once, after the snapshot POST resolves. The callback always comes after the user id slot, so for an anonymous call pass undefined first:
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).
The flow:
  1. The snippet collects signals and POSTs them to rest.shieldlabs.ai.
  2. Your callback fires with (ip, requestID).
  3. The server scores asynchronously, waiting up to ~60s for optional follow-up network checks, then delivers one webhook with the final score (~1s when no follow-up is expected).
  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.
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:
ShieldLabs surfaces the score and signals. Your own code owns the decision, and acting on the Risk Score shows how to turn the score and its signals into an allow / challenge / review / block path in your application.

Next steps

Content Security Policy

Allowlist the ShieldLabs snippet hosts if your site sends a strict CSP header.

API Keys

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

Webhooks

Receive the scored result keyed by requestID, one webhook per identification.

How it works

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