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.
| 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áquina | crown-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 conci_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).
| Alcance | Cubre |
|---|---|
match:read | POST /v1/match y conciliación |
search:read | Búsqueda, registros, entidades y colecciones |
sources:read | Fuentes, programas y estadísticas de colecciones |
exports:read | Descargas de registros, cuando la licencia lo permite |
webhooks:manage | Puntos de acceso de webhooks y sus bitácoras de entrega |
monitors:manage | Monitores de entradas de listas públicas |
cases:read, cases:write | Casos, resoluciones y paquetes de evidencia |
usage:read | Uso en unidades |
keys:manage | Creació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_serviceysource_accounta partir de la clave autenticada y toma el pedido deorder_idde la clave. Un socio no puede establecerlos por sí mismo. Si un encabezado enviado no coincide con su clave, la llamada se rechaza con 400billing_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 estableceparent_callcon la llamada que lo originó. typeesORDERcuando un cliente paga por la llamada. EsOVERHEADpara el tráfico del sistema, sin factura y con el costo igualmente registrado. UnORDERdebe llevarorder_id; unOVERHEADllevaorder_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.
| Estado | Significado | ¿Puede tratarlo como sin coincidencia? |
|---|---|---|
hit | Al menos una coincidencia en min_band o por encima | No. Revise las coincidencias. |
no_hit_searched | Se buscó en todos los registros listados. Nada coincidió. La respuesta enumera cada registro con loaded_at. | Sí. Es el único resultado negativo. |
not_searched | No se verificó nada, por ejemplo un identificador que ningún registro cargado cubre. Se indica el motivo. | Nunca. No verificado no equivale a limpio. |
error | La 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.
| Banda | Norma | Se devuelve cuando |
|---|---|---|
STRONG | Puntuación de 0.90 o más, o un IMO, MMSI o LEI exacto | Siempre, si está en min_band o por encima |
POSSIBLE | Puntuación de 0.75 a 0.89 | El valor predeterminado de min_band |
WEAK | Puntuación de 0.60 a 0.74 | Solo 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ímite | Valor predeterminado propuesto |
|---|---|
| Solicitudes por minuto, por clave | 120 |
| Unidades de consulta por minuto, por clave | 600 |
| Consultas por lote | 100 |
| Solicitudes de exportación por minuto, por clave | 10 |
| Unidades mensuales | Se 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."}}]} | HTTP | Código | Cuándo |
|---|---|---|
| 400 | invalid_request | El cuerpo o un parámetro no cumple con el esquema |
| 400 | billing_ref_missing, billing_ref_invalid | Una llamada interna no tiene referencia de facturación, o sus campos no coinciden con la clave |
| 400 | personal_data_not_accepted | El cuerpo de un monitor contiene un campo personal |
| 401 | unauthenticated, key_revoked | La clave falta, es desconocida o fue revocada |
| 403 | forbidden_scope, forbidden_environment | Falta el alcance, o una clave del entorno de pruebas llama a una ruta de producción |
| 404 | not_found | También se usa cuando un registro no es visible para la cuenta |
| 409 | conflict, idempotency_mismatch | Un duplicado, o una Idempotency-Key reutilizada con un cuerpo distinto |
| 413 | payload_too_large, batch_too_large | Más de 1 MB, o más de 100 consultas |
| 429 | rate_limited, quota_exceeded | Consulte los límites de frecuencia más arriba. Espere Retry-After. |
| 503 | register_unavailable, unavailable | Un registro o el servicio no está disponible. Reintente con retroceso exponencial. |
| 500 | internal_error | Infó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
}
}