# Sanctions Screening API - sanctions.io PEP, Watchlist, Media (`nabeelbaghoor/sanctions-io-screening-api`) Actor

Sanctions, PEP, criminal watchlist and adverse media screening with the sanctions.io API: screen people, companies, vessels and aircraft against OFAC, UN, EU, UK and 40+ lists, read batch screening matches and monitoring alerts, and list watchlist sources. Bring your own key.

- **URL**: https://apify.com/nabeelbaghoor/sanctions-io-screening-api.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** Business, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 screening match returneds

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

## Sanctions Screening API - sanctions.io PEP, Watchlist, Media

Screen people, companies, vessels and aircraft against global sanctions lists, politically exposed persons (PEPs), criminal watchlists and adverse media through the sanctions.io API with your own token, and get every match as a clean dataset row.

Works with the sanctions.io API (api-docs.sanctions.io) on api.sanctions.io: GET /search/ to screen a name, GET /search/media/ for adverse media, GET /search/batch/ and /search/batch-result/ for batch screening results, GET /monitoring/ for ongoing monitoring entries and alerts, and GET /sources/ for the watchlists and their short codes. Each match becomes one row with the matched name, entity type, confidence score, list (OFAC SDN, EU CFSP, UK Sanctions, UN, BIS Entity List, Interpol and many more), sanctions programs, aliases, countries, nationalities, birth dates, identifiers and remarks, plus the full sanctions.io record. Download as JSON, CSV or Excel, schedule it, or feed it into a KYC, KYB, onboarding or vendor due diligence workflow or an AI agent. Bring your own API key.

BYOK, not live-tested: every route, query parameter and response field comes from the sanctions.io API reference, and every route was confirmed to exist on api.sanctions.io (it answers an invalid token with 401, while an invented path answers 404), but the actor has not been run against a live sanctions.io account.

### What it does

- **Screen names**: one sanctions.io real-time screening per name against the collections you choose (all sanctions lists, PEP, criminal watchlists, high risk jurisdictions) and any individual lists by short code. Tune it with entity type, country, date or year of birth, an identifier (passport, tax ID, IMO number, wallet address and more), the minimum score and the boosting thresholds. One row per match with its confidence score.
- **Adverse media**: news articles about each name, filtered by 24 risk topics (fraud, corruption, money laundering related financial crime, sanctions, terrorism financing and more), news country, language, subject type, minimum score and publication dates.
- **Batch screening results**: every match of every name in a batch screening you ran in sanctions.io (up to 10,000 names a batch), tagged with your external identifier. Names with no match are listed too, free.
- **Monitoring alerts**: every alert a monitoring entry raised, with its review status (New, False Positive, Real Positive) and the matched watchlist record.
- **Monitoring entries**: your monitored names with their new, false positive and real positive counters, filtered by alert or review status.
- **Batch screenings list** and **Watchlist data sources**: your batches with their status, and every list with the short code to use in screening.
- **Read only**: no route that creates a batch, adds or deletes a monitoring entry, resolves an alert, or changes tokens, users or webhooks is called.
- **Pay only for results**: a name with no matches, or a lookup that returns nothing, gives one free row that says why.

### Important: each screened name counts on your plan

Screen and Adverse media modes call GET /search/ or GET /search/media/ once per name, and sanctions.io counts each one as a screening under your own sanctions.io plan, which sanctions.io bills separately. Screening the same list twice uses twice the screenings. Results come 25 to a page and each further page is one more API call, so keep Matches per name at 25 unless you need more. The run stops starting new screenings once `maxResults` rows are reached. Every other mode only reads your account.

### How to get an API key

sanctions.io sells plans with API access (see the pricing calculator on sanctions.io; a free trial signs up at app.sanctions.io/signup). Sign in to the sanctions.io portal, open Settings, API and Webhooks, and copy a Live API token (your default token is created with the account). Paste it into the API key field, or set the DATA_API_KEY secret. The token is sent only to api.sanctions.io in the Authorization header as `Bearer <token>` (never as a URL parameter) and is never logged. Sandbox tokens only reach the sanctions.io test dataset. Adverse media needs a plan that includes it, and monitoring must be switched on by sanctions.io support. A missing or rejected token ends the run cleanly with a status message.

### Input

| Field | Modes | Description |
| --- | --- | --- |
| `mode` | all | `screen`, `adverseMedia`, `batchResults`, `monitoringAlerts`, `monitoringEntries`, `batchList` or `dataSources` |
| `names` | screen, adverse media | Names, one per line (up to 1,000 a run, 15 words each) |
| `collections` | screen | SANCTIONS-LISTS, PEP, CRIME, HIGH-RISK-JURISDICTIONS |
| `sourceCodes` | screen | Individual list short codes such as SDN, CFSP or UK-SANCTIONS |
| `minScore` | screen | 0.8 to 1, default 0.88 |
| `entityType` | screen | individual, entity, vessel or aircraft |
| `country` | screen | One ISO alpha-2 code |
| `dateOfBirth`, `yearOfBirth` | screen | Birth date YYYY-MM-DD or year, for individuals |
| `identifier` | screen | One identifier, with one name |
| `nameBoostThreshold`, `identifierBoostThreshold` | screen | 0.7 to 1 |
| `matchesPerName` | screen | Matches read per name, default 25 |
| `mediaKeywords` | adverse media | Risk topics such as Fraud, Corruption, Sanctions |
| `mediaCountries`, `mediaLanguages` | adverse media | News countries (ISO alpha-2) and languages (ISO 639-1) |
| `mediaEntityType`, `precise`, `mediaMinScore` | adverse media | Individual or Entity, strict matching, 0.65 to 1 |
| `publishedFrom`, `publishedTo` | adverse media | Publication date range |
| `articlesPerName` | adverse media | Articles read per name, default 25 |
| `batchIds` | batch results | Batch screening IDs |
| `batchProcessed`, `batchFrom`, `batchTo` | batch list | Status and created date range |
| `monitoringIds` | monitoring alerts | Monitoring entry IDs |
| `monitoringFilter`, `monitoringSearch`, `showInactive` | monitoring entries | Alert or review status filter, free text, deleted entries |
| `maxResults` | all | Row ceiling for the run (default 100) |
| `requestsPerMinute` | all | Pacing, default 60 |
| `apiKey` | all | Your sanctions.io API token (or the DATA_API_KEY secret) |

An input set for a mode that does not take it is left off with a warning, never sent.

Example: screen two companies against OFAC and EU lists plus all PEPs.

```json
{
    "mode": "screen",
    "names": ["Acme Trading Ltd", "Northwind Shipping LLC"],
    "collections": ["PEP"],
    "sourceCodes": ["SDN", "NONSDN", "CFSP"],
    "entityType": "entity",
    "minScore": 0.9,
    "maxResults": 50
}
```

### Example output

An illustrative screening match, shaped like the documented GET /search/ response (values are the reference's fictional sandbox example). The full match is kept under `record`.

```json
{
    "mode": "screen",
    "recordType": "match",
    "found": true,
    "input": "Pied Piper Inc.",
    "externalIdentifier": null,
    "matchName": "Pied Piper Inc.",
    "entityType": "Entity",
    "confidenceScore": 1,
    "dataSource": "FSL",
    "dataSourceName": "Fictional Sanctions List",
    "programs": null,
    "altNames": "PiedPiper Systems; PP Inc.",
    "countries": "US",
    "nationalities": "US",
    "datesOfBirth": null,
    "identifiers": null,
    "remarks": "Tech firm facilitating distributed hosting of sanctioned content",
    "siIdentifier": "FSL-NONE-005",
    "sourceListUrl": null,
    "lastUpdate": "2025-06-16T15:42:29.381766+00:00",
    "alertStatus": null,
    "articleTitle": null,
    "articleUrl": null,
    "publishedAt": null,
    "mediaSource": null,
    "keywords": null,
    "language": null,
    "batchId": null,
    "processed": null,
    "resultsCount": null,
    "monitoringEntryId": null,
    "newMatches": null,
    "falsePositives": null,
    "realPositives": null,
    "monitoringStatus": null,
    "searchId": "689ed2fe-50d7-44bc-bdb5-0fd12b4e997b",
    "timestamp": "2026-03-23T22:34:27.121297+00:00",
    "note": null,
    "record": { "name": "Pied Piper Inc.", "confidence_score": 1.0, "data_source": { "short_name": "FSL" }, "si_identifier": "FSL-NONE-005" }
}
```

### FAQ

#### What is the sanctions.io API?

sanctions.io (sanctions.io Inc., Delaware) is an AML compliance screening service. Its REST API screens names against global sanctions lists (OFAC SDN and non-SDN lists, UN, EU, UK, Australia, Canada, France and more), BIS export control lists, a global politically exposed persons database, criminal watchlists such as FBI Most Wanted and Interpol Red Notices, high risk jurisdiction lists and an indexed adverse media dataset. sanctions.io updates its lists every 60 minutes.

#### Do I need my own sanctions.io API key?

Yes. This is a bring-your-own-key actor: it calls sanctions.io with your token, under your plan and its terms. A missing or rejected token ends the run cleanly with a status message, and nothing is charged.

#### Does screening use my sanctions.io screenings?

Yes. Each name in Screen or Adverse media mode is one screening on your sanctions.io plan, and each further page of results is one more API call. Reading batch results, monitoring entries and alerts, batches and sources does not screen anything.

#### How do I reduce false positives?

Set the entity type, add a country and, for people, a date or year of birth, raise the minimum score toward 0.93, and avoid a low name boosting threshold. Screen against the lists you need rather than every collection.

#### Can I screen vessels, aircraft or crypto wallets?

Yes. Set the entity type to vessel or aircraft, and put an IMO number, aircraft registration or wallet address in the identifier field with one name.

#### Can I run a batch of 10,000 names?

Create the batch screening in sanctions.io (its portal or batch API), then run Batch screening results with the batch ID. This actor reads the results; it does not create batches. sanctions.io deletes batches after 30 days.

#### Does this actor resolve monitoring alerts?

No. It reads monitoring entries and their alerts with review status, but never marks an alert as a false or real positive, and never adds or removes monitoring entries.

#### What do I pay?

Pay per result: 0.02 USD per screening match (from Screen, Batch screening results or Monitoring alerts), 0.01 USD per adverse media article and 0.005 USD per watchlist source, batch summary or monitoring entry. Names with no matches and lookups that return nothing are never charged. Your sanctions.io plan is billed separately by sanctions.io.

### Pricing

| Event | Price | Charged for |
| --- | --- | --- |
| `screening-match` | 0.02 USD | Each sanctions, PEP or watchlist match, from Screen, Batch screening results or Monitoring alerts |
| `adverse-media-article` | 0.01 USD | Each adverse media article |
| `account-record` | 0.005 USD | Each watchlist source, batch screening summary or monitoring entry |

### Keyword map

sanctions screening API, sanctions.io API, PEP screening API, AML screening, watchlist screening, OFAC SDN check, EU sanctions check, UK sanctions list check, adverse media screening, negative news screening, KYC screening, KYB screening, vendor due diligence, vessel sanctions screening, crypto wallet sanctions check, batch sanctions screening, ongoing sanctions monitoring, Interpol red notice check, AML compliance automation, sanctions data for AI agents.

### Terms and data use

sanctions.io data is provided under your agreement with sanctions.io Inc. (its Terms and Conditions, last updated April 25, 2022, plus your plan). Section 2 makes the site content available for your own use and forbids copying, reproducing, aggregating, republishing, distributing, selling or licensing it for any commercial purpose without written permission. Section 9 forbids systematically retrieving data to build a collection or database without written permission, and using the service to compete with sanctions.io or for any revenue-generating endeavour it has not approved. Section 8 licenses its software to you personally and non-transferably. The terms set no limit on how long you keep your own screening results. Run this actor with your own token, screen your own customers, vendors and counterparties, keep the results for your own compliance records, and do not resell, republish or pool them into a list of your own. This actor is not affiliated with or endorsed by sanctions.io.

# Actor input Schema

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

Screen runs one sanctions.io screening per name against the sanctions, PEP and criminal watchlists you pick and returns one row per match; each name counts as a screening on your sanctions.io plan. Adverse media returns news articles about each name. The other modes only read your account: batch screening results, monitoring alerts, monitoring entries, the batch screenings list and the watchlist sources with their short codes.

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

Screen and Adverse media. One person, company, vessel or aircraft name per line (at most 15 words each, up to 1,000 per run). Use the full legal or registered name when you have it.

## `collections` (type: `array`):

Screen only. Groups of lists to screen against: all sanctions lists, the global PEP database, criminal watchlists (FBI, Interpol) and high risk jurisdiction lists. Combine with source codes below, or use source codes alone.

## `sourceCodes` (type: `array`):

Screen only. Individual watchlists by short code, such as SDN, NONSDN, CFSP, UK-SANCTIONS, EL or DPL. The Watchlist data sources mode lists every code. At least one collection or code is required.

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

Screen only. The lowest confidence score (0.8 to 1) a match needs to be returned. sanctions.io recommends 0.88 as a balanced start and 0.93 for stricter matching.

## `entityType` (type: `string`):

Screen only. Individual, entity (organisation), vessel or aircraft. sanctions.io strongly recommends setting it: it targets the right lists and decides which attributes apply.

## `country` (type: `string`):

Screen only. One ISO 3166-1 alpha-2 code, such as US or RU: nationality or residence for people, incorporation or operating country for organisations. Cuts false positives.

## `dateOfBirth` (type: `string`):

Screen only, individuals. YYYY-MM-DD. Strongly recommended for PEP screening.

## `yearOfBirth` (type: `integer`):

Screen only, individuals. Four digit year of birth, when the full date is not known.

## `identifier` (type: `string`):

Screen only, with one name. A passport, national ID, tax ID, email, company domain, SWIFT code, IMO number, aircraft registration or wallet address (at most 120 characters), searched alongside the name.

## `nameBoostThreshold` (type: `number`):

Screen only. When the name match score reaches this value, it replaces the overall score. sanctions.io recommends 0.93 to 0.95; lower values raise false positives. Leave empty to turn it off.

## `identifierBoostThreshold` (type: `number`):

Screen only, with an identifier. When the identifier match score reaches this value, it replaces the overall score. Leave empty to turn it off.

## `matchesPerName` (type: `integer`):

Screen only. The most matches read for each name. sanctions.io returns 25 per page and each further page is one more API call.

## `mediaKeywords` (type: `array`):

Adverse media only. Keep articles on these risk topics. Leave empty for every topic.

## `mediaCountries` (type: `array`):

Adverse media only. ISO 3166-1 alpha-2 codes of the countries the news comes from, such as US or BR.

## `mediaLanguages` (type: `array`):

Adverse media only. Two letter ISO 639-1 language codes, such as en or pt.

## `mediaEntityType` (type: `string`):

Adverse media only. Restrict the search to an individual or an entity.

## `precise` (type: `boolean`):

Adverse media only. Stricter name matching, for fewer but closer articles.

## `mediaMinScore` (type: `number`):

Adverse media only. The lowest confidence score (0.65 to 1) an article needs. Leave empty for the sanctions.io default of 0.8.

## `publishedFrom` (type: `string`):

Adverse media only. Articles published on or after this date, YYYY-MM-DD.

## `publishedTo` (type: `string`):

Adverse media only. Articles published on or before this date, YYYY-MM-DD.

## `articlesPerName` (type: `integer`):

Adverse media only. The most articles read for each name, up to 100 per API call.

## `batchIds` (type: `array`):

Batch screening results only. IDs of batch screenings in your account (the Batch screenings list mode gives them). sanctions.io keeps batches for 30 days.

## `batchProcessed` (type: `string`):

Batch screenings list only. All batches, only finished ones, or only those still processing.

## `batchFrom` (type: `string`):

Batch screenings list only. Batches created on or after this date, YYYY-MM-DD.

## `batchTo` (type: `string`):

Batch screenings list only. Batches created before this date, YYYY-MM-DD.

## `monitoringIds` (type: `array`):

Monitoring alerts only. IDs of monitoring entries (the Monitoring entries mode gives them). Each alert raised for the entry becomes one row with its review status.

## `monitoringFilter` (type: `string`):

Monitoring entries only. All entries, or only those with alerts, without alerts, with new unreviewed matches, with dismissed false positives or with confirmed real positives.

## `monitoringSearch` (type: `string`):

Monitoring entries only. Free text search across entry names and external identifiers.

## `showInactive` (type: `boolean`):

Monitoring entries only. Also list inactive (deleted) monitoring entries.

## `maxResults` (type: `integer`):

The most rows this run returns. In Screen and Adverse media modes the run stops starting new screenings once it is reached, so no screening is wasted.

## `requestsPerMinute` (type: `integer`):

Pacing. A rate limit answer is waited out and retried.

## `apiKey` (type: `string`):

Your own sanctions.io API token, from Settings, API and Webhooks in the sanctions.io portal. Stored as a secret, sent only to api.sanctions.io in the Authorization header as a Bearer token, and never logged. You can instead set the DATA_API_KEY environment secret.

## Actor input object example

```json
{
  "mode": "screen",
  "names": [
    "Pied Piper Inc."
  ],
  "collections": [
    "SANCTIONS-LISTS",
    "PEP",
    "CRIME"
  ],
  "minScore": 0.88,
  "matchesPerName": 25,
  "precise": false,
  "articlesPerName": 25,
  "batchProcessed": "any",
  "monitoringFilter": "all",
  "showInactive": false,
  "maxResults": 20,
  "requestsPerMinute": 60
}
```

# Actor output Schema

## `records` (type: `string`):

One row per match, article, alert, entry, batch or source for the chosen mode.

# 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": [
        "Pied Piper Inc."
    ],
    "collections": [
        "SANCTIONS-LISTS",
        "PEP",
        "CRIME"
    ],
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/sanctions-io-screening-api").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": ["Pied Piper Inc."],
    "collections": [
        "SANCTIONS-LISTS",
        "PEP",
        "CRIME",
    ],
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/sanctions-io-screening-api").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 '{
  "names": [
    "Pied Piper Inc."
  ],
  "collections": [
    "SANCTIONS-LISTS",
    "PEP",
    "CRIME"
  ],
  "maxResults": 20
}' |
apify call nabeelbaghoor/sanctions-io-screening-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/sanctions-io-screening-api"
        }
    }
}
```

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/H9peY9UYr3TuHeSkw/builds/FuXLePZifKZDk3krX/openapi.json
