# Sanctions Update Alert — Watchlist Change Monitor (`zinin/sanctions-update-alert`) Actor

Watch a list of names against OFAC SDN and EU consolidated sanctions lists and get ONLY the changes since your last check — a new hit, a hit that disappeared, or an existing hit's details (score, program, alias) shifting.

- **URL**: https://apify.com/zinin/sanctions-update-alert.md
- **Developed by:** [Tim Zinin](https://apify.com/zinin) (community)
- **Categories:** Lead generation, Automation
- **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/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

## Sanctions Update Alert — Watchlist Change Monitor

Watch a list of names against OFAC SDN and EU consolidated sanctions lists and get only
the CHANGES since your last check — a brand-new hit, an existing hit's details shifting
(score, program, alias), or a hit that disappeared. Runs on our own live sanctions
screening engine under the hood.

### What you get

- A named "watch" (a list of names) that remembers what it has already shown you.
- Every scheduled run reports ONLY what changed — a new sanctions hit, an existing
  hit's score/program/matched-alias drifting, or a hit that no longer matches.
- Run several independent watches from one Actor (e.g. one for vendors, one for new
  hires) — each has its own memory.
- The very first run for a new watch tells you honestly that it's establishing a
  baseline, not hiding a "no changes" run as if it found something.
- Runs on Apify: schedule it daily, monitor it, call it from the API, export to
  JSON/CSV/Excel or push straight into your own pipeline.

### How to run it

1. Click **Try for free** — no card needed on the free plan.
2. Paste the names you want watched into **Names**, optionally a name for this watch.
3. Hit **Start**. The first run creates the baseline; schedule it to run again to get a
   stream of only the CHANGES each time.

### Pricing

Pay-per-event: **$0.005 per run start + $0.01 per new/changed hit /
baseline created**. A hit DISAPPEARING (delisted, or dropped below your score
threshold) is reported for visibility but never charged — it's the absence of new
risk, not a new finding. The "no changes" notice on a quiet run and any error/notice
row are also never charged. 10 new/changed hits cost about $0.11 (the one-time start fee plus 10 billed rows).

### Input

| Field | Required | What it does |
|---|---|---|
| `names` | yes | Person or company names to watch, one per row. Up to 100. |
| `minScore` | no | Minimum match score to consider (0-1, default 0.5). |
| `baseline_key` | no | Name for this watch, so you can run several independent watches. |
| `max_items` | no | Max new/changed-hit rows delivered (and charged) per run (1-200, default 20). |

```json
{
    "names": ["Yevgeniy Prigozhin", "Acme Trading LLC"],
    "baseline_key": "vendor-list"
}
```

### Output

Baseline-created row (first run for a watch — real output, live run 30.07.2026):

```json
{
    "baselineKey": "selftest-sanctions-2",
    "found": true,
    "changeType": null,
    "baselineCreated": true,
    "name": null,
    "entityName": null,
    "listName": null,
    "entityType": null,
    "program": null,
    "matchedName": null,
    "score": null,
    "currentHitsCount": 50,
    "changedHitsCount": null,
    "disappearedHitsCount": null,
    "error": "",
    "summary": "First check for \"selftest-sanctions-2\" — baseline created with 50 current sanctions hit(s). Future runs report only NEW or CHANGED hits against this baseline.",
    "checkedAt": "2026-07-30T08:54:19.175Z"
}
```

New-hit and changed-hit rows (real output, live run 30.07.2026):

```json
{
    "baselineKey": "selftest-sanctions-2",
    "found": true,
    "changeType": "new-hit",
    "name": "Yevgeniy Prigozhin",
    "entityName": "Yevgeniy Viktorovich LEBEDEV",
    "listName": "EU Consolidated",
    "program": "UKR",
    "score": 0.5,
    "error": "",
    "summary": "New sanctions hit for \"selftest-sanctions-2\": \"Yevgeniy Prigozhin\" now matches Yevgeniy Viktorovich LEBEDEV [EU Consolidated], program UKR (score 0.5)."
}
```

```json
{
    "baselineKey": "selftest-sanctions-2",
    "found": true,
    "changeType": "changed-hit",
    "name": "Acme Trading LLC",
    "entityName": "ACS TRADING LLC",
    "listName": "OFAC SDN",
    "program": "SDGT",
    "score": 0.667,
    "error": "",
    "summary": "Sanctions hit changed for \"selftest-sanctions-2\": \"Acme Trading LLC\" vs ACS TRADING LLC [OFAC SDN] — score 0.222 -> 0.667."
}
```

| Field | Meaning |
|---|---|
| `baselineKey` | Which watch this row belongs to. |
| `found` | `true` for a real result row (a hit or baseline-created); `false` for a notice/error row. |
| `changeType` | `"new-hit"`, `"changed-hit"`, or `null` for a notice row. |
| `baselineCreated` | `true` only on the first-ever run for this watch. |
| `name` | The screened name this hit belongs to. |
| `entityName`, `listName`, `program`, `matchedName`, `score` | The sanctioned entity's own fields. |
| `currentHitsCount` | Only set on the baseline-created row. |
| `disappearedHitsCount` | Only set on a "hits disappeared" notice row. |
| `error` | Empty string when the check completed cleanly (including "nothing changed" and "a hit disappeared"); non-empty only on a real problem. |
| `summary` | Human-readable one-liner. |

### Other tools we built

#### Related tools

Related tools for adjacent workflows in compliance and public procurement.

| Actor | What it does |
|---|---|
| [Sanctions Screening API](https://apify.com/zinin/sanctions-screening) | Pair it in the compliance and public procurement workflow: Screen names against the live OFAC SDN and EU consolidated sanctions lists |
| [Tender Alert — New EU Tender Watch](https://apify.com/zinin/tender-alert) | Pair it in the compliance and public procurement workflow: Watch EU public-sector tenders (TED Europa) matching your keywords/CPV codes and get ONLY the new ones... |
| [Counterparty Risk Rollup — Sanctions, Courts, Registry, Hiring](https://apify.com/zinin/counterparty-risk-rollup) | Pair it in the compliance and public procurement workflow: One call, one row per counterparty: sanctions screening (OFAC + EU), legal-entity registry (GLEIF),... |
| [Company Registry Enricher](https://apify.com/zinin/company-registry-enricher) | Pair it in the compliance and public procurement workflow: Turn a company name, LEI or UK company number into an official registry card: legal name, status,... |
| [Gov Tender Radar](https://apify.com/zinin/gov-tender-radar) | Pair it in the compliance and public procurement workflow: Search EU public-sector tenders (TED Europa) by keyword or CPV code, optionally filtered by buyer country |

### FAQ / Limitations

**Is this a legal or compliance determination?** No. This is a screening SIGNAL only —
verify any hit against official OFAC/EU sources before acting on it. Matching is
soft on purpose (a missed hit is worse than a false one), so expect some noise on
common names.

**What happens if a source list fails to load mid-run?** The run reports it honestly
and does not touch your baseline or charge you — a "no changes" read off an
incomplete list would be a guess, not a real answer.

**What this is NOT.** Not a substitute for your compliance team's own due diligence
process, and not a guarantee of completeness — sanctions lists change on their own
schedule, independent of this Actor's run schedule.

Found a bug or need a custom watch? Issues on the Actor's page.

# Actor input Schema

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

Person or company names to watch against the OFAC SDN and EU consolidated sanctions lists, one per row. Every scheduled run re-screens these same names and reports ONLY what changed since a previous run of this watch: a new hit, a hit that disappeared, or an existing hit's score/program/alias shifting.

## `minScore` (type: `number`):

Only consider candidate matches scoring at or above this (0 = everything, 1 = only a full token match). Kept soft on purpose — a missed hit is worse than a false one.

## `baseline_key` (type: `string`):

A name for THIS watch, so you can run several independent screening watches from one Actor (e.g. "vendor-list", "new-hires") without one overwriting another's memory of what's already been seen. Each name is scoped to YOUR OWN Apify account. The prefilled value is only there so this Actor's own daily test run has a stable, obviously-a-test name; replace it with your own watch name.

## `max_items` (type: `integer`):

Caps how many new-hit / changed-hit rows a single run will deliver and charge for, even if more were found.

## Actor input object example

```json
{
  "names": [
    "Yevgeniy Prigozhin"
  ],
  "minScore": 0.5,
  "baseline_key": "apify-daily-test",
  "max_items": 20
}
```

# Actor output Schema

## `results` (type: `string`):

API URL for the default dataset items produced by this run.

# 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 = {
    "names": [
        "Yevgeniy Prigozhin"
    ],
    "baseline_key": "apify-daily-test"
};

// Run the Actor and wait for it to finish
const run = await client.actor("zinin/sanctions-update-alert").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 = {
    "names": ["Yevgeniy Prigozhin"],
    "baseline_key": "apify-daily-test",
}

# Run the Actor and wait for it to finish
run = client.actor("zinin/sanctions-update-alert").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 '{
  "names": [
    "Yevgeniy Prigozhin"
  ],
  "baseline_key": "apify-daily-test"
}' |
apify call zinin/sanctions-update-alert --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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