> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shieldlabs.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# API Overview

> How the snippet, webhooks and the Server API fit together, and which key each one uses.

ShieldLabs scores your users, devices, visitors and IP addresses. Each time the snippet runs, it makes one identification: ShieldLabs returns its Risk Score with every risk signal named and weighted, and links it to the device, visitor, public IP and local IP it belongs to, and to the user when a signed-in page passes a User HID. Your backend receives each identification by webhook and reads any identification, or every identification of one account, device, visitor or public IP, through the History API. You choose the action for each case (allow, step up, review or block) and act on the result in your backend.

## The three surfaces

<CardGroup cols={3}>
  <Card title="JS snippet" icon="code">
    Collects device and network signals in the browser and posts each identification to `rest.shieldlabs.ai` automatically. On signed-in pages, `checkAuthenticatedUser` passes the hashed User HID. You install it once; you do not call this endpoint yourself.
  </Card>

  <Card title="Webhooks" icon="bolt">
    Push delivery. ShieldLabs POSTs each identification's [Risk Score](/features/risk-scoring) and named risk signals to every endpoint you register in the analytics dashboard, about 300 ms after the check in the browser.
  </Card>

  <Card title="Server API" icon="server">
    Pull. Read any identification by its request ID, or every identification of one user, device, visitor or public IP (History API), and the remaining included volume on your account (Management API).
  </Card>
</CardGroup>

A typical integration uses all three: the snippet runs on your pages and passes a hashed User HID on signed-in pages, webhooks deliver each identification about 300 ms after the check, and the History API is your guaranteed read and your view of an account's history.

## What the API returns

Each webhook and each History row is one identification, the event layer under your users, devices, visitors and IPs. It carries the keys that link it to each of them, so the account-level view is one lookup away.

| Result | Webhook | History API | Analytics dashboard |
| - | - | - | - |
| Risk Score | Yes, `risk_score` | Yes, `score` | Yes, on each [identification card](/dashboard/identification-card) |
| Named and weighted risk signals | Yes, the `signals` array | No `signals` array; rows carry `score_details`, an internal log | Yes, with their weights, on each identification card |
| Detection flags | Yes, the 19 `detection_flags` | `is_*` flags, without `browser_vpn_proxy` or `ip_mismatch` | Yes, by name, next to the risk signals |
| Traffic source | Yes, the `traffic_source` object | Flat fields, such as `traffic_channel`, `entry_url` and `utm_source` | Yes, on each identification card and as filters in [Analytics](/dashboard/analytics) |
| Band of an identification: Trusted, Suspicious or Dangerous | Map it from `risk_score` | Map it from `score` | Yes |
| User HID, Device ID, Visitor ID, public IP, local IP | Yes | Search by `user_hid`, `device_id`, `visitor_id` or public `ip` | Yes |
| Risk of a user, device, visitor or IP (the worst band of its identifications) and what it is linked to | Group deliveries by the keys above | [Read its identifications](/api/server-api#read-every-identification-of-one-account) by the keys above | Yes, on the [user, device, visitor and IP cards](/dashboard/entity-card) |

High-Risk Events (Multi-accounting, Account sharing, Impossible travel and Account takeover, each at Medium or High confidence) are detected on your users and are available in the analytics dashboard, the API and webhooks. In the analytics dashboard, [Overview](/dashboard/overview) shows how many of your users have each one, [Analytics](/dashboard/analytics) filters by them, and the user card shows each event with its confidence.

Pass a hashed User HID with `checkAuthenticatedUser` on every signed-in page. Users, account-level risk and all four High-Risk Events are built on it. [Users, devices, visitors and IPs](/concepts/entities) explains the model.

## Hosts

| Host | Purpose | Who calls it |
| - | - | - |
| `cdn.shieldlabs.ai` | Serves the JS snippet | The browser |
| `rest.shieldlabs.ai` | Receives collected signals | The snippet (automatic) |
| `webrtc.shieldlabs.ai`, `ice.shieldlabs.ai:3478` | Network check endpoints | The snippet (automatic) |
| `account.shieldlabs.ai` | **History API** (Private API Key), paths under `/api/v1/` | Your backend |
| `api.shieldlabs.ai` | **Management API** (Secret Key): profile, with the remaining included volume on your account | Your backend |
| `app.shieldlabs.ai` | Analytics dashboard | You |

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](/setup/environments) walks through it.

## Authentication

Each domain has three keys, one for the browser and two for your backend, plus a signing secret for each webhook endpoint. They are not interchangeable.

| Key | Where it goes | What it does |
| - | - | - |
| **Public Key** | The snippet URL, `?publicKey=...` | Identifies the domain in the browser. Safe to expose. |
| **Private API Key** | Your backend only (`sec_…`) | Authenticates the [History API](/api/server-api) on `account.shieldlabs.ai/api/v1/…` |
| **Secret Key** | Your backend only (hex) | Authenticates the [Management API](/api/server-api) on `api.shieldlabs.ai` |
| **Webhook signing secret** | Your backend only (`whsec_…` per endpoint) | Verifies the `X-Shield-Signature` header on incoming webhooks |

**History API (recommended for reads):**

```
GET https://account.shieldlabs.ai/api/v1/history/request_id/{requestID}?limit=1
Authorization: Bearer sec_your_private_api_key
```

**Management API (profile and included volume):**

```
GET https://api.shieldlabs.ai/v1/profile
X-Shield-Domain: myshop.com
Authorization: Bearer YOUR_SECRET_KEY
```

<Warning>
  Private API Keys and Secret Keys must never appear in the browser, the snippet, client logs, or a public repository. If one leaks, rotate it in the [analytics dashboard](https://app.shieldlabs.ai/) under **Integration > API keys** with **Rotate** ([Integration](/dashboard/integration)). The [API keys](/setup/keys) page covers where each credential belongs.
</Warning>

## Asynchronous scoring

Scoring is asynchronous. The snippet posts the collected signals and receives an acknowledgment; ShieldLabs scores the identification in about 300 ms and delivers the result by [webhook](/api/webhooks) and through the [History API](/api/server-api). The `request_id` ties the snippet call, its webhook and its History record together, and the `user_hid`, `device_id`, `visitor_id` and IP fields tie the identification to your users, devices, visitors and IPs.

## Billing and limits

* Each identification uses **1** of your account's included identifications. All your domains share one quota.
* Reading your profile, receiving webhooks, using the analytics dashboard and History API reads are **free**.
* The History API defaults to **20** rows and accepts a `limit` up to **100**, with `offset` for paging.
* When your account's included volume is used up, the identification request sent by the snippet returns HTTP `402` until the billing cycle resets or you change plan. The [Billing](/billing) page has the details. History and profile reads keep working.
* Infrastructure [rate limits](/rate-limits) protect the gateways. During a per-IP ban, identifications carry the marker value `999` in place of a Risk Score; treat any value above 100 as that marker.

## Conventions

* **Responses** are JSON. Error bodies are not uniform, so branch on the HTTP status code rather than parsing a body field. The [Errors](/errors) page enumerates each case.
* **Timestamps** are ISO 8601 UTC on webhooks and the Management API; the History API `created_at` may use `YYYY-MM-DD HH:MM:SS` instead of ISO 8601.
* **Identifiers** (`request_id`, `device_id`, `visitor_id`, `session_id`, `cookie_id`) are UUIDs. `user_hid` is the hashed User HID you pass for a signed-in account, a free-form string, and `"anonymous"` on anonymous checks.

## Next steps

<CardGroup cols={2}>
  <Card title="Identification Flow" icon="diagram-project" href="/api/identification-flow">
    How an identification is scored, reaches your backend, and leads to the account behind it.
  </Card>

  <Card title="Webhooks" icon="bolt" href="/api/webhooks">
    The flat webhook payload, `X-Shield-Signature` verification, and delivery guarantees.
  </Card>

  <Card title="Server API" icon="server" href="/api/server-api">
    The History API, the account read, and the Management API profile.
  </Card>

  <Card title="Data Models" icon="table-cells" href="/api/models">
    Every object the API returns, and the user, device, visitor or IP each identifier maps to.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.