# n8n

> Index event photos and email guests their photos from a selfie in n8n, with the SightRadar community node, a signed webhook trigger and two example workflows.

Source: https://sightradar.com/docs/guides/n8n

> **Coming soon.** `n8n-nodes-sightradar` is not on npm yet, so n8n cannot install it by name until it publishes. Everything below describes the node as it ships.

The `n8n-nodes-sightradar` package adds two nodes to n8n:

* **SightRadar**, an action node with Collection, Face, Batch and Account resources. It is also usable as an AI Agent tool.
* **SightRadar Trigger**, which starts a workflow when batch photos finish or a collection deletion completes. It verifies every delivery's signature.

It is built for the event-photo workflow: index every photo after the event, then let each guest upload a selfie and email them the photos they appear in.

## Install

### Add the package

In a self-hosted n8n, an Owner or Admin opens **Settings → Community Nodes → Install**, enters `n8n-nodes-sightradar`, acknowledges the risk notice and selects **Install**. See n8n's [community node installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) for queue-mode and manual installs.

The package needs an n8n version with `n8nNodesApiVersion: 1` and resource locators (n8n 1.x or later). It has no runtime dependencies.

### Create the credential

Create an API key in the [console](/dashboard/keys) under **API Keys**. It looks like `frs_<prefix>_<secret>` and is shown once. In n8n, create a **SightRadar API** credential and paste the key.

The credential test lists one collection, a free call, so testing never spends credits. The key is sent as `Authorization: Bearer …` by the credential itself and never appears in node parameters.

## Operations

| Resource   | Operation         | What it does                                                                                                                                                 | Credits      |
| ---------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ |
| Collection | Create            | Create a collection, for example one per event. An ID that already exists and is active returns that collection.                                             | free         |
| Collection | Get               | Photo, face and selfie counts for one collection                                                                                                             | free         |
| Collection | Get Many          | List collections, newest first, with an **ID Contains** filter, **Return All** or a **Limit** (default 50, maximum 200)                                      | free         |
| Collection | Delete            | Soft delete by default (restorable during the grace window). Options: **Delete Immediately**, or **Compliance Erasure** for an audited, irreversible erasure | free         |
| Face       | Index             | Store the faces in one photo, from a URL or a binary file. Set **Photo ID** to your file name so matches link back                                           | 93           |
| Face       | Search by Image   | Find every photo in a collection that contains the person in a selfie (URL or binary)                                                                        | 93           |
| Face       | Register Selfie   | Store one person's selfie under a **User ID** and get a `point_id` for repeat searches                                                                       | 93           |
| Face       | Search by Face ID | Search with a stored `point_id`. No image processing                                                                                                         | 62           |
| Face       | Compare           | Similarity between the main faces in two image URLs                                                                                                          | 93 per image |
| Face       | Detect            | Find faces and check quality, storing nothing                                                                                                                | 93           |
| Batch      | Submit            | Index up to 1,000 photo URLs per batch. Each input item is one photo, and the node makes as many batches as it needs                                         | 62 per photo |
| Batch      | Get Status        | Progress counts, optionally with every photo's outcome (**Include Photo Results**)                                                                           | free         |
| Account    | Get Balance       | Prepaid balance in credits, plus `balance_usd`                                                                                                               | free         |

Details that matter when you build a workflow:

* **Image Source.** Index, Search by Image, Register Selfie and Detect take either a public HTTPS **URL** that SightRadar downloads, or a **Binary File** from a previous node, such as a form upload (default binary field `data`). Compare and Batch take URLs only. Images can be up to 30 MB in JPEG, PNG, WebP, HEIC, TIFF, GIF or BMP.
* **Simplify** (on by default) trims Index, both searches and Register Selfie to the fields a workflow uses. Search output becomes `match_count`, `photo_ids`, `matches` and, when nothing matched, `reason`. Turn it off for the raw API response.
* **Minimum Similarity** and **Max Matches** (defaults `0.5` and `100`) filter the searches. Scores are cosine similarity from 0 to 1, and no one threshold fits every use case. Start at 0.5 for gallery search, check results by hand and adjust. See [Choosing a threshold](/docs/guides/thresholds).
* **Idempotency Key** on every Face operation. A retry under the same key is never charged twice. Reusing a key for a *different* request returns `409`, so the key must be unique to the operation, the collection and the photo, for example `{{ 'index:' + $json.collectionId + ':' + $json.photoId }}`. A bare photo id collides as soon as the same photo is indexed into a second collection or also sent to Detect.
* **Credits remaining.** Billable Face operations add `credits_remaining` from the `X-Credits-Remaining` header.
* **Batch Submit runs once for all input items**, not once per item, and outputs one item per batch with its `batch_id`.

## SightRadar Trigger

### How it registers

When you activate the workflow, the trigger registers its **Production URL** with SightRadar (`POST /v1/webhooks`) and stores the signing secret SightRadar returns once. On deactivation it disables the endpoint. You do not create the webhook yourself.

To route a batch to the trigger, paste the trigger's Production URL into **Batch → Submit → Options → Notify Webhook URL**. SightRadar sends batch results only to the endpoint named on the batch. The Submit node looks up the endpoint ID for that URL, so the trigger's workflow must be active first.

**Public HTTPS only.**
SightRadar delivers webhooks only to public HTTPS URLs and rejects private hosts and plain HTTP. Activating the trigger on an n8n that is not publicly reachable fails with a clear error. For local testing, run n8n behind a tunnel and set `WEBHOOK_URL` to its public HTTPS address. Test URLs exist only while n8n is listening for a test event, so use the Production URL for real batches.

### Signature verification

Every delivery carries `X-SightRadar-Timestamp` and `X-SightRadar-Signature`. The trigger recomputes `HMAC-SHA256(secret, "<timestamp>.<raw body>")` over the raw body, compares it in constant time and rejects timestamps more than five minutes old. A delivery that fails gets `401` and never starts the workflow. Delivery is at least once, so the trigger also drops repeats by `X-SightRadar-Idempotency-Key`. The scheme is the one in [batch and webhooks](/docs/guides/batch-and-webhooks#verify-the-signature).

### Events

| Event                         | Fires                                           | Output                                                                                                        |
| ----------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| **Batch Completed** (default) | Once per batch, when every photo has a result   | Batch counts (`total_photos`, `succeeded`, `failed`, …) and, with **Include Photo Results**, a `photos` array |
| **Photo Result**              | Once per photo, as soon as it succeeds or fails | The per-photo [webhook body](/docs/guides/batch-and-webhooks#receive-results) plus `delivery_id`              |
| **Collection Deleted**        | When a collection's faces are verified erased   | The `collection.deletion.completed` event                                                                     |

### Batch Completed is derived

SightRadar has no "batch finished" event; it sends one webhook per photo. The trigger works out completion itself. After each photo result it calls the free batch status endpoint, and the first delivery that finds no pending or in-progress photos fires **Batch Completed**. It remembers the batch so a late retry cannot fire it twice.

The catch is that if that status check fails, for example on a network blip, the event waits for the next photo's delivery. If the failure happens on the last photo, no later delivery comes and Batch Completed never fires for that batch. Two ways to cover it:

* **Poll as a fallback.** Add a schedule that runs **Batch → Get Status** on recent `batch_id`s and treats `pending + claimed = 0` as done. Batch status is free.
* **Use Photo Result** and count results yourself if you need every photo in real time anyway.

## Example workflows

Both workflows are in the package's `examples/` folder. Import them with **Workflows → Import from File**, then attach your SightRadar and SMTP credentials.

### Batch index, then notify

Loads an event gallery at the batch rate and emails you when indexing is done.

**Start indexing** (Manual Trigger) → **Create collection** (`my-event-2026`, free).

**Photo list** (Code) emits one item per photo with a public `url` and a `name`. Replace it with your real source: a storage bucket listing, a CSV or a gallery API.

**Submit batch** (Batch → Submit) maps **Photo URL** to `{{ $json.url }}` and **Photo ID** to `{{ $json.name }}`, so search results come back as file names. **Notify Webhook URL** is the trigger's Production URL.

A second flow starts at **Batch finished** (SightRadar Trigger, Batch Completed, Include Photo Results on). **Summarize** counts succeeded, failed and no-face photos and lists failures with their reason codes. **Email summary** sends the result.

Activate the workflow **before** you run the first flow, so the trigger is registered when Submit looks up its URL.

### Event selfie finder

A guest opens a form, uploads a selfie and gets an email with every event photo they appear in.

**Guest uploads selfie** (n8n Form Trigger) collects name, email and a selfie file. The form text says what the selfie is used for. Keep it that way, because a selfie is biometric data.

**Find guest's photos** (Face → Search by Image) searches `my-event-2026` with **Image Source** set to Binary File, field `Selfie`. It uses Minimum Similarity 0.5 and Max Matches 200.

**Found any photos?** (If) branches on `match_count > 0`. **Build gallery links** turns `photo_ids` into links under your photo base URL, and **Email gallery link** sends them.

The no-match branch emails a retry message that uses `reason`. `no_face` means no face was visible, and `low_quality_selfie` means the selfie was too dark, blurry or small.

Index the gallery first with the batch workflow, using file names as Photo IDs, then set your collection ID and base URLs.

## Costs

1 credit is $0.00001, prepaid. You are never charged for a `4xx` or `5xx`, and a photo with no faces is still one charge. See [Billing](/docs/billing).

| Step                                                                      | Credits | USD      |
| ------------------------------------------------------------------------- | ------- | -------- |
| Credential test, collections, batch status, balance, trigger registration | 0       | free     |
| Batch → Submit, per photo                                                 | 62      | $0.00062 |
| Face → Index, Search by Image, Register Selfie, Detect                    | 93      | $0.00093 |
| Face → Search by Face ID                                                  | 62      | $0.00062 |
| Face → Compare (two images)                                               | 186     | $0.00186 |

For a 2,000-photo wedding with 500 guests searching once each:

|                                        | Credits     | USD        |
| -------------------------------------- | ----------- | ---------- |
| Index 2,000 photos with Batch → Submit | 124,000     | $1.24      |
| 500 guests × Search by Image           | 46,500      | $0.465     |
| **Total**                              | **170,500** | **$1.705** |

Storing faceprints also costs $6 per million faces per month. If a guest searches more than once, Register Selfie (93) and then Search by Face ID (62) beats repeating Search by Image. Delete the collection when the event's purpose ends: **Collection → Delete → Compliance Erasure** erases it immediately and records the erasure. See [deleting data](/docs/guides/deleting-data).
