Risk · · 2 min read
Sanctions screening: lists, fuzzy names and false positives
Where the OFAC and UN lists come from, how names are normalised and scored, why a hit never declines a session on its own, and what screening does not cover.
Sanctions screening checks whether the person you are about to onboard is named on a sanctions list. The lists are public; the difficulty is names. The same person appears with aliases, transliterations, reordered names and missing dates of birth, and ordinary customers share names with listed people. This guide explains how KYCVerify handles that.
The two lists
| List | Publisher | Format | What KYCVerify reads |
|---|---|---|---|
| Specially Designated Nationals (SDN) | US Treasury, OFAC | sdn.csv plus alt.csv | Names, aliases, programmes, dates of birth and nationalities from the remarks |
| Consolidated list | UN Security Council | XML | Individuals and entities, every alias quality, original-script names, date ranges, nationalities |
The server downloads both from their official URLs, following the redirects to the publishers' signed storage, parses them and builds an in-memory index. It checks every 6 hours and re-downloads a list older than 7 days; an admin can refresh at any time. Each list's fetch time, size and checksum are recorded and returned with every screening, so a decision says exactly which version of which list it used.
Normalising names
- Lower-case and strip diacritics (Unicode NFKD), so
José Müllerandjose mullercompare equal. - Drop punctuation and honorifics such as
mranddr. - Keep particles as their own tokens (
al-Rashidbecomesal rashid), so they neither vanish nor glue to the surname. - Collapse whitespace. OFAC's
SURNAME, Givenorder is rewritten asGiven SURNAMEfor individuals.
Scoring
Names are compared as sets of tokens with Jaro-Winkler similarity, which is forgiving of small spelling differences and insensitive to order: Hussein Saddam scores like Saddam Hussein. Every alias is scored, and the best one is reported as matched_name.
- Below 0.82: not reported
- 0.82 to 0.90: potential_match (warn), session to review
- 0.90 and above: potential_match (high), session to review
Name score
token-set Jaro-Winkler, order-insensitive, diacritics and honorifics removed
Date of birth
match +0.05, mismatch −0.10, unknown leaves the score as is
Review, not decline
a hit sends the AML check to review; a session still declines if another check fails with auto_decline on
When a date of birth is known it adjusts the score: a match with a listed date, year or range adds 0.05, a clear mismatch subtracts 0.10, and an entry with no dates is left alone. UN entries recorded as approximate ("circa 1960") match within a year.
Why a hit never declines on its own
A name score cannot tell a listed person from a namesake. Declining automatically would turn away ordinary customers; approving would be worse. So in KYCVerify a potential match never fails the AML check by itself: the check goes to review with the matched entry, its list, programmes, dates of birth and source link. If nothing else failed, the session goes to review and a reviewer decides. If another check failed and auto_decline is on, the session is declined and the hit is recorded in the decision. The match's severity (warn from 0.82, high from 0.90) helps them prioritise.
What it does not cover
- Other sanctions regimes, such as the EU, UK or Indian lists, unless you add them.
- Politically exposed persons (PEP) and adverse media.
- Ongoing monitoring: a person is screened when their session is submitted, not again when a list changes.
- Entity and vessel screening for business verification.
If your obligations include any of these, combine KYCVerify with a provider that covers them, or treat KYCVerify's screening as one control among several. Try a name with POST /v1/checks/aml; the response lists the exact list versions it was screened against.