- History API (recommended) on
account.shieldlabs.ai. Read identifications by request ID or by the user, device, visitor, public IP, session or cookie they belong to. Free: reads never use your included identifications. Response envelope{ data, total }(snake_case). - Management API on
api.shieldlabs.ai. Read your profile: the remaining included volume on your account and your masked keys. For history, use the History API.
user_hid (your account), device_id, visitor_id, ip (public IP), request_id, session_id and cookie_id.
Register webhook endpoints in the analytics dashboard under Integration > Webhooks (up to 10 per domain); the setup guide walks through it.
See also
- Collect signals in the browser: JS snippet.
- Receive each identification as it is scored: Webhooks.
- How signals become a Risk Score: Identification Flow.
- How identifications link to users, devices, visitors and IPs: Users, devices, visitors and IPs.
Base URLs
Paths start at the host: join the base URL and the path as they are written below.
For development and staging, register a separate domain (for example
dev.example.com) and call the same hosts with that domain’s keys. The environments guide walks through it.
Authentication
Each API uses a different backend credential. Both are server-side only; an unauthenticated request returns401.
Trying it out
The fastest check: read one scored identification back by itsrequest_id with your Private API Key.
200 with a data array (empty is valid) means your key and host are correct. Full endpoint detail follows.
History API (recommended)
Read stored identifications from your backend with the Private API Key (authentication above). Each key reads the domain it belongs to. Wrong or missing credentials return401 with a JSON body like {"error":"invalid api key"}.
Endpoints at a glance
For a single identification, query
history/request_id/{value} with limit=1 (shown below). For an account, use the recipe that follows.
Read every identification of one account
Your users are the accounts you pass as a hashed User HID withcheckAuthenticatedUser. To see how risky an account has been, read its identifications by user_hid, newest first, and page with offset while offset is below total.
accountView helper in the shared tutorial helpers, which reads the newest 100 identifications.
The worst band across the account’s identifications is the account’s risk, and the distinct Device IDs, Visitor IDs and public IPs are what the account is linked to. An all-zero Device ID (00000000-0000-0000-0000-000000000000) means no usable device signals reached ShieldLabs for that identification; the rate-limit marker (Risk Score 999) is one such case. Route it to review rather than allowing it; the recipe never counts it as a device. Read the same way by device_id, visitor_id or ip to see which accounts share a device, a visitor or an IP (skip rows whose user_hid is anonymous). Each call counts toward the soft limit of 15 requests per second per domain and never uses your included identifications. High-Risk Events on the account are available in the analytics dashboard, the API and webhooks. When one arrives for a user, act on the account; the Risk Score and risk signals of the identification remain the input at signup, login, checkout or withdrawal.
The same account, with its band, its High-Risk Events and each linked device, visitor and IP with the band of the identifications it shares with the account, is on the user’s card in the analytics dashboard (User, device, visitor and IP cards).
GET /api/v1/history/{search_type}/{value}
Searches the identifications ShieldLabs has stored for your domain. Returns a paginated envelope, newest first. This is the guaranteed read path when a webhook may have been missed.
Path parameters
string
required
The field to search on. One of:
user_hid: the hashed User HID of one of your accounts (free-form string)device_id: a Device ID (UUID)visitor_id: a Visitor ID (UUID)ip: a public IP address (IPv4)request_id: the request ID of one identification (UUID)session_id: a Session ID (UUID), the browsing sessioncookie_id: a Cookie ID (UUID)
local_ip from each webhook to group by it.string
required
The value to match for the chosen
search_type.Query parameters
integer
default:"20"
Maximum number of rows to return. Must be between 1 and 100; values outside that range fall back to 20. Rows are ordered newest first.
integer
default:"0"
Number of rows to skip for pagination. Page while
offset is below total.Response
data array holds identifications in snake_case. The score_details field is a JSON string; parse it to get the signal list. Each entry carries a numeric Value (the weight) and a free-text Description; branch on Value and the row score, not on the Description text, which is written for people and can change. Skip entries whose Value is 0: they are diagnostic notes, not risk signals. Field names map to the webhook body (request_id to request_id, score to risk_score, parsed score_details to signals). The example shows the core fields; a full row also carries the connection, network, traffic-attribution and per-signal flag columns:
- Flags use History names such as
is_vpn,is_proxy,is_datacenter,is_antidetect,is_js_disabled,is_browser_automation,is_search_botandcheck_incomplete.browser_vpn_proxyandip_mismatchare on the webhook only. - Traffic attribution is flat on the row:
traffic_channel,referrer_domain,entry_url,utm_source,utm_medium,utm_campaign,utm_content,utm_termandclick_id_type. The webhook nests the same values undertraffic_source, wherechannelistraffic_channelandlanding_urlisentry_url.
402.
Common search patterns
Management API (api.shieldlabs.ai)
The Management API runs on api.shieldlabs.ai. It returns your profile: the domain, the remaining included volume on your account and your masked keys. For identification history, use the History API.
Authentication
Credentials in headers, not in the URL:401 with an empty body.
Endpoints at a glance
GET /v1/profile
Returns the domain, the remaining included volume on your account and your masked keys. Keys are masked to their last four characters. This call is free.
Response
string
The registered domain this profile belongs to.
integer
The remaining included volume on your account, in identifications, shared by all your domains. Each identification uses 1. When your account’s included volume is used up, the identification request returns HTTP
402 until the billing cycle resets or you change plan; the Billing page has the details. History and profile reads never use it.string
Legacy field kept for older integrations. Webhook delivery uses the endpoints you register in the analytics dashboard under Integration > Webhooks.
string
Your Public Key, masked to the last four characters. The browser-safe credential that goes in the snippet URL. Read the full value in the analytics dashboard under Integration > API keys.
string
Your Secret Key, masked to the last four characters. Used for this API only. Copy it or replace it with Rotate in the analytics dashboard under Integration > API keys.
string
ISO 8601 UTC timestamp of when the domain was created.
GET /v1/history/{type}/{value}
Returns a JSON array of snapshot objects in PascalCase, newest first. Lookup types match the History API (seven identifiers). The call never uses your included identifications and never returns 402.
Path parameters
string
required
The field to search on. One of (same set as the History API):
user_hid: the hashed User HID of one of your accounts (free-form string)device_id: a Device ID (UUID validated)visitor_id: a Visitor ID (UUID validated)ip: a public IP address (IPv4 validated)request_id: the request ID of one identification (UUID validated)session_id: a Session ID (UUID validated)cookie_id: a Cookie ID (UUID validated)
404. A value in the wrong format (for example a non-UUID for device_id) returns 400.string
required
The value to match for the chosen
type. UUID types are UUID validated, ip is IPv4 validated, user_hid is a free string.Query parameters
integer
default:"100"
Maximum number of rows to return. Capped at 100: a higher value is clamped to 100. Rows are ordered newest first.
The Snapshot object (deprecated Management History)
Onapi.shieldlabs.ai, the deprecated History path returns identity and score fields in PascalCase, plus network columns captured during scoring. It carries no traffic source or detection flags. New work should parse the History API snake_case envelope instead.
See Snapshot.
string
Detected browser name, for example
Chrome or Safari.string
Form factor:
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
Optional network attribute on the snapshot. Keep it server-side.
integer
Optional network attribute on the snapshot. Keep it server-side.
string
Optional network attribute on the snapshot (a short label). Keep it server-side.
string
Optional local IP field on the snapshot. Keep it server-side and do not display it to end users.
string
Country associated with that local IP, when present.
string
Connection type associated with that local IP, when present (for example
direct).A snapshot is a point-in-time record of one identification. The stored snapshot reflects the final Risk Score delivered on the webhook.
Reading the result
The Risk Score of one identification is a number from 0 to 100 that falls into three Risk Score bands: Trusted 0-29, Suspicious 30-59, Dangerous 60-100. The row carries the number (score), so map it to a band in your backend, and treat any value above 100 as the 999 rate-limit marker. A user, device, visitor or IP takes the worst band of its identifications, which the account read above computes. Read a high Risk Score together with its named risk signals (score_details, or signals on the webhook) 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: allow, step up, review or block. The per-band playbook has starting policies and worked examples.
Errors
Error bodies are not uniform across surfaces, so branch on the HTTP status code first.History API (account.shieldlabs.ai)
Management API (api.shieldlabs.ai)
On the Management API,
401 returns an empty body, and 400 and 404 return a bare JSON string. Only the identification request sent by the snippet returns 402, when your account’s included volume is used up; see Billing.
The Errors page is the full reference across every surface.
Next steps
Data Models
The full Snapshot, webhook body, and Score Detail schemas, and the identity each identifier maps to.
Webhooks
The push delivery path: payload,
X-Shield-Signature verification, and delivery guarantees.Identification Flow
How an identification is scored and how the webhook and History API fit together.
API keys
Public Key, Private API Key, Secret Key: where each one belongs, and how to rotate.