API de socios v1 · Borrador, aún no disponible

API para socios v1: descripción general

Borrador: aún no disponible. Esta página describe el contrato propuesto de la v1 para socios (versión 1.0.0-rc.1). Ningún punto de acceso de esta página está desplegado y todavía no se puede emitir ninguna clave de API.

La versión 1 es la capa orientada a socios sobre el servicio de datos de Crown Intelligence. Añade claves de API con alcances, medición de uso, coincidencias por lotes con un estado claro para cada consulta, webhooks, monitoreo de entradas de listas públicas y paquetes de evidencia. Esta página explica las reglas que sigue cada operación.

Estado de esta API

El contrato v1 es un borrador, versión 1.0.0-rc.1. No está desplegado, publicado ni facturado. Las direcciones siguientes son propuestas; todavía no resuelven a un servicio en funcionamiento.

Direcciones base propuestas para la API para socios v1
En vivo (propuesta)https://api.crownintelligence.net
Entorno de pruebas (propuesto)https://sandbox.api.crownintelligence.net, los mismos registros públicos, nunca se factura
Contrato legible por máquinacrown-intelligence-v1.yaml (OpenAPI 3.1.0, borrador)

Claves de API y alcances

Envíe la clave en el encabezado X-Api-Key en cada solicitud, excepto en GET /v1/status, que no requiere clave.

  • Las claves en vivo comienzan con ci_live_. Las claves del entorno de pruebas comienzan con ci_test_. Una clave del entorno de pruebas nunca llega a una ruta en vivo ni crea un pedido facturable.
  • El secreto se muestra una sola vez, al crear la clave. Crown Intelligence conserva únicamente un hash y el prefijo visible.
  • Cada clave tiene alcances explícitos. Una clave sin el alcance que requiere una ruta recibe 403 forbidden_scope.
  • La revocación es inmediata y definitiva. Una clave revocada devuelve 401 key_revoked. Las claves se retiran, nunca se eliminan.
  • Una clave en vivo debe indicar el pedido de suscripción con el que se factura (order_id).
Alcances de la API y lo que cubre cada uno
AlcanceCubre
match:readPOST /v1/match y conciliación
search:readBúsqueda, registros, entidades y colecciones
sources:readFuentes, programas y estadísticas de colecciones
exports:readDescargas de registros, cuando la licencia lo permite
webhooks:managePuntos de acceso de webhooks y sus bitácoras de entrega
monitors:manageMonitores de entradas de listas públicas
cases:read, cases:writeCasos, resoluciones y paquetes de evidencia
usage:readUso en unidades
keys:manageCreación y revocación de claves

Pruébelo: una solicitud con clave

curl:

curl https://api.crownintelligence.net/v1/sources \
  -H "X-Api-Key: $CI_API_KEY"

Node (20 o posterior):

const res = await fetch("https://api.crownintelligence.net/v1/sources", {
  headers: { "X-Api-Key": process.env.CI_API_KEY }
});
if (!res.ok) throw new Error("HTTP " + res.status);
const body = await res.json();

Comprobación de estado sin clave:

curl https://api.crownintelligence.net/v1/status

Referencia de facturación: solo llamadas internas

Cada llamada entre servicios lleva una referencia de facturación, enviada en el encabezado X-Billing-Ref como JSON ASCII compacto de máximo 1,024 bytes. Registra para quién es la llamada, de modo que el uso pueda facturarse y el costo quede registrado.

{"source_service":"partner-api","source_account":"acct_demo_bank",
 "order_id":"ord_2026_1041","type":"ORDER","parent_call":null,"invoice_line_id":null}
  • Las llamadas de socios pueden omitir el encabezado. La puerta de enlace completa source_service y source_account a partir de la clave autenticada y toma el pedido de order_id de la clave. Un socio no puede establecerlos por sí mismo. Si un encabezado enviado no coincide con su clave, la llamada se rechaza con 400 billing_ref_invalid.
  • Las llamadas internas deben enviarlo. Un servicio de Crown que llame a Crown Intelligence sin el encabezado es rechazado con 400 billing_ref_missing. El objeto pasa sin cambios a lo largo de la cadena, y cada salto establece parent_call con la llamada que lo originó.
  • type es ORDER cuando un cliente paga por la llamada. Es OVERHEAD para el tráfico del sistema, sin factura y con el costo igualmente registrado. Un ORDER debe llevar order_id; un OVERHEAD lleva order_id: null.
  • No se permiten otros campos. La API nunca muestra montos: el uso se informa solo en unidades y los precios se fijan en la factura.
// Internal Crown service calling match: pass the caller's billing_ref unchanged in X-Billing-Ref.
const billingRef = {
  source_service: "your-registered-service-id",
  source_account: null,
  order_id: null,
  type: "OVERHEAD",
  parent_call: incomingBillingRefId,   // id of the call that triggered this one, or null at the top
  invoice_line_id: null
};
const res = await fetch("https://api.crownintelligence.net/v1/match", {
  method: "POST",
  headers: {
    "X-Api-Key": process.env.CI_INTERNAL_KEY,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
    "X-Billing-Ref": JSON.stringify(billingRef)
  },
  body: JSON.stringify({ queries: [{ query_ref: "svc-1", entity_type: "Company", name: "Northwind Trading LLC" }] })
});

Puntos pendientes: el identificador de fuente partner-api aún no está registrado en el catálogo de servicios y el responsable aún no ha decidido si las filas de uso incluyen una referencia de precio. Consulte el contrato, secciones 4 y 16.

Estados de coincidencia: nunca se da por limpio de forma predeterminada

Cada consulta en una respuesta de coincidencias tiene uno de cuatro estados. La regla es simple: una consulta se informa como limpia solo cuando se buscó en todos los registros que debía cubrir y nada coincidió. La palabra clear no es un valor en ninguna parte de la API.

Los cuatro estados de coincidencia
EstadoSignificado¿Puede tratarlo como sin coincidencia?
hitAl menos una coincidencia en min_band o por encimaNo. Revise las coincidencias.
no_hit_searchedSe buscó en todos los registros listados. Nada coincidió. La respuesta enumera cada registro con loaded_at.Sí. Es el único resultado negativo.
not_searchedNo se verificó nada, por ejemplo un identificador que ningún registro cargado cubre. Se indica el motivo.Nunca. No verificado no equivale a limpio.
errorLa verificación falló. Reintente.Nunca. Una verificación fallida no es limpia.

Un estado not_searched o error nunca debe mostrarse como limpio, almacenarse como limpio ni transmitirse como limpio. Diseñe su lógica de decisión de modo que solo no_hit_searched pueda producir un resultado negativo.

Bandas de coincidencia

Cada coincidencia incluye una banda en lugar de un umbral sin procesar. Las bandas se derivan de la puntuación (0 a 1) y de los identificadores que concuerdan.

Bandas de coincidencia y sus reglas
BandaNormaSe devuelve cuando
STRONGPuntuación de 0.90 o más, o un IMO, MMSI o LEI exactoSiempre, si está en min_band o por encima
POSSIBLEPuntuación de 0.75 a 0.89El valor predeterminado de min_band
WEAKPuntuación de 0.60 a 0.74Solo cuando min_band es WEAK

No se devuelve nada por debajo de 0.60. Los límites inferiores de las bandas son propuestos y aún no se han calibrado con un conjunto etiquetado de pares, por lo que no construya una regla fija sobre ellos hasta que se publique la calibración. Las versiones del motor de coincidencias se mostrarán en cada respuesta.

Límites de frecuencia y cuotas

Estos valores predeterminados son propuestos. Los límites de los planes son marcadores de posición hasta que el responsable los fije.

Límites de frecuencia propuestos
LímiteValor predeterminado propuesto
Solicitudes por minuto, por clave120
Unidades de consulta por minuto, por clave600
Consultas por lote100
Solicitudes de exportación por minuto, por clave10
Unidades mensualesSe define según el plan. Al excederlo se devuelve 429 quota_exceeded.

Cada respuesta incluye RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset. Las llamadas medidas también incluyen X-Usage-Units. Una respuesta 429 incluye Retry-After.

Idempotencia y versiones

Cada POST acepta un Idempotency-Key de hasta 255 caracteres. Si se repite la misma clave con el mismo cuerpo dentro de 24 horas, se devuelve la respuesta almacenada sin un segundo cobro. Si se reutiliza la clave con un cuerpo distinto, se devuelve 409 idempotency_mismatch.

La versión va en la ruta (/v1). Los cambios dentro de v1 son aditivos. Un cambio incompatible pasa a /v2, con al menos seis meses de aviso previo ante cualquier obsolescencia.

Errores

Cada error es application/problem+json (RFC 9457). Cada error incluye un code estable, un request_id que debe indicar al soporte técnico y su mensaje en inglés (messages.en) y francés (messages.fr).

{"type":"https://api.crownintelligence.net/problems/invalid_request","title":"Invalid request",
 "status":400,"code":"invalid_request","detail":"queries[3].name must be at least 2 characters",
 "messages":{"en":"queries[3].name must be at least 2 characters",
   "fr":"queries[3].name doit comporter au moins 2 caractères"},
 "request_id":"req_01J9Z3K4M6","errors":[{"pointer":"/queries/3/name","code":"too_short",
   "message":{"en":"Use at least 2 characters.","fr":"Utilisez au moins 2 caractères."}}]}
Códigos de error comunes
HTTPCódigoCuándo
400invalid_requestEl cuerpo o un parámetro no cumple con el esquema
400billing_ref_missing, billing_ref_invalidUna llamada interna no tiene referencia de facturación, o sus campos no coinciden con la clave
400personal_data_not_acceptedEl cuerpo de un monitor contiene un campo personal
401unauthenticated, key_revokedLa clave falta, es desconocida o fue revocada
403forbidden_scope, forbidden_environmentFalta el alcance, o una clave del entorno de pruebas llama a una ruta de producción
404not_foundTambién se usa cuando un registro no es visible para la cuenta
409conflict, idempotency_mismatchUn duplicado, o una Idempotency-Key reutilizada con un cuerpo distinto
413payload_too_large, batch_too_largeMás de 1 MB, o más de 100 consultas
429rate_limited, quota_exceededConsulte los límites de frecuencia más arriba. Espere Retry-After.
503register_unavailable, unavailableUn registro o el servicio no está disponible. Reintente con retroceso exponencial.
500internal_errorInfórmelo con el request_id

En un lote, una consulta individual puede fallar con un estado error. El lote en sí sigue devolviendo 200, y esa consulta nunca se informa como sin coincidencias.

const res = await fetch(url, { headers: { "X-Api-Key": process.env.CI_API_KEY } });
if (!res.ok) {
  const problem = await res.json();              // application/problem+json
  console.error(problem.code, problem.request_id, problem.messages.en);
  if (res.status === 429 || res.status === 503) {
    const wait = Number(res.headers.get("Retry-After") ?? 5);   // back off, then retry the same request
  }
}

Páginas de esta sección