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 richer object the Management History API (api.shieldlabs.ai) returns (PascalCase). It is a superset of the webhook visit fields with network fields added. The recommended History API on account.shieldlabs.ai returns the same data as snake_case rows in a { data, total } envelope — see Server API.
  • ScoreDetail is one entry in the explainable Details array on a Snapshot (Value, Description).
  • WebhookSignal is one entry in the explainable signals array inside WebhookEvent.data (name, weight).
A fifth object, Profile, is the per-domain configuration you read from the Server API.
ShieldLabs surfaces these objects. Your own code owns the decision. The payloads carry a Risk Score (0–100) and the signals behind it. You decide allow / challenge / review / block in your application from that data.

Object map

WebhookEvent

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

Snapshot

Returned by the Management History API (PascalCase). Everything in the webhook payload plus connection and network fields.

WebhookSignal

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

ScoreDetail

One signal in a Snapshot Details entry: { Value, Description }.

Profile

Your domain’s configuration: weight balance and masked keys.

WebhookEvent

The envelope delivered when ShieldLabs finishes scoring an identification. Each enabled endpoint receives one POST per check. 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 real visits; webhook.ping for endpoint Verify. See Webhooks.
string
Contract version, currently 2026-06-01.
string (RFC 3339)
When the webhook event was created.
object
Scored visit payload. Omitted on webhook.ping. Fields below describe data on identification.scored.
string (UUID)
The client-generated UUID for this identify call. Use as the idempotency key and the join key to the History API.
string (UUID)
The per-visit identifier from sessionStorage (short-lived). Resets each browser session or tab.
The first-party cookie / localStorage identifier minted in the browser. It is lost when the visitor clears cookies or storage.
string (UUID)
Server-derived from hundreds of stable browser and device characteristics. It survives cookie clears, incognito, and IP rotation because it is derived from the environment, not stored, as the Identifiers reference explains.
string (UUID)
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
Your own account identifier, passed in through the snippet. Always pass a hashed or pseudonymous value, never a raw email or user id. null when not provided; literal anonymous on anonymous calls.
string
The registered site domain key for this identification.
object
Public HTTP IP and country: { "ip": "<dotted IPv4>", "country": "<ISO code>" }.
object
The real network IP and 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 visitor, 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 (0–100)
The explainable Risk Score. Integer, hard-capped at 100. Higher means more anonymous, masked, spoofed, or abusive. Map bands in your code: Clean 0–9, Low 10–29, Medium 30–59, High 60–100. The value 999 is a rate-limit ban marker; guard risk_score > 100 before reading the band.
WebhookSignal[]
The full list of scored signals that contributed to risk_score. 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, javascript_disabled, incognito, suspicious_paid_click, ip_mismatch.
Branch on risk_score, signal name slugs, and detection_flags.
string (RFC 3339)
When the visit was scored and this payload was finalized, for example 2026-06-26T14:20:42Z.

WebhookSignal

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

ScoreDetail

One entry in the Snapshot Details array (History API, PascalCase). It is what makes the Risk Score explainable on stored snapshots.
integer
The points this signal added to the Risk Score. The score is additive: the entries’ Value fields sum to the total, then the total is capped at 100. Use the weight table below to interpret a Value.
string
The customer-facing name of the signal, for example "VPN", "OS Mismatch", or "Datacenter IP". Match this against the signal reference to understand what fired.

Interpreting Value: the signal-weight reference

Each signal contributes a fixed number of points to the Risk Score, and a higher weight is stronger evidence of anonymity or spoofing. The full weight table lives on Risk Scoring; match a Description against the signal reference to see what each one covers.
A high Value does not by itself mean fraud. A real user behind a corporate proxy, a VPN, or a privacy browser can legitimately fire these checks. Decide on the Score plus the Details plus your own context, never the raw number alone, following the per-band playbook.

Snapshot

The object returned by the Management History API (GET /v1/history/{type}/{value} on api.shieldlabs.ai). A Snapshot is a superset of the webhook payload: it carries the same identity, score, traffic, and detection fields in PascalCase and adds raw network columns. That endpoint returns an array of these, newest first. (The recommended History API on account.shieldlabs.ai returns the same data as snake_case rows in a { data, total } envelope.)
The identity, score, and Details fields map to webhook fields as follows: RequestIDrequest_id, Scorerisk_score, Details[{ Value, Description }]signals[{ name, weight }], IP/Countrypublic_ip, the network-check IP fields ↔ local_ip, traffic columns ↔ traffic_source, signal flags ↔ detection_flags. The fields a Snapshot adds on top:
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 visitor, 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 power the score; they are not meant for end-user display. Keep them on your server.
The History API on account.shieldlabs.ai accepts request_id, visitor_id, device_id, user_hid, ip, session_id, and cookie_id. The alternate Management History path on api.shieldlabs.ai accepts the first five only and bills 1 request per returned row. The full query, limit rules, and response shapes are in the Server API.

Profile

The per-domain configuration object returned by GET /v1/profile on api.shieldlabs.ai. This read is free (it does not consume requests).
string
The domain this configuration belongs to.
integer
Your remaining request balance for this domain. Each identification consumes 1; each History row consumes 1, as the Billing page details.
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. Use the dashboard to view it in full.
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). It does not sign webhooks; each webhook endpoint has its own whsec_… secret. Never put the Secret Key in the browser.
string (RFC 3339)
When the domain configuration was created.

Patterns are not in these payloads

The 8 Patterns are a dashboard feature, not part of the API or webhook payloads above. They are computed server-side from your historical data, graded over a time window, and shown on the dashboard Patterns view. You retrieve them through dashboard export (CSV or JSON), not from the webhook body, Snapshot, or any API field documented on this page. They are also conceptually different from the scoring signals: For completeness, the shape an exported pattern detection follows conceptually:
string
The pattern’s machine name, for example many_accounts_one_device or multiple_countries_on_account. All 8 Patterns are named there with what each detects.
string
The kind of identifier flagged: user_hid, visitor_id, device_id, cookie_id, or the Local IP entity (a dashboard label).
string
The specific identifier value that was flagged.
string
The grade: suspicious or dangerous. An entity that never crosses the suspicious threshold is implicitly “Normal” and is not recorded. A level never downgrades on later runs.
Pattern thresholds are server-side and adapt to an entity’s risk. There is no in-product rules engine: ShieldLabs grades patterns and scores requests, and your own code (using the Risk Score and signals from webhooks and the API) owns the allow / challenge / review / block decision.

Webhooks

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

Server API

History search, profile, limit rules, and per-row billing.

Risk Score

How the 0–100 explainable score and the Clean / Low / Medium / High bands work.

Signals

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