Documentation · Screening API

The request

How to describe the parties you screen, where the matcher looks for them, and which parameters narrow and tune the result.

A match request describes the parties you want to check, says which collection to look in, and optionally narrows the candidates and tunes the scoring. You can try every element on Screening.

An example request

Three parties in one request: a person with names in two scripts, a company with its country, and a vessel with its IMO number. The query string keeps only sanctions listings, leaves out one register and asks for a stricter threshold.

curl -X POST "https://api.crownintelligence.net/api/match/default?limit=3&threshold=0.8&topics=sanction&exclude_dataset=Wikidata%20PEPs" \
  -H "Content-Type: application/json" \
  -d '{"queries":{"person":{"schema":"Person","properties":{"name":["Igor Putin","Игорь Путин"],"birthDate":["1953-03-30"],"nationality":["ru"]}},"company":{"schema":"Company","properties":{"name":["Rosneft"],"country":["ru"]}},"vessel":{"schema":"Vessel","properties":{"name":["Example Star"],"imoNumber":["9000000"]}}}}'
import requests

BASE = "https://api.crownintelligence.net"
PARAMS = {
    "limit": 3,
    "threshold": 0.8,           # stricter than the 0.75 default
    "algorithm": "standard",
    "topics": ["sanction"],     # sanctions listings only
    "exclude_dataset": ["Wikidata PEPs"],
}
PERSON = {"schema": "Person", "properties": {"name": ["Igor Putin", "Игорь Путин"], "birthDate": ["1953-03-30"], "nationality": ["ru"]}}
COMPANY = {"schema": "Company", "properties": {"name": ["Rosneft"], "country": ["ru"]}}
VESSEL = {"schema": "Vessel", "properties": {"name": ["Example Star"], "imoNumber": ["9000000"]}}

r = requests.post(f"{BASE}/api/match/default", params=PARAMS,
                  json={"queries": {"person": PERSON, "company": COMPANY, "vessel": VESSEL}}, timeout=90)
r.raise_for_status()
for key, answer in r.json()["responses"].items():
    best = answer["results"][0] if answer["results"] else None
    print(key, answer["status"], best and (best["score"], best["caption"], best["datasets"]))
const BASE = "https://api.crownintelligence.net";
const params = new URLSearchParams({ limit: "3", threshold: "0.8", algorithm: "standard" });
params.append("topics", "sanction");
params.append("exclude_dataset", "Wikidata PEPs");

const queries = {
  person: { schema: "Person", properties: { name: ["Igor Putin", "Игорь Путин"], birthDate: ["1953-03-30"], nationality: ["ru"] } },
  company: { schema: "Company", properties: { name: ["Rosneft"], country: ["ru"] } },
  vessel: { schema: "Vessel", properties: { name: ["Example Star"], imoNumber: ["9000000"] } },
};
const res = await fetch(`${BASE}/api/match/default?${params}`, {
  method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ queries }),
});
const data = await res.json();
for (const [key, answer] of Object.entries(data.responses)) console.log(key, answer.status, answer.results[0]?.caption);

Scoping: where the matcher looks

Matching runs in two stages. First the service gathers candidates from the collection: records that contain every word of the query name, then, if there are fewer than 50, records that share any name word, start with the query name, or carry the IMO number. Then each candidate is scored against the full query and the best are returned. Scoping and filters act on the first stage, so they decide which records can be scored at all.

The collection

The collection is part of the path and is required: /api/match/default, /api/match/sanctions, /api/match/peps, /api/match/crime or /api/match/maritime. An unknown name returns 404 with the list of collections.

CollectionContentsRecordsRegisters
defaultEvery active record: sanctions, PEPs, debarment, enforcement and other risk lists——
sanctionsSanctions listings only——
pepsPolitically exposed persons——
crimeDebarment, tax warrants and insolvency notices——
maritimeVessels, and records that carry an IMO number——

Figures are from the current build (/api/catalog). A single register cannot be used as the path; use include_dataset instead.

Filtering

Filters are query-string parameters and can be repeated. Several values of the same filter are combined with OR; different filters are combined with AND. So ?topics=sanction&topics=debarment&exclude_dataset=US%20CSL means "sanctions or debarment listings, but not from the US CSL register". The filters you applied are echoed back in filters.

Filtering on topics

topics accepts sanction, role.pep, debarment and reg.action (also as a comma-separated list). Topics are currently derived from the kind of list a record comes from; see Risk topics. An unknown topic returns 400 with the accepted values.

Filtering on registers

include_dataset keeps only records from the named registers; exclude_dataset removes them. Use the register names shown by Sources, /api/sources and the datasets field of each result, for example include_dataset=UK%20OFSI. Names must be exact; an unknown name simply matches nothing.

The query

The body holds up to 20 named queries under queries. Name them after your own customer or row IDs so you can join the answers back. A single query without the queries wrapper is also accepted and answered as q1.

{"schema": "Company", "properties": {"name": ["Example Trading LLC"], "country": ["ae"]}}

The schema

schema says what kind of party you are describing: Person, Company, Organization, Vessel, Airplane or LegalEntity (any kind). It is optional and defaults to LegalEntity. A record of a clearly different type (a vessel when you asked for a person) loses 0.20; records whose type is unknown are not penalised. Use the most specific type you know.

The properties

Properties are lists of strings, up to five values each. These are the ones the matcher reads; anything else is ignored. The query echoed in the response shows exactly what was read, which is the quickest way to spot a misspelled property.

PropertyAlso accepted asFormat and use
namequeryNames and aliases. Required unless an IMO number is given. Any script; accents are ignored.
birthDatedobYYYY, YYYY-MM or YYYY-MM-DD. Partial dates are compared at the precision you give.
nationalitycountry, countries, jurisdiction, flagTwo-letter ISO 3166 codes, any case. A person's nationality, a company's jurisdiction or a vessel's flag.
imoNumberimoSeven-digit IMO number. Non-digits are stripped.

Person

Give the full name as one string (given names and family name); split name parts are not read separately. Add the birth date, even just the year, and nationality: each agreeing value raises the score and each conflicting one lowers it.

Company and Organization

Give the registered name and any trading names, and the country of registration. Registration, tax and LEI numbers are not scored yet, so include them in your own records for review but do not rely on them here.

Vessel

The IMO number is the strongest evidence: an agreeing number lifts the score to at least 0.98, a different one takes 0.30 off. Use flag for the flag state. See Maritime for coverage.

Tuning parameters and defaults

ParameterDefaultMeaning
limit5Results per query, 1 to 50.
threshold0.75Score from which match is true, 0 to 1. Results below it are still returned.
algorithmstandardstandard or name-only; best is accepted as the current default. See Tuning.
topics, include_dataset, exclude_datasetnoneCandidate filters, above.
changed_sincenoneISO 8601 date or time: only records added or changed since then. For scheduled re-screening; see Monitoring.

Read more: The response, Model reference, Tuning the matcher.

Last updated 2026-10-03