# OFAC Sanctions Changes Feed: Entities, Vessels & Aircraft (`moment-data/ofac-sanctions-changes-feed`) Actor

Official US Treasury OFAC sanctions list changes as clean JSON: companies, vessels and aircraft added, removed or amended per publication, with programs (RUSSIA-EO14024...), aliases, IMO/MMSI/call sign, tax and registration IDs, city/country. For KYC, trade and shipping compliance.

- **URL**: https://apify.com/moment-data/ofac-sanctions-changes-feed.md
- **Developed by:** [Luke Miller](https://apify.com/moment-data) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 sanction 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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## OFAC Sanctions Changes Feed: Entities, Vessels & Aircraft

Every change OFAC (US Treasury, Office of Foreign Assets Control) makes to its sanctions lists, delivered as clean JSON: **companies, banks, vessels and aircraft added, removed or amended**, one record per change, straight from the official **OFAC Sanctions List Service (SLS)**.

Built for **compliance / KYC / AML teams, trade and export-control desks, shipping and maritime risk, fintechs and payment processors** who need to know *what changed since yesterday*, not re-download a 110 MB list.

- **Official source only**: SLS delta files (`/changes/{publicationId}`), publication history (`/changes/history/{year}`) and the SDN / Consolidated XML exports. No scraping, no third-party aggregators.
- **Change-level data**: `added` (new designations), `removed` (delistings), `amended` (new aliases, addresses, IDs, programs, vessel flag/name changes) with a plain-English `amendmentSummary`.
- **Screening-ready fields**: primary name + all aliases (incl. Cyrillic / Chinese / Arabic script), programs (`RUSSIA-EO14024`, `IRAN-EO13902`, `SDGT`...), lists (SDN / non-SDN), legal authorities, IMO, MMSI, call sign, flag, vessel type and build year, aircraft tail number / model / serial, company tax and registration IDs (INN, OGRN, USCC, RFC...), website, date established, secondary-sanctions risk, remarks, related entities.
- **Filters**: programs (exact or prefix: `RUSSIA` = all Russia programs), countries (address, vessel flag, registration country), record types (entity / vessel / aircraft), change types, days back, max items.
- **Schedules**: `sinceLastRun` mode delivers each publication's changes exactly once per State key - perfect for a daily alert into Slack, email, a webhook or your case-management system.
- **Never empty**: if recent changes are sparse, the default run walks back through older publications and, if still short, tops up with currently listed records flagged `changeType: "current"`.
- **Entities only**: individuals are never included (by design - no personal data). Addresses are reduced to city / state / country. Names of individuals referenced inside remarks (e.g. "Linked To: SURNAME, Given") are replaced with `[individual]`.

### Quick start

Run with `{}`: you get the newest publications' entity, vessel and aircraft changes (about 40 records, ~10 seconds).

Russia-related changes involving the UAE or Turkey in the last 90 days:

```json
{ "programs": ["RUSSIA"], "countries": ["AE", "TR"], "daysBack": 90, "maxItems": 200 }
```

New vessel designations only (shadow-fleet watch):

```json
{ "entityTypes": ["vessel"], "actionTypes": ["added"], "daysBack": 180 }
```

Daily alert feed (schedule it once a day):

```json
{ "mode": "sinceLastRun", "stateKey": "daily-all", "maxItems": 500 }
```

### Input

| Field | Default | What it does |
|---|---|---|
| `mode` | `window` | `window` = publications in the last `daysBack` days, newest first, stateless. `sinceLastRun` = only publications/changes not delivered before for `stateKey`, oldest first. |
| `daysBack` | 30 | Lookback in days (US Eastern publication dates). |
| `entityTypes` | all | `entity`, `vessel`, `aircraft`. Individuals are not available. |
| `actionTypes` | all | `added`, `removed`, `amended`. |
| `programs` | all | OFAC program tags, exact or prefix (`RUSSIA`, `IRAN`, `SDGT`, `CYBER`, `DPRK`, `ILLICIT-DRUGS`...). |
| `countries` | all | ISO codes or OFAC country names; matches address countries, vessel flag and registration-ID issuing country. |
| `maxItems` | 40 | Hard cap on records (and spend). |
| `autoExtend` | true | Window mode: read older publications (up to 180 days) until at least 25 matches. |
| `fallbackToCurrent` | true | Window mode: top up with currently listed records (`changeType: "current"`) if still short. |
| `stateKey` | `default` | Saved position for `sinceLastRun`; use one per schedule. |

### Output (one record per change)

```json
{
  "changeType": "added",
  "action": "added",
  "publicationId": 1075,
  "publicationDate": "2026-10-21",
  "publicationType": "Standard Action",
  "entityId": 58873,
  "entityType": "vessel",
  "name": "WHALES DIAMOND",
  "aliases": [],
  "programs": ["IRAN-EO13902"],
  "lists": ["SDN List"],
  "sanctionsTypes": ["Block"],
  "legalAuthorities": ["Executive Order 13902 (Iran)"],
  "listedDate": "2026-10-21",
  "countries": ["United Arab Emirates"],
  "countryCodes": ["AE"],
  "imoNumber": "9375032",
  "mmsi": "470132000",
  "callSign": "A6E2076",
  "vesselFlag": "United Arab Emirates",
  "vesselType": "Crew/Supply Vessel",
  "vesselYearOfBuild": "2006",
  "registrationIds": [{ "type": "Vessel Registration Identification", "value": "IMO 9375032", "country": null }],
  "relatedEntities": [{ "type": "Property in the interest of", "relatedEntityId": 58810, "relatedName": "WHALES SHIPPING LINE LLC" }],
  "remarks": "(Linked To: WHALES SHIPPING LINE LLC)",
  "amendments": null,
  "amendmentSummary": null,
  "ofacUrl": "https://sanctionssearch.ofac.treas.gov/Details.aspx?id=58873",
  "deltaFileUrl": "https://sanctionslistservice.ofac.treas.gov/changes/1075",
  "ofacRecentActionsUrl": "https://ofac.treasury.gov/recent-actions/20261021"
}
```

Also on every record: `addresses` (city / stateOrProvince / country / countryCode), `identifiers` (all ID documents), `attributes` (other OFAC features), `aircraftTailNumber`, `aircraftModel`, `aircraftSerialNumber`, `aircraftOperator`, `vesselOwner`, `vesselTonnage`, `website`, `establishedDate`, `organizationType`, `targetType`, `secondarySanctionsRisk`, `firstSeenAt`. Amended records carry `amendments` (list of `{action, field, value}`) and a readable `amendmentSummary`, e.g. `added sanctionsProgram "IRAN-CON-ARMS-EO"`. For amended records the other fields show the record's **current** listing. See `sample-output.json` for full examples.

The run summary (key-value store `OUTPUT`) lists the publications scanned, counts by change and record type, and why the run stopped.

### How it works

1. Reads the SLS publication history (`/changes/history/{year}`) - OFAC publishes a few times a week, each with an ID.
2. Downloads each publication's official delta file (`/changes/{id}`, the same file `/changes/latest` serves for the newest one) and classifies each record as added / removed / amended.
3. Joins the SDN.XML and CONSOLIDATED.XML exports for remarks, vessel details and the current state of amended records.
4. Drops individuals, applies your filters, delivers.

### Pricing

Pay per event: a small **actor start** fee plus **one `sanction-record` event per delivered record**. Your run's max charge is respected - you never get more records than you pay for. See the Pricing tab.

### Notes and limits

- Data comes from the official OFAC SLS and is in the public domain. This Actor is a data feed, **not a screening engine or legal advice** - always confirm matches against the official OFAC lists.
- Publication dates are US Eastern. `ofacRecentActionsUrl` points at OFAC's Recent Actions page for that date (best-effort link).
- `removed` records show the record as it was when delisted.
- Individuals are excluded by design; remarks are passed through from OFAC except that individuals referenced in "Linked To:" notes are replaced with `[individual]` (OUTPUT.redactedRemarks counts them).

# Actor input Schema

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

window (default): changes from OFAC publications in the last N days, newest first, no saved state. sinceLastRun: only publications (and changes) not delivered before for this State key, oldest first - use this for daily schedules and alerts.

## `daysBack` (type: `integer`):

Publications from the last N days (US Eastern dates; OFAC publishes a few times a week). Also the first-run window in sinceLastRun mode.

## `entityTypes` (type: `array`):

entity (companies, banks, organizations), vessel and/or aircraft. Empty = all three. Individuals are never included by this Actor.

## `actionTypes` (type: `array`):

added (new designations), removed (delistings) and/or amended (updated names, aliases, addresses, IDs, programs, vessel flags...). Empty = all.

## `programs` (type: `array`):

OFAC program tags, exact or prefix, case-insensitive: RUSSIA-EO14024, RUSSIA (matches all RUSSIA-\*), IRAN, SDGT, CYBER, ILLICIT-DRUGS-EO14059, DPRK, VENEZUELA, NPWMD, TCO, CUBA... Empty = all.

## `countries` (type: `array`):

ISO codes or OFAC country names (RU, IR, AE, CN, HK, TR, Hong Kong, United Arab Emirates...). Matches address countries, vessel flag and the issuing country of registration IDs. Empty = all.

## `maxItems` (type: `integer`):

Hard cap on delivered records (also caps your spend). One sanction-record event per record.

## `autoExtend` (type: `boolean`):

If the Days back window holds fewer than 25 matching changes (or Max records if lower), keep reading older publications (up to 180 days) until it does. Turn off to get exactly the Days back window.

## `fallbackToCurrent` (type: `boolean`):

If still short, top up with currently listed records matching your filters (newest OFAC listings first), flagged changeType: "current", so a run is never empty. Not used in sinceLastRun mode or when Change types excludes added.

## `stateKey` (type: `string`):

Name of the saved feed for sinceLastRun mode. Each key keeps its own position, so use one key per schedule / filter set.

## Actor input object example

```json
{
  "mode": "window",
  "daysBack": 30,
  "entityTypes": [],
  "maxItems": 40,
  "autoExtend": true,
  "fallbackToCurrent": true,
  "stateKey": "default"
}
```

# Actor output Schema

## `changes` (type: `string`):

One record per entity, vessel or aircraft change (or current listing when topped up).

## `summary` (type: `string`):

Publications scanned, filters, counts, why the run stopped.

# 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 = {
    "entityTypes": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("moment-data/ofac-sanctions-changes-feed").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 = { "entityTypes": [] }

# Run the Actor and wait for it to finish
run = client.actor("moment-data/ofac-sanctions-changes-feed").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 '{
  "entityTypes": []
}' |
apify call moment-data/ofac-sanctions-changes-feed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,moment-data/ofac-sanctions-changes-feed"
        }
    }
}
```

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/BbNq5xIwdNUbmKly5/builds/h7XMHNCv5kkiFnt3w/openapi.json
