Sanctions Screening List Change Monitor — CSL / OFAC Delta API
Pricing
from $4.40 / 1,000 results
Sanctions Screening List Change Monitor — CSL / OFAC Delta API
Sanctions screening list change monitor. Diffs the US Trade.gov Consolidated Screening List (OFAC SDN/Non-SDN, BIS Entity/Denied/Unverified/MEU, State DDTC/ISN) against the last run and emits added/removed/modified entries with field-level changes. Keyless. Monitoring tool, not compliance advice.
Pricing
from $4.40 / 1,000 results
Rating
0.0
(0)
Developer
Kyle Maloney
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Sanctions Screening List Change Monitor - CSL / OFAC Delta API
Track what changed on the U.S. Consolidated Screening List (CSL) - the single feed that merges OFAC (SDN and Non-SDN: SSI, CMIC, NS-MBS, PLC, CAPTA), BIS (Entity List, Denied Persons, Unverified, Military End User) and the State Department (DDTC ITAR Debarred, ISN nonproliferation) restricted-party lists. 12 constituent lists, 25,921 entries as of 2026-08-01.
Most sanctions actors screen one name against the list. This one treats the list itself as the object and emits a change feed: on every run it diffs the current CSL against the previous run and returns only the entries that were added, removed or modified - down to the field that changed (a new alias, a new address, a programme change, a delisting, a change to a BIS licence policy). Keyless, official source.
Compliance note: This is a change-monitoring / research tool over public U.S. government lists. It is not a certified sanctions-screening service and its output is not a compliance, export-licensing or denied-party determination. Always confirm against the official source and your compliance programme before acting.
What was wrong before v1.1, and what it means for you
Three defects were found and fixed on 2026-08-01. All three were reproduced live.
- The delta had never actually run. v1.0 stored its baseline in the actor's default key-value store, which Apify creates fresh for every run. Two consecutive runs against a byte-identical list both logged "No prior snapshot found (first run)" and both reported added=25,825. A scheduled feed was reporting the entire list as newly designated, every single run. v1.1 uses a named store, so the baseline survives.
- A filter could fabricate delistings. v1.0 saved the full list as the baseline but
diffed it against the filtered current list, so every entry that did not match your
filter landed in the "in the baseline but not in the current list" branch. Measured with
country: "russia": 25,027 fabricatedremovedrows, including AEROCARIBBEAN AIRLINES, which is still on the SDN list. v1.1 diffs full-against-full and filters the resulting changes. This was masked only by defect 1 - fixing the store alone would have shipped a catastrophe. - The snapshot key was not unique. The CSL
_idis the issuing agency'sentity_number, and 96 ids collide because the same party is carried on two lists (VTB Bank is17013on both the SSI list and the SDN list). Those 96 records were silently overwritten and could never be diffed. The key is now source-qualified.
Read delta_comparable before treating any row as news. It is true only when a real
baseline existed. The first run after this upgrade establishes a fresh baseline and reports
every entry with change_type: "added" and is_baseline_row: true - those are not new
designations.
Who it's for
- Trade-compliance and export-control teams who need a daily "what's new / what's gone" digest instead of re-diffing a 26k-row file by hand.
- KYB / AML / onboarding platforms re-screening only the entities affected by today's designations and delistings.
- RegTech / GRC builders wiring an alerting pipeline (Slack, email, ticket) off new designations, or off a change to an Entity List licence policy.
- AI agents doing due diligence that need a clean, chainable "recent sanctions changes" tool that can tell a real change from a baseline artefact.
What it does
- Normalizes every CSL entry into a clean snake_case record (aliases, addresses,
programmes, IDs and dates as arrays; a flattened
search_namesfor easy matching). - Delta engine: keyed on
source+_id, it diffs the current list against the stored snapshot and setschange_type=added|removed|modified|unchanged. Formodifiedit reportschanged_fieldsand a field-levelchangesarray (before/after, plus per-itemadded/removedfor list fields such as aliases). - Filters: optional
name(contains, over name + aliases),source,programandcountry. In delta mode these are applied after the diff.
Example input
{"mode": "delta","source": "OFAC","program": "RUSSIA","maxResults": 5000,"monitor": true}
Run it once to seed the baseline, then schedule it daily - each later run returns only that
day's added / removed / modified entries. Set mode to full for a complete current
snapshot. Set monitor: false for a one-off read that must not touch the stored baseline.
Output fields (48)
Change and trust
| Field | Meaning |
|---|---|
change_type | added, removed, modified or unchanged (full-snapshot mode). |
changed_fields | Names of the tracked fields that changed. modified rows only. |
changes | Field-level before/after, with per-item added / removed for list fields. |
delta_comparable | Read this first. true only when a real baseline existed and this row is a genuine change. |
is_baseline_row | true when the row exists only because the run had no baseline. Not a new designation. |
delta_baseline_status | ok, no_baseline_first_run, or not_applicable_full_mode. |
baseline_entry_count | Size of the baseline this delta was computed against. |
baseline_retrieved_at | When the baseline was captured. |
Per-source outcome contract (on every row)
| Field | Meaning |
|---|---|
csl_fetch_status | ok or unavailable. A run where the list did not load emits nothing at all. |
csl_endpoint | The keyless CSV endpoint that answered. |
csl_endpoints_failed | Endpoints tried first and why each failed. null when the first worked. |
csl_entry_count | Entries in the full unfiltered list on this run. |
csl_retrieved_at | ISO 8601 timestamp of the download. |
source_lists_expected | How many constituent government lists the CSL should contain (12). |
source_lists_present | How many were actually present. |
source_lists_missing | Any constituent list entirely absent. null on a healthy run - a missing list means parties on it would screen clean. |
The entry
| Field | Meaning |
|---|---|
id | The issuing agency's entity number. Not unique across the feed - the change key is source + id. |
entity_number | Agency entity number as published (OFAC rows only). |
source | The exact constituent list, e.g. Entity List (EL) - Bureau of Industry and Security. |
source_list_group | Coarse agency group: OFAC (Treasury), BIS (Commerce), DDTC/ISN (State). Nothing may fall through to Other; that is asserted live. |
type | Entity, Individual, Vessel, Aircraft, or null (BIS and State rows do not publish it). |
name, title | Primary name and title. |
alt_names | Published aliases. |
search_names | Flattened lower-cased name plus aliases, for matching. |
programs | Sanctions or control programme tags, e.g. CMIC-EO13959. |
addresses, nationalities, citizenships, places_of_birth, dates_of_birth, ids | Published identifiers, as arrays. |
standard_order | BIS Denied Persons standard order text, the operative terms of the denial (1,594 entries). |
license_requirement | BIS Entity List licence requirement: which exports need a licence (3,490 entries). |
license_policy | The licence review policy applied, e.g. Presumption of denial (3,490 entries). |
call_sign, vessel_type, vessel_flag, vessel_owner, gross_tonnage, gross_registered_tonnage | The maritime block for designated vessels (1,524 vessels in the feed). |
federal_register_notice, start_date, end_date | Designation paperwork and dates. |
remarks | Free-text remarks as published. |
source_list_url, source_information_url | Links back to the authoritative list. |
source_system | Constant: US Trade.gov Consolidated Screening List. |
The nine export-control and maritime columns above were parsed out of the CSV on every run
since v1.0 and then discarded. license_requirement and license_policy are the operative
terms of an Entity List designation, and a change to either is now a modified event.
Live drift assertions
Every run asserts the following before any billable row is produced, and fails the run when an assertion breaks:
- the exact 29-column CSV header, catching both missing columns and unexpected new ones (v1.0 required only 3 of the 29, so a rename anywhere else silently nulled that field)
- total row count inside a measured band (15,000 to 60,000; live 25,921)
- the closed 12-list source vocabulary: an unknown constituent list fails the run,
because it would otherwise be grouped as
Otherand missed by every source filter - per-list count bands, and any constituent list entirely absent fails the run, which is the dangerous direction since parties on a missing list would screen clean
- zero records may fall through to
source_list_group: "Other" - freshness: the newest
start_datemust be within 400 days - delta sanity: more than 25 percent of the baseline reported removed, or more than 50 percent reported added, fails the run. A five-figure swing is a key-format or data problem, not news
- positive canaries: each agency group must be reachable by a source filter and return only rows from that group, and an entry must be findable by its own exact name
- negative controls: nonsense
name,country,programandsourcefilters must each match nothing, which is what catches a filter that has started matching everything
Every measured value is logged on each run ([drift] and [canary]) so bands can be
tightened on evidence.
Use as an MCP tool
Callable by AI agents (Claude, Cursor, etc.) via mcp.apify.com. An agent can pull recent
sanctions-list changes, filter by programme or country, and check delta_comparable and
source_lists_missing to know whether the answer is trustworthy before acting on it.
Data source
US International Trade Administration, Consolidated Screening List, keyless CSV:
https://data.trade.gov/downloadable_consolidated_screening_list/v1/consolidated.csv
with api.trade.gov/static/consolidated_screening_list/consolidated.csv as a fallback. That
host's wildcard certificate expired on 2026-07-28 and Node surfaces the failure only as the
opaque "fetch failed", so the healthy-certificate host is tried first. No API key required.
Pricing
Pay-per-result: you are billed per change (or snapshot) record returned. A run with no changes costs only the fractional actor start, which is a cheap way to monitor daily. A run that fails its drift assertions emits nothing and bills nothing beyond that.
FAQ
Is this an OFAC sanctions screening API? It monitors the official OFAC, BIS and State Consolidated Screening List for changes. It is a monitoring and research tool, not a certified screening or compliance determination. Verify against the official source.
How do I get only new designations? Use mode: "delta" (the default) on a schedule. The
first run seeds the baseline; every run after returns only real changes. Filter to
delta_comparable = true.
Can I watch one company or person? Yes, set name to a substring; it matches the primary
name and every alias. In delta mode the filter is applied to the changes, so it can never
fabricate a delisting.
Which lists are covered? All 12: OFAC SDN, SSI, CMIC, NS-MBS, PLC and CAPTA; BIS Entity List, Denied Persons, Unverified and Military End User; State DDTC (ITAR Debarred) and ISN.
Do I need an API key? No. The source is a keyless public government feed.
Related actors
- Medicaid Exclusion Screener - the healthcare-exclusion side of a vendor or clinician check.
- KYB Company Verifier - cross-registry business verification for the entity you just matched.