# OFAC Sanctions Screening: UN, EU, UK Lists + LEI & EU VAT Check (`rich_minds/counterparty-check-ai`) Actor

First 25 counterparty checks free. Sanctions screening of companies and vessels, one verdict each — pay per qualified counterparty check. Denied party lists: OFAC, Entity List, UN, EU, UK; LEI lookup; validation of EU VAT numbers. AI with Apify model access or your own key. Free demo on any plan.

- **URL**: https://apify.com/rich_minds/counterparty-check-ai.md
- **Developed by:** [Rich Minds](https://apify.com/rich_minds) (community)
- **Categories:** Business, Agents, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.90 / 1,000 counterparty check (rules)s

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 Screening: UN, EU, UK Lists + LEI & EU VAT Check

**Every trade partner screened, with one clear / review / block verdict — re-checked every week.**

⚡ First **25 counterparty checks free** · 💵 **$0.0039** per company · 🤖 **≈ $0.013** per AI-assessed company, tokens included · ⏱️ 5 real companies in 55 s on Apify

![Verdicts of a real run: Rosneft and Mahan Air blocked, Google Ireland clear with LEI and VAT](https://api.apify.com/v2/key-value-stores/NkoPJOBF8J1vhjZV7/records/shortlist.svg)

> **Try it in 30 seconds.** Click **Try it** — the form is pre-filled with a free demo of 3 labelled sample
> companies. Paste your own, one per line, and press Start — on **any Apify plan**; your first **25** are free.
> → [What a run costs](#-pricing--what-a-run-really-costs) · [What the AI adds](#-what-the-ai-tier-adds) · [Run it weekly](#-run-it-weekly)

### ⚡ At a glance

| | |
|---|---|
| **What you get** | One row per company: verdict and reason, every possible hit weighed, the GLEIF entity and parents, EU VAT validity, a certificate page for your file |
| **You provide** | Names with their country, one per line — `Acme Trading FZE, AE` — or a link to your supplier sheet (Google Sheets, CSV, Excel) with its VAT and LEI columns |
| **Lists screened** | OFAC, the US Consolidated Screening List (Entity List, Denied Persons …), UN, EU, UK — each list's publication date on every row |
| **Output** | A ranked sheet, blocks first (Excel, CSV, Sheets), an e-mail digest and a forwardable report |
| **Typical run** | 5 real companies → 2 block, 3 clear in 55 s on Apify, 2026-10-23 (run kpao7Upb4QfaG7wRM) |
| **Cost of that run** | $0.02 rules only · ≈ $0.04 with the AI on the 2 blocks — inside your free 25 |
| **Free tier** | Your first 25 counterparty checks on this Actor — one free tier per Apify account |
| **Keys / setup** | No key for the lists. AI: with Apify model access none; otherwise your own key — a free Gemini key gives 1–3 AI verdicts per run, a paid key all |
| **Which plan** | Any plan — the free demo, the live search of your counterparties (this Actor reads the lists itself), your own list ([template](https://api.apify.com/v2/key-value-stores/NkoPJOBF8J1vhjZV7/records/list-template.json)) |
| **Works with** | Schedules, webhooks, Sheets, Slack, Teams, Discord, Telegram, Make / n8n / Zapier, MCP & AI agents |

### 🎯 What this Actor does

- **All trade sanctions regimes in one row** — OFAC SDN and non-SDN, the BIS Entity List and 5 more US lists, UN, EU, UK.
- **Each possible hit weighed** — a namesake in another country, a person, a different LEI or IMO is ruled out with the reason.
- **The legal entity behind the name** — GLEIF legal name, status, jurisdiction and the **direct and ultimate parents**, screened too.
- **EU VAT validity** — VIES valid or not, the registered name, and a consultation number for your file.
- **One verdict you can act on** — `block`, `review` or `clear` with list, entry and programme. Blocks and reviews are always delivered.
- **A screening certificate per company** — lists with their dates, each hit and why, GLEIF, the VIES consultation number: one page to file.

#### 🛡️ Never a silent "clear"

A list that cannot be read is named in `listsUnavailable` and the row turns `review`; haketa/sanctions-screening fills in (capped).

#### 🏢 Parent and ownership screening

A listed GLEIF parent turns the row to `review` — OFAC's 50 % rule blocks a company owned 50 % or more by blocked persons. GLEIF has consolidation parents, not every shareholder.

### 🚀 How to use it

1. **Click Try it** — the demo of 3 labelled sample companies runs (nothing charged).
2. **Paste your counterparties** into **Counterparties to check**, one per line: `Name, CC` — or link your supplier sheet. Keep **AI hit adjudication** on.
3. **Press Start** — verdicts land blocks first; export or wire a webhook.
4. **Schedule it weekly** with your address in **E-mail me the verdicts** and a **Re-screen memory** name — only changes reach you.

![Legal entity and VAT view: GLEIF legal name, LEI status, jurisdiction and the VIES answer per company](https://api.apify.com/v2/key-value-stores/NkoPJOBF8J1vhjZV7/records/entity.svg)

#### 📦 Screen suppliers for sanctions before the first order

Paste the supplier master's names and countries: every supplier gets a verdict, its parents screened too.

#### 💳 Check a company before paying it

One name, one row in under a minute: a block or review says why before the money leaves.

📚 **Learn more:** [Tutorial — screen suppliers for sanctions, step by step](https://api.apify.com/v2/key-value-stores/NkoPJOBF8J1vhjZV7/records/tutorial.html)

### 🆚 Why this instead of four free lookups by hand?

| | By hand: OFAC search + trade.gov CSL + GLEIF + VIES | **This Actor** |
|---|---|---|
| **Your time per 100 counterparty checks** | ≈ 5 h: four sites, one name at a time | ≈ 1 h: read the reviews, blocks already explained |
| **First result** | ≈ 3 min per company | 5 companies in 55 s on Apify |
| **Same 100 companies, all in** | $0 + ≈ 5 h of your time | **$0.39** rules-only, ranked and explained, junk $0 · **≈ $1.11** with the AI on the ≈ 80 that need it |
| **Re-screening** | the same four sites again | only changed results, never charged twice |

#### vs other sanctions screening Actors

| Actor | 100 companies | What you pay for | What it lacks |
|---|---|---|---|
| **This Actor** | **$0.39** rules · ≈ $1.11 with AI | each counterparty check | PEP, adverse media |
| [haketa/sanctions-screening](https://apify.com/haketa/sanctions-screening) | $0.30 + start fee (≈ $1.00–1.30 with LEI and VAT tools) | every row | LEI, parents, VAT; namesakes left to you (its README) |
| [pink_comic/ofac-sanctions-screening](https://apify.com/pink_comic/ofac-sanctions-screening) | $0.20 + start fee | every row | OFAC SDN only (its title) |
| [zinin/sanctions-screening](https://apify.com/zinin/sanctions-screening) | $0.40–0.50 + $0.005 start | every useful row | OFAC SDN + EU only, ≤ 100 names a run (its description) |
| [ventura_workalong/counterparty-check](https://apify.com/ventura_workalong/counterparty-check) | $3.00 + start fee | every row | US lists only; every match "possible match, verify" |
| [ryanclinton/opensanctions-search](https://apify.com/ryanclinton/opensanctions-search) | $0.30 + start fee | every row | your OpenSanctions key and licence |

#### vs the free official search tools

<details><summary>OFAC search, trade.gov CSL, GLEIF, VIES — where each wins</summary>

| Free tool | Where it wins | What it lacks |
|---|---|---|
| [OFAC Sanctions List Search](https://sanctionssearch.ofac.treas.gov/) | official, OFAC's own score | OFAC only, one name at a time |
| [Consolidated Screening List search (trade.gov)](https://www.trade.gov/consolidated-screening-list) | all 11 US export lists | US only; no verdict |
| [GLEIF LEI search](https://search.gleif.org/) | the full relationship graph | no sanctions, one entity at a time |
| [VIES VAT number validation](https://ec.europa.eu/taxation_customs/vies/) | the official answer | one number at a time |

</details>

### 💵 Pricing — what a run really costs

| Event | When it is charged | Price |
|---|---|---|
| `free-tier` | your first 25 counterparty checks on this Actor | **$0.00** |
| `qualified-counterparty-check-basic` | a company screened by the rules: verdict, hits, GLEIF, VIES | **$0.0039** |
| `qualified-counterparty-check-ai` | the same + the AI read of its open hits, the GLEIF pick, the reviewer note | **$0.0097** |

**One free tier:** your first 25 counterparty checks are free, whatever the tier. **Never charged:** duplicates, excluded names, empty names, unchanged re-screens, clears below your minimum score, companies beyond **Max counterparties**. No source bill: this Actor reads the lists, GLEIF and VIES itself.

**How that compares** — the top 10 "sanctions screening" Store Actors charge a median $0.003875 per row; $0.0039 here is 1.01× that, but only per qualified counterparty check — one replaces ≈ 3 raw rows scanned (sanctions, LEI, VAT): $0.0013 per raw-row equivalent. The closest combined check charges $0.03.

**Worked example** (local test run, 2026-10-23) — 10 real companies, AI on: 8 with possible hits → 8 × ($0.0097 + ≈ $0.0032 tokens); 2 with none → 2 × $0.0039. **≈ $0.11, $0.011 per company** — inside the free 25. Per 100 at 8 in 10: ≈ $1.11 with AI, $0.39 without.

**AI tier, all in:** ≈ $0.013 per AI-assessed company — $0.0097 + ≈ $0.0032 tokens (1,671 in / 292 out — gemini-3.5-flash-lite, own key, 2026-10-23 — priced at the default Apify model's rate), billed by Apify or by your own key's provider.

**At volume** — 500 partners re-screened weekly: ≈ $1.95 the first run, then only the changes (≈ $0.02–0.08 a week). A marketplace onboarding 2,000 sellers a month: $7.80 rules · ≈ $22 with AI.

### 🤖 What the AI tier adds

The same company — Mahan Air (Iran), real run 2026-10-23 — AI **off**:

```json
{"name": "Mahan Air", "verdict": "block", "hitCount": 3, "sanctionsHits": [{"list": "EU", "entryId": "EU-EU.12240.1", "assessment": "likely", "decidingFields": ["name", "country"], "adjudicatedBy": "rules"}], "generatedText": "Hold the deal: Mahan Air matches EU entry 'Mahan Air' under EU Iran regime (IRN) on name, country — compare the source entry before deciding.", "assessedBy": "rules"}
```

AI **on** (`qualified-counterparty-check-ai`, an own Gemini key) — it ruled out the US Denied Persons namesake "MAHAN AIR GENERAL TRADING LLC" and wrote the file note, each programme with its list:

<details><summary>The AI-on row</summary>

```json
{
  "name": "Mahan Air", "verdict": "block", "aiModel": "google:gemini-3.5-flash-lite", "assessedBy": "ai",
  "sanctionsHits": [
    {"list": "OFAC_SDN", "entryId": "OFAC_SDN-12927", "assessment": "likely", "programmes": ["SDGT", "NPWMD", "IFSR"], "adjudicatedBy": "ai"},
    {"list": "US_CSL", "matchedName": "MAHAN AIR GENERAL TRADING LLC", "assessment": "unlikely", "decidingFields": ["country"], "reason": "The list entry country is AE while the counterparty is in IR.", "adjudicatedBy": "ai"}
  ],
  "generatedText": "Mahan Air matches EU-EU.12240.1 under EU Iran regime (IRN) on the EU list and OFAC_SDN-12927 under SDGT, NPWMD, IFSR on OFAC SDN due to matching name and country."
}
```

</details>

Reading a possible hit by hand — countries, addresses and IDs compared, the file note written — takes ≈ 8 minutes per company (on 7 sample companies); the AI takes ≈ 1 s and never clears an identifier match.

**Which AI your plan gets:** with Apify model access the AI runs on your plan; without it, the demo shows labelled sample verdicts and your own key runs it — a free Gemini key ([aistudio.google.com/apikey](https://aistudio.google.com/apikey)) gives 1–3 AI verdicts per run, a paid key all.

### ⚙️ Input

| Field | Default | What it does |
|---|---|---|
| `counterparties` | — | one per line, `Name, CC`; a vessel `PEGAS, IMO 9256860`; via the API also objects with `lei`, `vatNumber`, `registrationNumber`, `address`, `type`, `imo` |
| `sheetUrl` | — | your supplier sheet (Google Sheets link, CSV or .xlsx URL); headers matched to name, country, VAT, LEI, reg. no., IMO |
| `sourceMode` | `"live"` | `live`: this Actor reads the lists, no other Actor runs (`actor` = 0.1 name); `dataset` / `list`: your rows |
| `lists` | all six | OFAC_SDN, OFAC_CONS, US_CSL, UN, EU, UK |
| `screenParents` | `true` | GLEIF direct + ultimate parent screened too |
| `requesterVatNumber` | `""` | your EU VAT number — VIES then returns a consultation number per check |
| `rescreenStoreName` | `""` | remember results; later runs deliver only changes |
| `enableAi` | `true` | AI hit adjudication |
| `minScore` | `0` | drops only clears below it — blocks and reviews are always delivered |
| `maxQualified` | `100` | cap on rows and spend; the rest are counted, never charged |
| `notifyEmail` | — | the digest by e-mail after every run |

<details><summary>Every other input</summary>

`preset`, `checkVat`, `includeNoMatch`, `minNameScore`, `datasetId`, `itemsList`, `autoSwitchToLive`, `failOnSourceError`, `targetFlags`, `suppressionList`, `llmProvider`, `llmModel`, `llmApiKey`, `maxDiscoveryChargeUsd`, `discoveryActorId`, `sendAlertsTo`, `webhookUrl`, `historyDatasetName` — and the API-only ones (per-service alert URLs, webhook headers / batching / signing, store names, scan bounds) in the API reference.

**Flags** (`targetFlags`) are listed in the [API reference](https://api.apify.com/v2/key-value-stores/NkoPJOBF8J1vhjZV7/records/api-reference.md); how often a `likely_hit` is a true match is not yet measured (roadmap 2026-11-06).

</details>

### 📤 Output

**A real row** (Google Ireland Limited, AI off) is in the API reference.

**Upsert key:** `dedupeKey` — the normalised name + country (+ LEI / VAT), stable across runs. **Sort** by `score`; `ruleScore` is the rule part, `fitScore` the AI's — trend across runs on `ruleScore`. **Views:** Shortlist (blocks first), Evidence, Legal entity & VAT, CRM export, Score breakdown. `OUTPUT` holds the run summary, next to a Markdown `DIGEST` and an HTML `REPORT`.

<details><summary>Every field of a row</summary>

| Field | Description |
|---|---|
| `itemId`, `name`, `url`, `input`, `country` | identity; `url`: GLEIF record, else the hit's list page |
| `verdict`, `verdictReason` | `clear` / `review` / `block` (never null) and why |
| `sanctionsHits`, `bestHitScore`, `hitCount` | each hit: `list`, `entryId`, `score`, `assessment`, `decidingFields`, `reason`, `programmes` …; null = no hit |
| `legalName`, `lei`, `leiStatus`, `jurisdiction`, `legalAddress`, `registrationNumber`, `leiChosenBy` | GLEIF |
| `parents` | `relation`, `lei`, `legalName`, `verdict` of each parent |
| `vatNumber`, `vatValid`, `vatName`, `vatAddress`, `vatNameMatches`, `vatCheckedAt`, `vatConsultationNumber`, `vatError` | VIES; `vatCheckedAt` = the time this run consulted VIES |
| `listsChecked` | per list, the authority's publication date of the file read in this run — downloaded fresh at `checkedAt` |
| `listsUnavailable`, `changeType`, `checkedAt`, `isSample` | lists not read, re-screen change, the time this run screened the row, sample flag |
| `evidenceUrl` | the certificate page: lists and publication dates, each hit and why, GLEIF, VIES consultation no., verdict, row SHA-256 |
| `flags`, `targetFlagsMatched`, `ruleScore`, `score`, `label`, `fitScore`, `assessedBy` | score = 100 − risk; `label` sorts — read `verdict` |
| `scoreReasons`, `summary`, `generatedText`, `recommendedNextStep`, `aiModel` | the AI read and the reviewer note |
| `chargedEvent`, `billedAs`, `dedupeKey`, `source`, `scrapedAt` | billing, provenance; `scrapedAt` = the time the row was written |

</details>

⭐ **Found it useful? A review on the Store helps others find it.**

### 🔁 Run it weekly

1. After your first real run, open the saved task its status links and click **Schedule** (weekly).
2. Type a **Re-screen memory** name (`rescreenStoreName`): later runs deliver only `new`, `changed` or `delisted` companies — an unchanged one is neither delivered nor charged.
3. Put your address in **E-mail me the verdicts**; Slack, Teams, Google Chat, Discord or Telegram go into **Send alerts to**. For a sheet, start from the [tracker template](https://api.apify.com/v2/key-value-stores/NkoPJOBF8J1vhjZV7/records/tracker.csv) and a webhook — upsert on `dedupeKey`.

The book renews by change: week 2 of an unchanged book delivers 0 rows and costs $0 — a company comes back only when a list, GLEIF or VIES changes its result. The change rate is not measured yet (estimate ≈ 1–4 % of the checks a week; roadmap 2026-11-13): 500 partners ≈ $0.02–0.08 a week.

#### 🎯 Try it for your niche

Pick one in **Start from a ready check** and press Start.

<details><summary>6 ready checks — measured in a local test run 2026-10-23, rules only</summary>

| Preset | What it checks | Measured |
|---|---|---|
| `exporter-buyers` | 4 buyers before the invoice, one sanctioned | 4 qualified (1 block, 3 clear), 31 s |
| `freight-shipping` | carriers and consignees: Sovkomflot, IRISL, Maersk, Mahan Air | 4 qualified (3 block, 1 clear), 32 s |
| `us-export-control` | the US lists only: Huawei, SMIC, Siemens Mobility | 3 qualified (2 block, 1 clear), 20 s |
| `eu-suppliers-vat` | EU suppliers, VAT checked in VIES | 4 qualified (4 clear), 36 s |
| `marketplace-sellers` | new sellers, one state arms exporter | 4 qualified (1 block, 3 clear), 28 s |
| `vessel-screening` | vessels by IMO number: 4 OFAC-listed tankers, 1 container ship | 5 qualified (4 block on the IMO, 1 clear), 33 s |

</details>

### 🔌 Integrations, automation and API

#### Run outcomes

<details><summary>What your integration sees, per outcome</summary>

| Outcome | Run status | Dataset | `OUTPUT` | Charged? |
|---|---|---|---|---|
| Free demo (`{}`) | SUCCEEDED | 3 sample rows | `mode: demo`, `ok: true` | no |
| Success | SUCCEEDED | one row per company | `ok: true`, `outcome: ok` | per company |
| A list unreachable | SUCCEEDED | rows `review` | `listsUnavailable` | per company |
| Nothing new / nothing matched | SUCCEEDED | empty | `ok: true`, `outcome: empty`, `rescreen.unchanged` | not by us — no source scan to pay |
| Your plan cannot run the Store fallback | SUCCEEDED; check `OUTPUT.ok` | Console: the sample · schedule / API: an alert | `ok: false`, `outcome: source_refused`, `sourceRefused: plan` | no |
| Source failed (dataset unreadable) | FAILED | empty | `ok: false`, `outcome: source_failed`, `sourceError` | no |
| Source partial (a dataset run aborted) | SUCCEEDED | the units scraped | `sourceStatus` (`partial: true`) | per company |
| AI unavailable | SUCCEEDED | rule verdicts | `aiError`, `aiCoverage` | basic price |
| Invalid input | FAILED | empty | — | no |
| Crashed | FAILED, status "Failed: <reason>" | rows delivered before it | `ok: false`, `outcome: error`, `error` | delivered rows only |

Branch on `OUTPUT.ok` / `OUTPUT.outcome` — never on an empty dataset.

</details>

- **Webhook** — `webhookUrl` POSTs `{"event": "counterparty_check.qualified", "counterparty_check": {…}, "runId"}` per company, or with `webhookBatchSize` > 1 one `counterparty_checks.qualified` POST per batch. A 429 / 5xx is retried once; a failure never fails the run and is re-sent next run. `webhookSecret` signs every POST (HMAC-SHA256).
- **Which delivery field wins:** each URL is posted once; `webhookUrl` gets the rows, the others the digest.
- **Your own list** — `list` mode on any plan; start from the [template](https://api.apify.com/v2/key-value-stores/NkoPJOBF8J1vhjZV7/records/list-template.json).
- **After 1688 Supplier Finder or Alibaba RFQ Leads** — in that Actor's Integrations tab, "Run succeeded" starts this one in `dataset` mode on its dataset with a re-screen memory: every new supplier or buyer is screened once ([recipe](https://api.apify.com/v2/key-value-stores/NkoPJOBF8J1vhjZV7/records/api-reference.md)).

<details><summary>List-mode rows — what a pasted record needs</summary>

| Field | Needed? | What it enables |
|---|---|---|
| `name` (or `supplierName`, `buyerName`, `companyName`, `legalName`, `title`) | required | the name screened |
| `country` (or `countryCode`, `buyerCountry`) | recommended | decides namesakes |
| `lei` | optional | the GLEIF record by LEI |
| `vatNumber` (or `vat`, `vatId`) | optional | the VIES check |
| `registrationNumber`, `imo` | optional | an identifier match decides "likely" |
| `address` | optional | weighs a fuzzy name |
| `type` | optional | `company` / `person` / `vessel` |
| `website` | optional | kept in `input` |

</details>

<details><summary>API snippets — Python and JavaScript (the real check, a free first call commented)</summary>

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("rich_minds/counterparty-check-ai").call(
    run_input={
        # free first call instead: {} or {"sourceMode": "list", ...} — the labelled demo, $0
        "counterparties": ["Rosneft Oil Company, RU", {"name": "Acme Trading FZE", "country": "AE"}],
        "enableAi": True,
        "maxQualified": 100,
        "maxDiscoveryChargeUsd": 0.5,
        "failOnSourceError": True,
    },
    timeout_secs=3240,  # 100 companies ≈ 4 min — see "How long does a run take?"
    # build="0.1.4",  # pin the build number your pipeline was tested with
)
out = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("OUTPUT")["value"]
if not out.get("ok", True) or out.get("sourceError"):
    raise RuntimeError(out.get("sourceError") or out.get("error"))
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["name"], item["verdict"], item["score"], item["url"])
```

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('rich_minds/counterparty-check-ai').call({
    // free first call instead: {} or { sourceMode: "list", ... } — the labelled demo, $0
    counterparties: ['Rosneft Oil Company, RU', { name: 'Acme Trading FZE', country: 'AE' }],
    enableAi: true,
    maxQualified: 100,
    maxDiscoveryChargeUsd: 0.5,
}, { timeout: 3240 /* , build: '0.1.4' — pin the build number your pipeline was tested with */ });
const out = (await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('OUTPUT')).value;
if (out.ok === false || out.sourceError) throw new Error(out.sourceError || out.error);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((i) => [i.name, i.verdict, i.score, i.url]));
```

</details>

**MCP & AI agents** — `{"mcpServers": {"apify": {"url": "https://mcp.apify.com/?actors=rich_minds/counterparty-check-ai"}}}`, then ask *"Is Acme Trading FZE (UAE) sanctioned?"*

**Minimal agent input** (your own rows on any plan: `{"sourceMode": "list", "itemsList": [{"name": "Acme Trading FZE", "country": "AE"}]}`):

```json
{"sourceMode": "live", "counterparties": ["Acme Trading FZE, AE"], "enableAi": true, "maxQualified": 10}
```

**API reference:** [a real item, the `OUTPUT` keys, which call runs what (`OUTPUT.mode`), webhook payloads](https://api.apify.com/v2/key-value-stores/NkoPJOBF8J1vhjZV7/records/api-reference.md).

### 👥 Who is it for?

| You are… | You run it to… | Start with |
|---|---|---|
| Exporter / importer | screen the buyer and its parent before the PI goes out | `exporter-buyers` |
| EU importer | re-screen the supplier book, VAT numbers checked | `eu-suppliers-vat` |
| B2B marketplace | gate every new seller, re-screen weekly | `marketplace-sellers` |
| Freight forwarder, broker | denied party screening of consignees | `freight-shipping` |
| Ship agent, charterer | the vessel by IMO number before the fixture | `vessel-screening` |
| US exporter | an Entity List check before an EAR shipment | `us-export-control` |

### 🧠 How the AI works

- **Only the open questions** — a hit not settled by an identifier, same-name GLEIF records, or a name to transliterate.
- **Grounded** — only the row's own hits and fields; a GLEIF pick only among the candidates; a mislabelled programme drops the AI note.
- **Rules first** — the AI never clears an identifier match, an invalid VAT number, an unknown LEI or a missing list.
- **Model** — `anthropic/claude-haiku-4.5` via Apify's model access, or your own key's model. Every speed and token figure here is `google:gemini-3.5-flash-lite` on an own key; the Haiku path is re-measured on a platform run (roadmap 2026-10-30).

### 🔒 Data, compliance and limits

- Official, commercially reusable sources only: OFAC and trade.gov (US public domain), UN, EU Financial Sanctions Files, UK FCDO (OGL v3.0), GLEIF (CC0), EU VIES.
- **Screening support, not legal advice** — a block or review needs a human decision; every row says so. Not covered: PEP lists, adverse media.

### ❓ FAQ

**How much will one run cost me?** $0.0039 per company, $0.0097 when the AI reads its hits; the first 25 are free. 100 companies: $0.39 rules, ≈ $1.11 with AI when 8 in 10 need it.

**Is this an OFAC sanctions check or only a name match?** Both: a name ≥ 85 is a possible hit, then country, address, IDs and type decide likely / unlikely / unclear.

**Does it cover denied party screening for export control?** Yes — the US Consolidated Screening List (Entity List, Denied Persons, Unverified, MEU, ITAR debarred) next to OFAC, UN, EU, UK.

**Is it an entity list check I can run before an EAR shipment?** Yes — preset `us-export-control` screens the US lists; the row names list, entry and programme.

**Is this an AML screening tool?** For AML sanctions screening, yes — the six lists, each hit weighed. Not PEP lists or adverse media.

**Can it do KYC / KYB checks on companies?** KYC company screening, yes: GLEIF legal name, status and parents, VIES, the lists. Not ID documents, registries or beneficial owners.

**Can it screen vessels by IMO number?** Yes — vessel sanctions screening: type `PEGAS, IMO 9256860`; an IMO on a list entry decides the hit (preset `vessel-screening`).

**Does it include an LEI lookup?** Yes — by your LEI, or by name and country; an unknown LEI turns the row to review.

**How does the EU VAT number validation work?** Format check, then VIES: valid or not, the registered name and address, and a consultation number with **Your own EU VAT number** set.

**How do I screen suppliers for sanctions in bulk?** Link the supplier sheet (`sheetUrl`: Google Sheets, CSV, Excel — VAT and LEI columns kept), paste the list, or set `datasetId` — one verdict row per supplier.

**Can I check a company before paying its invoice?** Yes — one name and country, a verdict in under a minute.

**Why pay when OFAC, GLEIF and VIES have free searches?** For one name they win; for a list, this runs all four and weighs every namesake.

**Can Minimum score drop a sanctioned company?** No — blocks and reviews are always delivered; it only drops clears.

**How fresh are the lists?** Every run downloads the six lists anew; `listsChecked` gives each authority's publication date of the file read (EU 2026-10-15 on a 2026-10-23 run: no EU change since).

**How long does a run take?** 5 real companies took 55 s with the rules on Apify (2026-10-23); an own key with gemini-3.5-flash-lite adds ≈ 0.6–1.2 s per AI-assessed company.

<details><summary>Measured per mode, with the `timeoutSecs` to set</summary>

| Mode | Measured | `timeoutSecs` |
|---|---|---|
| Free demo | 3.9 s on Apify | 120 |
| Live check, rules (5 companies, on Apify, 2026-10-23, run kpao7Upb4QfaG7wRM) | 55 s: ≈ 40 s for the six lists, then ≈ 1–3 s per company | 600 per 100 |
| AI, own key (`google:gemini-3.5-flash-lite`) | + ≈ 0.6–1.2 s per AI-assessed company — ≈ 50–100 a minute (0.6 s on 2026-10-23, 1.2 s on 2026-10-22) | + 240 per 50 |
| AI via Apify's model access (`anthropic/claude-haiku-4.5`) | not measured yet — platform run dated 2026-10-30 | + 300 per 100 |

</details>

A rate-limited own key stops the AI after 2 minutes of waiting, rule verdicts kept; a free key gives 1–3 AI verdicts per run.

**Will I be charged for the same company twice?** Not in one run (duplicates are free). Across runs, with a re-screen memory only changed companies are delivered and charged.

**Can a remembered company miss a new designation?** No — the re-screen memory skips only unchanged results; a new hit always comes through.

**What happens if nothing matches?** The company is `clear`, delivered as evidence (or skipped, free, with **Deliver clear counterparties** off).

**Do rule-scored companies use my free ones?** Yes — except the last 5, kept for your first AI-assessed ones.

**Which Apify plan do I need?** Any plan — the live check reads the official lists itself; the AI as in **Keys / setup** above.

### 🧩 More Actors from the same developer

- **[Alibaba RFQ Leads AI](https://apify.com/rich_minds/alibaba-rfq-leads-ai)** — found a buyer on Alibaba? Screen it here before you quote.
- **[1688 Supplier Finder](https://apify.com/rich_minds/1688-supplier-finder-ai)** — new Chinese factories every week; check each one here before the first order.
- **[Email List Cleaner](https://apify.com/rich_minds/email-list-qualifier-ai)** — keep the contact list of your cleared partners deliverable.

### 🆘 Support

Something missing or wrong? Open an issue on the Actor's page — buyer requests ship first.

### 📝 Changelog

- **0.1.4** (2026-10-23) — your supplier sheet as input; a certificate per company; a shorter form; vessels by IMO number.
- **0.1.3** (2026-10-23) — the status explains blocks and reviews kept below Minimum score.
- **0.1.2** (2026-10-23) — reliable live checks; VIES consultation numbers.
- **0.1.1** (2026-10-23) — first release: six lists, GLEIF, VIES, AI.

# Actor input Schema

## `preset` (type: `string`):

Pick a ready check and press Start: it <b>replaces the free sample</b> with a real example list for that trade and runs the live check (the untouched sample counts as empty); a value you typed yourself always wins. <b>Custom</b> = fill the fields yourself.

## `counterparties` (type: `array`):

One per line: name, 2-letter country — <code>Acme Trading FZE, AE</code>, or a vessel <code>PEGAS, IMO 9256860</code>. Typing here replaces the demo and starts the live check on any Apify plan (a plan that cannot run the Store fallback still gets every row). VAT / LEI numbers: link your sheet below. Affects what you pay.

## `sheetUrl` (type: `string`):

A Google Sheet share link or any CSV / .xlsx URL — headers matched automatically: <b>Name</b> (or Company / Supplier), <b>Country</b>, <b>VAT</b>, <b>LEI</b>, <b>Registration number</b>, IMO. Every row with a name is checked, on any Apify plan (a plan that cannot run the Store fallback still gets every row). Affects what you pay.

## `notifyEmail` (type: `string`):

The digest (counts by verdict, every block and review with its reason) is e-mailed here after every run with something to report; weekly with a re-screen memory, only changes arrive. Never sent for the free demo.

## `minScore` (type: `integer`):

<b>Blocks and reviews are always delivered</b> — this only drops <b>clear</b> rows scoring below it. Score = 100 − risk: clear ≈ 95, review ≈ 40, block ≈ 5. Dropped rows are not charged. Leave 0 to keep every clear verdict too (a clear verdict is evidence for your file).

## `maxQualified` (type: `integer`):

Hard cap on rows and on what <b>this Actor</b> charges: at most this many × $0.0097 with AI on (× $0.0039 off), e.g. 100 × $0.0039 = $0.39. Blocks and reviews come first; counterparties beyond the cap are screened, not delivered and not charged — the status says how many. Affects what you pay.

## `maxDiscoveryChargeUsd` (type: `number`):

Only used when an official list cannot be downloaded: <code>haketa/sanctions-screening</code> then screens the names for the sanctions part on your account, capped here — $0.50 in the form and for an API or agent call that leaves it out. Normal runs read the official lists themselves and spend nothing here. Affects what you pay.

## `enableAi` (type: `boolean`):

Reads every open possible hit against the counterparty's own facts, picks the right GLEIF record among same-name companies, searches name variants and writes a reviewer note. <b>On = $0.0097 per counterparty the AI assessed; off = $0.0039</b>; nothing to adjudicate stays $0.0039. Tokens: with Apify model access ≈ $0.003 a check on top; with your own key, your provider's.

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

Leave all six on for trade. A list switched off is not downloaded and not named in <code>listsChecked</code>.

## `screenParents` (type: `boolean`):

Looks up the direct and ultimate parent in GLEIF and screens them through the same lists — a listed parent turns the verdict to <b>review</b> (the OFAC 50 % rule).

## `checkVat` (type: `boolean`):

For a counterparty with a <code>vatNumber</code>: format check, then the EU VIES service — valid or not, the registered name and address, and whether that name matches yours. An invalid number turns the verdict to <b>review</b>.

## `requesterVatNumber` (type: `string`):

Optional. With your EU VAT number here (e.g. <code>DE811569869</code>), VIES returns a <b>consultation number</b> for every VAT check — <code>vatConsultationNumber</code> in the row, the proof of the check for your audit file. Empty = the check runs without one.

## `minNameScore` (type: `integer`):

A list name scoring this or more against the counterparty (legal forms dropped, transliterated) is a possible hit and gets weighed. Lower = more possible hits to review; higher = only near-identical names.

## `includeNoMatch` (type: `boolean`):

On: every counterparty gets a row — a clear verdict is evidence for your file. Off: only counterparties with a possible hit, a VAT or an LEI problem are delivered (the rest are not charged).

## `targetFlags` (type: `array`):

Only deliver counterparties that have at least one of these flags (e.g. <code>likely_hit</code>, <code>vat_invalid</code>). Leave empty to keep everything. An API call passes the flag names from the README's flag table (<code>likelyHit</code> works too); an unknown name stops the run at once with the list of valid ones.

## `suppressionList` (type: `array`):

Counterparty names to skip (e.g. your own group companies). Skipped before any check and never charged.

## `llmProvider` (type: `string`):

<b>Apify (no keys)</b> — the AI runs through Apify's model access (<code>anthropic/claude-haiku-4.5</code>) on plans that include it; its tokens (≈ $0.003 a check) are billed to your Apify account on top of the $0.0097. <b>My own key</b> — your OpenAI / Anthropic / Gemini / Groq key: measured ≈ 0.6–1.2 s per counterparty check with <code>google:gemini-3.5-flash-lite</code> (0.6 s on 2026-10-23, 1.2 s on 2026-10-22) — give a 50-company run a 240 s timeout. A free-tier key: expect 1–3 AI checks per run (the rest keep their rule score); a paid key (billing on) assesses every counterparty with an open hit.

## `llmModel` (type: `string`):

Leave empty for the default: <code>anthropic/claude-haiku-4.5</code> through Apify's model access, <code>google:gemini-3.5-flash-lite</code> with your own key (a free Gemini key works as is). Apify mode takes an OpenRouter slug such as <code>openai/gpt-4.1-mini</code>; own-key mode takes <code>provider:model</code>, e.g. <code>anthropic:claude-haiku-4-5-20251001</code> or <code>groq:openai/gpt-oss-120b</code>.

## `llmApiKey` (type: `string`):

Required when <b>AI model access</b> is <i>My own API key</i>. Stored encrypted by Apify, never logged.

## `aiCandidateMultiplier` (type: `integer`):

API only — hidden on the form. How many counterparties with open hits get the AI pass, as a multiple of <b>Max counterparties</b> — the riskiest rule verdicts first. Counterparties with nothing to adjudicate never go to the AI.

## `sendAlertsTo` (type: `string`):

Paste one or more URLs, one per line — the service is detected from the address: a Slack or Discord channel webhook, a Teams Workflows or Google Chat space webhook, your Telegram bot's send link (<code>https://api.telegram.org/bot\<token>/sendMessage?chat_id=@yourchannel</code>) or any other https URL (Zapier, Make, n8n, your CRM), which gets every verdict as JSON. After every run with at least one counterparty to report, the digest (how many are new, the top 10 with links) is posted there. Never sent for the free demo. Headers, batching and signing: <i>Delivery details (advanced)</i>.

## `rescreenStoreName` (type: `string`):

Type a name (e.g. <code>suppliers-weekly</code>) and every run remembers each counterparty's result in that key-value store on your account; later runs deliver — and charge — only the counterparties whose verdict or hits changed (<code>changeType</code>: new / changed / delisted). Empty = every counterparty every run. One name per list you monitor.

## `dedupeAcrossRuns` (type: `boolean`):

API only — hidden on the form. A re-screen never skips a counterparty for good: <code>true</code> turns on the re-screen memory (store <code>\<dedupeStoreName>-rescreen</code> unless <b>Re-screen memory</b> names one), so unchanged counterparties are skipped and every new designation is still delivered.

## `dedupeTtlDays` (type: `integer`):

API only — hidden on the form; a 0.1 name. A re-screen compares every run with the last result, so only the re-screen memory decides what comes back.

## `historyDatasetName` (type: `string`):

Optional. Type a name (e.g. <code>counterparty-check-ai-seen-log</code>) and every run appends its verdicts with the date to that named dataset on your account — one list across months to connect to Google Sheets or your BI tool once. Empty = off. Costs nothing extra.

## `sourceMode` (type: `string`):

<b>live</b> — the counterparties typed in section 1 (or your sheet), checked live: the official lists, GLEIF and VIES are read by this Actor, no other Actor runs and nothing else is billed (any plan; <code>actor</code> is the same mode under its 0.1 name). <b>dataset</b> — an Apify dataset of companies (fields: <code>name</code> / <code>companyName</code> / <code>legalName</code>, <code>country</code>, <code>vatNumber</code>, <code>lei</code>). <b>list</b> — records you paste into <code>itemsList</code>. The mode you choose always runs as chosen; only the untouched sample records next to counterparties you typed switch to the live check. <code>{}</code> over the API runs the free demo — nothing charged.

## `autoSwitchToLive` (type: `boolean`):

On (default): counterparties typed next to the untouched sample records start the live check (<code>OUTPUT.switchedToLive</code> names them). Off: the mode you send is the mode that runs — the sample stays the free demo and the status names the counterparties it did not check. API pipelines that must never start a paid read on their own: send <code>false</code>.

## `failOnSourceError` (type: `boolean`):

Off (default): a run whose dataset or list delivers no counterparty ends SUCCEEDED with 0 rows and <code>OUTPUT.ok: false</code>. On: the same run ends FAILED, so a schedule's failed-run alert fires.

## `datasetId` (type: `string`):

Only for <b>dataset</b> mode. Pick the dataset so the Actor is granted read access to it.

## `itemsList` (type: `array`):

Only for <b>list</b> mode. JSON array of objects with at least <code>name</code> and optionally <code>country</code>, <code>lei</code>, <code>vatNumber</code>, <code>registrationNumber</code>, <code>address</code>, <code>website</code>, <code>type</code>. The prefilled 3 are the free demo's fictional samples (precomputed, labelled <code>isSample</code>).

## `discoveryActorId` (type: `string`):

Runs on your account only when an official list cannot be downloaded, to screen the names for the sanctions part (capped by <b>Max fallback spend</b>). The rows still name the missing list and are never <code>clear</code> while it is missing.

## `discoveryInput` (type: `object`):

API only — hidden on the form. Extra input passed to the fallback Store Actor as-is (e.g. <code>{"sources": \["OFAC", "EU"]}</code>); the names to screen are filled in by this Actor.

## `maxToProcess` (type: `integer`):

API only — hidden on the form. Upper bound on how many counterparties are screened in one run (controls run time). Default = 3 × max counterparties.

## `webhookUrl` (type: `string`):

Every delivered verdict is POSTed here as JSON (Zapier, Make, n8n, your CRM) — flat columns: <code>verdict</code>, <code>verdictReason</code>, <code>lei</code>, <code>vatValid</code>, <code>bestHitScore</code>. Wins over a webhook URL in <b>Send alerts to</b>; every URL is posted once. Stored encrypted — Zapier / Make hook URLs carry their secret in the path.

## `webhookHeaders` (type: `object`):

API only — hidden on the form. Extra HTTP headers for the webhook, e.g. <code>{"Authorization": "Bearer …"}</code>. Stored encrypted by Apify, never logged.

## `webhookBatchSize` (type: `integer`):

API only — hidden on the form. 1 = one POST per counterparty the moment its verdict is ready (body <code>{event, counterparty_check, runId}</code>). Higher = one POST per N counterparties (body <code>{event, counterparty_checks: \[rows], runId}</code>). A 429 / 5xx is retried once after 2 s; a failed POST never fails the run.

## `webhookSecret` (type: `string`):

API only — hidden on the form. Any random string. Every webhook POST then carries <code>X-Signature: sha256=\<HMAC-SHA256 of the raw body with this secret></code>, so your endpoint can verify it came from this Actor. Stored encrypted by Apify, never logged.

## `dedupeStoreName` (type: `string`):

API only — hidden on the form. Key-value store of the "never deliver twice" memory (only with that setting on). One name per client.

## `discoveryTimeoutSecs` (type: `integer`):

API only — hidden on the form. How long the fallback Store Actor may run — never more than 60 % of the run's time left.

## `slackWebhookUrl` (type: `string`):

API only — hidden on the form, where <code>sendAlertsTo</code> takes it. Slack incoming-webhook URL for the digest.

## `discordWebhookUrl` (type: `string`):

API only — hidden on the form, where <code>sendAlertsTo</code> takes it. Discord channel webhook URL for the digest.

## `teamsWebhookUrl` (type: `string`):

API only — hidden on the form, where <code>sendAlertsTo</code> takes it. Teams Workflows webhook URL for the digest.

## `googleChatWebhookUrl` (type: `string`):

API only — hidden on the form, where <code>sendAlertsTo</code> takes it. Google Chat space webhook URL for the digest.

## `telegramUrl` (type: `string`):

API only — hidden on the form, where <code>sendAlertsTo</code> takes it. The bot's sendMessage link with its chat_id.

## Actor input object example

```json
{
  "preset": "custom",
  "counterparties": [],
  "minScore": 0,
  "maxQualified": 100,
  "maxDiscoveryChargeUsd": 0.5,
  "enableAi": true,
  "lists": [
    "OFAC_SDN",
    "OFAC_CONS",
    "US_CSL",
    "UN",
    "EU",
    "UK"
  ],
  "screenParents": true,
  "checkVat": true,
  "requesterVatNumber": "",
  "minNameScore": 85,
  "includeNoMatch": true,
  "llmProvider": "apify",
  "aiCandidateMultiplier": 2,
  "rescreenStoreName": "",
  "dedupeAcrossRuns": false,
  "dedupeTtlDays": 0,
  "historyDatasetName": "",
  "sourceMode": "list",
  "autoSwitchToLive": true,
  "failOnSourceError": false,
  "itemsList": [
    {
      "name": "Northwind Industrial Supplies GmbH",
      "sample": true,
      "country": "DE",
      "vatNumber": "DE000000001",
      "website": "https://northwind-industrial.example",
      "sampleScreening": {
        "legalName": "Northwind Industrial Supplies GmbH",
        "lei": "529900SAMPLE00000001",
        "leiStatus": "ISSUED",
        "jurisdiction": "DE",
        "legalAddress": "Hafenstrasse 12, 20457, Hamburg, DE",
        "registrationNumber": "HRB 000001 (sample)",
        "leiChosenBy": "rules",
        "parents": [
          {
            "relation": "direct",
            "lei": "529900SAMPLE00000002",
            "legalName": "Northwind Holding AG",
            "verdict": "clear"
          }
        ],
        "vatNumber": "DE000000001",
        "vatValid": true,
        "vatName": "NORTHWIND INDUSTRIAL SUPPLIES GMBH",
        "vatAddress": "HAFENSTRASSE 12, 20457 HAMBURG",
        "vatNameMatches": true,
        "vatCheckedAt": "2026-10-23T08:00:00+00:00",
        "sanctionsHits": [],
        "listsChecked": {
          "OFAC_SDN": "2026-10-21",
          "OFAC_CONS": "2026-10-21",
          "US_CSL": "2026-10-21",
          "UN": "2026-10-21",
          "EU": "2026-10-15",
          "UK": "2026-10-16"
        }
      }
    },
    {
      "name": "Oceanic Vantage Shipping FZE",
      "sample": true,
      "country": "AE",
      "address": "Office 1407, Jebel Ali Free Zone, Dubai",
      "sampleScreening": {
        "parents": [],
        "sanctionsHits": [
          {
            "list": "OFAC_SDN",
            "entryId": "OFAC_SDN-SAMPLE-1",
            "matchedName": "OCEANIC VANTAGE SHIPPING FZE",
            "entryName": "OCEANIC VANTAGE SHIPPING FZE",
            "entryType": "company",
            "score": 100,
            "weakAlias": false,
            "assessment": "likely",
            "decidingFields": [
              "name",
              "country",
              "address"
            ],
            "reason": "name 100/100 and country AE agree, address shares jebel, dubai",
            "adjudicatedBy": "rules",
            "programmes": [
              "IRAN-EO13846"
            ],
            "countries": [
              "AE"
            ],
            "listedOn": "2024-03-14",
            "sourceUrl": "https://sanctionssearch.ofac.treas.gov/",
            "subject": "counterparty",
            "foundVia": "name"
          },
          {
            "list": "UK",
            "entryId": "UK-SAMPLE-2",
            "matchedName": "Oceanic Vantage Shipping FZE",
            "entryName": "Oceanic Vantage Shipping FZE",
            "entryType": "company",
            "score": 100,
            "weakAlias": false,
            "assessment": "likely",
            "decidingFields": [
              "name",
              "country"
            ],
            "reason": "name 100/100 and country AE agree",
            "adjudicatedBy": "rules",
            "programmes": [
              "The Iran (Sanctions) Regulations 2023"
            ],
            "countries": [
              "AE",
              "IR"
            ],
            "listedOn": "2024-05-02",
            "sourceUrl": "https://sanctionslist.fcdo.gov.uk/docs/UK-Sanctions-List.csv",
            "subject": "counterparty",
            "foundVia": "name"
          }
        ],
        "listsChecked": {
          "OFAC_SDN": "2026-10-21",
          "OFAC_CONS": "2026-10-21",
          "US_CSL": "2026-10-21",
          "UN": "2026-10-21",
          "EU": "2026-10-15",
          "UK": "2026-10-16"
        }
      }
    },
    {
      "name": "Baltic Timber Export OU",
      "sample": true,
      "country": "EE",
      "vatNumber": "EE100000000",
      "sampleScreening": {
        "parents": [],
        "vatNumber": "EE100000000",
        "vatValid": false,
        "vatCheckedAt": "2026-10-23T08:00:00+00:00",
        "sanctionsHits": [
          {
            "list": "EU",
            "entryId": "EU-SAMPLE-3",
            "matchedName": "Baltik Timber Export LLC",
            "entryName": "Baltik Timber Export LLC",
            "entryType": "company",
            "score": 89,
            "weakAlias": false,
            "assessment": "unlikely",
            "decidingFields": [
              "country"
            ],
            "reason": "listed for BY, RU, the counterparty is in EE",
            "adjudicatedBy": "rules",
            "programmes": [
              "BLR"
            ],
            "countries": [
              "BY",
              "RU"
            ],
            "listedOn": "2023-02-25",
            "sourceUrl": "https://eur-lex.europa.eu/",
            "subject": "counterparty",
            "foundVia": "name"
          }
        ],
        "listsChecked": {
          "OFAC_SDN": "2026-10-21",
          "OFAC_CONS": "2026-10-21",
          "US_CSL": "2026-10-21",
          "EU": "2026-10-15",
          "UK": "2026-10-16"
        },
        "listsUnavailable": [
          "UN"
        ]
      }
    }
  ],
  "discoveryActorId": "haketa/sanctions-screening",
  "webhookBatchSize": 1,
  "dedupeStoreName": "counterparty-check-ai-seen",
  "discoveryTimeoutSecs": 3600
}
```

# Actor output Schema

## `qualified` (type: `string`):

All qualified counterparty checks as JSON, best-scoring first.

## `sheet` (type: `string`):

The same counterparty checks as a spreadsheet.

## `runSummary` (type: `string`):

JSON record with the funnel (loaded -> filtered -> AI-assessed -> qualified), per-reason skip counts, charged events by type, free-tier counterparty checks used and remaining, whether a budget limit was reached, webhook delivery counts and the dedupe store size.

# 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 = {
    "counterparties": [],
    "maxDiscoveryChargeUsd": 0.5,
    "sourceMode": "list",
    "itemsList": [
        {
            "name": "Northwind Industrial Supplies GmbH",
            "sample": true,
            "country": "DE",
            "vatNumber": "DE000000001",
            "website": "https://northwind-industrial.example",
            "sampleScreening": {
                "legalName": "Northwind Industrial Supplies GmbH",
                "lei": "529900SAMPLE00000001",
                "leiStatus": "ISSUED",
                "jurisdiction": "DE",
                "legalAddress": "Hafenstrasse 12, 20457, Hamburg, DE",
                "registrationNumber": "HRB 000001 (sample)",
                "leiChosenBy": "rules",
                "parents": [
                    {
                        "relation": "direct",
                        "lei": "529900SAMPLE00000002",
                        "legalName": "Northwind Holding AG",
                        "verdict": "clear"
                    }
                ],
                "vatNumber": "DE000000001",
                "vatValid": true,
                "vatName": "NORTHWIND INDUSTRIAL SUPPLIES GMBH",
                "vatAddress": "HAFENSTRASSE 12, 20457 HAMBURG",
                "vatNameMatches": true,
                "vatCheckedAt": "2026-10-23T08:00:00+00:00",
                "sanctionsHits": [],
                "listsChecked": {
                    "OFAC_SDN": "2026-10-21",
                    "OFAC_CONS": "2026-10-21",
                    "US_CSL": "2026-10-21",
                    "UN": "2026-10-21",
                    "EU": "2026-10-15",
                    "UK": "2026-10-16"
                }
            }
        },
        {
            "name": "Oceanic Vantage Shipping FZE",
            "sample": true,
            "country": "AE",
            "address": "Office 1407, Jebel Ali Free Zone, Dubai",
            "sampleScreening": {
                "parents": [],
                "sanctionsHits": [
                    {
                        "list": "OFAC_SDN",
                        "entryId": "OFAC_SDN-SAMPLE-1",
                        "matchedName": "OCEANIC VANTAGE SHIPPING FZE",
                        "entryName": "OCEANIC VANTAGE SHIPPING FZE",
                        "entryType": "company",
                        "score": 100,
                        "weakAlias": false,
                        "assessment": "likely",
                        "decidingFields": [
                            "name",
                            "country",
                            "address"
                        ],
                        "reason": "name 100/100 and country AE agree, address shares jebel, dubai",
                        "adjudicatedBy": "rules",
                        "programmes": [
                            "IRAN-EO13846"
                        ],
                        "countries": [
                            "AE"
                        ],
                        "listedOn": "2024-03-14",
                        "sourceUrl": "https://sanctionssearch.ofac.treas.gov/",
                        "subject": "counterparty",
                        "foundVia": "name"
                    },
                    {
                        "list": "UK",
                        "entryId": "UK-SAMPLE-2",
                        "matchedName": "Oceanic Vantage Shipping FZE",
                        "entryName": "Oceanic Vantage Shipping FZE",
                        "entryType": "company",
                        "score": 100,
                        "weakAlias": false,
                        "assessment": "likely",
                        "decidingFields": [
                            "name",
                            "country"
                        ],
                        "reason": "name 100/100 and country AE agree",
                        "adjudicatedBy": "rules",
                        "programmes": [
                            "The Iran (Sanctions) Regulations 2023"
                        ],
                        "countries": [
                            "AE",
                            "IR"
                        ],
                        "listedOn": "2024-05-02",
                        "sourceUrl": "https://sanctionslist.fcdo.gov.uk/docs/UK-Sanctions-List.csv",
                        "subject": "counterparty",
                        "foundVia": "name"
                    }
                ],
                "listsChecked": {
                    "OFAC_SDN": "2026-10-21",
                    "OFAC_CONS": "2026-10-21",
                    "US_CSL": "2026-10-21",
                    "UN": "2026-10-21",
                    "EU": "2026-10-15",
                    "UK": "2026-10-16"
                }
            }
        },
        {
            "name": "Baltic Timber Export OU",
            "sample": true,
            "country": "EE",
            "vatNumber": "EE100000000",
            "sampleScreening": {
                "parents": [],
                "vatNumber": "EE100000000",
                "vatValid": false,
                "vatCheckedAt": "2026-10-23T08:00:00+00:00",
                "sanctionsHits": [
                    {
                        "list": "EU",
                        "entryId": "EU-SAMPLE-3",
                        "matchedName": "Baltik Timber Export LLC",
                        "entryName": "Baltik Timber Export LLC",
                        "entryType": "company",
                        "score": 89,
                        "weakAlias": false,
                        "assessment": "unlikely",
                        "decidingFields": [
                            "country"
                        ],
                        "reason": "listed for BY, RU, the counterparty is in EE",
                        "adjudicatedBy": "rules",
                        "programmes": [
                            "BLR"
                        ],
                        "countries": [
                            "BY",
                            "RU"
                        ],
                        "listedOn": "2023-02-25",
                        "sourceUrl": "https://eur-lex.europa.eu/",
                        "subject": "counterparty",
                        "foundVia": "name"
                    }
                ],
                "listsChecked": {
                    "OFAC_SDN": "2026-10-21",
                    "OFAC_CONS": "2026-10-21",
                    "US_CSL": "2026-10-21",
                    "EU": "2026-10-15",
                    "UK": "2026-10-16"
                },
                "listsUnavailable": [
                    "UN"
                ]
            }
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("rich_minds/counterparty-check-ai").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 = {
    "counterparties": [],
    "maxDiscoveryChargeUsd": 0.5,
    "sourceMode": "list",
    "itemsList": [
        {
            "name": "Northwind Industrial Supplies GmbH",
            "sample": True,
            "country": "DE",
            "vatNumber": "DE000000001",
            "website": "https://northwind-industrial.example",
            "sampleScreening": {
                "legalName": "Northwind Industrial Supplies GmbH",
                "lei": "529900SAMPLE00000001",
                "leiStatus": "ISSUED",
                "jurisdiction": "DE",
                "legalAddress": "Hafenstrasse 12, 20457, Hamburg, DE",
                "registrationNumber": "HRB 000001 (sample)",
                "leiChosenBy": "rules",
                "parents": [{
                        "relation": "direct",
                        "lei": "529900SAMPLE00000002",
                        "legalName": "Northwind Holding AG",
                        "verdict": "clear",
                    }],
                "vatNumber": "DE000000001",
                "vatValid": True,
                "vatName": "NORTHWIND INDUSTRIAL SUPPLIES GMBH",
                "vatAddress": "HAFENSTRASSE 12, 20457 HAMBURG",
                "vatNameMatches": True,
                "vatCheckedAt": "2026-10-23T08:00:00+00:00",
                "sanctionsHits": [],
                "listsChecked": {
                    "OFAC_SDN": "2026-10-21",
                    "OFAC_CONS": "2026-10-21",
                    "US_CSL": "2026-10-21",
                    "UN": "2026-10-21",
                    "EU": "2026-10-15",
                    "UK": "2026-10-16",
                },
            },
        },
        {
            "name": "Oceanic Vantage Shipping FZE",
            "sample": True,
            "country": "AE",
            "address": "Office 1407, Jebel Ali Free Zone, Dubai",
            "sampleScreening": {
                "parents": [],
                "sanctionsHits": [
                    {
                        "list": "OFAC_SDN",
                        "entryId": "OFAC_SDN-SAMPLE-1",
                        "matchedName": "OCEANIC VANTAGE SHIPPING FZE",
                        "entryName": "OCEANIC VANTAGE SHIPPING FZE",
                        "entryType": "company",
                        "score": 100,
                        "weakAlias": False,
                        "assessment": "likely",
                        "decidingFields": [
                            "name",
                            "country",
                            "address",
                        ],
                        "reason": "name 100/100 and country AE agree, address shares jebel, dubai",
                        "adjudicatedBy": "rules",
                        "programmes": ["IRAN-EO13846"],
                        "countries": ["AE"],
                        "listedOn": "2024-03-14",
                        "sourceUrl": "https://sanctionssearch.ofac.treas.gov/",
                        "subject": "counterparty",
                        "foundVia": "name",
                    },
                    {
                        "list": "UK",
                        "entryId": "UK-SAMPLE-2",
                        "matchedName": "Oceanic Vantage Shipping FZE",
                        "entryName": "Oceanic Vantage Shipping FZE",
                        "entryType": "company",
                        "score": 100,
                        "weakAlias": False,
                        "assessment": "likely",
                        "decidingFields": [
                            "name",
                            "country",
                        ],
                        "reason": "name 100/100 and country AE agree",
                        "adjudicatedBy": "rules",
                        "programmes": ["The Iran (Sanctions) Regulations 2023"],
                        "countries": [
                            "AE",
                            "IR",
                        ],
                        "listedOn": "2024-05-02",
                        "sourceUrl": "https://sanctionslist.fcdo.gov.uk/docs/UK-Sanctions-List.csv",
                        "subject": "counterparty",
                        "foundVia": "name",
                    },
                ],
                "listsChecked": {
                    "OFAC_SDN": "2026-10-21",
                    "OFAC_CONS": "2026-10-21",
                    "US_CSL": "2026-10-21",
                    "UN": "2026-10-21",
                    "EU": "2026-10-15",
                    "UK": "2026-10-16",
                },
            },
        },
        {
            "name": "Baltic Timber Export OU",
            "sample": True,
            "country": "EE",
            "vatNumber": "EE100000000",
            "sampleScreening": {
                "parents": [],
                "vatNumber": "EE100000000",
                "vatValid": False,
                "vatCheckedAt": "2026-10-23T08:00:00+00:00",
                "sanctionsHits": [{
                        "list": "EU",
                        "entryId": "EU-SAMPLE-3",
                        "matchedName": "Baltik Timber Export LLC",
                        "entryName": "Baltik Timber Export LLC",
                        "entryType": "company",
                        "score": 89,
                        "weakAlias": False,
                        "assessment": "unlikely",
                        "decidingFields": ["country"],
                        "reason": "listed for BY, RU, the counterparty is in EE",
                        "adjudicatedBy": "rules",
                        "programmes": ["BLR"],
                        "countries": [
                            "BY",
                            "RU",
                        ],
                        "listedOn": "2023-02-25",
                        "sourceUrl": "https://eur-lex.europa.eu/",
                        "subject": "counterparty",
                        "foundVia": "name",
                    }],
                "listsChecked": {
                    "OFAC_SDN": "2026-10-21",
                    "OFAC_CONS": "2026-10-21",
                    "US_CSL": "2026-10-21",
                    "EU": "2026-10-15",
                    "UK": "2026-10-16",
                },
                "listsUnavailable": ["UN"],
            },
        },
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("rich_minds/counterparty-check-ai").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 '{
  "counterparties": [],
  "maxDiscoveryChargeUsd": 0.5,
  "sourceMode": "list",
  "itemsList": [
    {
      "name": "Northwind Industrial Supplies GmbH",
      "sample": true,
      "country": "DE",
      "vatNumber": "DE000000001",
      "website": "https://northwind-industrial.example",
      "sampleScreening": {
        "legalName": "Northwind Industrial Supplies GmbH",
        "lei": "529900SAMPLE00000001",
        "leiStatus": "ISSUED",
        "jurisdiction": "DE",
        "legalAddress": "Hafenstrasse 12, 20457, Hamburg, DE",
        "registrationNumber": "HRB 000001 (sample)",
        "leiChosenBy": "rules",
        "parents": [
          {
            "relation": "direct",
            "lei": "529900SAMPLE00000002",
            "legalName": "Northwind Holding AG",
            "verdict": "clear"
          }
        ],
        "vatNumber": "DE000000001",
        "vatValid": true,
        "vatName": "NORTHWIND INDUSTRIAL SUPPLIES GMBH",
        "vatAddress": "HAFENSTRASSE 12, 20457 HAMBURG",
        "vatNameMatches": true,
        "vatCheckedAt": "2026-10-23T08:00:00+00:00",
        "sanctionsHits": [],
        "listsChecked": {
          "OFAC_SDN": "2026-10-21",
          "OFAC_CONS": "2026-10-21",
          "US_CSL": "2026-10-21",
          "UN": "2026-10-21",
          "EU": "2026-10-15",
          "UK": "2026-10-16"
        }
      }
    },
    {
      "name": "Oceanic Vantage Shipping FZE",
      "sample": true,
      "country": "AE",
      "address": "Office 1407, Jebel Ali Free Zone, Dubai",
      "sampleScreening": {
        "parents": [],
        "sanctionsHits": [
          {
            "list": "OFAC_SDN",
            "entryId": "OFAC_SDN-SAMPLE-1",
            "matchedName": "OCEANIC VANTAGE SHIPPING FZE",
            "entryName": "OCEANIC VANTAGE SHIPPING FZE",
            "entryType": "company",
            "score": 100,
            "weakAlias": false,
            "assessment": "likely",
            "decidingFields": [
              "name",
              "country",
              "address"
            ],
            "reason": "name 100/100 and country AE agree, address shares jebel, dubai",
            "adjudicatedBy": "rules",
            "programmes": [
              "IRAN-EO13846"
            ],
            "countries": [
              "AE"
            ],
            "listedOn": "2024-03-14",
            "sourceUrl": "https://sanctionssearch.ofac.treas.gov/",
            "subject": "counterparty",
            "foundVia": "name"
          },
          {
            "list": "UK",
            "entryId": "UK-SAMPLE-2",
            "matchedName": "Oceanic Vantage Shipping FZE",
            "entryName": "Oceanic Vantage Shipping FZE",
            "entryType": "company",
            "score": 100,
            "weakAlias": false,
            "assessment": "likely",
            "decidingFields": [
              "name",
              "country"
            ],
            "reason": "name 100/100 and country AE agree",
            "adjudicatedBy": "rules",
            "programmes": [
              "The Iran (Sanctions) Regulations 2023"
            ],
            "countries": [
              "AE",
              "IR"
            ],
            "listedOn": "2024-05-02",
            "sourceUrl": "https://sanctionslist.fcdo.gov.uk/docs/UK-Sanctions-List.csv",
            "subject": "counterparty",
            "foundVia": "name"
          }
        ],
        "listsChecked": {
          "OFAC_SDN": "2026-10-21",
          "OFAC_CONS": "2026-10-21",
          "US_CSL": "2026-10-21",
          "UN": "2026-10-21",
          "EU": "2026-10-15",
          "UK": "2026-10-16"
        }
      }
    },
    {
      "name": "Baltic Timber Export OU",
      "sample": true,
      "country": "EE",
      "vatNumber": "EE100000000",
      "sampleScreening": {
        "parents": [],
        "vatNumber": "EE100000000",
        "vatValid": false,
        "vatCheckedAt": "2026-10-23T08:00:00+00:00",
        "sanctionsHits": [
          {
            "list": "EU",
            "entryId": "EU-SAMPLE-3",
            "matchedName": "Baltik Timber Export LLC",
            "entryName": "Baltik Timber Export LLC",
            "entryType": "company",
            "score": 89,
            "weakAlias": false,
            "assessment": "unlikely",
            "decidingFields": [
              "country"
            ],
            "reason": "listed for BY, RU, the counterparty is in EE",
            "adjudicatedBy": "rules",
            "programmes": [
              "BLR"
            ],
            "countries": [
              "BY",
              "RU"
            ],
            "listedOn": "2023-02-25",
            "sourceUrl": "https://eur-lex.europa.eu/",
            "subject": "counterparty",
            "foundVia": "name"
          }
        ],
        "listsChecked": {
          "OFAC_SDN": "2026-10-21",
          "OFAC_CONS": "2026-10-21",
          "US_CSL": "2026-10-21",
          "EU": "2026-10-15",
          "UK": "2026-10-16"
        },
        "listsUnavailable": [
          "UN"
        ]
      }
    }
  ]
}' |
apify call rich_minds/counterparty-check-ai --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rich_minds/counterparty-check-ai"
        }
    }
}
```

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/85Bcw37sZhsDF4ZrK/builds/DyNjU4ZpzbLYXtDlF/openapi.json
