Skip to main content
The ShieldLabs Server API is the server-side surface for your domain — the visitor identification and device fingerprinting API your backend calls to read scored results. ShieldLabs scores each visit asynchronously: the JS snippet collects signals, ShieldLabs scores them in about a second, and the result arrives by webhook and is stored for this API to read. Two backend APIs, both server-side only — never call them from the browser:
  • History API (recommended) on account.shieldlabs.ai — served by Shield.Portal.Admin. Read scored snapshots by identifier. Free: reads do not consume requests. Response envelope { data, total } (snake_case).
  • Management API on api.shieldlabs.ai — served by Shield.Core. Read your domain profile and balance, plus an alternate history path that bills per returned row (PascalCase JSON array).
Both History surfaces accept the same lookup types: ip, user_hid, visitor_id, request_id, device_id, session_id, cookie_id. Register webhook endpoints in the dashboard Webhooks tab (up to 10 per domain).

See also

Base URLs

Use these hosts for the History API and Management API. The development hosts mirror production for local and staging work.

Authentication

Each API uses a different backend credential. Both are server-side only; an unauthenticated request returns 401.
All server credentials must stay on your backend. Never put a Private API Key or Secret Key in the browser, the JS snippet, client logs, or a public repository. Webhook endpoints use separate whsec_… signing secrets. The browser-safe credential is the Public Key, which goes in the snippet, not here.

Trying it out

The fastest check: read one scored identification back by its request_id with your Private API Key.
A 200 with a data array (empty is valid) means your key and host are correct. Full endpoint detail follows.
Read stored snapshots from your backend with the Private API Key (authentication above). Wrong or missing credentials return 401 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). Two extended routes — /api/v1/request/{request_id} and /api/v1/debug/… — return one snapshot or a search in an extended PascalCase shape with extra network and attribution fields, for investigations. They are not the standard integration path, and their response shape differs from the snake_case history envelope below.

GET /api/v1/history/{search_type}/{value}

Searches the snapshots 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:
  • ip: client IP address (IPv4)
  • user_hid: the hashed user id you passed via the snippet (free-form string)
  • visitor_id: a VisitorID (UUID)
  • request_id: a single identification’s RequestID (UUID)
  • device_id: a DeviceID (UUID)
  • session_id: a SessionID (UUID) — browsing session within a visit window
  • cookie_id: a CookieID (UUID)
Always send one of the supported values above. An unsupported {search_type} is not validated and will not return the result you expect.
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.

Response

The data array holds snapshot objects 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-form Description; branch on Value and the row score, not on the Description text, which is human-readable and not a stable contract. Field names map to the webhook body (request_idrequest_id, scorerisk_score, parsed score_detailssignals). The example shows the core fields; a full snapshot also carries the connection, network, traffic-attribution, and per-signal flag columns. History reads through this API do not consume request balance and do not return 402.

Common search patterns

Query by request_id with limit=1 when you only need one scored result. Reserve wider device_id / user_hid / ip searches for investigations.

Management API (api.shieldlabs.ai)

The Management API runs on api.shieldlabs.ai. It serves profile and balance, and an alternate History path that bills against your domain balance.

Authentication

Credentials in headers, not in the URL:
Wrong credentials, an unknown domain, or a disabled domain return 401 with an empty body.

Endpoints at a glance

GET /v1/profile

Returns your domain’s configuration and current balance. Keys are masked to their last four characters. This call is free.

Response

string
The registered domain this profile belongs to.
integer
Your remaining balance, measured in requests. One identification consumes 1 request, and the Management History API consumes 1 request per returned row. When this reaches 0, scoring and Management History calls return 402, as the Billing page details.
string
Your Public Key, masked to the last four characters. The browser-safe credential that goes in the snippet URL. Read the full value from the dashboard.
string
Your Secret Key, masked to the last four characters. Used for this API only. The full value is shown only at creation in the dashboard.
string
ISO 8601 UTC timestamp of when the domain was created.

GET /v1/history/{type}/{value}

Alternate History path on the Management API. Returns a JSON array of snapshot objects in PascalCase, newest first. Prefer the History API for new work.

Path parameters

string
required
The field to search on. One of (same set as the History API):
  • ip: client IP address (IPv4 validated)
  • user_hid: the hashed user id you passed via the snippet (free-form string)
  • visitor_id: a VisitorID (UUID validated)
  • request_id: a single identification’s RequestID (UUID validated)
  • device_id: a DeviceID (UUID validated)
  • session_id: a SessionID (UUID validated)
  • cookie_id: a CookieID (UUID validated)
Any other value returns 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.

Billing

The Management History API bills 1 request per returned row. An empty result still bills 1 request (the lookup itself). If your balance is insufficient for the result, the call returns 402.
The 1-request lookup charge is taken before the lookup is validated, so a 400 (malformed value) or 404 (unsupported {type}) still bills 1 request. Only 401 (bad credentials) and 402 (out of requests) cost 0.

The Snapshot object (Management API)

On api.shieldlabs.ai, History returns a superset of the webhook body: identity and score fields in PascalCase, plus connection and network detail captured during scoring.
The identity and score fields map to the webhook body (request_id, risk_score, signals[{ name, weight }], …). Note the field name differs by surface: this PascalCase Management snapshot uses Score, the recommended account.shieldlabs.ai History rows use score, and the webhook data uses risk_score. See Snapshot.
string
Detected browser name, e.g. Chrome, 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).
A snapshot also carries the Network Intelligence fields below. They describe the connection itself, are captured during scoring, and are useful for your own forensics and correlation.
integer
The TCP maximum segment size observed for the connection, a low-level network attribute captured during the network check.
integer
The network MTU (maximum transmission unit) derived from the connection.
string
A short label for the link type inferred from the MTU, for example ethernet.
string
The visitor’s local (host) IP observed during the network check. This is a server-side correlation field for the local-IP entity: keep it server-side and do not display it to end users.
string
Country derived from the network-check IP, used to cross-check against the public-IP Country.
string
Connection type classified from the network check, for example direct.
A snapshot is a point-in-time record of one identification. When a follow-up network check completes after the first score, the stored snapshot reflects the recomputed value (the webhook itself is sent once, after that follow-up window).

Reading the score

ShieldLabs scores. Your application decides. The Risk Score is a 0 to 100 number that falls into four Risk Score bands, and your code is the actor for allow, challenge, review, or block. Decide on Score + Details + action context, never the number alone: a legitimate user can score high behind a corporate proxy, a VPN, or a privacy browser. Tune your thresholds gradually, working from the per-band playbook and its worked examples.

Errors

Error bodies are not uniform across surfaces — branch on the HTTP status code first.

History API (account.shieldlabs.ai)

Management API (api.shieldlabs.ai)

On the Management API, 401 and 402 return an empty body. 400 and 404 return a bare JSON string. The Errors page is the full reference across every surface.

Next steps

Data Models

The full Snapshot, webhook body, and Score Detail schemas in one place.

Webhooks

The push delivery path: payload, X-Shield-Signature verification, and delivery guarantees.

Identification Flow

How signals become a score and how the webhook and History API fit together.

Keys

Public Key, Private API Key, Secret Key — where each one belongs, and how to rotate.