Developers
API reference
The public endpoints behind Screening, Search, Sources and the collection pages — the same ones this site calls. Read-only, JSON, no key required for the endpoints below. New to the API? Start with the API guide; machine-readable: openapi.json (OpenAPI 3). For production screening volume and support commitments, see the Screening Licence.
https://api.crownintelligence.net. Responses are JSON unless a download format is requested. Every response reflects the compilation's current refresh; there is no separate "as of" parameter — the figure shown is live. The service can apply a per-address request limit (HTTP 429 with Retry-After; see Authentication). Rate limits and volume caps may apply to automated or systematic use; see Terms of use.
POST /api/match/<collection>
Entity matching. Send what you know about a person, company, organization or vessel and get back the closest records in a collection, each with a score from 0 to 1, a match flag and a feature-by-feature explanation of the score. This is the endpoint behind the Screening page. Query bodies are not stored.
| Parameter | Type | Notes |
|---|---|---|
collection | path | default, sanctions, peps, crime or maritime. |
limit | integer | Results per query, up to 50. Default 5. |
threshold | number | Score from which match is true, 0 to 1. Default 0.75. |
algorithm | string | standard (default) or name-only; best means the default. See Algorithms. |
topics | string[] | Query string, repeatable: sanction, role.pep, debarment, reg.action. |
include_dataset / exclude_dataset | string[] | Query string, repeatable: register names to keep or leave out (as in datasets). Several values of one filter are OR-ed; different filters are AND-ed. |
queries | object | Body. Up to 20 named queries, each {"schema": …, "properties": {…}}. A single flat query such as {"schema":"Person","name":"…"} is also accepted and answered as q1. |
schema | string | Person, Company, Organization, LegalEntity or Vessel. A record of a different type is penalised (type_mismatch). |
properties.name | string[] | Names to match. Required unless imoNumber is given. |
properties.birthDate | string[] | YYYY, YYYY-MM or YYYY-MM-DD. |
properties.nationality / country | string[] | Two-letter ISO 3166 codes. Used for a person's nationality, a company's jurisdiction or a vessel's flag. |
properties.imoNumber | string[] | Seven-digit IMO number for vessels. |
| Response field | Contents |
|---|---|
algorithm, threshold, limit, filters | The settings that applied |
responses.<key>.status, total | 200, or 400 with error; candidate records compared for that query |
results[].score, match | Score from 0 to 1; match is true at 0.75 and above |
results[].features[] | feature, explanation, score, weight and, for names, matched_name |
results[].id, caption, schema, url | Record ID (use with Entity), primary name, type and the record page |
results[].datasets, topics, source, list_type, programme | Register name, risk topics, short list name, list type and programme |
results[].birth_date, nationality, imo, aliases | The record's own values, for comparison with the query |
results[].merged_entity, first_seen, last_seen | Merged-entity ID across registers, if any; when the record was first collected and last loaded |
checked_at | When the check ran (UTC) |
| Feature | What it measures | Effect on the score |
|---|---|---|
name_match | Word-by-word alignment of the query name with the record's name and aliases (exact, then close spellings); record words missing from the query lower it slightly. | Sets the base score |
dob_match | Birth date, at the record's precision. | +0.10 match, 0 same year, −0.25 different |
country_match | Nationality or country code. | +0.05 match, −0.10 different |
identifier_match | IMO number. | At least 0.98 on a match, −0.30 different |
type_mismatch | The record is a different entity type from schema. | −0.20 |
curl -X POST "https://api.crownintelligence.net/api/match/default?limit=5" \
-H "Content-Type: application/json" \
-d '{"queries":{"q1":{"schema":"Person","properties":{"name":["Jane Example"],"birthDate":["1970"],"nationality":["ca"]}}}}'
import requests
body = {"queries": {"q1": {"schema": "Person", "properties": {
"name": ["Jane Example"], "birthDate": ["1970"], "nationality": ["ca"]}}}}
r = requests.post("https://api.crownintelligence.net/api/match/default", params={"limit": 5}, json=body)
for hit in r.json()["responses"]["q1"]["results"]:
print(round(hit["score"] * 100), hit["caption"], hit["source"])
const res = await fetch("https://api.crownintelligence.net/api/match/default?limit=5", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ queries: { q1: { schema: "Vessel",
properties: { name: ["Example Star"], imoNumber: ["9000000"] } } } }),
});
console.log((await res.json()).responses.q1.results);
A score measures resemblance, not identity. Confirm every match against the publisher's official list before acting on it.
GET /api/algorithms
The scoring methods accepted by algorithm on Match, with each feature and its effect, the name-comparison constants, the default method and threshold, and the topics accepted by topics. See Matching algorithms.
curl "https://api.crownintelligence.net/api/algorithms"
GET /api/catalog
Every collection from the current build index: name, title, version, records, distinct entities, registers, last change, links (page, build index, statistics, and the match, search and reconcile endpoints) and the files with their sizes. Poll it and compare version to know when a collection was rebuilt.
curl "https://api.crownintelligence.net/api/catalog"
GET /api/overview
Headline totals for the whole compilation: active screening records, sanctions, PEPs, debarments, registry counts, nationalities, source-feed totals and the record-type breakdown. This is what powers the figures on the home page.
| Parameter | Type | Notes |
|---|---|---|
| None — the endpoint takes no query parameters. | ||
curl "https://api.crownintelligence.net/api/overview"
import requests
r = requests.get("https://api.crownintelligence.net/api/overview")
print(r.json())
const res = await fetch("https://api.crownintelligence.net/api/overview");
console.log(await res.json());
GET /api/sources
The source register: one row per publisher feed reconciled into the compilation, with publisher, country, list type, cadence and last-run status. Backs the Sources page.
| Parameter | Type | Notes |
|---|---|---|
q | string | Free-text filter across source name, jurisdiction, country and list type. |
list_type | string | Filter by list type, e.g. SANCTION, PEP, DEBARMENT. |
page | integer | 1-indexed page number. Default 1. |
limit | integer | Rows per page, up to 100. Default 50. |
curl "https://api.crownintelligence.net/api/sources?list_type=SANCTION&limit=25"
import requests
r = requests.get(
"https://api.crownintelligence.net/api/sources",
params={"list_type": "SANCTION", "limit": 25},
)
print(r.json())
const url = new URL("https://api.crownintelligence.net/api/sources");
url.searchParams.set("list_type", "SANCTION");
url.searchParams.set("limit", "25");
const res = await fetch(url);
console.log(await res.json());
GET /api/search
Full-text search across active records by name, with optional filters. Requires at least two characters in q. Backs the Search page; each result links to a record via the Entity endpoint.
| Parameter | Type | Notes |
|---|---|---|
q | string | Name to search, minimum 2 characters. Optional when a filter is set. |
topics, include_dataset, exclude_dataset | string[] | Repeatable filters, as on Match. |
source, program, sort | string | One register; exact programme; first_seen for newest first. |
offset | integer | Record offset, instead of page. |
type | string | Entity type filter, e.g. INDIVIDUAL, COMPANY, VESSEL, AIRCRAFT, ORGANIZATION. |
list_type | string | Filter by list type, e.g. SANCTION, PEP, DEBARMENT. |
nationality | string | Nationality code filter. |
dob | string | Date of birth filter, YYYY, YYYY-MM or YYYY-MM-DD. |
page | integer | 1-indexed page number. Default 1. |
limit | integer | Rows per page, up to 50. Default 25. |
curl "https://api.crownintelligence.net/api/search?q=Jane+Example&limit=25"
import requests
r = requests.get(
"https://api.crownintelligence.net/api/search",
params={"q": "Jane Example", "limit": 25},
)
print(r.json())
const url = new URL("https://api.crownintelligence.net/api/search");
url.searchParams.set("q", "Jane Example");
url.searchParams.set("limit", "25");
const res = await fetch(url);
console.log(await res.json());
GET /api/search/<collection>
The same full-text search as /api/search, limited to one collection. Takes every /api/search parameter; results are not scored.
| Parameter | Type | Notes |
|---|---|---|
collection | path | default, sanctions, peps, crime or maritime. |
q | string | Name to search, minimum 2 characters, unless a filter is given. |
| other | — | type, list_type, nationality, dob, source, program, sort=first_seen, page, limit, as for /api/search. |
curl "https://api.crownintelligence.net/api/search/sanctions?q=Jane+Example&limit=10"
import requests
r = requests.get("https://api.crownintelligence.net/api/search/sanctions", params={"q": "Jane Example", "limit": 10})
print(r.json()["total"])
const url = new URL("https://api.crownintelligence.net/api/search/sanctions");
url.searchParams.set("q", "Jane Example");
const res = await fetch(url);
console.log((await res.json()).results);
GET /api/facets
Counts that break a search down by list type, entity type, nationality (top 30) and source register (top 30). Use it to build filters next to search results. Needs q or at least one filter.
| Parameter | Type | Notes |
|---|---|---|
q | string | Name to search, as for /api/search. |
list_type, type, nationality, source | string | Filters, combined with AND. |
scope | string | Collection: default, sanctions, peps, crime or maritime. |
curl "https://api.crownintelligence.net/api/facets?q=Jane+Example&list_type=SANCTION"
import requests
r = requests.get("https://api.crownintelligence.net/api/facets", params={"q": "Jane Example"})
print(r.json()["nationality"])
const res = await fetch("https://api.crownintelligence.net/api/facets?q=Jane+Example");
console.log((await res.json()).source);
GET /api/entity/<id>
A single record by numeric id, as returned by Search or Match: source, register, name, alternate names, programme, list type, entity type, birth date and precision, nationality, IMO number, source link, first and last load, related (the same party in other registers), listings (the record and its related records as nested listings) and merged_entity_url. A merged-entity UUID in the path returns the merged entity: caption, schema, combined properties, registers, topics, referents, and nested listings and records (up to 200). A record no longer active whose merged entity is answers 308 to it. The query forms /api/entity?id= and ?entity_id= still work. Guide: The entities API.
| Parameter | Type | Notes |
|---|---|---|
id | path | Record id from a Search or Match result (or crown-<id> from the bulk files), or a merged-entity UUID. |
nested | boolean | false returns the record or merged entity alone. |
format | string | ftm: the record as a FollowTheMoney entity, as in entities.ftm.json; with nested=true, as in targets.nested.json. |
entity_id | string | Query form for a merged-entity UUID (entity_id on a record, merged_entity on a match). |
curl "https://api.crownintelligence.net/api/entity/379781867"
import requests
r = requests.get("https://api.crownintelligence.net/api/entity/379781867")
print(r.json()["listings"])
const res = await fetch("https://api.crownintelligence.net/api/entity/379781867");
console.log(await res.json());
GET /api/source
One source register in detail: its register entry (publisher, country, list type, status, last run), record and distinct-entity totals, first and last load, and breakdowns by entity type, country (top 60) and programme (top 50), plus its 15 most recently added records.
| Parameter | Type | Notes |
|---|---|---|
name | string | Register name exactly as returned by /api/sources. Required. |
curl "https://api.crownintelligence.net/api/source?name=OFAC%20SDN"
import requests
r = requests.get("https://api.crownintelligence.net/api/source", params={"name": "OFAC SDN"})
print(r.json()["records"])
const url = new URL("https://api.crownintelligence.net/api/source");
url.searchParams.set("name", "OFAC SDN");
console.log(await (await fetch(url)).json());
GET /api/countries
Every nationality present in active records, with a record count and a distinct-source count per nationality. Takes no parameters.
| Parameter | Type | Notes |
|---|---|---|
| None — the endpoint takes no query parameters. | ||
curl "https://api.crownintelligence.net/api/countries"
import requests
r = requests.get("https://api.crownintelligence.net/api/countries")
print(r.json())
const res = await fetch("https://api.crownintelligence.net/api/countries");
console.log(await res.json());
GET POST /api/reconcile/<collection>
A reconciliation service for OpenRefine (Reconciliation API 0.2). Add https://api.crownintelligence.net/api/reconcile/default as a standard service in OpenRefine to match a column of names against a collection. Without queries it returns the service manifest; with them it scores each query using the same matcher as /api/match.
| Parameter | Type | Notes |
|---|---|---|
collection | path | default, sanctions, peps, crime or maritime. |
queries | JSON | Query string (GET) or form/JSON body (POST). Up to 20 queries: {"q0":{"query":"Jane Example","type":"Person","limit":5,"properties":[{"pid":"birthDate","v":"1970"}]}}. Property ids are those of /api/match. |
| response | object | For each query key, result: a list of candidates with id, name, score (0–100), match and type. id opens at /estate/record.html?id=. |
curl -G "https://api.crownintelligence.net/api/reconcile/default" --data-urlencode 'queries={"q0":{"query":"Jane Example","type":"Person"}}'
import json, requests
q = {"q0": {"query": "Jane Example", "type": "Person"}}
r = requests.post("https://api.crownintelligence.net/api/reconcile/default", data={"queries": json.dumps(q)})
print(r.json()["q0"]["result"])
const res = await fetch("https://api.crownintelligence.net/api/reconcile/default", {
method: "POST",
body: new URLSearchParams({ queries: JSON.stringify({ q0: { query: "Jane Example", type: "Person" } }) }),
});
console.log(await res.json());
GET /api/programs
Sanctions and other programs grouped across active records, with the record count, distinct source-list count and the names of the contributing lists for each program.
| Parameter | Type | Notes |
|---|---|---|
q | string | Free-text filter on program name or source list name. |
page | integer | 1-indexed page number. Default 1. |
limit | integer | Rows per page, up to 100. Default 50. |
curl "https://api.crownintelligence.net/api/programs?q=Magnitsky"
import requests
r = requests.get(
"https://api.crownintelligence.net/api/programs",
params={"q": "Magnitsky"},
)
print(r.json())
const url = new URL("https://api.crownintelligence.net/api/programs");
url.searchParams.set("q", "Magnitsky");
const res = await fetch(url);
console.log(await res.json());
GET /api/collection
Summary totals for one collection type — sanctions, PEPs or debarments — with an optional scope narrowing to a specific angle such as maritime or company records within that type.
| Parameter | Type | Notes |
|---|---|---|
type | string | One of SANCTION, PEP, DEBARMENT. Required. |
scope | string | Optional narrowing, e.g. sanctions, peps, crime, maritime, kyb, securities. |
curl "https://api.crownintelligence.net/api/collection?type=SANCTION"
import requests
r = requests.get(
"https://api.crownintelligence.net/api/collection",
params={"type": "SANCTION"},
)
print(r.json())
const url = new URL("https://api.crownintelligence.net/api/collection");
url.searchParams.set("type", "SANCTION");
const res = await fetch(url);
console.log(await res.json());
GET /api/export
Streams a free download of one register's active records as CSV or newline-delimited JSON, for registers Crown has cleared for direct download. Registers not cleared for download return an error explaining that the register is available for licensed use instead.
| Parameter | Type | Notes |
|---|---|---|
source | string | Exact register name, as shown on its Sources page row. Required. |
format | string | csv or jsonl. Default csv. |
curl "https://api.crownintelligence.net/api/export?source=OFAC%20SDN&format=csv" -o ofac-sdn.csv
import requests
r = requests.get(
"https://api.crownintelligence.net/api/export",
params={"source": "OFAC SDN", "format": "csv"},
)
with open("ofac-sdn.csv", "wb") as f:
f.write(r.content)
import { writeFile } from "node:fs/promises";
const url = new URL("https://api.crownintelligence.net/api/export");
url.searchParams.set("source", "OFAC SDN");
url.searchParams.set("format", "csv");
const res = await fetch(url);
await writeFile("ofac-sdn.csv", Buffer.from(await res.arrayBuffer()));
GET /downloads/collections/<collection>/<file>
Bulk files for each collection (default, sanctions, peps, crime or maritime), rebuilt after every refresh and kept at the same address. index.json lists every file with its size, row count and SHA-256 checksum, with the collection's figures, version and last change. Formats, columns and delta updates are described in Using the bulk data.
| File | Contents |
|---|---|
index.json | Build index: version, figures and every file with checksum |
targets.simple.csv | One row per record, flat table |
targets.nested.json | Each record with sanction details nested, one per line |
entities.ftm.json | FollowTheMoney entities, one per line |
senzing.json | Senzing records, one per line |
statements.csv | One row per property value |
names.txt | Every distinct name and alias |
delta.json | ADD, MOD and DEL operations since the previous build |
curl -O "https://api.crownintelligence.net/downloads/collections/sanctions/index.json" curl -O "https://api.crownintelligence.net/downloads/collections/sanctions/targets.simple.csv"
import requests
idx = requests.get("https://api.crownintelligence.net/downloads/collections/sanctions/index.json").json()
for f in idx["files"]:
print(f["name"], f["rows"], f["sha256"])
const idx = await (await fetch("https://api.crownintelligence.net/downloads/collections/sanctions/index.json")).json();
console.log(idx.version, idx.files.map(f => f.name));