New: our AI Agent is live — 140+ live registry connections, KYB without an integration. Try it →
On this page

Test monitoring in the sandbox

The one thing to know first: monitoring is a polling surface

In the real KYC product, monitoring alerts are not delivered by webhook. Live Monitoring (new AML matches, corporate-structure changes, expired documents, manual and risk reviews) surfaces its alerts on the Live Monitoring screen in the Workspace and on the polling endpoints below; the retrieval pattern is polling lm-cases / lm-alerts.

Webhooks are a separate feature with ten event types (CaseCreated, CaseReady, CaseClosed, CaseReopened, CaseAssigned, AmlMatch, IdFailure, DocumentUploaded, DocumentsRequested, CaseRequestSubmitted). Monitoring alerts are not among what webhooks deliver; the exact trigger conditions for each event are described in the webhook documentation.

The sandbox behaves exactly the same way, so the integration you build and test here is the one that works in production: poll the alert endpoints; do not wait on a webhook for monitoring events, because none will come, in the sandbox or in production.

The monitoring API surface (byte-parity with production)

All of these are live in the sandbox at https://api.knowyourcustomer.dev, with the production wire shapes:

CallWhat it does
POST /v2/Companies/lm-cases
POST /v2/Individuals/lm-cases
List your alerting cases with per-type counts (amlAlertCount, expiredDocumentsAlertCount, reviewAlertCount, manualReviewAlertCount). Filterable by alert type, case status, assignee, case id.
GET /v2/Companies/{caseCommonId}/lm-alerts
GET /v2/Individuals/{caseCommonId}/lm-alerts
The detailed alerts for one case. Each alert’s changes object carries exactly one typed delta: officer, shareholder, amlAlert, expirationAlert. A manual-review alert carries no typed delta (only changeId); identify that family from the list call’s manualReviewAlertCount.
POST /v2/Companies/{caseCommonId}/lm-alerts-action
POST /v2/Individuals/{caseCommonId}/lm-alerts-action
Action one alert: Apply (accept the change into the case), Exclude (decline a case-details review), Dismiss (remove an AML or expired-document alert). Applying an AML alert reopens a closed case, adds the match, and flags the case AML-positive.
PUT /v2/Companies/{caseCommonId}/review-date
PUT /v2/Individuals/{caseCommonId}/review-date
Set or clear the periodic review date (presets or DD/MM/YYYY).
GET /v2/Companies/{caseCommonId}/amlchecks
GET /v2/Individuals/{caseCommonId}/amlchecks
The case’s AML check results.

Response samples

Captured from a live sandbox case (ids normalised). GET /v2/Companies/{caseCommonId}/lm-alerts returns a ListPage of alerts; each alert’s changes object carries exactly one typed delta (here: an officer change, a new AML match, and a shareholder change on the same case):

{
  "pageSize": 100,
  "itemCount": 3,
  "pageIndex": 0,
  "list": [
    {
      "name": "Thames Valley Logistics Ltd",
      "caseId": 1000000123,
      "address": "120 Holborn, London, EC1N 2TD, United Kingdom",
      "caseType": 1,
      "jurisdiction": "GB",
      "caseStatus": "Open",
      "caseStepId": null,
      "changes": {
        "changeId": 9901,
        "officer": {
          "name": "Cheung Man Kit",
          "address": "Flat 12B, Harcourt House, 39 Gloucester Road, Wan Chai, Hong Kong",
          "role": "Director"
        }
      }
    },
    {
      "name": "Thames Valley Logistics Ltd",
      "caseId": 1000000123,
      "address": "120 Holborn, London, EC1N 2TD, United Kingdom",
      "caseType": 1,
      "jurisdiction": "GB",
      "caseStatus": "Open",
      "caseStepId": null,
      "changes": {
        "changeId": 9902,
        "amlAlert": {
          "amlAlertType": 10,
          "name": "Perlhaven Marine Services Ltd",
          "amlType": "SANCTIONS",
          "country": "United Kingdom",
          "updatedOn": "2026-07-28T00:00:00+00:00",
          "biography": "Added to a consolidated sanctions list during a simulated live-monitoring re-screen."
        }
      }
    },
    {
      "name": "Thames Valley Logistics Ltd",
      "caseId": 1000000123,
      "address": "120 Holborn, London, EC1N 2TD, United Kingdom",
      "caseType": 1,
      "jurisdiction": "GB",
      "caseStatus": "Open",
      "caseStepId": null,
      "changes": {
        "changeId": 9903,
        "shareholder": {
          "name": "Veldmoor Capital Partners Limited",
          "address": "21/F, Jardine House, 1 Connaught Place, Central, Hong Kong",
          "sharesHeld": 15.0
        }
      }
    }
  ],
  "hasMore": false
}

Note the real wire quirk the samples preserve: caseType is an INTEGER in lm-alerts rows (1 = Company, 2 = Individual) but a STRING (“Company” / “Individual”) in lm-cases rows. That is production’s own contract, not a documentation inconsistency.

POST /v2/Companies/lm-cases returns the alerting cases with per-type counts (a count is null when the case carries no alerts of that type):

{
  "pageSize": 500,
  "itemCount": 1,
  "pageIndex": 0,
  "list": [
    {
      "name": "Thames Valley Logistics Ltd",
      "caseId": 1000000123,
      "address": "120 Holborn, London, EC1N 2TD, United Kingdom",
      "caseType": "Company",
      "jurisdiction": "GB",
      "caseStatus": "Open",
      "alertType": {
        "reviewAlertCount": 2,
        "expiredDocumentsAlertCount": null,
        "manualReviewAlertCount": null,
        "amlAlertCount": 1
      }
    }
  ],
  "hasMore": false
}

The alert-type vocabulary is production’s five types: AML, EXP (Expired Documents), Review (Case Details Review), ManualReview, and RiskDiscrepancy. The sandbox’s simulation currently generates the first four; filtering by Risk Discrepancy returns an honest empty list rather than invented data.

Generating monitoring activity on demand: the simulation controls

Real monitoring is schedule-driven (periodic reviews, weekly AML sweeps, daily document checks). Your test suite should not wait days, so the sandbox adds two sandbox-only controls under /v2/sandbox/monitoring (the explicit sandbox segment marks them as sandbox-only: they do not exist in production, exactly like /v2/sandbox/case-statuses).

Both controls require a Ready case: a case still building rejects with 409 (real monitoring only ever runs against a built case). Wait for statusId 3, then simulate.

Run the scripted re-screen: POST /v2/sandbox/monitoring/rescreen/{caseCommonId}

Runs the case’s next scripted monitoring scenario. Scripts are fixed per seed company:

Seed companyScript
Dragon Pearl Holdings Limited (HK)Director change (a new officer is detected)
Selverhaven Harbour Trading Co Limited (HK)Shareholder change WITH a new AML hit (two linked alerts)
Thames Valley Logistics Ltd (GB)Shareholder change

A case past its script (or any other case) re-screens clean: no alert, the review date rolls forward one year, and the sweep is recorded in the audit trail. The clean outcome is deliberate and first-class: automated suites need the everyday nothing-changed case as their negative class.

Timing is realistic: the response names the outcome immediately, but the alerts land on the polling surface only after the case’s per-jurisdiction latency window (the same deterministic delay a case build takes in that jurisdiction; the response’s visibleFrom tells you when). Poll until they land; that rhythm is exactly a production integration’s.

Inject a typed alert: POST /v2/sandbox/monitoring/alerts

{"caseCommonId": 1000000123, "kind": "ShareholderChangeWithAmlHit"}

Kinds: DirectorChange, ShareholderChange, ShareholderChangeWithAmlHit, AmlMatch, ExpiredDocument, ManualReview. Injection is immediate (no latency window) and fully deterministic: personas come from a fixed fictional catalogue, so identical calls yield identical alert content. A persona must match the kind (a contract 400 otherwise).

Discover everything: GET /v2/sandbox/monitoring/catalogue

Returns the per-seed scripts, the injectable kinds with default personas, the persona catalogue, and each jurisdiction’s latency band, so a suite can discover every deterministic input at runtime.

Reset: the tenant reset (POST /sandbox/admin/reset) restores monitoring state completely: seeded alerts back, scenario scripts rewound, applied changes gone, alert history cleared. Repeatable CI runs.

The Workspace Monitoring section

The sandbox Workspace (https://workspace.knowyourcustomer.dev) carries the real product’s Live Monitoring section: the rail item with the red alert-count badge, the alert list with per-type cards, accept/decline for case-details changes, apply/dismiss for AML alerts, the filter drawer with the full five-type vocabulary, and a clearly badged SANDBOX SIMULATION panel that drives the two endpoints above from the page.

Fidelity notes, stated plainly:

  • The expired-document alert rendering and the page chrome (title, subtitle, filter drawer fields and option values) mirror the production Workspace as captured. The case-details accept/decline delta view, the AML alert body, and the manual-review body are built from the product documentation rather than pixel captures; their behaviour follows the production action matrix.
  • The list paginates with a simple previous / current-of-total / next control, a deliberate simplification of production’s numbered pager.
  • Production’s “Recently Changed” tab is a button among (future) siblings; the sandbox shows the same chip as non-interactive text because only that one view exists here.
  • The review-date editor is not implemented in the sandbox Workspace. Set or clear review dates over the API (PUT /v2/Companies/{caseCommonId}/review-date); a clean simulated re-screen also rolls the date forward, and the result is visible on the case read.
  • Production gates some monitoring controls by user role. The sandbox authenticates tenants, not users, so every connected user is an operator and sees all the controls the sandbox Workspace implements; the simulation panel is fenced by its explicit sandbox badging instead of a role.

What a sandbox monitoring test proves, and what it does not

Valid conclusions: the monitoring integration contract (wire shapes, status codes, paging, the alert-kind vocabulary and typed deltas, the action matrix and its side effects on the case, review-date semantics), the polling retrieval pattern, the accept/decline lifecycle of case-data deltas, and the Workspace operator flow.

Not valid conclusions: screening quality or coverage (simulated matches and deltas are scripted fiction, not screening-provider output; production re-screens, scheduled or manually run, screen against real providers and registries), real watchlist or registry deltas, and email notification behaviour (out of scope in the sandbox). A sandbox pass proves your code handles monitoring correctly; it proves nothing about what monitoring will find.