AML, PEP and background screening
Screen a person or a company for sanctions, public office and negative news, with the same API key you use for every other IdentifyOrg service. Pick only the checks you need, send only the details each one needs, and pay per check. Test keys return sample results for free, so you can build the whole flow before you spend anything.
The checks
| AML compliance screening POST /v1/screening/aml | A person or company against the UN, US OFAC, EU and UK sanctions lists. Reference |
| PEP screening POST /v1/screening/pep | Whether a person holds or held a public office, with positions and dates. Reference |
| Adverse media POST /v1/screening/adverse-media | Negative news stories from the past several years, sorted by type and severity. Reference |
| Background check POST /v1/screening/background-check | AML, PEP and adverse media together, one overall result, one lower price. Reference |
| Employee background check POST /v1/screening/requests | Check an employee, applicant, tenant or partner with their consent (a private link) or discreetly with a stated lawful basis. Leads with source links for a person to review. Reference |
| Business (KYB) screening POST /v1/screening/kyb | A company: register entry, sanctions, news, and (optionally) its directors. Reference |
| List status GET /v1/screening/lists | Free. The sanctions lists we screen against and when each was last updated. Reference |
Prices are on the pricing page. The background check costs less than its three checks separately. A check is charged only when its sources answered, and refunded in full when they could not.
Quick start
Use a secret key (io_test_sk_... to test, io_live_sk_... for real checks), on your server.
curl -X POST https://api.identifyorg.com/v1/screening/aml \
-H "X-IdentifyOrg-Key: io_test_sk_..." \
-H "Content-Type: application/json" \
-d '{"name": "Amina Bello", "birth_year": 1980, "country": "NG"}'import { IdentifyOrg } from "@identifyorg/node-sdk";
const io = new IdentifyOrg({ apiKey: process.env.IDENTIFYORG_KEY });
// Pick the checks you need...
const aml = await io.screening.aml({ name: "Amina Bello", birth_year: 1980, country: "NG" });
const pep = await io.screening.pep({ name: "Amina Bello", birth_year: 1980 });
// ...or run all three person checks for one lower price
const bg = await io.screening.backgroundCheck({ name: "Amina Bello", birth_year: 1980 });
if (bg.overall !== "clear") sendToCompliance(bg);
// A company, its register entry and its directors
const kyb = await io.screening.kyb({ company_name: "Sample Trading Ltd", country: "GB", registration_number: "01234567", include_officers: true });from identifyorg import IdentifyOrg
io = IdentifyOrg(api_key="io_test_sk_...")
aml = io.screen_aml("Amina Bello", birth_year=1980, country="NG")
pep = io.screen_pep("Amina Bello", birth_year=1980)
media = io.screen_adverse_media("Amina Bello", context="Lagos fintech founder")
bg = io.background_check("Amina Bello", birth_year=1980) # all three, one price
kyb = io.screen_business("Sample Trading Ltd", country="GB", registration_number="01234567", include_officers=True)aml, err := client.ScreenAML(map[string]any{"name": "Amina Bello", "birth_year": 1980, "country": "NG"})
bg, err := client.BackgroundCheck(map[string]any{"name": "Amina Bello", "birth_year": 1980})
kyb, err := client.ScreenBusiness(map[string]any{"company_name": "Sample Trading Ltd", "country": "GB", "registration_number": "01234567", "include_officers": true})$aml = $io->screenAml('Amina Bello', 'person', 1980, 'NG');
$pep = $io->screenPep('Amina Bello', 1980);
$bg = $io->backgroundCheck('Amina Bello', 1980);
$kyb = $io->screenBusiness('Sample Trading Ltd', 'GB', '01234567', true);Prefer no code? Open AML & background screening in your dashboard: choose the checks, enter the details and read the results.
Long checks: run them in the background
Most checks answer in a second or two. The news and business checks can take longer, so any screening call also accepts ?mode=async. It answers at once with a job id, the check runs in the background, and you read its progress and result (or receive it by webhook) when it is ready. Your server never holds a connection open waiting.
# 1. Start it: you get an id straight away
curl -X POST "https://api.identifyorg.com/v1/screening/background-check?mode=async" \
-H "X-IdentifyOrg-Key: io_test_sk_..." -H "Content-Type: application/json" \
-d '{"name": "Amina Bello", "birth_year": 1980}'
# -> 202 {"id": "scj_8f2c...", "status": "queued", "poll_after_ms": 1500, ...}
# 2. Read progress and the result
curl https://api.identifyorg.com/v1/screening/jobs/scj_8f2c... -H "X-IdentifyOrg-Key: io_test_sk_..."
# -> {"status": "running", "progress": [{"step": "Sanctions lists", "state": "done"}, ...]}
# -> {"status": "done", "result": { ...the same answer a direct call returns... }}Billing is the same: you are charged when the check completes, a failed check costs nothing, and results are kept for seven days. You can have up to 10 checks active at once. See the jobs endpoint and the webhook events screening.completed and screening.failed.
Employee background check
To check an employee, a job applicant, a tenant or a partner, use POST /v1/screening/requests. By default the person receives a private link and nothing is checked or charged until they agree. If you have a lawful basis to check without asking (for example a legal duty), send mode: "discreet" with your basis; it is recorded. You get leads, each with a link to where it came from. You open them, decide whether each is about the right person, and record that with POST /v1/screening/requests/{id}/decisions. Results are leads for human review, never a verdict, and criminal records are not searched. Reports are deleted after 90 days. Prefer no code? Use Employee background check in your dashboard.
What to send
- name: a person's full name as on their ID (at least two words), or a company's registered name. A single name gives too many false matches, so people need two or more words.
- birth_year and country: optional, but send them whenever you have them. Many people share a name, and a matching birth year confirms a match while a different one lowers it.
- type:
person(default) orentityfor sanctions and news checks on a company. - context (adverse media): a few words such as "Lagos fintech founder" to help tell the subject from a namesake.
- countries (adverse media, background check, KYB): the countries whose news to search, as two-letter codes such as
["NG", "GH"]. Leave it out to search all countries. Use this when you know where the person has lived or worked, or search every country to see whether they have been in trouble anywhere.GET /v1/screening/countrieslists what is available. - company_name, country, registration_number, include_officers (KYB).
Reading the result
resulton a single check isclear,possible_matchormatch(adverse media:clear,possibleoradverse_found).overallon the background check and KYB isclear,possible_findings,review_requiredorincomplete. Open the check that has findings to see why. If the news search is temporarily unavailable, you still get the other checks:partialis true,adverse_media.resultisunavailable, the news part is not charged, andoverallisincompletewhen nothing was found. Run the news check again later on its own.- Every sanctions finding carries its score (0 to 100), the alias it matched, the list's own reference, the programme, the date listed, and a link to the publisher.
lists_checkedshows when each list was published and when we last updated it. Keep it with your records as evidence of how current the check was;GET /v1/screening/listsshows the same at any time.- A match is a prompt for a person to confirm, not a verdict. Clear means nothing was found by these checks, not that the person is cleared of everything.
Coverage
Each check is clear about what it covers and what it does not. This is not a criminal-records or credit check.
| Sanctions | The UN Security Council, US Treasury (OFAC), European Union and United Kingdom sanctions lists, updated every day. Each result shows the date. |
| PEP | Prominent public office-holders with a public record: heads of state and government, ministers, legislators, governors, judges, diplomats and senior officers. Not every local official, and not relatives or close associates. |
| Adverse media | News from major African and international outlets, collected continuously and going back up to ten years where outlets keep their archives online. Print-only publications, paywalled reports and social media are not covered. |
| Company register (KYB) | Official registers for Nigeria, the UK, US listed companies, Norway, Czechia and France. Directors where the register publishes them (UK, Norway, France). |
Test mode
Test keys never contact a list or a news source and are never charged. They return the real response shape with sample data. Put one of these phrases anywhere in the name (case does not matter):
| sample sanctioned | AML: a strong match on a made-up listing |
| sample possible | AML: a possible match that needs a person to look |
| sample pep | PEP: a current office-holder with a position and dates |
| sample adverse | Adverse media: a confirmed sample headline |
| sample outage | Any check: the source did not answer (a 502 that is never charged) |
| sample newsdown | Only the news search is down: a single news check is a 502; a bundle returns the rest with the news part unavailable |
| anything else | Clear |
For KYB, send country GB with registration number 01234567 and include_officers: true to see a sample register entry and two sample directors.
Using it responsibly
- Screening results are an aid to your own due diligence, not a legal determination. Your compliance team or regulator decides what is required of you and what to do with a match.
- Names are personal data. Screen only people you have a lawful reason to screen, tell them you do, and keep results no longer than you need.
- We do not store the details you send beyond the record of the check (type, outcome, time and cost).
Finding this hard to integrate?
Open a ticket and our technical team will help you get it working. We reply by email. Or WhatsApp or call +234 913 995 7618.

