Documentación · API de verificación
Lista de verificación de integración
Qué decidir, construir y probar antes de poner en producción la verificación de Crown Intelligence en su sistema: la colección, el mapeo de campos, el umbral de coincidencia, cómo se revisan y se registran las posibles coincidencias, cómo se mantienen actualizados los registros y cómo maneja la integración los límites y los errores.
Hoy la API de verificación no requiere clave y responde a solicitudes anónimas. Las comprobaciones siguientes usan los puntos de acceso de la guía de la API de verificación y de la referencia de la API. La verificación automatizada o sistemática, y el uso en un proceso de negocio, requieren una licencia comercial conforme a nuestros términos de uso. Confírmelo antes de conectar un sistema en producción.
Elija una colección
Cada colección es una ruta de coincidencia independiente. Elija la que corresponda a las listas que abarcan sus obligaciones. Un registro no es una colección por sí mismo; para limitar una búsqueda a un registro, use include_dataset.
| Colección | Ruta de coincidencia | Contenido |
|---|---|---|
| default | /api/match/default | Todos los registros activos: sanciones, PEPs, inhabilitación para contratar, medidas coercitivas y otras listas de riesgo. |
| sanciones | /api/match/sanctions | Solo inclusiones en listas de sanciones. |
| peps | /api/match/peps | Personas expuestas políticamente (PEP). |
| crime | /api/match/crime | Inhabilitación para contratar, órdenes de cobro de impuestos y avisos de insolvencia. |
| maritime | /api/match/maritime | Embarcaciones y registros que incluyen un número IMO. |
Asigne los campos del cliente a la solicitud de coincidencia
Una solicitud de coincidencia envía hasta 20 consultas con nombre en un solo cuerpo, cada una con schema y properties. Use su propio ID de cliente o contraparte como clave de la consulta, de modo que cada respuesta se asocie con su registro.
| Su campo | Campo de coincidencia | Reglas |
|---|---|---|
| Nombre, o cada grafía que tenga | properties.name | Arreglo de hasta 5 cadenas. Agregue una forma transliterada cuando disponga de ella. Obligatorio, salvo que se envíe imoNumber o mmsi. |
| Fecha de nacimiento | properties.birthDate | YYYY, YYYY-MM o YYYY-MM-DD. Envíe la precisión de que disponga; un año por sí solo es válido. |
| Nacionalidad (persona) | properties.nationality | Código ISO 3166 de dos letras, como ca o ru. |
| País de constitución (empresa) | properties.country | Código de dos letras. El mismo campo también admite la bandera de una embarcación. |
| Número IMO (embarcación) | properties.imoNumber | Siete dígitos, como 9418286. |
| MMSI (embarcación) | properties.mmsi | Nueve dígitos. |
| Tipo de parte | schema | Person, Company, Organization, LegalEntity o Vessel. Un registro de otro tipo reduce la puntuación (type_mismatch). Envíe el tipo que conozca en lugar de LegalEntity por defecto. |
Un punto de partida que asigna un registro de cliente, envía un lote con reintentos e imprime el resultado principal de cada parte.
import os, time, json, requests
BASE = os.environ.get("CROWN_API_BASE", "https://api.crownintelligence.net")
session = requests.Session()
session.headers["User-Agent"] = "my-screening-tool/1.0 ([email protected])"
def to_query(customer):
"""Map one customer record to a match query (see the field table above)."""
props = {"name": customer["names"][:5]}
if customer.get("birth_date"):
props["birthDate"] = [customer["birth_date"]] # YYYY, YYYY-MM or YYYY-MM-DD
if customer.get("nationality"):
props["nationality"] = [customer["nationality"]] # ISO 3166-1 alpha-2, e.g. "ca"
if customer.get("imo"):
props["imoNumber"] = [customer["imo"]] # seven digits
return {"schema": customer["schema"], "properties": props}
def match(collection, queries, limit=5, threshold=0.75, changed_since=None, retries=3):
"""POST /api/match with retries for 429 (honour Retry-After) and 5xx (back off)."""
params = {"limit": limit, "threshold": threshold}
if changed_since:
params["changed_since"] = changed_since
for attempt in range(retries + 1):
r = session.post(f"{BASE}/api/match/{collection}", params=params,
json={"queries": queries}, timeout=60)
if r.status_code == 429 and attempt < retries:
time.sleep(int(r.headers.get("Retry-After", "5")))
continue
if r.status_code >= 500 and attempt < retries:
time.sleep(2 ** attempt)
continue
r.raise_for_status()
return r.json()
customers = {
"C-1001": {"schema": "Person", "names": ["Igor Putin", "Игорь Путин"], "birth_date": "1953-03-30", "nationality": "ru"},
"C-1002": {"schema": "Vessel", "names": ["Selam"], "imo": "9418286"},
"C-1003": {"schema": "Person", "names": ["Zz Crown Checklist Testperson"], "birth_date": "1980", "nationality": "ca"},
}
queries = {cid: to_query(c) for cid, c in customers.items()}
out = match("default", queries, limit=3, threshold=0.75)
for cid, answer in out["responses"].items():
print(cid, answer["status"], "candidates:", answer["total"])
for hit in answer["results"][:1]:
print(" top:", hit["caption"], hit["score"], "match" if hit["match"] else "no match", hit["datasets"][:1])
print("checked_at:", out["checked_at"], "| collection:", out["collection"], "| threshold:", out["threshold"])
Defina el umbral e interprete el indicador de coincidencia
Cada resultado tiene un valor score de 0 a 1 y un indicador match, que es true cuando la puntuación es igual o superior a threshold. El umbral predeterminado es 0.75 y el valor predeterminado de limit es de 5 resultados por consulta (hasta 50). Los resultados por debajo del umbral también se devuelven, con match establecido en false, para que los revisores vean los casi coincidentes.
| Característica | Qué mide | Efecto en la puntuación |
|---|---|---|
name_match | Alineación palabra por palabra del nombre de la consulta con los nombres y alias del registro. | Establece la puntuación base. |
dob_match | Fecha de nacimiento, con la precisión del registro. | +0.10 si coincide; 0 si solo coincide el año; −0.25 si es distinta. |
country_match | Nacionalidad o código de país. | +0.05 si coincide; −0.10 si es distinta. |
identifier_match | Número IMO. | Al menos 0.98 si coincide; −0.30 si es distinto. |
type_mismatch | El registro es de un tipo distinto de schema. | −0.20. |
Gestione las posibles coincidencias
Un resultado con match establecido en true es una posible coincidencia, no una conclusión. Envíelo a una cola de revisión y conserve una decisión para cada uno.
Registre lo que se verificó
No almacenamos los cuerpos de las consultas, por lo que su sistema debe conservar su propio registro de cada verificación, incluidas las que no arrojan coincidencia. Almacene la respuesta tal como se recibió y agregue los campos siguientes.
| Campo que se debe registrar | Origen |
|---|---|
| Su ID de cliente o contraparte | Su sistema. |
| Consulta tal como se envió | El cuerpo de su solicitud. |
| Colección y su versión | El nombre de la colección que utilizó y su version de /api/catalog al momento de la verificación. |
| Algoritmo, umbral y límite | Los parámetros de consulta que envió. La respuesta devuelve algorithm, threshold y limit. |
| Hora de la verificación | checked_at en la respuesta (UTC). |
| ID del registro, entidad combinada, puntaje y características | id, merged_entity, score y features de cada resultado. |
| Registros, temas y programa | datasets, topics y programme de cada resultado. |
| Decisión, revisor y fecha de la decisión | Su cola de revisión. |
Reverificar y monitorear
Las listas cambian. Una parte aprobada el mes pasado puede generar una coincidencia tras una nueva inclusión en la lista. Vuelva a verificar según un calendario y cada vez que se reconstruya una colección.
import os, json, requests
BASE = os.environ.get("CROWN_API_BASE", "https://api.crownintelligence.net")
# Versions now, to compare with the versions stored at the last run
catalog = requests.get(f"{BASE}/api/catalog", timeout=30).json()
versions = {c["name"]: c["version"] for c in catalog["collections"]}
last_run = {"sanctions": "20261004022212-jhp"} # the version stored at the last run
changed = [name for name, v in versions.items() if last_run.get(name) not in (None, v)]
print("collections rebuilt since the last run:", changed)
# Only records added or changed since the last run (ISO 8601 date or time)
body = {"queries": {"C-1001": {"schema": "Person", "properties": {"name": ["Igor Putin"], "birthDate": ["1953"]}}}}
r = requests.post(f"{BASE}/api/match/sanctions", params={"limit": 10, "changed_since": "2026-10-01"},
json=body, timeout=60)
r.raise_for_status()
answer = r.json()["responses"]["C-1001"]
print("changed since 2026-10-01:", answer["total"], "candidates;", r.json()["filters"]["changed_since"])
# Entity lookup for the review screen
ent = requests.get(f"{BASE}/api/entity/379781867", timeout=30).json()
print(ent["id"], ent["name"], ent["register"], ent["list_type"], ent["listings"][0]["register"])
Límites de velocidad, reintentos y volumen
El servicio de datos tiene un límite de solicitudes por dirección que el operador puede activar. Hoy está desactivado y no se publica ninguna cifra. Los términos se reservan el derecho de aplicar límites o topes de volumen al uso automatizado, por lo que debe acordar sus volúmenes con nosotros antes de enviar un lote grande.
Pruebas con nombres conocidos
Pruebe la integración con nombres que tengan inclusiones conocidas en listas antes de la puesta en producción y mantenga el conjunto de pruebas bajo control de versiones. Incluya:
Una verificación que realizamos para esta página: la consulta Igor Putin, año de nacimiento 1953 y nacionalidad ru, contra la colección de sanciones con un umbral de 0.8, devolvió la inclusión en la lista de sanciones con puntaje 1 y match establecido en true. Los resultados dependen de la compilación en uso, por lo que debe registrar la versión de la colección en cada ejecución de pruebas y repetirlas después de cada reconstrucción.
Verificaciones previas a la puesta en producción
Ejemplos
Los ejemplos siguientes son puntos de partida, por lo que debe ejecutarlos en un entorno de pruebas antes de confiar en ellos. Defina CROWN_API_BASE para cambiar la dirección base; el valor predeterminado es el servicio público.
Node.js: solicitud de coincidencias
const BASE = process.env.CROWN_API_BASE ?? "https://api.crownintelligence.net";
const queries = {
vessel: { schema: "Vessel", properties: { name: ["Selam"], imoNumber: ["9418286"] } },
person: { schema: "Person", properties: { name: ["Igor Putin"], birthDate: ["1953-03-30"], nationality: ["ru"] } },
};
const params = new URLSearchParams({ limit: "3", threshold: "0.75" });
const res = await fetch(`${BASE}/api/match/maritime?${params}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ queries }),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
for (const [key, answer] of Object.entries(data.responses)) {
const top = answer.results[0];
console.log(key, answer.status, answer.total, top ? [top.caption, top.score, top.match] : "no hits");
}
curl: versiones de colecciones y una coincidencia
# Versions of each collection, to see when a list was rebuilt
curl -s "$CROWN_API_BASE/api/catalog" | python3 -c 'import json,sys; [print(c["name"], c["version"]) for c in json.load(sys.stdin)["collections"]]'
# One party against the sanctions collection
curl -s -X POST "$CROWN_API_BASE/api/match/sanctions?limit=3&threshold=0.8&topics=sanction" \
-H "Content-Type: application/json" \
-d '{"queries":{"q1":{"schema":"Person","properties":{"name":["Igor Putin"],"birthDate":["1953"],"nationality":["ru"]}}}}'
Última actualización: 2026-10-10