The product
What is ShieldLabs?
What is ShieldLabs?
ShieldLabs is a visitor identification, anonymous-traffic detection, and abuse and fraud prevention platform. One JS snippet collects 100+ browser, device, and network signals. The server returns a persistent identity (a DeviceID and VisitorID) plus an explainable Risk Score (0-100) and the anonymity signals behind it, delivered by webhook and readable through the Server API and a dashboard that also surfaces ready-made patterns.ShieldLabs surfaces the evidence. Your own code owns the decision. We score a request; you decide whether to allow, challenge, review, or block in your application. There is no in-product rules engine and no auto-blocking.
What problems does it solve?
What problems does it solve?
The recurring jobs developers wire it into:
- Suspicious signups and logins from account farms and multi-accounting (one device behind many accounts, or accounts that keep changing identifiers).
- Referral, promo, and bonus abuse where one person poses as many users.
- Anonymous traffic at sensitive moments such as payment or withdrawal, where VPN, proxy, Tor, or anti-detect browsers mask the visitor.
- Traffic-quality measurement, telling real visitors from anonymous ones across all your traffic and ranking each paid or organic source by its anonymous-traffic share, so you pay for real visitors, not masked clicks.
- Recognizing trusted returning visitors to personalize their experience or cut friction for a known-good device, the inverse of the fraud checks.
Keys and setup
What is the difference between the Public Key and the Secret Key?
What is the difference between the Public Key and the Secret Key?
Each domain gets one key pair.
- Public Key goes in the snippet URL as
?publicKey=.... It identifies your domain and is safe to expose in the browser. - Secret Key is backend only, for the Management API on
api.shieldlabs.ai(profile and balance). The History API onaccount.shieldlabs.aiuses a separate Private API Key (sec_…) as a Bearer token. Neither belongs in front-end code. - Webhook signing secret (
whsec_…) is backend only, one per endpoint. You use it to verify theX-Shield-Signatureheader on incoming webhooks.
What counts as a request?
What counts as a request?
One user check is one request. The snippet creates that check when you call
checkAnonymous, checkAuthenticatedUser, or the forceCheck* variants. The Risk Score, its signals, and the webhook for that check are all part of that single request.Reading history later is billed by which surface you use: the History API on account.shieldlabs.ai (Private API Key) is free, while the Management API History path on api.shieldlabs.ai bills one request per returned row (an empty result still bills one). Webhook delivery, dashboard views and exports, and reading your profile and balance are free, as the Billing & Plans breakdown spells out in full.My installation is not working. How do I troubleshoot?
My installation is not working. How do I troubleshoot?
Work down the path the data takes:If checks succeed but you see no scores, jump to the Why is my score 0? question below.
1
Confirm the snippet loads
Open the browser network tab and check that
cdn.shieldlabs.ai/snippet.js?publicKey=... loads with a 200, with the correct Public Key for this domain. A wrong or missing key, or a typo in the import URL, stops everything.2
Confirm the function runs
Make sure you actually call an export (
checkAnonymous() or checkAuthenticatedUser(hashedUserId)) after the import resolves. Nothing is sent until one of them runs. There is also a Check installation button in the dashboard.3
Clear CSP and ad-block
A strict Content-Security-Policy or an ad-blocker can silently block the snippet or its network calls. Allow the hosts in CSP setup.
4
Webhook not arriving?
Check your webhook endpoints: each must be HTTPS with a valid certificate and return quickly. If your handler returns a 4xx or 5xx, or your
X-Shield-Signature check rejects the payload, you will see no usable result. There are no retries, so verify the HMAC over the raw request body with the endpoint’s whsec_… secret.Identifiers and scoring
Why is my Risk Score 0?
Why is my Risk Score 0?
A 0 is usually correct, not a bug. The Risk Score is 0-100, and 0 means no meaningful anonymity signals fired (the Clean band, 0-9). On clean test traffic from a normal browser, a score of 0 is exactly what you should expect.It can also be 0 when a network check is blocked, so fewer signals are available. Only treat a permanent 0 as a problem if you see it on all real production traffic, which points at a setup issue. In that case, work through the installation troubleshooting above.
What do the score bands mean and where do I draw the line?
What do the score bands mean and where do I draw the line?
The bands are a guide; the action per band is yours to configure in your code. There are four: Clean (0-9), Low (10-29), Medium (30-59), and High (60-100), defined in full on the Risk Score page. A common starting point is to pass Clean and Low through, give Medium a step-up challenge or second look, and block, review, or verify on High.Always decide on Score plus
signals plus action context, never the number alone. A legitimate user can score high (corporate proxy, VPN, privacy browser), so the guide to acting on the Risk Score walks through tuning thresholds gradually.The customer-facing Risk Score is capped at 100. A rate-limit-banned request can still surface the internal value
999 on a webhook or History row, so guard your logic with if (score > 100) return; (webhook: data.risk_score). The browser receives an HTTP 429 at the gateway; your backend may see the 999.Reading your results
Do I need a webhook?
Do I need a webhook?
No, a webhook is optional. Without a registered endpoint, checks still run and still bill exactly the same. The difference is only how you read the result: with no webhook configured, scores land in the dashboard and stay queryable through the History API, but you get no real-time push.Configure webhook endpoints when you want to act on the score live, for example to challenge a risky login or hold a withdrawal. Add them in the dashboard Webhooks tab (up to 10 per domain).
Dashboard versus History API: which do I use?
Dashboard versus History API: which do I use?
Both read the same scored requests; they differ in shape.
- The dashboard is the visual surface: overview, visitors, traffic sources, patterns, and a searchable per-request data table. You search by one identifier type at a time and can export to CSV. Reading and exporting are free.
- The History API is the programmatic surface:
GET https://account.shieldlabs.ai/api/v1/history/{type}/{value}, authenticated with a Bearer Private API Key, returns JSON snapshots, newest first, wheretypeisip,visitor_id,device_id,user_hid,request_id,session_id, orcookie_id. Account History reads are free (limitcaps at 100).
Performance
Does the snippet slow down my page?
Does the snippet slow down my page?
The impact is minimal. The snippet is loaded with a dynamic
import(), which is non-blocking, and signal collection runs asynchronously after the page is interactive. It does not sit on the critical render path.Scoring also happens on the server, not in the browser: the Risk Score and identifiers are computed server-side (about a second) and pushed to your webhook, so the visitor never waits on it. The browser only collects signals and posts them.