# Node / TypeScript SDK

> The official sightradar package for Node, Deno and browsers. No runtime dependencies, built-in fetch, full TypeScript types.

Source: https://sightradar.com/docs/sdks/node

```bash
npm install sightradar
```

Source and issues: [github.com/sightradar-hq/sightradar-node](https://github.com/sightradar-hq/sightradar-node). MIT licensed. Uses the built-in `fetch` (Node 18 or newer, Deno, browsers) and ships full types.

**Keep keys server-side.**
The package runs in a browser, but an API key spends your credits. Call it from your backend and expose your own endpoints to the client. See [Authentication](/docs/authentication#keep-keys-off-the-client).

## Authenticate

```ts
import { SightRadar } from "sightradar";

const sr = new SightRadar({ apiKey: "frs_..." }); // or new SightRadar() with SIGHTRADAR_API_KEY
```

## Core workflow

```ts
// 1. Create a collection to hold faces.
await sr.createCollection("event-2026");

// 2. Index faces from photos (URL, GCS key, or an uploaded file).
await sr.index("event-2026", { url: "https://example.com/group.jpg" });
await sr.index("event-2026", { file: buffer, filename: "photo.jpg", photoId: "img-42" });

// 3. Search the collection with one selfie.
const result = await sr.search("event-2026", { url: "https://example.com/selfie.jpg" });
for (const m of result.matches) console.log(m.photo_id, m.similarity);
```

## Stateless operations

```ts
// Detect and quality-gate faces in an image. Nothing is stored.
const det = await sr.detect({ url: "https://example.com/photo.jpg" });
console.log(det.detected_face_count, det.gated_face_count);

// 1:1 verification between two faces.
const cmp = await sr.compare({
  sourceUrl: "https://example.com/a.jpg",
  targetUrl: "https://example.com/b.jpg",
});
console.log(cmp.match, cmp.similarity);
```

## Selfies

```ts
const reg = await sr.registerSelfie("event-2026", { url: "https://example.com/selfie.jpg", userId: "u_42" });
```

## Account

```ts
console.log((await sr.wallet()).balance_credits);
console.log(await sr.usage(30));
```

## Image inputs

Index, search, detect and register-selfie accept exactly one image source:

| Field    | Meaning                                                                          |
| -------- | -------------------------------------------------------------------------------- |
| `url`    | a public image URL                                                               |
| `gcsKey` | a Google Cloud Storage object key                                                |
| `file`   | a `Blob`/`File` (browser) or `Buffer`/`Uint8Array` (Node), uploaded as multipart |

`search` additionally accepts `embedding` (a 512-number array).

## Errors

Every non-2xx response rejects with a typed error:

```ts
import { NotFoundError, AuthenticationError } from "sightradar";

try {
  await sr.describeCollection("missing");
} catch (e) {
  if (e instanceof NotFoundError) console.log(e.statusCode, e.message);
}
```

Error classes: `SightRadarError` (base), `AuthenticationError` (401), `InsufficientCreditsError` (402), `NotFoundError` (404), `RateLimitError` (429). See [errors and status codes](/docs/errors).

## Method reference

| Method                                                                          | Endpoint                                       |
| ------------------------------------------------------------------------------- | ---------------------------------------------- |
| `createCollection`, `listCollections`, `describeCollection`, `deleteCollection` | [Collections](/docs/api/collections)           |
| `index`                                                                         | `POST /v1/collections/{id}/index`              |
| `search`                                                                        | `POST /v1/collections/{id}/search`             |
| `registerSelfie`                                                                | `POST /v1/collections/{id}/selfies`            |
| `detect`                                                                        | `POST /v1/detect`                              |
| `compare`                                                                       | `POST /v1/compare`                             |
| `wallet`, `usage`                                                               | [Wallet and usage](/docs/api/wallet-and-usage) |

Search-by-id, batches and webhooks are not wrapped yet; call them over REST with `fetch`. See [batch and webhooks](/docs/guides/batch-and-webhooks).
