1Visión general
Kiai Verify ejecuta consultas asíncronas contra fuentes oficiales (RUNT, SIMIT, RUAF, OFAC, entre otras), agrupadas en perfiles (por ejemplo "Conductor", "Vehículo" o "Background Check"). Tu sistema envía una o varias personas a verificar y, cuando las consultas terminan, recibe un reporte PDF y los datos de cada fuente.
Flujo resumido
| # | Método | Endpoint | Respuesta |
|---|---|---|---|
| 1 | POST | /oauth/token | accessToken (TTL 15 min) |
| 2 | POST | /profiles/consultation-parameters | Campos requeridos |
| 3 | POST | /verifications | verificationId + process |
| 4a | GET | /verifications/{id}/result | 202 PENDING (repetir) → 200 SUCCESS + data + PDF |
| 4b | POST | (callback a tu urlCallback) | Mismo payload de 4a |
El paso 4 tiene dos modalidades; elige la que mejor encaje en tu arquitectura:
- Polling (
GET /verifications/{id}/result): tu sistema consulta cada 10 segundos hasta recibir 200. Elides elverificationIdque te devolvió la creación. - Callback: Kiai hace
POSTalurlCallbackque registraste. Tu servidor debe responder 2xx en menos de 30 s.
Ambas devuelven el mismo payload.
2Acceso y credenciales
Kiai te entrega por un canal seguro:
clientId(permanente).clientSecret(se muestra una sola vez; no se puede recuperar, solo rotar).- La lista de
profileIdautorizados para tu empresa. - La dirección base (
baseUrl) del entorno de pruebas y, cuando certifiques tu integración, la de producción. - (Opcional) Si quieres callback, entrégale a Kiai la URL pública de tu
urlCallback.
- Almacena las credenciales en un gestor de secretos; nunca las subas a tu repositorio.
- Usa el entorno de pruebas hasta certificar tu integración.
clientId se mantiene. Tus integraciones activas dejan de funcionar hasta que despliegues el nuevo.3Autenticación: OAuth 2.0 (client_credentials)
3.1 Solicitar token
POST{{baseUrl}}/api/v1/external/oauth/token
Headers: Content-Type: application/json
{
"clientId": "tu-client-id",
"clientSecret": "tu-client-secret"
}{
"accessToken": "eyJhbGciOi...",
"tokenType": "Bearer",
"expiresIn": 900
}- TTL: 900 s (15 min). Pide uno nuevo antes de que expire.
- Límite: 10 req/min por IP. No lo pidas en cada llamada: guarda el token en memoria hasta que falten 30 s para expirar.
- Cabeceras de respuesta:
Cache-Control: no-store,Pragma: no-cache.
3.2 Errores
| Código | error | Causa |
|---|---|---|
| 400 | invalid_request | Falta clientId o clientSecret. |
| 401 | invalid_client | Credenciales incorrectas, revocadas o inactivas. |
| 429 | — | Límite por IP excedido. |
La respuesta 401 no indica si falló el clientId o el clientSecret (protección contra enumeración).
3.3 Usar el token
En todas las llamadas siguientes:
Authorization: Bearer eyJhbGciOi...4Consultar parámetros de perfiles
Antes de crear una verificación necesitas saber qué campos exige cada perfil. Cambia según el tipo de consulta (persona natural, vehículo, empresa…) y según la configuración pactada con tu empresa. Por ejemplo, los perfiles de vehículos exigen plate y los de personas naturales document_type + document_number.
4.1 Endpoint
POST{{baseUrl}}/api/v1/external/profiles/consultation-parameters
Headers: Authorization: Bearer {{externalToken}}, Content-Type: application/json
{ "profileIds": [123, 456] }[
{
"profileId": 123,
"name": "Perfil Conductor",
"fields": [
{ "name": "document_type", "required": true, "options": ["CC", "CE", "PPT"] },
{ "name": "document_number", "required": true }
]
}
]4.2 Reglas
- Máximo 100 profileIds por request.
- Los
profileIdsajenos a tu empresa no se devuelven y causan403 forbiddensi no hay ninguno válido. - El orden de
fieldses el orden en que se esperan en el body de creación: úsalo como contrato. - Límite: 10 req/min por IP.
4.3 Errores
| Código | error | Causa |
|---|---|---|
| 400 | invalid_request | profileIds vacío o ausente. |
| 401 | — | Token ausente, expirado o revocado. |
| 403 | forbidden | Todos los profileIds son de otra empresa. |
5Crear verificación
Encola una o varias verificaciones. El endpoint responde de inmediato con verificationId y process; el procesamiento toma de segundos a unos pocos minutos. Consulta el resultado por polling o configura un urlCallback.
5.1 Endpoint
POST{{baseUrl}}/api/v1/external/verifications
Headers: Authorization: Bearer {{externalToken}}, Content-Type: application/json
{
"profiles": [
{
"profileId": 123,
"persons": [
{
"document_type": "CC",
"document_number": "1234567890",
"first_name": "Juan",
"last_name": "Perez"
}
]
}
]
}{
"verificationId": 98765,
"process": "d3b45f40-c9c7-4c6a-9f84-1a2b3c4d5e6f",
"status": "PROCESSING",
"createdAt": "2026-04-22T14:30:00Z"
}verificationId: entero estable que identifica la verificación. Guárdalo: es la llave para el polling y también llega en el callback.process: GUID interno de correlación, útil para soporte y logs.statussiempre esPROCESSINGal inicio.
Varias personas en un perfil
Una sola llamada agrupa N personas en el mismo perfil. Internamente se crea un verification_profile por persona y los resultados se devuelven indexados en el mismo orden (0..N-1).
{
"profiles": [
{
"profileId": 123,
"persons": [
{ "document_type": "CC", "document_number": "1234567890", "first_name": "Juan", "last_name": "Perez" },
{ "document_type": "CC", "document_number": "9876543210", "first_name": "Maria", "last_name": "Gomez" }
]
}
]
}5.2 Límites
- Máximo 10 perfiles por request.
- Máximo 50 personas en total (suma de
personsentre todos los perfiles). - Límite: 30 req/min por IP.
- Todos los perfiles deben pertenecer al mismo
CompanyCountry(no puedes mezclar países).
5.3 Errores
| Código | error | Causa |
|---|---|---|
| 400 | invalid_request | Body mal formado, profiles vacío, algún persons vacío o profileIds duplicados. |
| 400 | missing_fields | Alguna persona no trae los campos requeridos; error_description indica cuáles. |
| 400 | too_many_profiles | Más de 10 perfiles en la request. |
| 400 | too_many_persons | Más de 50 personas en total. |
| 400 | mixed_company_country | Perfiles de distintos países en la misma request. |
| 401 | — | Token inválido. |
| 403 | forbidden | Algún profileId no pertenece a tu empresa. |
| 403 | profile_inactive | Algún perfil está deshabilitado. |
| 429 | — | Límite excedido. |
5.4 Ejemplo de missing_fields
{
"error": "missing_fields",
"error_description": "profileId=123 personIndex=0: document_type, document_number"
}personIndex es el índice de la persona dentro del persons de ese perfil (empieza en 0). Usa el paso 4 para conocer los campos exigidos antes de enviar.
6Obtener el resultado
Una vez creada la verificación, las consultas tardan entre segundos y unos pocos minutos. Tienes dos formas de recibir el resultado; el payload es idéntico en ambas.
6.1 Opción A: polling
GET{{baseUrl}}/api/v1/external/verifications/{id}/result
Donde {id} es el verificationId que te devolvió POST /verifications. Headers: Authorization: Bearer {{externalToken}}
Límite: 1 request cada 10 segundos por combinación (cliente OAuth, id). Puedes consultar varias verificaciones a la vez sin bloquearte, pero una misma verificación no acepta más de una request cada 10 s; si te excedes recibes 429.
| Código | Significado |
|---|---|
| 200 | Verificación terminada. Body completo (ver 6.3). |
| 202 | Aún en proceso: { verification_id, status: "PENDING" }. Reintenta en 10 s. |
| 400 | El id no es un entero positivo válido. |
| 401 | Token ausente o expirado. |
| 403 | El id pertenece a otro cliente OAuth. |
| 404 | El id no existe. |
| 429 | Límite superado; espera. |
while True:
resp = GET /verifications/{id}/result
if resp.status == 200:
handle_result(resp.body)
break
elif resp.status == 202:
sleep(10)
elif resp.status == 429:
sleep(10)
else:
log_error(resp)
breakAñade un tiempo máximo global (por ejemplo 15 min) y un corte por si el proceso queda atascado.
6.2 Opción B: callback
Si registraste un urlCallback al crear tu credencial OAuth, Kiai hace POST a esa URL con el payload de 6.3 en cuanto el proceso termina. Requisitos de tu endpoint:
- HTTPS obligatorio.
- Responder 2xx en menos de 30 segundos.
- Ser idempotente: se puede reintentar la entrega si responde 5xx.
- Verificar que
verification_id/processcorresponden a una request tuya (no confíes ciegamente en el body; valida contra tu estado local).
6.3 Payload del resultado
{
"verification_id": 98765,
"status": "SUCCESS",
"result": "APTO",
"pdf_base64": "JVBERi0xLjQK...",
"data": {
"123": [
{
"id": "1234567890",
"runt_vehiculo": {
"status": "SUCCESS",
"data": { /* respuesta de la fuente */ },
"message": "Consulta exitosa"
},
"runt_remolque": {
"status": "FAILURE",
"data": null,
"message": "No se pudo completar la consulta"
}
}
]
}
}verification_id: entero, tu identificador.status:"SUCCESS"o"FAILURE".result: veredicto global,"APTO"o"NO_APTO".pdf_base64: el reporte PDF en base64. Puede venirnullsi falló la generación del PDF pero los datos sí están.data: objeto cuyas llaves son elprofileIdcomo texto y cuyos valores son la lista de personas en el orden original (0..N-1). Cada persona trae:id: identificador de la persona (priorizadocument_number, luegoname, luegofirst_name+last_name).- Una llave por cada fuente consultada. Si una falla, el resto sigue apareciendo con sus datos; solo la fallida trae
status: "FAILURE". Cada fuente devuelvestatus(SUCCESS|FAILURE|NOT_PRESENT),data(JSON de la fuente onull) ymessage(descripción legible).
{
"verification_id": 98765,
"status": "FAILURE",
"error": "El proceso de verificación falló"
}FAILURE significa que ninguna fuente pudo producir un resultado válido. En ese caso no se generan el veredicto global ni el PDF.
{ "verification_id": 98765, "status": "PENDING" }6.4 PDF
El campo pdf_base64 trae el reporte completo (con la marca de tu empresa, el perfil evaluado y el resultado de cada fuente). Decodifícalo y guárdalo:
import base64
with open(f"verification_{process}.pdf", "wb") as f:
f.write(base64.b64decode(payload["pdf_base64"]))7Semántica de result
| Valor | Significado |
|---|---|
APTO | Todas las reglas configuradas se cumplen. La persona pasa el filtro. |
NO_APTO | Al menos una regla crítica falla. |
Las reglas que producen este veredicto están configuradas en el perfil; escríbenos si necesitas modificarlas.
8Límites de uso
| Endpoint | Límite | Partición |
|---|---|---|
POST /oauth/token | 10 req/min | IP |
POST /profiles/consultation-parameters | 10 req/min | IP |
POST /verifications | 30 req/min | IP |
GET /verifications/{id}/result | 1 req / 10 s | Cliente OAuth + id |
Si excedes alguno recibes 429 Too Many Requests. La cabecera Retry-After (cuando aplica) indica cuántos segundos esperar.
9Checklist de integración
- Guarda el
accessTokenen memoria y reúsalo hasta 30 s antes de que expire. - Guarda el
verificationIden tu base: es la llave del polling. Guarda también elprocesspara soporte. - Implementa el polling con espera progresiva (10 s base, con variación aleatoria opcional) y un tiempo máximo global.
- Si usas callback: HTTPS, respuesta 2xx en menos de 30 s y validación contra tu estado local.
- Registra
verification_idyprocessen cada request para soporte. - Maneja explícitamente los tres estados de cada fuente (
SUCCESS/FAILURE/NOT_PRESENT):status=SUCCESSno implica datos completos. - Prueba en el entorno de pruebas antes de pedir producción.
10Soporte y resolución de problemas
| Síntoma | Causa probable |
|---|---|
| 401 invalid_client persistente | Secret revocado o rotado; pide nuevas credenciales. |
| 403 forbidden en la creación | El profileId no está autorizado para tu empresa. Confírmalo con Kiai. |
| El polling siempre devuelve 202 | El proceso quedó atascado; reporta el verificationId y el process a Kiai. |
| El callback nunca llega | Tu urlCallback respondió 5xx o tardó demasiado. Usa el polling como respaldo. |
| pdf_base64 viene null | Falló la generación del PDF pero los datos están. Consulta data y, si necesitas el PDF, repórtalo. |
| data vacío pero status=SUCCESS | Verificación sin fuentes asignadas en el perfil. Revisa la configuración del perfil. |
Ante cualquier incidente, repórtalo a Kiai con el process, el verificationId, la fecha y hora, y el payload recibido (sin el base64, para no saturar el mensaje).
AAnexos
A. Variables de la colección Postman
Kiai te entrega también una colección Postman con estas llamadas y sus pruebas automáticas. Orden sugerido para el caso completo: autenticación → parámetros → crear verificación → consultar resultado.
| Variable | Se llena con |
|---|---|
baseUrl | Dirección del entorno (pruebas o producción) que te entrega Kiai. |
clientId | Lo entrega Kiai. |
clientSecret | Lo entrega Kiai (una sola vez). |
profileId | Lo entrega Kiai o lo obtienes del paso 4. |
externalToken | Automático: lo guarda la prueba de autenticación. |
verificationId | Automático: lo guarda la prueba de creación y lo usa la de resultado. |
process | Automático: lo guarda la prueba de creación, para soporte. |
B. Glosario
- Perfil (profile): conjunto preconfigurado de fuentes y reglas que define qué se valida de cada persona.
- Fuente (source): base de datos que se consulta (RUNT, SIMIT, OFAC, etc.).
- Regla (rule): condición evaluada sobre los datos devueltos por una fuente; produce APTO / NO_APTO / ALERTA.
- verification_id: entero único asignado a cada verificación; es la llave pública para el polling y aparece en el callback.
- process: GUID interno de correlación, útil para reportar incidentes a soporte.