CSL Restricted-Party Screening - No API Key Required
Pricing
from $4.00 / 1,000 restricted-party records
CSL Restricted-Party Screening - No API Key Required
No API key required - screen names against Commerce's Consolidated Screening List (BIS, State Dept, and OFAC lists combined) for export-control and sanctions compliance.
Pricing
from $4.00 / 1,000 restricted-party records
Rating
0.0
(0)
Developer
Moose & Raven
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
20 hours ago
Last modified
Categories
Share
CSL Restricted-Party Screening API - BIS + State + OFAC, One Feed (JSON)
Built for export compliance teams, freight forwarders, manufacturers, and banks who need to
clear a customer, distributor, or wire counterparty against every U.S. restricted- and
denied-party list before shipping goods or moving money. Instead of manually checking BIS's
Denied Persons/Entity/Unverified/MEU lists, State's AECA Debarred list, and OFAC's SDN plus five
other Treasury lists one by one (11 separate government feeds), send this actor a names list
and get every match across all 11 lists back in one JSON call - no API key required.
Worked example: about to ship to a new distributor called "Russian Agricultural Bank"? Run
this actor with input {"names": ["Russian Agricultural Bank"]}. It returns two
restricted-party-record items for that one entity - one with
source: "Non-SDN Menu-Based Sanctions List (NS-MBS List) - Treasury Department"source: "Sectoral Sanctions Identifications List (SSI) - Treasury Department"programs (e.g.
"UKRAINE-EO13662; RUSSIA-EO14024") and addresses, so you can see exactly which sanctions
program is triggered and why, instead of cross-referencing 11 separate agency pages by hand. See
"Real sample output" in section 6 below for the full record with every field populated.
This actor screens names against the U.S. Commerce Department's Consolidated Screening List (CSL)
- the single feed that bundles BIS (Bureau of Industry and Security), State Department, and OFAC
(Treasury) restricted- and denied-party lists into one normalized dataset, covering 11 separate
export-control and sanctions lists in total. It works entirely off
data.trade.gov's official bulk CSV download - genuinely keyless, no scraping, no search-API subscription dependency. Optional daily-delta monitoring flags newly added listings between runs.
1. What's actually in the CSL, and why this is one feed, not 11 integrations
The CSL is Commerce's own consolidation of:
- Bureau of Industry and Security (BIS): Denied Persons List, Entity List, Unverified List, Military End-User (MEU) List.
- Department of State: AECA Debarred List (Directorate of Defense Trade Controls), Nonproliferation Sanctions.
- Department of the Treasury (OFAC): Specially Designated Nationals (SDN), Foreign Sanctions Evaders (FSE), Sectoral Sanctions Identifications (SSI), Non-SDN Menu-Based Sanctions, Non-SDN Chinese Military-Industrial Complex Companies (CMIC), CAPTA List, Palestinian Legislative Council (PLC) List.
Commerce's own bulk file already merges all 11 - this actor consumes that single feed rather than scraping each source agency separately (which would be worse sourcing, not better: independent agency pages don't all publish the same clean bulk format the CSL already provides).
1a. An alternative to enterprise denied-party screening software
Descartes Visual Compliance, the market-leading dedicated denied-party screening product, publishes its own pricing guidance (visualcompliance.com blog, "How Much Does a Denied Party Screening Solution Cost?"): a basic single-user deployment "starts at a few thousand dollars a year," and "a typical customer screening 50,000 entities should budget around $20,000 a year" - rising to "$100,000 or more" for enterprise-wide deployments. Capterra separately lists Descartes' starting price as "$3,000 per user, per year." This actor covers the same core need - screening a name against BIS/State/OFAC's restricted- and denied-party lists - at $0.004 per record delivered, no subscription, no per-seat licensing, no annual contract. It won't match Descartes' enterprise workflow tooling (case management, audit dashboards, dedicated support), so treat this as the right fit for teams that need the underlying screen without buying a full compliance platform, not a 1:1 replacement for one. (E2open's Global Trade Management screening is a second incumbent in this space; it publishes no public pricing - contact-sales only - so no price comparison is made here.)
2. Access: bulk files ONLY - the CSL search API requires a paid subscription key
Confirmed live: data.trade.gov's search API returns
HTTP 401 "Access denied due to missing subscription key"data.trade.gov/downloadable_consolidated_screening_list/v1/ consolidated.csv3. Legal/regulatory basis for screening against these lists
- EAR General Prohibition Four (15 CFR Section 736.2(b)(4)) bars dealing with Denied-Persons-List entities in a manner that violates the terms of their denial order.
- Entity List license triggers (15 CFR Section 744.11 + Supp. No. 4 to Part 744) apply when a listed entity is purchaser/consignee/end-user in a transaction.
- ITAR debarment (22 CFR Section 127.7, under the Arms Export Control Act, 22 U.S.C. Section 2778) - a 3-year bar; anyone with knowledge a party is debarred cannot proceed without DDTC disclosure.
- The law itself prohibits transacting with listed parties - it does not literally mandate "run a screening tool" - but BIS's own freight-forwarder guidance explicitly recommends checking the CSL, and strict-liability exposure makes screening the practical due-diligence mechanism exporters, reexporters, freight forwarders, and controlled-goods sellers actually use.
4. How it works
- Names to screen (
namesinput, optional): substring match, diacritic-folded, tolerant of "Last, First" vs "First Last" order - screens both the primarynamefield AND any listedalt_names(aliases), so a real match hiding behind an alias isn't a false negative. Same deliberately simple approach (not a fuzzy-matching compliance engine) this fleet's OFAC and Healthcare Exclusion Suite actors use, and the same documented limitation applies. - Bare/no-names default stays cheap on purpose: with no
namesandmonitorModeoff, this actor caps delivery at 500 records (a real, non-empty sample) rather than pushing the entire ~26,000-row list. Pushing all ~26,000 entries as individual dataset items on every zero-input auto-test run risks the same Apify run-cost-cap abort this fleet's OFAC actor hit once on its own unbounded default. A real screen (names provided) is always uncapped by default - this narrowing never applies once there's something real to screen.monitorModeis also treated as deliberate intent (Apify's own default-input auto-test never turns monitoring on), so a monitoring run is uncapped too. - Daily-delta monitoring (
monitorMode): the CSL's bulk file updates daily at 5am ET and carries a real, stable per-entry ID (_id) - this actor remembers what it's already seen (via a persistent named key-value store) and emits a separatenew-listingrecord for anything newly added. Unlike some sources, the CSL does not publish a smaller "just today's changes" file, so monitoring re-fetches and re-compares the full ~26,000-row list each run (cheap to fetch: one ~16.6MB request, ~700s to process end-to-end - see the note ontimeoutSecsbelow)- but billing is fair, not literal: when
monitorModeis on with nonames(pure monitoring, no specific counterparty), you're charged the flatmonitor-runfee plusrestricted-party-recordonly for genuinely NEW listings since your last run - never per-record for re-delivering the unchanged ~26,000-row baseline every day (that would be ~$104/day at this actor's per-record rate, a billing surprise this fleet won't ship). The data is still fully delivered to your dataset every run (nothing is withheld) - only the charging changes. If you instead providenames(a real screen for specific counterparties), normal per-match billing applies on every run regardless of monitor-mode "seen" state, since you're paying to re-check that specific name, not to receive the whole list.
- but billing is fair, not literal: when
- A quota guard (
maxRecordsPerRun) caps total records delivered, independent of the bare-path's own internal 500 cap.
5. Input
| Field | Type | Notes |
|---|---|---|
names | array | Names to screen against the full CSL (primary name + aliases). Omit for a bare/monitoring-only run |
monitorMode | boolean | Persistent incremental "new since last run" tracking, by the CSL's own stable _id |
maxRecordsPerRun | integer | Quota guard, independent of the bare-path's own 500-record default cap |
See the Input tab for the full form with inline descriptions.
6. Output fields
Each dataset item has a recordType of "restricted-party-record", "new-listing" (monitor
mode only), or "screening-status" (only when delivery was capped/truncated).
restricted-party-record
| Field | Type | Notes |
|---|---|---|
cslId | string | null | The CSL's own stable per-entry identifier |
source | string | null | Which of the 11 bundled lists this entry came from, e.g. "Sectoral Sanctions Identifications List (SSI) - Treasury Department" |
entityNumber, type | string | null | type is "Individual", "Entity", or "Vessel" |
name, altNames | string | null | altNames is a semicolon-separated alias list, also screened against names input |
title, programs, addresses, remarks | string | null | programs names the specific sanctions program(s), e.g. "UKRAINE-EO13662; RUSSIA-EO14024" |
federalRegisterNotice, startDate, endDate, standardOrder, licenseRequirement, licensePolicy | string | null | Present on some list types, not others - genuinely absent, not a parsing gap |
callSign, vesselType, grossTonnage, grossRegisteredTonnage, vesselFlag, vesselOwner | string | null | Vessel-specific fields - null for Individual/Entity types |
citizenships, datesOfBirth, nationalities, placesOfBirth | string | null | Individual-specific fields - null for Entity/Vessel types |
sourceListUrl, sourceInformationUrl | string | null | Links to the originating agency's own list page |
fetchedAt, sourceApi | sourceApi is always "data.trade.gov/downloadable_consolidated_screening_list" |
new-listing (monitor mode only): { recordType: "new-listing", cslId, record, detectedAt }
recordis the fullrestricted-party-recordshape above, embedded.
screening-status: emitted whenever delivery was capped/truncated (bare-path's own 500-cap or
maxRecordsPerRun binding) -
{ status: "TRUNCATED", reason, matchedCount, deliveredCount, message, detectedAt }message - a screen is never silently reported as exhaustive when it
wasn't.
Real sample output
Live-fetched screening {"names":["Russian Agricultural Bank"]} - not a fabricated example. Note
the same entity appears twice, once per bundled list it's actually listed on - multi-list
appearances are surfaced, not deduplicated away, since a compliance screen hiding a second listing
would be the worse failure mode:
{"recordType": "restricted-party-record","cslId": "17014","source": "Non-SDN Menu-Based Sanctions List (NS-MBS List) - Treasury Department","entityNumber": "17014","type": "Entity","name": "Joint Stock Company Russian Agricultural Bank","altNames": "Russian Agricultural Bank; Russian Agricultural Bank Open Joint Stock Company; Rosselkhozbank; Russian Agricultural Bank OJSC; RusAg","title": null,"programs": "UKRAINE-EO13662; RUSSIA-EO14024","addresses": "3, Gagarinsky Pereulok, Moscow, 119034, RU; 3 Gagarinsky per., Moscow, 119034, RU","federalRegisterNotice": null,"startDate": null,"endDate": null,"standardOrder": null,"licenseRequirement": null,"licensePolicy": null,"callSign": null,"vesselType": null,"grossTonnage": null,"grossRegisteredTonnage": null,"vesselFlag": null,"vesselOwner": null,"remarks": "For more information on directives, please visit the following link: http://www.treasury.gov/resource-center/sanctions/Programs/Pages/ukraine.aspx#directives.","citizenships": null,"datesOfBirth": null,"nationalities": null,"placesOfBirth": null,"sourceListUrl": "https://sanctionslist.ofac.treas.gov/Home/ConsolidatedList","sourceInformationUrl": "https://ofac.treasury.gov/other-ofac-sanctions-lists","fetchedAt": "2026-07-18T01:33:35.637Z","sourceApi": "data.trade.gov/downloadable_consolidated_screening_list"}
The second record is identical except
"source": "Sectoral Sanctions Identifications List (SSI) - Treasury Department"cslId, same entity, a genuinely separate listing on a second
bundled list.
7. Use cases
- Exporters, reexporters, and freight forwarders - the direct, named audience of BIS's own CSL-screening guidance (see Legal basis above); screen counterparties before shipment.
- Trade-compliance SaaS platforms - feed a normalized 11-list screening result into an existing onboarding/KYC workflow via one integration instead of eleven.
- Banks & financial institutions - sanctions-screen wire/LC counterparties against the full CSL bundle, not just OFAC's SDN list alone.
- Legal / M&A due diligence - screen a target company's known counterparties and subsidiaries before closing.
- Ongoing portfolio monitoring -
monitorModecatches newly-added listings against a standing counterparty list without re-paying for the unchanged ~26,000-row baseline every day.
8. Setting up monitoring alerts (Apify Schedules + your own notification channel)
This actor produces structured data; wiring that into an email/Slack/Teams alert is done with Apify's own platform features, not actor-specific code:
- Create an Apify Schedule pointing at this actor, with
monitorMode: true. Daily is a natural fit - the CSL's own bulk file updates once daily at 5am ET, so more frequent runs won't see fresher data. - Attach a Webhook to the schedule/actor for the
ACTOR.RUN.SUCCEEDEDevent. Apify's webhook payload includes the run's dataset ID, so your webhook target can fetch the new items. - Route the webhook to Slack/Teams via their native "incoming webhook" URL, or to email via
a lightweight relay (e.g. a Zapier/Make webhook-to-email step) - filter for so every triggered notification represents a genuinely new addition to the CSL, not a repeat of the standing baseline.recordType: "new-listing"
- Because the dataset always distinguishes
restricted-party-record/new-listingfromscreening-statusrecords, your alert logic can (and should) treat aTRUNCATEDstatus as "this screen was capped" rather than silently trusting an incomplete result as final.
9. Pricing
Pay per event (current live pricing - confirmed via the Apify API at time of writing):
restricted-party-record- $0.004 per record deliveredmonitor-run- $0.05 per scheduled monitor-mode run, in addition to per-record charges
See "Daily-delta monitoring" above for the billing-fairness detail: a pure-monitoring run
(monitorMode on, no names) is only charged restricted-party-record for genuinely NEW
listings, never for re-delivering the unchanged ~26,000-row baseline every day.
See the actor's Pricing tab for the authoritative, current numbers.
10. Use from Claude, Cursor, and other AI agents (MCP)
This actor can be called as a tool by any MCP-compatible AI client (Claude Desktop, Cursor, VS Code, etc.) via Apify's hosted MCP server, without any actor-specific integration code:
- Point your MCP client at
https://mcp.apify.com, authenticated with your Apify API token (as a bearer header or via OAuth - see Apify's MCP docs for client-specific config). - Expose this actor specifically with the
toolsquery parameter:https://mcp.apify.com?tools=mooseandraven/csl-restricted-party-suite - Your agent can then call it directly - e.g. "screen Rosselkhozbank against the restricted-party
lists" maps naturally onto
names. The actor's own input schema (this page's Input tab) is what the MCP tool schema is built from, so any filter documented here is available to the agent.
11. FAQ
How fresh is the data? The CSL's own bulk file updates once daily at 5am ET - this actor fetches live at run time, so results are as current as that daily refresh, not cached or delayed further by this actor.
Do I need a data.trade.gov API key? No - the bulk CSV download this actor uses is fully
keyless. Only the separate CSL search API requires a paid subscription key, and this actor never
uses that endpoint (see Access above).
Why did I get two records for the same name? A real entity can be listed on more than one of the 11 bundled lists (e.g. both a Treasury sectoral-sanctions list and a non-SDN menu-based list) - this actor surfaces every listing rather than deduplicating, since hiding a second listing would be the worse failure mode for a compliance tool.
What's the pricing/subscription model? Pay-per-event, not a flat subscription - see Pricing above, including the billing-fairness rule for pure-monitoring runs.
Why might a run occasionally fail with a 404, then succeed on retry? See Limitations below - this is a confirmed, observed, intermittent backend blip on Commerce's own hosting, handled by this actor's retry logic, not something you need to work around yourself.
12. What it does NOT do / Limitations
- The bulk-download endpoint is intermittently flaky - confirmed live: an identical request
returned a bare
HTTP 404with no body, then succeeded on retry moments later (5/5 subsequent attempts succeeded cleanly). No request-header combination reliably reproduced or fixed this, ruling out a missing-header requirement - it reads as a transient backend/gateway blip on Commerce's Azure-hosted endpoint, not a systematic block. This actor retries on 404 (not just 5xx) specifically because of this observed behavior; a 404 persisting across all retries still surfaces as a real, loud error. - This is a deliberately simple screen (substring + diacritic-fold + name-order-swap), not a fuzzy-matching/phonetic compliance engine - same documented limitation as this fleet's OFAC and Healthcare Exclusion Suite actors. A materially different phrasing/spelling of a name will not match.
- The law prohibits transacting with listed parties; it does not itself mandate running a screening tool. See "Legal/regulatory basis" above for the honest framing - screening is the practical due-diligence mechanism, not a literal statutory requirement to use this actor specifically.
- No small "changes-only" upstream file exists - every monitor-mode run re-fetches and
re-compares the full ~26,000-row CSL, not a delta feed from Commerce itself; this actor's own
"seen" tracking is what makes
new-listingdetection incremental, not the upstream source.
Local development
npm installnpm test # recorded-fixture unit tests, no network needednpx apify-cli run # local end-to-end run against the REAL live CSL bulk file (keyless,# no credentials needed) - see MAINTENANCE.md for the full# live-verification record from this actor's initial build
Support
Built and maintained by Moose & Raven. Questions or issues: support@mooseandraven.com.