# OFAC Sanctions Screening API - No API Key Required (`mooseandraven/ofac-sanctions-screening-suite`) Actor

No API key required - screen names against the official U.S. Treasury OFAC SDN and Consolidated sanctions lists for AML/KYB compliance. Keyless, no scraping.

- **URL**: https://apify.com/mooseandraven/ofac-sanctions-screening-suite.md
- **Developed by:** [Moose & Raven](https://apify.com/mooseandraven) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 0 monthly users, 94.4% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 sanctions records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## OFAC Sanctions Screening API - No API Key Required

**Screen a new customer, vendor, or business counterparty against the U.S. Treasury's federal
sanctions lists before you onboard them.** Built for fintechs and banks running AML/KYB checks at
account opening, and for compliance or procurement teams vetting a vendor before signing - a
straightforward name screen against the official SDN and Consolidated sanctions lists, with no
paid compliance vendor subscription needed just to run a sanctions check.

**Worked example:** A bank's onboarding team needs to clear a new commercial customer, "Example
Trading Co", before opening an account. They run the actor with `names: ["Example Trading Co"]` -
the default `lists` value already screens both SDN and CONSOLIDATED, so there's nothing extra to
configure. Every match comes back as a dataset item with `recordType: "sanctions-listing"`,
`listSource` ("SDN" or "CONSOLIDATED"), `sdnName`, `sdnType`, `program` (the sanctions program
code, e.g. "CUBA" or "IRAN"), and `remarks` with any further detail OFAC published. No match on
either list means a clean result - and because this actor aborts loudly rather than reporting "0
matches" when a list fails to load (see below), a clean result here means the lists were actually
checked, not silently skipped.

**No API key required.** This actor screens names against the official U.S. Treasury OFAC
Specially Designated Nationals (SDN) list and the Consolidated (non-SDN) sanctions list for
AML/KYB compliance - via the official, keyless Sanctions List Service. No account, no
registration, no scraping: just supply names and screen. Optional incremental monitoring flags
newly-added listings on scheduled runs.

**Live-validated 2026-07-15** against the real, current lists (19,217 real SDN entries fetched and
correctly parsed/filtered in testing) - the CSV parsing, name matching, and monitor-mode diff
logic have all been exercised against live data, not just fixtures.

> **This is a screening aid, not legal advice.** It does substring matching against the official
> lists, not certified fuzzy/phonetic compliance matching. Use it to narrow down candidates for
> review, not as a standalone legal clearance - see Limitations below.

### What makes this different

**Zero setup.** Treasury's Sanctions List Service (`sanctionslistservice.ofac.treas.gov`) is a
free, official REST service - no account, no API key, nothing to configure beyond your search
input. Most comparable actors on the Store require registration or scrape a web UI; this hits the
official bulk-data service directly.

**Built for ongoing monitoring, not just one-off lookups.** Incremental new-listing detection
flags newly-added sanctions designations on scheduled runs - most comparable actors in this
category only support one-off searches.

**Natural pairing**: combine with our SAM.gov Federal Contracting Suite actor for a combined
"federal debarment + OFAC sanctions" screening pass.

**A lightweight, no-subscription complement to enterprise AML platforms, not a replacement for
one.** ComplyAdvantage publishes pricing starting "from $99 per month for 100" monitored entities
(complyadvantage.com/pricing), and LexisNexis Bridger Insight XG's published UK public-sector
pricing (via the Digital Marketplace G-Cloud framework) starts at an annual license "for up to
10,000" screenings/year - both are enterprise-annual-contract products with fuzzy/phonetic
matching, PEP and adverse-media coverage, and case management this actor does not do (see the
Limitations warning below). If all you need is a fast, no-subscription OFAC/SDN gut-check on a
name, this actor does that at $0.004/matched record with zero monthly commitment; if you need
fuzzy matching, global watchlist coverage, or a compliance case-management workflow, a platform
like those is the right tool, not this one.

### How it works

- **No API key needed.** Nothing to register, nothing to configure beyond your search input.
- Supply `names` to screen (case-insensitive substring match against the official `SDN_Name`
  field). **Any real screen always checks both SDN and CONSOLIDATED by default** - the primary
  sanctions list is never silently dropped just because you didn't specify `lists` yourself.
- Choose which lists to check (`SDN`, `CONSOLIDATED`, or both) and optionally filter by sanctions
  `program` code (e.g. "CUBA", "IRAN"). Explicitly narrowing `lists` yourself is always respected
  exactly as given.
- **Leaving `names` empty with no explicit `lists` choice** (nothing to screen at all) uses a
  cheaper, CONSOLIDATED-only default rather than pulling the full ~19,659-entry combined list -
  this keeps a zero-configuration run fast and inexpensive. This run always pushes an explicit
  `lists-coverage` record naming exactly what was and wasn't included, so it's never silent. Pass
  `lists` explicitly (with or without `names`) to include SDN in a no-screen run too.
- **This actor downloads and filters locally** - Treasury's service is a bulk-file distribution
  endpoint, not a server-side search API, so there's no way to query it more surgically than
  "fetch the current list, then filter." The full SDN list is a manageable ~5-6MB/~19K entries, so
  this is fast and cheap in practice, not a real limitation in disguise.
- Optional **incremental monitor mode**: remembers which `ent_num` values it has seen (Apify
  key-value store) and emits a separate `new-listing` record for anything newly added since the
  last run - designed for scheduled runs watching for new designations. Confirmed live: a second
  run against unchanged data produces zero false-positive new-listing flags.
- An optional `maxRecordsPerRun` **per-list** cap (default 0 = uncapped). **Screening is exhaustive
  by default** - every matching record on every requested list is returned, because a silently
  partial sanctions screen is the worst failure mode this actor could have (see below). If you
  set a cap and it truncates a list, the actor emits a loud `screening-status` record with
  `status: "TRUNCATED"` plus a warning log - it never lets a capped run look like a complete one.
- **The actor aborts the whole run (non-zero exit, clear error) if a list fails to fetch** - it
  never reports "0 matches" when the authoritative list simply never loaded. A compliance user
  reading a clean result must be able to trust that the list was actually checked.

### WARNING: Limitations - read this before relying on it for compliance decisions

- **This is substring matching with diacritic-folding and Last,First/First-Last order-swapping -
  not a certified compliance-screening engine.** Real sanctions screening products use fuzzy/
  phonetic matching (to catch typos, transliteration variants beyond simple accent differences,
  etc.) - this actor doesn't. A name spelled meaningfully differently than OFAC's listing, or a
  nickname/alias not captured in the `SDN_Name` field itself, **can still produce a false
  negative** (a real match that this actor misses). Results are binary substring candidates, not
  scored/ranked matches. This is not legal advice. For compliance-critical decisions, always
  cross-check against OFAC's own official search tool (`sanctionssearch.ofac.treas.gov`) - do not
  treat a clean result from this actor as a legal clearance.
- **The Consolidated (non-SDN, e.g. NS-PLC) list is fetched and screened in full** - as of
  2026-07-15 it's ~442 real entries. This actor never treats a near-empty result as normal
  for either list; an unexpectedly small or missing list is treated as a fetch problem, not a
  quiet "nothing to report."
- **The legacy CSV format is undocumented/positional** (no header row, no official published
  schema for the exact column order) - the 12-column mapping used here (`entNum`, `sdnName`,
  `sdnType`, `program`, `title`, `callSign`, `vesselType`, `tonnage`, `grt`, `vesselFlag`,
  `vesselOwner`, `remarks`) is inferred from the well-known, long-standing OFAC SDN.CSV format and
  confirmed against real live data, but OFAC could change this format without notice since it
  isn't a versioned/documented API contract the way SAM.gov's or FMCSA's JSON APIs are.
- **Aliases (a.k.a./f.k.a. names) are not broken out as separate searchable records in v1** - they
  appear only within the free-text `remarks` field if present, not as structured, individually
  matchable entries. A more complete implementation would use the richer `SDN_ADVANCED.XML`
  format (which does have structured alias records) - deferred for now, since that file is
  \~126MB with a complex ID-based reference schema, too heavy for a cost-efficient per-run fetch.
- **A full-list export with no names to screen can hit a real cost limit if left uncapped.**
  Leaving `names` empty with the default `lists` gets a cheap, bounded default automatically (see
  above). But if you explicitly request a full list with nothing to screen (e.g. `lists: ["SDN"]`
  alone, no `names`) and leave `maxRecordsPerRun` at 0, fetching and delivering the entire
  \~19,000-row SDN list can exceed Apify's own per-run cost limit and abort partway through. This
  is a loud abort, not a silent miss - but set an explicit `maxRecordsPerRun` for a full-list
  export to avoid it.

### Pricing

Pay per event:

- `sanctions-record` - $0.004 / screened record returned
- `monitor-run` - $0.05 / scheduled monitor-mode run, in addition to per-record charges

### Input

Key fields (see the Input tab for the full form): `names`, `lists`, `programFilter`,
`monitorMode`, `maxRecordsPerRun`. No required fields - a run with all defaults screens against
both full lists.

### Output

Each dataset item has a `recordType` of `"sanctions-listing"`, `"new-listing"` (monitor mode
only), `"screening-status"` (only when a run is truncated), or `"lists-coverage"` (only when a
run covers fewer than both sanctions lists - see Limitations below). See the Output tab for the
full field reference.

### Local development

```
npm install
npm test                # recorded-fixture unit tests, no network needed
npx apify-cli run       # local end-to-end run - works immediately, no key/account needed
```

### Support

Built and maintained by Moose & Raven. Questions or issues: support@mooseandraven.com.

# Actor input Schema

## `names` (type: `array`):

Individual or entity names to screen against the sanctions lists (case-insensitive substring match against the official SDN\_Name field). Leave empty to fetch the full list instead (subject to maxRecordsPerRun).

## `lists` (type: `array`):

Which official Treasury lists to check. SDN = Specially Designated Nationals (primary sanctions list). CONSOLIDATED = the non-SDN consolidated sanctions list (e.g. Foreign Sanctions Evaders, Sectoral Sanctions Identifications). Any REAL screen (names provided) always defaults to BOTH lists regardless of this field's own default — SDN coverage is never silently dropped from an actual screen. Only a run with no names to screen at all uses a cheaper single-list default; that run always discloses exactly which list(s) were and weren't included via a lists-coverage output record.

## `programFilter` (type: `array`):

Optional: restrict results to specific sanctions programs (e.g. "CUBA", "IRAN", "DPRK3"). Leave empty for no filter. Program codes are as published by OFAC; check a full-list run's output for the exact codes in use if unsure.

## `monitorMode` (type: `boolean`):

When on, the actor remembers which entity numbers (ent\_num) it has seen before (via Apify key-value store) and emits an additional 'new-listing' record for anything that's newly appeared on the list since the last run. Designed for scheduled runs watching for new sanctions designations. Charges one monitor-run PPE event in addition to per-record events.

## `maxRecordsPerRun` (type: `integer`):

Applied INDEPENDENTLY to each list in `lists` (not shared across them). Default 0 = no cap — every matching record on every requested list is returned, because a sanctions screen must be exhaustive by default; a silently-partial screen is the worst failure mode for this actor. If you set a cap and it truncates a list, the actor emits a loud `screening-status` TRUNCATED record and a warning log — it never reports a capped run as a complete screen. The full SDN + Consolidated lists together are roughly 17,000-20,000 entries. IMPORTANT: if you request a full-list export with no `names` (e.g. explicitly setting `lists: ["SDN"]` with nothing to screen) and leave this at 0, fetching and pushing the entire ~19,000-row SDN list can exceed Apify's own per-run cost limit and abort partway through — set an explicit cap for full-list exports.

## Actor input object example

```json
{
  "names": [],
  "lists": [
    "SDN",
    "CONSOLIDATED"
  ],
  "programFilter": [],
  "monitorMode": false,
  "maxRecordsPerRun": 0
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("mooseandraven/ofac-sanctions-screening-suite").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("mooseandraven/ofac-sanctions-screening-suite").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call mooseandraven/ofac-sanctions-screening-suite --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=mooseandraven/ofac-sanctions-screening-suite",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/K3bU3g9UVc8WLIqx8/builds/l3CHOsBadWKGKqMct/openapi.json
