# OFAC SDN Sanctions List Scraper — Name Screening + Bulk Export (`devilscrapes/ofac-sdn-sanctions-list-scraper`) Actor

Screen names against the US Treasury OFAC SDN sanctions list with fuzzy alias matching, or bulk-export the parsed list filtered by program and entity type. Structured JSON, no OFAC CSV wrangling required.

- **URL**: https://apify.com/devilscrapes/ofac-sdn-sanctions-list-scraper.md
- **Developed by:** [DevilScrapes](https://apify.com/devilscrapes) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/actors/running/actors-in-store.md#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

<div align="center">
  <img src=".actor/icon.svg" width="160" alt="Devil Scrapes mark" />

## OFAC SDN Sanctions List Scraper

**💰 $10.00 / 1 000 names screened**  ·  pay only for results  ·  no credit card to try

*The devil's in the data — we do the parsing so your compliance checks don't have to.* 😈

Screen names against the US Treasury OFAC Specially Designated Nationals (SDN) sanctions list with fuzzy alias matching, or bulk-export the parsed list filtered by program and entity type. Structured JSON in, structured JSON out — no hand-rolled CSV parsing, no `-0-` sentinel bugs, no fuzzy-matching pipeline to build yourself.

</div>

***

### 🎯 What this scrapes

This Actor fetches the US Treasury's public OFAC SDN export
(`SDN.CSV`, plus its `ALT.CSV` alias and `ADD.CSV` address companion
files) and turns Treasury's raw legacy CSV format into structured,
typed records. It runs in two modes:

- **Screen** (default) — submit a list of names and get back a fuzzy-
  matched verdict per name: matched or not, which SDN entities it
  matched, the match type (primary name vs. alias), and a score.
  A name that clears with zero matches is a **successful** result,
  not an error — that's a clean screening outcome, exactly what a
  compliance workflow needs to log.
- **Bulk** — export the parsed SDN list itself, filterable by OFAC
  program code (e.g. `CUBA`, `SDGT`) and entity type (individual vs.
  entity), with aliases and addresses joined in on request.

The SDN list itself is free and public. What you're paying for is the
parsing, normalization, alias cross-referencing, and fuzzy-matching
layer on top of it — delivered as a hosted Actor you can call from
any workflow, without writing OFAC ingestion code.

### 🔥 What we handle for you

- 🧊 **Correct CSV parsing** — Treasury's SDN export has no header row and uses a literal `-0-` string as its null sentinel; we map columns by position and convert `-0-` to a real `null` so you never see it in your data.
- 🔗 **Alias + address cross-referencing** — `ALT.CSV` and `ADD.CSV` rows are joined back to their parent SDN entity by `ent_num`, not left as three disconnected files you'd have to join yourself.
- 🎯 **Tunable fuzzy matching** — names are normalized (case, punctuation, diacritics) and scored with a string-similarity ratio, not brittle exact/substring matching. `matchThreshold` is yours to tighten or loosen per screening run.
- ✅ **Zero matches is a success, not a failure** — a screened name that clears the sanctions list finishes with a clean `matched: false` row and a `SUCCEEDED` run, so you can log every screening outcome without treating "no hit" as an error.
- 🔁 **Retries with exponential backoff** on `408 / 429 / 5xx` — up to 5 attempts, `Retry-After` honoured, before we fail loud.
- 💰 **Pay-Per-Event pricing** — you pay per name screened or record exported, not per page fetched. No results, no charge beyond the small warm-up fee.

### 💡 Use cases

- **KYC/AML onboarding checks** — screen new customer or counterparty names before account opening.
- **Vendor and partner due diligence** — batch-screen a supplier or partner list ahead of a contract.
- **Payroll and HR screening** — check new-hire names against the SDN list as part of a compliance workflow.
- **Compliance data warehousing** — bulk-export the current SDN list filtered by program to keep an internal sanctions table fresh.
- **Fintech transaction screening prototypes** — a pay-per-use SDN check to validate a screening flow before committing to a monitored SaaS contract.

### ⚙️ How to use it

1. Click **Try for free** (or **Start**) on the Actor page.
2. Leave **Mode** on `screen` and edit **Names to screen** to your own list — or switch to `bulk` to export parsed SDN records instead.
3. Run it. Each screened name (or exported record) lands in your dataset as one row.
4. Export the dataset as JSON, CSV, Excel, or pull it via the Apify API.

### 📥 Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | enum `screen`/`bulk` | `screen` | Screen names, or bulk-export the parsed list. |
| `namesToScreen` | array of strings | 2 sample names | Required (non-empty) when `mode` is `screen`. |
| `matchThreshold` | number (0.5–1.0) | `0.82` | Minimum fuzzy-match ratio to count as a hit. |
| `includeAliases` | boolean | `true` | Match against (screen) / attach (bulk) OFAC alias names. |
| `includeAddresses` | boolean | `false` | Bulk mode only — attach known addresses. |
| `maxMatchesPerName` | integer (1–100) | `10` | Screen mode only — cap matches returned per name. |
| `programFilter` | array of strings | none | Bulk mode only — restrict to these OFAC program codes. |
| `entityTypeFilter` | enum `all`/`individual`/`entity` | `all` | Bulk mode only — restrict by SDN entity type. |
| `limit` | integer (1–20 000) | `1000` | Bulk mode only — max rows exported. |
| `proxyConfiguration` | object | Apify Proxy on | Fleet-standard field; this target has no known anti-bot. |

```json
{
  "mode": "screen",
  "namesToScreen": ["Ayman Al-Zawahiri", "Jane Smith"],
  "matchThreshold": 0.82,
  "includeAliases": true,
  "maxMatchesPerName": 10,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

### 📤 Output

Screen mode, matched case:

```json
{
  "mode": "screen",
  "fetched_at": "2026-09-09T07:24:46Z",
  "queried_name": "Ayman Al-Zawahiri",
  "matched": true,
  "match_count": 1,
  "matches": [
    {
      "ent_num": 2676,
      "matched_name": "AL ZAWAHIRI, Dr. Ayman",
      "match_type": "primary_name",
      "sdn_type": "individual",
      "program": "SDGT",
      "score": 0.91
    }
  ]
}
```

Screen mode, zero-match case (a successful screening outcome):

```json
{
  "mode": "screen",
  "fetched_at": "2026-09-09T07:24:46Z",
  "queried_name": "Jane Smith",
  "matched": false,
  "match_count": 0,
  "matches": []
}
```

Bulk mode:

```json
{
  "mode": "bulk",
  "fetched_at": "2026-09-09T07:24:46Z",
  "ent_num": 2676,
  "sdn_name": "AL ZAWAHIRI, Dr. Ayman",
  "sdn_type": "individual",
  "program": "SDGT",
  "title": "Operational and Military Leader of JIHAD GROUP",
  "remarks": "DOB 19 Jun 1951; POB Giza, Egypt; ...",
  "aliases": [],
  "addresses": []
}
```

### 💰 Pricing

Pay-Per-Event — you're charged only for the warm-up and for rows that actually land in your dataset.

| Event | Price | Trigger |
|---|---|---|
| Actor start | $0.20 | Once per run, after input validation succeeds |
| Record exported | $0.004 | Per parsed SDN record pushed (bulk mode) — ~$4 / 1 000 |
| Name screened | $0.01 | Per screened name pushed (screen mode), matched or not — ~$10 / 1 000 |

### 🚧 Limitations

- **SDN list only, v1.** The Consolidated (Non-SDN) sanctions list isn't included — its export filename wasn't confirmed live at build time.
- **US OFAC only.** No EU, UN, UK, or other national sanctions lists.
- **Screening aid, not a compliance guarantee.** Fuzzy matching can produce false positives or false negatives on ambiguous names. `matchThreshold` and per-match `score` are yours to tune and audit — this Actor doesn't replace a licensed compliance program.
- **No historical snapshots.** Every run screens against the SDN list as currently published by Treasury; there's no diffing between publication dates.
- **No recurring monitoring in-Actor.** For scheduled re-screening, layer Apify's own Scheduler on top of this Actor.

### ❓ FAQ

**Is the OFAC SDN list free?**
Yes — Treasury publishes it publicly. You're paying for the parsing, alias cross-referencing, and fuzzy-matching layer, not the underlying data.

**What counts as a "match"?**
Any SDN primary name (and alias, if `includeAliases` is on) whose fuzzy-match score against your queried name is at or above `matchThreshold`.

**Does a "no match" result cost anything?**
Yes, the same as a match — the deliverable is the verdict, not just a hit. A clean screening result is still a result you need to log.

**Can I screen a large batch of names in one run?**
Yes — add as many entries to `namesToScreen` as you need; each is billed and returned as its own row.

**Does this cover the EU, UN, or UK sanctions lists?**
Not in v1 — this Actor is US OFAC SDN only.

### 💬 Your feedback

Found a gap, a parsing edge case, or want another sanctions list covered? Message **DevilScrapes** on Apify — we read every note and ship fixes fast.

# Actor input Schema

## `mode` (type: `string`):

"screen" fuzzy-matches your names against the SDN list; "bulk" exports parsed SDN records filtered by program/entity type.

## `namesToScreen` (type: `array`):

Required (non-empty) when Mode is "screen". One entry per name to check against the SDN list and its aliases.

## `matchThreshold` (type: `number`):

Minimum fuzzy-match ratio (0.5-1.0) for a candidate to count as a hit. Higher = stricter.

## `includeAliases` (type: `boolean`):

Also match/attach OFAC's known-alias (AKA) names, not just each entity's primary name.

## `includeAddresses` (type: `boolean`):

Bulk mode only — attach known addresses to each exported record.

## `maxMatchesPerName` (type: `integer`):

Screen mode only — cap on how many matches to return per screened name.

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

Bulk mode only — restrict export to these OFAC program codes (e.g. CUBA, SDGT). Leave empty for all programs.

## `entityTypeFilter` (type: `string`):

Bulk mode only — restrict export by SDN entity type.

## `limit` (type: `integer`):

Bulk mode only — max rows to export.

## `proxyConfiguration` (type: `object`):

Fleet-standard proxy field. The OFAC export service has no known anti-bot; Apify Proxy default is fine to leave on.

## Actor input object example

```json
{
  "mode": "screen",
  "namesToScreen": [
    "Ayman Al-Zawahiri",
    "Jane Smith"
  ],
  "matchThreshold": 0.82,
  "includeAliases": true,
  "includeAddresses": false,
  "maxMatchesPerName": 10,
  "entityTypeFilter": "all",
  "limit": 1000,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

All dataset items as JSON.

## `datasetItemsCsv` (type: `string`):

Same data exported to CSV.

## `datasetView` (type: `string`):

Open the run dataset in the Console.

# 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 = {
    "mode": "screen",
    "namesToScreen": [
        "Ayman Al-Zawahiri",
        "Jane Smith"
    ],
    "matchThreshold": 0.82,
    "includeAliases": true,
    "includeAddresses": false,
    "maxMatchesPerName": 10,
    "entityTypeFilter": "all",
    "limit": 1000,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("devilscrapes/ofac-sdn-sanctions-list-scraper").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 = {
    "mode": "screen",
    "namesToScreen": [
        "Ayman Al-Zawahiri",
        "Jane Smith",
    ],
    "matchThreshold": 0.82,
    "includeAliases": True,
    "includeAddresses": False,
    "maxMatchesPerName": 10,
    "entityTypeFilter": "all",
    "limit": 1000,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("devilscrapes/ofac-sdn-sanctions-list-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "mode": "screen",
  "namesToScreen": [
    "Ayman Al-Zawahiri",
    "Jane Smith"
  ],
  "matchThreshold": 0.82,
  "includeAliases": true,
  "includeAddresses": false,
  "maxMatchesPerName": 10,
  "entityTypeFilter": "all",
  "limit": 1000,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call devilscrapes/ofac-sdn-sanctions-list-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,devilscrapes/ofac-sdn-sanctions-list-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/5XtcJTXEHDoLFe6GI/builds/bvkbxCoicOyyQ7mjW/openapi.json
