Skip to content

Sanctions screening

HalvorAI screens every payee, by name, country and wallet address, against public sanctions lists. A screening is explainable: it shows which list, which entry, which field matched and the score.

IdListPublisher
ofac_sdnSpecially Designated Nationals, including published digital currency addressesUS Treasury OFAC
ofac_consConsolidated non-SDN listsUS Treasury OFAC
uk_uslUK Sanctions ListUK FCDO
eu_fsfEU Financial Sanctions FileEuropean Commission
un_scUN Security Council Consolidated ListUnited Nations

Lists are refreshed every six hours. Each fetch is versioned by the hash of the file, and the previous twelve versions are kept, so a pack can say exactly which list version a screening used. If a list cannot be fetched, the last good version stays in use and HalvorAI raises an operational alert after 24 hours. The overview shows how fresh each list is.

  • The first time a payee is seen, before the detectors run, so a sanctions_hit alert is never late.
  • When a list changes, for every payee seen in the last 90 days whose names or wallets touch an added or changed entry. All active payees are re-screened weekly.
  • On demand, with POST /v1/screen.

Names are normalized before comparison: accents removed, transliterated to plain letters, lower-cased, punctuation removed, and legal-form words such as “ltd”, “llc” and “gmbh” dropped. Words are sorted, so word order does not matter. The original name is always kept for display.

A candidate’s score blends a string-similarity measure with a word-overlap measure, then adjusts for country: a small boost when the countries agree, a small penalty when both are known and differ, and a penalty when a list entry is a person but the payee is a business.

ResultRule
matchThe wallet address matches exactly, or the normalized name is equal and the country is compatible.
potential_matchThe score reaches 0.88, which an organization can lower to a floor of 0.82.
clearAnything else.

A screening stores every candidate at 0.80 or above, even when the result is clear, so reviewers can see near misses.

A match or potential_match raises a high sanctions_hit alert and enters the review queue. An analyst decides:

  • True match. The payee really is the listed party. A true match must be escalated to a case.
  • False positive. A reason is required. The same payee, entry and list version will not raise a match again until that entry changes.

Decisions are recorded in the audit log and included in evidence packs.

Terminal window
curl "https://api.sandbox.halvorai.com/v1/screenings?result=potential_match&reviewed=false" \
-H "Authorization: Bearer $HALVOR_API_KEY"
curl -X POST "https://api.sandbox.halvorai.com/v1/screenings/scr_01JA8X.../review" \
-H "Authorization: Bearer $HALVOR_API_KEY" -H "Content-Type: application/json" \
-d '{ "decision": "false_positive", "reason": "Different company in a different country" }'

POST /v1/screen checks a name, a country and a wallet without needing a payment. It needs the screening:write scope.

Terminal window
curl -X POST https://api.sandbox.halvorai.com/v1/screen \
-H "Authorization: Bearer $HALVOR_API_KEY" -H "Content-Type: application/json" \
-d '{ "name": "Example Trading FZE", "country": "AE" }'

The overview reports screening coverage: the share of active payees screened in the last 24 hours. It is one of the five numbers usually asked for in a bank review.

To be told of a new match as soon as it is found, use the screening.potential_match webhook.