checkAnonymous, checkAuthenticatedUser, forceCheckAnonymous, or forceCheckAuthenticatedUser call runs a full identification and draws one request from that domain’s prepaid balance. There is no client-side result you can re-read for free: the snippet keeps only a short visit session (about 10 minutes, governing the SessionID), and the identification itself re-runs and bills on every call. So the only cost lever is where and how often you call, never reusing a stored id to dodge a billed call.
This page has two parts: tune your integration before it ships, and localize a usage spike if one shows up.
Optimize proactively
The goal is one billed identification at each point you actually act on a result, with the connection already warm so that call is fast.Warm the connection early
ShieldLabs talks to two hosts: the module loads fromcdn.shieldlabs.ai, and the identification posts to rest.shieldlabs.ai (plus a local-network check). Hint both early so the TLS handshake is done before you ever call. Put these in <head>:
Pre-warm the module, trigger the call at the decision point
import() and the identification are two separate steps, and only the identification bills. Pre-warm the module on load so it is parsed and ready, then call checkAnonymous or forceCheck* only at the moment you act on the result, the login submit or the checkout click. That way you never spend a request on a page where you read nothing.
Call only where you act on the result
Map each touchpoint to one call and trigger it at the action, not on render. Each row below is one request.| Touchpoint | Call | Trigger | Expected volume |
|---|---|---|---|
| Logged-out browsing you want to grade | checkAnonymous | Once per visit, on the entry page you care about | 1 request per visit |
| Sign-up or login | forceCheckAuthenticatedUser(hashedUserId) | On submit, after you know the user | 1 request per sign-in |
| Checkout or payment | forceCheckAnonymous or forceCheckAuthenticatedUser | On the place-order / pay click | 1 request per attempt |
| Other sensitive action (withdrawal, password change, device approval) | forceCheck* | On the action, not on page view | 1 request per action |
Diagnose a usage spike
If the request count climbs faster than your traffic explains, it is almost always one of three things: an implementation that calls too often, a key used from a domain you do not own, or a genuine traffic burst. Work through them in that order.Implementation causes
Most unexpected usage is a call firing more often than intended. Check for:- Firing on every page load. An unconditional
checkAnonymousin a shared layout or on every route runs an identification on every navigation. Move the call to the specific touchpoint where you act on the result. - Duplicate or looping calls. A component-lifecycle effect without a stable dependency re-runs the identify on every re-render. Pin the dependency list and guard against double invocation so each mount calls once. The snippet framework examples show the mount-once pattern.
- Calling where the result is never used. Any page that identifies but never reads the score is pure spend. If you do not branch on it, do not call it there.
Key-misuse cause
Public keys are domain-scoped. A key used from a domain you did not register is rejected with 401, but the attempt still shows up as traffic against that key. If you see requests you cannot attribute to your own pages, your public key may be in use on a domain that is not yours.A 401 from a domain mismatch is the server refusing an unregistered origin, not a scoring event. If a public key has leaked onto a site you do not control, rotate that domain’s key set so the old key stops working. Each domain has its own public and secret keys and its own domain registration.
Traffic cause
If the integration is clean and the keys are yours, a spike is real volume: a campaign, a referral surge, or a wave of automated traffic all inflate the count the same way, because each identification bills regardless of who is behind it. This is the case where the usage is legitimate and the answer is capacity, not a code fix.How to investigate
The dashboard Data table is one row per identification, and reading or exporting it is free. Use it to localize the spike:Export the spike window
On the dashboard Data tab, filter by the date range of the spike and export the result to CSV or JSON. Reads and exports never consume requests.
Group to find the source
In your own tooling, group the export by identifier (visitor ID, device ID, IP, or user HID), by entry URL, and by traffic source. A handful of identifiers or a single URL dominating the count points at a loop or a hot page; a broad spread across many IPs points at a real traffic surge.
Watch the balance and the 402 state
Track the domain’s remaining request balance. When a domain’s balance is exhausted, the identification POST and the Server API both return HTTP 402, separate from rate limiting. The Billing page covers the balance, and the rate limits page covers the gateway 429.