Resillia
Integración

API de inteligencia jurídica

Contrato B2B para consultar causas consolidadas de personas y empresas.

Producción consulta el corpus privado de Resillia. Una coincidencia documental no acredita por sí sola identidad, rol procesal ni situación tributaria o legal.

Autenticación

Cada organización administra sus credenciales desde el panel. La clave completa se muestra una sola vez y puede enviarse en X-API-Key o como token Bearer.

POST /api/v1/person-search
Content-Type: application/json
X-API-Key: rsl_test_...
Idempotency-Key: cliente-operacion-0001

Consulta por cédula o RUC

{
	"type": "cedula",
	"value": "4567890",
	"purpose": "due_diligence"
}

Para buscar un contribuyente utiliza "type": "ruc" con un valor como "80012345-6"; la consulta puede corresponder a una persona o empresa. Para consulta exploratoria por nombre, utiliza "type": "name". purpose declara el uso autorizado de la consulta: controla permisos y queda registrado para auditoría, pero no cambia ni oculta las fuentes recuperadas. Admite legal_review, due_diligence, credit_risk, fraud_prevention y other; si se omite, se registra legal_review por compatibilidad. La cédula se normaliza a dígitos, el RUC a número-dígito verificador y el nombre para búsqueda. El valor completo nunca se guarda en el ledger.

Respuesta

{
	"requestId": "cm...",
	"generatedAt": "2026-10-31T12:00:00.000Z",
	"query": {
		"type": "cedula",
		"preview": "••••890",
		"matchMode": "exact",
		"purpose": "due_diligence"
	},
	"subject": {
		"documentType": "cedula",
		"documentMasked": "••••890",
		"name": "PERSONA EJEMPLO",
		"identityStatus": "confirmed"
	},
	"coverage": {
		"documents": 2,
		"cases": 1,
		"period": { "from": "2024-05-10", "to": "2025-09-18" },
		"asOf": "2025-09-18T00:00:00.000Z"
	},
	"summary": {
		"status": "conclusive",
		"activeCases": 0,
		"closedCases": 1,
		"indeterminateCases": 0,
		"favorableCases": 1,
		"adverseCases": 0,
		"mixedCases": 0,
		"text": "Se localizó 1 causa consolidada: 1 finalizada. Todas las fuentes recuperadas quedaron representadas por conclusiones publicables."
	},
	"abstentions": [],
	"resultCount": 1,
	"caseCount": 1,
	"billableUnits": 1,
	"source": "resillia_corpus",
	"disclaimer": "Los resultados son menciones documentales localizadas...",
	"documentarySummary": {
		"status": "preliminary",
		"documentCount": 2,
		"documentTypes": [{ "label": "Resolución judicial", "count": 2 }],
		"period": { "from": "2024-05-10", "to": "2025-09-18" },
		"signals": ["executive_proceeding", "asset_inhibition", "final_judgment"],
		"mentionedAmounts": [
			{ "currency": "PYG", "amount": "98180160", "sourceResultIds": ["version-2"] }
		],
		"reviewRequired": true
	},
	"cases": [
		{
			"id": "identificador-opaco-de-causa",
			"jurisdiction": "PY",
			"legalArea": "civil",
			"caseStatus": "closed",
			"decisionFinality": "final",
			"caseResult": "favorable",
			"currentEffect": "no_adverse_effect",
			"participationRole": "defendant",
			"summary": "La pretensión fue rechazada y la causa se encuentra cerrada.",
			"controllingDecision": {
				"type": "final_judgment",
				"date": "2025-09-18T00:00:00.000Z",
				"outcome": "claim_rejected",
				"finality": "final"
			},
			"relevance": {
				"purpose": "due_diligence",
				"category": "resolved_or_inactive"
			},
			"firstEventAt": null,
			"latestEventAt": "2025-09-18T00:00:00.000Z",
			"documentIds": ["version-1", "version-2"],
			"documentCount": 2,
			"matchedDocumentIds": ["version-1"],
			"matchBasis": "identifier",
			"identityConfidence": "direct_identifier",
			"economicEffects": [],
			"evidence": [],
			"confidenceBasisPoints": 9900,
			"reviewStatus": "approved",
			"modelAssisted": false
		}
	],
	"results": [
		{
			"id": "version-2",
			"documentType": "Sentencia definitiva",
			"documentCategory": "judicial",
			"decisionStatus": "closed",
			"subjectRole": "Demandado",
			"outcome": "Pretensión rechazada",
			"title": "Fuente documental de la causa",
			"sourceName": "Corpus Resillia",
			"sourceUrl": "https://fuente-publica.example/documento",
			"publishedAt": "2025-09-18",
			"matchType": "exact",
			"matchReasons": ["Identificador localizado en el documento"],
			"snippet": "Fragmento documental disponible como evidencia.",
			"synthetic": false
		}
	]
}

Los valores del ejemplo son ilustrativos; no corresponden a una persona ni causa real.

source vale resillia_corpus en producción. synthetic se reserva para pruebas aisladas y legaltax_corpus para diagnóstico interno. La integración del cliente no debe cambiar de comportamiento según el origen.

cases es la salida canónica. Consolida documentos pertenecientes a una misma causa y solo incluye snapshots vigentes que superaron la política automática o una revisión auditada. La integración debe utilizar participationRole, caseStatus, decisionFinality, caseResult, controllingDecision, currentEffect, economicEffects y relevance; las fuentes quedan en documentIds y evidence. matchBasis describe cómo se localizó evidencia y no sustituye la participación verificada.

summary.status distingue cuatro resultados sin exigir inferencias al cliente: no_sources cuando no se localizaron fuentes dentro de la cobertura disponible, preliminary cuando hay documentos pero ninguna causa publicable, partial cuando solo parte de las fuentes está representada por causas publicables y conclusive cuando toda la respuesta recuperada quedó consolidada. no_sources nunca debe interpretarse como certificación universal de inexistencia de procesos.

abstentions explica por qué una parte de la consulta no produjo una conclusión. Puede indicar ausencia de fuentes en la cobertura, evidencia consolidada insuficiente, cobertura parcial o identidad nominal ambigua. Una abstención no es un error técnico: evita atribuciones o efectos económicos no respaldados.

caseStatus, decisionFinality y caseResult son conceptos independientes. Por ejemplo, una causa puede estar cerrada, tener una decisión firme y haber resultado favorable para la persona consultada. Cada elemento de economicEffects incluye direction, que diferencia montos a pagar, a recibir, garantías, cauciones, embargos y fondos liberados. Los montos de causas o naturalezas distintas nunca deben sumarse como una exposición total.

La respuesta se construye desde la perspectiva de la identidad consultada. participationRole corresponde a esa persona o empresa; economicEffects excluye efectos atribuidos exclusivamente a terceros y summary describe solamente el rol, las medidas y los montos que pueden vincularse con ella. Cuando una causa tiene varios participantes y la evidencia no individualiza el resultado de fondo, caseResult permanece indeterminate. Una aparición como mentioned, lawyer o judge no se clasifica como exposición jurídica activa.

reviewStatus: "not_required" significa que la causa superó la política automática de publicación con identidad, cobertura y evidencia suficientes. approved identifica una aprobación auditada. Si la información no alcanza, Resillia se abstiene de publicar la causa en lugar de esperar una revisión humana durante la consulta.

documentarySummary ofrece una síntesis determinista inmediata cuando existen fuentes aunque cases todavía esté vacío. Informa cobertura, período, señales literales y montos mencionados; siempre lleva status: "preliminary" y reviewRequired: true. No afirma el rol de la persona, la vigencia de una medida ni que los montos correspondan a una obligación actual. Sirve para priorizar revisión y no sustituye una causa consolidada.

results está deprecado y se conserva temporalmente para compatibilidad y trazabilidad documental. Puede contener menciones aun cuando cases esté vacío; eso significa que todavía no existe una causa aprobada y no debe interpretarse como ausencia ni presencia confirmada de riesgo. Las integraciones nuevas no deben derivar conclusiones desde results.

En results, matchType: "exact" significa únicamente que el identificador normalizado fue localizado literalmente en el documento. No confirma por sí solo que el título, la carátula, el rol procesal o el efecto económico correspondan a la persona consultada; esa atribución existe únicamente dentro de una causa publicable en cases.

Errores

EstadoCódigoSignificado
400BAD_REQUESTJSON o consulta inválida
401UNAUTHORIZEDCredencial ausente, desconocida, revocada o vencida
403SERVICE_SUSPENDEDServicio suspendido para la organización
403QUERY_NOT_ALLOWEDTipo o finalidad no habilitados para la organización
409IDEMPOTENCY_CONFLICTLa clave ya se usó para una consulta diferente
409IDEMPOTENCY_IN_PROGRESSLa solicitud original continúa en proceso
413PAYLOAD_TOO_LARGEEl cuerpo supera el máximo de 16 KiB
429RATE_LIMITEDSe alcanzó el límite mensual o por minuto
503SERVICE_UNAVAILABLEFalla temporal; la unidad reservada se libera

Todas las respuestas incluyen X-Request-Id y los errores incluyen el mismo valor en el cuerpo para correlación. Las reservas mensual y por minuto son atómicas: solicitudes simultáneas no pueden superar los límites configurados. Un 429 por ráfaga incluye Retry-After.

Envía una Idempotency-Key distinta por operación lógica y reutiliza esa misma clave únicamente al reintentar la misma consulta. Durante 24 horas, una repetición completada devuelve la respuesta original con Idempotency-Replayed: true sin crear otra unidad facturable. No reutilices la clave para otro cuerpo.

Cada respuesta exitosa crea una unidad facturable y una entrada de auditoría. El registro conserva el propósito, una vista enmascarada y una huella HMAC, no la cédula, el RUC o el nombre completos. El contrato OpenAPI legible por herramientas está disponible en GET /api/v1/openapi.json. La consola Swagger navegable está disponible en GET /api/v1/docs; no conserva credenciales entre recargas y mantiene desactivada la ejecución automática de ejemplos.

JavaScript

const response = await fetch("https://api.resilia.com.py/api/v1/person-search", {
	method: "POST",
	headers: {
		"Content-Type": "application/json",
		"X-API-Key": process.env.RESILLIA_API_KEY,
		"Idempotency-Key": crypto.randomUUID(),
	},
	body: JSON.stringify({
		type: "cedula",
		value: "4567890",
		purpose: "due_diligence",
	}),
});

const result = await response.json();
if (!response.ok) throw new Error(`${result.error}: ${result.requestId}`);

Python

import os
import requests

response = requests.post(
    "https://api.resilia.com.py/api/v1/person-search",
    headers={
        "X-API-Key": os.environ["RESILLIA_API_KEY"],
        "Idempotency-Key": "operacion-interna-0001",
    },
    json={"type": "cedula", "value": "4567890", "purpose": "due_diligence"},
    timeout=15,
)
response.raise_for_status()
result = response.json()

La colección Postman versionada se encuentra en artifacts/integration/resillia-person-search.postman_collection.json dentro del repositorio.

En esta página