Screening Appliance docs

Monitoring Guide

Register subjects for continuous re-screening, poll or receive webhook alerts when a change in the data affects them, and how dismissals persist across updates.

Last updated 2026-08-02

Monitoring Guide

Monitoring turns screening from a point-in-time check into an ongoing control: register a subject once, and the appliance re-screens it every time the underlying data changes β€” a new designation, a delisting, an amended alias β€” without you re-submitting the search.

How it works

  1. You register a subject with PUT /v1/monitor/subjects.
  2. After every successful data sync (see Updates & synchronization), the appliance re-screens every monitored subject against changed entities only β€” not a full re-scan of the whole corpus each time, so sync-triggered re-screening stays cheap even with a large monitored population.
  3. If a subject's match set changes as a result, an alert is created. Poll for it with GET /v1/monitor/alerts, or receive it as a webhook push if ALERT_WEBHOOK_URL is configured.
  4. You dismiss alerts you've reviewed with POST /v1/monitor/alerts/{id}/dismiss. A dismissal is durable β€” it survives future data syncs β€” and only reopens if the specific matched entity itself changes again.

Register a subject

curl -s -X PUT http://localhost:8400/v1/monitor/subjects \
  -H 'content-type: application/json' \
  -d '{
    "id": "customer-4471",
    "name": "Viktor Bout",
    "dob": "1967-01-13",
    "country": "RU",
    "datasets": ["us_ofac_sdn", "un_sc_sanctions"],
    "threshold": 90
  }'
{
  "id": "customer-4471",
  "name": "Viktor Bout",
  "dob": "1967-01-13",
  "country": "RU",
  "datasets": ["us_ofac_sdn", "un_sc_sanctions"],
  "threshold": 90,
  "createdAt": "2026-08-02T03:00:00Z"
}

id is your own identifier for the subject (e.g. a customer or case id) β€” supply it yourself so it's stable across calls; re-PUTting the same id updates that subject's screening parameters in place.

List monitored subjects

curl -s http://localhost:8400/v1/monitor/subjects
{
  "subjects": [
    {
      "id": "customer-4471",
      "name": "Viktor Bout",
      "dob": "1967-01-13",
      "country": "RU",
      "datasets": ["us_ofac_sdn", "un_sc_sanctions"],
      "threshold": 90,
      "createdAt": "2026-08-02T03:00:00Z"
    }
  ]
}

Remove a subject

curl -s -X DELETE http://localhost:8400/v1/monitor/subjects/customer-4471

A removed subject stops being re-screened on future syncs immediately; alerts already raised for it are unaffected (see dismissal semantics below).

Poll for alerts

curl -s "http://localhost:8400/v1/monitor/alerts?since=2026-08-01T00:00:00Z"
{
  "alerts": [
    {
      "id": "alert-77b2",
      "subjectId": "customer-4471",
      "entity": {
        "id": "NK-a1b2c3d4",
        "schema": "Person",
        "name": "Viktor Anatolyevich Bout",
        "datasets": ["us_ofac_sdn", "un_sc_sanctions"]
      },
      "score": 97,
      "matchedOn": ["name", "dob", "country"],
      "reason": "new_match",
      "dataVersion": "2026-08-02T03:00:00Z",
      "createdAt": "2026-08-02T03:05:00Z",
      "dismissed": false
    }
  ]
}

since is required and filters to alerts created at or after that timestamp β€” poll with the timestamp of your last successful poll (or your last processed alert's createdAt) to fetch only what's new.

Dismiss an alert

curl -s -X POST http://localhost:8400/v1/monitor/alerts/alert-77b2/dismiss \
  -H 'content-type: application/json' \
  -d '{ "note": "Reviewed 2026-08-02 β€” confirmed not our customer, false positive." }'
{ "id": "alert-77b2", "dismissed": true, "dismissedAt": "2026-08-02T14:12:00Z" }

Dismissal semantics

  • A dismissal is durable across data updates β€” dismissing an alert does not get undone by the next sync, and does not need to be re-applied.
  • A dismissed alert re-opens only if the specific entity it matched changes again (e.g. the designation is amended, a new alias is added, the entity is re-listed after delisting) β€” a routine data sync that leaves that entity untouched never resurfaces a dismissed alert.
  • Dismissal is per-alert, not per-subject: if the same subject later produces a new match (a different entity, or the same entity changed in a way that counts as a fresh match), that's a new alert, evaluated on its own.

Alert quality

Monitoring is unattended, so it is deliberately more conservative than a one-off search: a candidate only raises an alert if it clears both

  • the MONITOR_THRESHOLD score floor (default 90 β€” see Configuration reference), and
  • at least one genuine name-similarity signal. A candidate whose only resemblance to the subject is a structural/contextual signal β€” e.g. every query token matched only as a bare initial, or the tokens merely matched out of order β€” is suppressed even if it scored above the threshold. Matches carrying a real name-similarity basis (an exact or alias match, a nickname, a phonetic match, or a close edit distance) are never suppressed by this check.

This exists to kill low-value noise (e.g. a short, initials-only fragment of a subject's name aligning against an unrelated entity) without dropping legitimate partial matches β€” a query like "J. Smith" against a listed "John Smith" still alerts, because "Smith" itself matched exactly.

Prefer dismissing over lowering the threshold. If you're tuning out false positives for a specific subject, use POST /v1/monitor/alerts/{id}/dismiss rather than lowering MONITOR_THRESHOLD β€” a dismissal is precise (it clears one alert and survives future data updates, reopening only if that entity itself changes) and container-wide, while lowering the threshold raises noise for every monitored subject going forward.

/v1/search is unaffected. This alert-quality gate applies only to monitoring's unattended alert creation. A one-off POST /v1/search or POST /v1/batch call still returns its full ranked candidate list β€” including weak-signal-only matches β€” down to whatever threshold you supplied, so you can review lower-confidence candidates yourself when you're screening interactively.

Webhook push (optional)

Set ALERT_WEBHOOK_URL (see Configuration reference) to have the appliance POST each new alert to your endpoint as it's created, in addition to it being retrievable via GET /v1/monitor/alerts:

POST <ALERT_WEBHOOK_URL>
content-type: application/json

{
  "id": "alert-77b2",
  "subjectId": "customer-4471",
  "entity": { "id": "NK-a1b2c3d4", "schema": "Person", "name": "Viktor Anatolyevich Bout", "datasets": ["us_ofac_sdn", "un_sc_sanctions"] },
  "score": 97,
  "matchedOn": ["name", "dob", "country"],
  "reason": "new_match",
  "dataVersion": "2026-08-02T03:00:00Z",
  "createdAt": "2026-08-02T03:05:00Z",
  "dismissed": false
}

The webhook payload is the same alert object returned by GET /v1/monitor/alerts β€” treat the webhook as a low-latency push notification and GET /v1/monitor/alerts?since= as the reliable source of truth (e.g. to recover from a missed delivery or an outage on your receiving end).

See also


More Screening Appliance docs

← All Screening Appliance docs