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
/api/screeningsRequest
laneenumRequiredcustomerIdstringsubjectTypeenumRequiredfullNamestringRequireddateOfBirthstring (YYYY-MM-DD)nikstringnationalitystring (ISO-3166-1 a2)emailstringexternalIdstringResponse
{
"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
status | Meaning |
|---|---|
confirmed | Top match score above per-org confirmedHit threshold. Alert auto-created. |
review | Score above review threshold but below confirmedHit. Alert created, marked for analyst review. |
no_match | Top 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
/api/screeningsFilters: 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):
/api/lookup{ "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.