> ## 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

> An overview of how the ShieldLabs API is organized and how to authenticate.

ShieldLabs has a small, focused API surface. You install a snippet, you receive scored results, and you read history when you need a guaranteed pull. ShieldLabs scores every visit; your own code decides whether to allow, challenge, review, or block.

## The three surfaces

<CardGroup cols={3}>
  <Card title="JS snippet" icon="code">
    Collects browser, device, and network signals and posts them to `rest.shieldlabs.ai` automatically. You install it once; you do not call this endpoint yourself.
  </Card>

  <Card title="Webhooks" icon="bolt">
    Push delivery. ShieldLabs POSTs the [Risk Score](/features/risk-scoring) and signals to each endpoint you register in the dashboard, about a second after a visit.
  </Card>

  <Card title="Server API" icon="server">
    Pull. Call from your backend to read scored snapshots (History API) and, when needed, your domain profile and balance (Management API).
  </Card>
</CardGroup>

A typical integration uses all three: the snippet runs on your pages, webhooks deliver scores in real time, and the History API is your guaranteed fallback for anything a webhook might miss.

## 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/api`                      | **History API** (Private API Key)                                                     | Your backend            |
| `api.shieldlabs.ai`                              | **Management API** (Secret Key) — profile, balance, and a per-row-billed history path | Your backend            |
| `app.shieldlabs.ai`                              | Dashboard UI                                                                          | You                     |

The [development hosts](/setup/environments) mirror these for local and staging work (`dev.account.shieldlabs.ai/api`, `dev.cdn.shieldlabs.ai`, …).

## Authentication

Each domain has three server credentials plus per-webhook signing secrets. 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 snapshot 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 balance):**

```
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 from the [dashboard](https://app.shieldlabs.ai/). The [Keys](/setup/keys) page covers where each credential belongs.
</Warning>

## No synchronous score endpoint (today)

There is no request that returns a Risk Score in its response. Scoring is asynchronous: it combines IP reputation, network analysis, and a follow-up network check that take about a second to resolve. So the snippet posts signals, ShieldLabs scores them, and the result reaches you by [webhook](/api/webhooks) and through the [History API](/api/server-api).

<Note>
  A cleaner synchronous server endpoint (`POST /v1/verify`) is planned but not yet available. Integrate today via webhooks plus the History API, both documented here. The [`RequestID`](/features/identification) is the join key that ties a snapshot, its webhooks, and its history rows together.
</Note>

## Billing and limits

* One identification consumes **1 request** from your domain balance.
* The **Management API** History path on `api.shieldlabs.ai` consumes **1 request per returned row** (an empty result still costs 1). The **History API** on `account.shieldlabs.ai` does not bill per row.
* Reading your profile, receiving webhooks, viewing the dashboard, and History reads through `account.shieldlabs.ai` are **free**.
* The Management API history path returns at most **100 rows** per call. The History API defaults to **20** rows and accepts a `limit` up to **100**.
* When the balance reaches 0, new identifications and Management API history calls return `402`, as the [Billing](/billing) page details.
* Infrastructure [rate limits](/rate-limits) protect the gateways and never feed the Risk Score.

## 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 the Management API; the History API may return ClickHouse datetime strings in `created_at`.
* **Identifiers** (`RequestID`, `DeviceID`, `VisitorID`, `SessionID`, `CookieID`) are UUIDs. `UserHID` is your own hashed user id, a free-form string.

## Next steps

<CardGroup cols={2}>
  <Card title="Identification Flow" icon="diagram-project" href="/api/identification-flow">
    How signals become a score, and how the webhook and History API fit together.
  </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">
    History API, Management API profile, and full request and response detail.
  </Card>

  <Card title="Data Models" icon="table-cells" href="/api/models">
    WebhookEvent, Snapshot, WebhookSignal, ScoreDetail, and Profile schemas in one place.
  </Card>
</CardGroup>
