Skip to main content
This page is the schema reference for every object the ShieldLabs API and webhooks return. Four objects carry the result of an identification:
  • WebhookEvent is the signed JSON envelope pushed to each configured endpoint (snake_case): event_type, schema_version, created_at, and scored fields under data.
  • Snapshot is the PascalCase object the deprecated Management History path (GET /v1/history/… on api.shieldlabs.ai) still returns. It carries the identity and score fields in PascalCase plus network columns, without the webhook’s traffic source or detection flags. The History API on account.shieldlabs.ai is the recommended read: snake_case rows in a { data, total } envelope. See Server API.
  • ScoreDetail is one { Value, Description } entry, in the deprecated Snapshot Details array and in the parsed History score_details string.
  • WebhookSignal is one entry in the explainable signals array inside WebhookEvent.data (name, weight).
A fifth object, Profile, is what the Management API returns: the domain, the remaining included volume on your account and masked keys.
Each payload is one identification: a Risk Score (0-100) with the risk signals behind it, and the user, device, visitor and IPs it belongs to. You choose the action for each case (allow, step up, review or block) and act on the result in your backend.

Object map

WebhookEvent

The webhook envelope: event_type, schema_version, created_at, and scored data.

Snapshot

Returned by the deprecated Management History path (PascalCase). Prefer History API snake_case rows.

WebhookSignal

One risk signal in a webhook data.signals entry: { name, weight }.

ScoreDetail

One entry in History score_details or a Snapshot Details array: { Value, Description }.

Profile

Your domain, the remaining included volume on your account and masked keys.

Identifiers and the identities they map to

An identification is the event layer: one check by the snippet, with one Risk Score. Five of its fields are identities that ShieldLabs scores and links over time; the others identify the call itself. Each user, device, visitor and IP takes the worst band of its identifications; Read every identification of one account shows how to compute it. High-Risk Events are detected on users, each at Medium or High confidence; see High-Risk Events below. In the analytics dashboard they show on Overview and on each user card. Users, devices, visitors and IPs explains the model.

WebhookEvent

The envelope delivered when ShieldLabs finishes scoring an identification. Each enabled endpoint receives one POST per identification. Field names are snake_case. The HMAC signature travels in the X-Shield-Signature header, not in the body. See Webhooks for verification, service event types, and delivery timing.
string
identification.scored for every scored identification; webhook.ping for endpoint Verify. See Webhooks.
string
Contract version, currently 2026-06-01.
string (RFC 3339)
When the webhook event was created.
object
The scored identification. Omitted on webhook.ping. Fields below describe data on identification.scored.
string (UUID)
The client-generated UUID of this identification. Use as the idempotency key and the join key to the History API.
string (UUID)
The Session ID: the browsing session, written by the snippet to localStorage (legacy sessionStorage keys are read once and migrated), so it is shared across tabs rather than tied to one tab.
The Cookie ID: a first-party cookie / localStorage identifier minted in the browser. It is lost when the user clears cookies or storage.
string (UUID)
The Device ID, server-derived and not stored in the browser. It holds through cleared cookies, incognito mode and IP changes; another browser on the same machine gets its own Device ID. The Identifiers reference explains it.
string (UUID)
The Visitor ID, server-derived from device_id plus cookie_id. It changes when the cookie is cleared. Multiple visitor_id values can map to one device_id. The durability claim belongs to device_id, not visitor_id.
string | null
The User HID: your account key, passed with checkAuthenticatedUser. Always pass a hashed or pseudonymous value, never a raw email or user id. Literal anonymous on anonymous checks; null when an empty string is passed and on the test delivery sample. Users, account-level risk and all four High-Risk Events are built on it.
string
The registered site domain key for this identification.
object
The public IP and its country: { "ip": "<dotted IPv4>", "country": "<ISO code>" }.
object
The local IP: the address the browser itself reports, with its country, from an optional follow-up network check when captured. Same shape as public_ip. Both ip and country may be empty when no local IP was resolved.
string
The operating system derived for the device, for example Windows, Mac OS X, or IOS (iPhone). May be empty when the OS could not be determined.
string
Browser family, for example Chrome.
string
desktop, mobile, or tablet.
string
The classified connection type, one of direct, mobile, vpn, proxy, tor, privacy_relay, browser_vpn_proxy, or unknown (when the type could not be resolved).
integer
The explainable Risk Score of this identification, an integer from 0 to 100. Higher means riskier: more likely masked, spoofed, or abusive. The payload carries the number, with no band field. Map it to a band in your backend: Trusted 0-29, Suspicious 30-59, Dangerous 60-100. The only value above 100 is 999, the rate-limit marker; guard risk_score > 100 before reading the band.
WebhookSignal[]
The full list of risk signals with a non-zero weight. A slug can repeat with a partial weight when an earlier verdict is carried forward; read risk_score for the total. Each entry follows the WebhookSignal shape below.
object
Traffic attribution: channel, referrer_domain, landing_url, click_id_type, and five UTM fields when present.
object
Boolean detection flags: vpn, privacy_relay, browser_vpn_proxy, tor, proxy, datacenter_ip, abuser, os_mismatch, os_not_detected, timezone_mismatch, stun_not_checked, anti_detect_browser, browser_automation, javascript_disabled, incognito, search_bot, suspicious_paid_click, ip_mismatch, check_incomplete.
Branch on risk_score, signal name slugs, and detection_flags.
string (RFC 3339)
When the identification was scored and this payload was built (same value as created_at), for example 2026-06-26T14:20:42Z.

WebhookSignal

One entry in the webhook data.signals array. Each entry is a risk signal that fired and the weight it contributed.
string
Stable machine slug, for example vpn, datacenter_ip, os_mismatch, or antidetect_browser. The flag key for the same detection is anti_detect_browser, and History score_details names it in free text. Match slugs against the signal reference. Safe to branch on in application code.
integer
The weight this risk signal added to the Risk Score. weight can be signed (negative when a follow-up check lowers the Risk Score). Always read risk_score for the running total; never reconstruct it by summing signals.

ScoreDetail

One entry in the parsed History score_details string, and in the deprecated Management Snapshot Details array. It is what makes the Risk Score explainable on stored identifications.
integer
The weight this risk signal added to the Risk Score. Read the row score for the total rather than summing entries; a row whose score is 999 is the rate-limit marker, not a sum, so skip it as the account read does. The Risk Scoring weight table interprets each Value. Entries whose Value is 0 are diagnostic notes; skip them.
string
A free-text description of the signal for people to read. Its wording can change and can carry diagnostic detail, so branch on Value, the row score and the row’s is_* flags.

Interpreting Value: the signal-weight reference

Each risk signal contributes a fixed weight to the Risk Score, and a higher weight is stronger evidence of masking or spoofing. The full weight table lives on Risk Scoring, and the risk signals reference explains what each one covers.
Read a high Risk Score together with its named risk signals and the user’s history. A real customer on a corporate VPN can reach the Suspicious band; the signals show why, and you choose the action for each case. The per-band playbook has a starting policy for each band.

Snapshot

The object returned by the deprecated Management History path (GET /v1/history/{type}/{value} on api.shieldlabs.ai). A Snapshot carries the identity and score fields in PascalCase and adds raw network columns. It has no traffic source and no detection flags. That endpoint returns an array of these, newest first. New integrations should use the History API on account.shieldlabs.ai (snake_case rows in a { data, total } envelope).
The identity, score and signal fields map across three public surfaces. Names and shapes differ, so do not assume one JSON shape: Do not treat display labels such as “Anti-detect Browser” as JSON keys. On the webhook, branch on signals[].name (antidetect_browser) or detection_flags.anti_detect_browser; on History rows, on is_antidetect. Other Snapshot fields:
string
The classified connection type, one of direct, mobile, vpn, proxy, tor, privacy_relay, browser_vpn_proxy, or unknown (when the type could not be resolved).
string
The browser derived for the device, for example Chrome or Safari.
string
The device form factor, for example desktop or mobile.
The snapshot may include additional network-intelligence fields.
The additional network-intelligence fields are raw network internals. They feed the Risk Score; they are not meant for end-user display. Keep them on your server.
The History API on account.shieldlabs.ai accepts user_hid, device_id, visitor_id, ip (public IP), request_id, session_id and cookie_id. The deprecated Management History path on api.shieldlabs.ai accepts the same seven types. The full query, limit rules, and response shapes are in the Server API.

Profile

The object GET /v1/profile returns on api.shieldlabs.ai. This read is free.
string
The domain this configuration belongs to.
integer
The remaining included volume on your account, in identifications, shared by all your domains. Each identification uses 1; History and profile reads use none. The Billing page has the details.
string
Legacy field kept for older integrations. Webhook delivery uses the endpoints you register in the analytics dashboard under Integration > Webhooks.
string (masked)
Your per-domain Public Key, masked to the last four characters. The Public Key goes in the snippet URL and is safe to expose. Read it in full in the analytics dashboard under Integration > API keys.
string (masked)
Your per-domain Secret Key, masked to the last four characters. The Secret Key is backend-only: it authenticates the Management API (api.shieldlabs.ai). Webhooks are signed with a separate whsec_… secret per endpoint, not with the Secret Key. Never put the Secret Key in the browser.
string (RFC 3339)
When the domain configuration was created.

High-Risk Events

High-Risk Events are four detections on your users: Multi-accounting, Account sharing, Impossible travel and Account takeover. Each carries Medium or High confidence, a separate axis from the Risk Score, and the confidence depends on the combination of evidence. Events are keyed on the User HID, so pass a hashed User HID with checkAuthenticatedUser on every signed-in page. High-Risk Events are available in the analytics dashboard, the API and webhooks.

Webhooks

The webhook envelope, X-Shield-Signature verification, and at-most-once delivery.

Server API

History search, the account read, profile, and limit rules.

Risk Score

How the explainable 0-100 Risk Score and the Trusted, Suspicious and Dangerous bands work.

Risk Signals

The full catalog of risk signals, their weights and how they combine.