📘 Public beta · Endpoints are stable; OpenAPI specs and SDKs ship monthly. See changelog →
Products
AML Platform
Screening (PEP + sanctions)

Screening (PEP + sanctions)

Screen subjects (individuals or organizations) against curated watchlists. Optional adverse-media check. Returns matches with confidence scores; auto-creates alerts on confirmed hits.

Single screening

POST/api/screenings
Auth · API keyScope · screen.runRate limit · 60/min

Request

laneenumRequired
"onboarding" · "ongoing" · "transaction" — affects rule pack applied.
customerIdstring
Existing customer to re-screen. Omit for fresh subjects.
subjectTypeenumRequired
"individual" · "organization".
fullNamestringRequired
Full legal name as on KTP / corporate registry.
dateOfBirthstring (YYYY-MM-DD)
Tightens match precision for individuals.
nikstring
16-digit Indonesian NIK. Strong de-dup signal.
nationalitystring (ISO-3166-1 a2)
Two-letter country code. Default "ID".
emailstring
Used for adverse-media cross-check.
externalIdstring
Your reference for idempotent retries.

Response

{
  "ok": true,
  "data": {
    "screeningId": "scr_01HXY...",
    "customerId": "cus_01HXY...",
    "status": "confirmed | review | no_match",
    "topMatchScore": 0.95,
    "startedAt": "...",
    "completedAt": "...",
    "matches": [
      {
        "id": "mat_01HXY...",
        "score": 0.95,
        "watchlistEntry": {
          "fullName": "Umar Patek",
          "category": "sanctions | pep | adverse_media",
          "watchlistId": "wl_..."
        }
      }
    ]
  }
}

Status semantics

statusMeaning
confirmedTop match score above per-org confirmedHit threshold. Alert auto-created.
reviewScore above review threshold but below confirmedHit. Alert created, marked for analyst review.
no_matchTop match score below review threshold. No alert.

Thresholds are configurable per-org via GET/PATCH /api/decision-policy.

Bulk screening

Submit up to 100 subjects in a single call. Use for quarter-end refresh of an existing portfolio or batch onboarding.

POST /api/screenings
{
  "subjects": [
    { "lane": "ongoing", "subjectType": "individual", "fullName": "...", "nik": "..." },
    { "lane": "ongoing", "subjectType": "individual", "fullName": "...", "nik": "..." }
  ]
}

Response splits success and failure per subject:

{
  "ok": true,
  "data": {
    "total": 100,
    "succeeded": 98,
    "failed": 2,
    "results": [
      { "ok": true,  "screening": { ... }, "subjectName": "..." },
      { "ok": false, "error": "missing fullName", "subjectName": null }
    ]
  }
}

Bulk requests count as one request against the rate limit, regardless of subject count.

List + read

GET/api/screenings
Auth · API keyScope · read

Filters: lane, status, customerId, from, to, page, limit (default 20, max 100). Returns paginated screening rows.

Adverse-media

When enabled per-org, screenings also query Quantum AI's curated Indonesian adverse-media corpus. Matches with category: "adverse_media" come back with article references:

{
  "id": "mat_01HXY...",
  "score": 0.78,
  "watchlistEntry": {
    "fullName": "Bambang Setiawan Hartono",
    "category": "adverse_media",
    "watchlistId": "wl_qe_adverse_media",
    "articleRefs": ["amr_01HXY...", "amr_01HXZ..."]
  }
}

Pull article bodies with GET /api/adverse-media/articles?ids=amr_01HXY...,amr_01HXZ.... Articles are linked to the original source URL and a snapshot timestamp.

Fuzzy matching

Identity Platform uses a tuned Indonesian-aware fuzzy matcher: handles BIN/BINTI prefixes, single-name customers (common in Java), patronymic vs Western-style names, gendered diminutives. False-positive rate on sandbox synthetic data: ≈0.4% at the default confirmedHit threshold. Tunable per-org if you have a target false-positive rate from your compliance policy.

Pre-screen vs reactive screen

Best practice is to screen every new customer at creation (onboarding lane) and re-screen on each watchlist refresh (ongoing lane — triggered automatically when watchlists update). Transaction-lane screening is for cases where a transaction touches a counterparty you haven't onboarded.

Free-form quick lookup

For analyst fuzzy-search (not an audit-grade screening):

POST/api/lookup
Auth · API keyScope · readRate limit · 30/min
{ "fullName": "Budi Sant", "topK": 10 }

Returns the top-K name matches across watchlists, without creating a Screening row or alert. Use for the dashboard's quick-search box, not for audit-required screening.