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

# Quick Start

> Install a browser SDK, identify a visitor and retrieve the result with a server SDK.

Connect ShieldLabs to your website in two parts: a browser SDK obtains a Request ID, and your
backend reads the identification behind that ID. The browser never receives the Risk Score,
risk signals, Visitor ID or Device ID.

## 1. Create an account and add your domain

[Start Free](https://app.shieldlabs.ai/) or sign in to your analytics dashboard. Add and verify
the website domain where you will run the integration. For development or staging, register a
separate HTTPS domain and use its credentials.

## 2. Copy your keys

Open **Integration > API keys** for that domain.

| Credential | Where to use it |
| - | - |
| Public Key | Browser SDK configuration |
| Private API Key (`sec_...`) | Server SDK and History API |
| Management Secret Key | Management profile requests, with the domain header |
| Webhook signing secret (`whsec_...`) | Your server's raw-body webhook verification |

The signing secret belongs to a webhook endpoint and is available under **Integration > Webhooks**.

<Warning>
  Private API Keys, Management Secret Keys and webhook secrets stay on your backend. Never put
  them in browser code, public environment variables, a repository or Google Tag Manager.
</Warning>

## 3. Install the browser SDK

Choose your stack for the complete setup, integration files and verification steps.

<CardGroup cols={3}>
  <Card title="JavaScript" href="/sdks/javascript">npm package or browser integration</Card>
  <Card title="React" href="/sdks/react">Provider and identification hook</Card>
  <Card title="Vue" href="/sdks/vue">Plugin and identification composable</Card>
  <Card title="Angular" href="/sdks/angular">Provider and identification helper</Card>
  <Card title="Svelte" href="/sdks/svelte">Context and SvelteKit form flow</Card>
  <Card title="Next.js" href="/sdks/nextjs">Client components and server verification</Card>
</CardGroup>

For a plain JavaScript application:

<CodeGroup>
  ```bash npm theme={null}
  npm install @shieldlabs-ai/js
  ```

  ```bash yarn theme={null}
  yarn add @shieldlabs-ai/js
  ```

  ```bash pnpm theme={null}
  pnpm add @shieldlabs-ai/js
  ```
</CodeGroup>

```js theme={null}
import { load } from '@shieldlabs-ai/js';

const options = { publicKey: '0123456789abcdef0123456789abcdef' };
// Replace the placeholder with the Public Key for your registered domain.

export async function sendProtectedAction(actionData) {
  let requestId = null;
  try {
    const agent = await load(options);
    const result = await agent.identify();
    requestId = result.requestId;
  } catch {
    // Your backend must treat the action as unverified.
  }

  return fetch('/api/signup', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ ...actionData, requestId }),
  });
}
```

`/api/signup` is your own backend endpoint. Create it using a server quick start below.
Call this function from a protected action, not from every render. If you need an integration
without a build step, use the [snippet guide](/setup/snippet).

<Note>
  Keep the page alive while the agent sends collectors and your application sends the protected
  request. Receiving a Request ID does not mean that the History row or final score is ready.
  Test on your registered domain; receiving an ID on localhost does not prove that the check was accepted.
</Note>

## 4. Run a real check and find its Request ID

Open your website and trigger the protected action once. Look for the same Request ID in the
analytics dashboard's identification details and in your backend request.

ShieldLabs scores asynchronously. The server SDK wait helper polls within a bounded time budget;
handle an absent result or API error explicitly. Do not treat either as Risk Score zero.

## 5. Retrieve the identification on your backend

Copy your Private API Key into the backend environment as `SHIELDLABS_API_KEY`.
Choose the server SDK for your language:

<CardGroup cols={3}>
  <Card title="Node.js" href="/sdks/node">History reads and webhook verification</Card>
  <Card title="Python" href="/sdks/python">Sync and async server clients</Card>
  <Card title="Go" href="/sdks/go">Context-aware reads and webhooks</Card>
  <Card title="PHP" href="/sdks/php">Composer package and server handlers</Card>
  <Card title="Java" href="/sdks/java">Maven or Gradle and typed results</Card>
  <Card title=".NET" href="/sdks/dotnet">NuGet and ASP.NET Core integration</Card>
</CardGroup>

For Node.js:

```bash theme={null}
npm install @shieldlabs-ai/node
```

```js theme={null}
import { ShieldLabs } from '@shieldlabs-ai/node';

const client = new ShieldLabs({ apiKey: process.env.SHIELDLABS_API_KEY });

export async function readIdentification(requestId) {
  if (!requestId) return null;
  return client.identifications.get(requestId);
}
```

The returned identification includes `request_id`, `risk_score`, `signals`,
`detection_flags`, `visitor_id` and `device_id`. Field names and empty values follow the
[normalized model](/api/models). The raw History API returns `{ data, total }`; server SDKs
normalize each row for you.

<Warning>
  A valid Request ID is not authorization for your business action. Authenticate the action,
  check the expected domain and user association, enforce freshness, and atomically reject reuse
  of an accepted ID. Keep the verdict on the server.
</Warning>

## 6. Receive signed webhooks

If your backend should receive scored results without a History lookup, add an HTTPS endpoint
under **Integration > Webhooks**, store its signing secret privately, and verify the endpoint.

Use your server SDK to verify `X-Shield-Signature` against the original raw request body before
trusting the JSON. Handle `webhook.ping` separately from `identification.scored` and process
deliveries idempotently by Request ID. Follow [webhook setup](/setup/webhooks) and the
[signature reference](/api/webhooks). A test delivery is synthetic, not a new real visitor check.

## 7. Verify the complete integration

* The browser sends a fresh Request ID with the intended action.
* Your server finds that same ID using the matching domain's Private API Key.
* Risk Score and detection flags are read on the backend, not trusted from a browser body.
* Missing, malformed, reused or stale IDs and unavailable scoring stay unverified.
* Original webhook bytes verify; modified bytes with the old signature do not.

## Next steps

<CardGroup cols={2}>
  <Card title="SDK reference" href="/api/sdks">All browser and server packages</Card>
  <Card title="User linking" href="/concepts/accounts-and-identifications">Associate a pseudonymous User HID with checks</Card>
  <Card title="Content Security Policy" href="/setup/csp">Allow the required browser connections</Card>
  <Card title="Troubleshooting" href="/troubleshooting">Check domains, credentials and pending results</Card>
</CardGroup>


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