Saltar al contenido principal

Autenticación y convenciones

Credenciales​

FINORA emite las primeras credenciales al dar de alta tu cuenta; después las gestionas tú en /v1/credenciales. El prefijo decide el entorno sobre la misma URL:

PrefijoEntorno
kyc_live_…Producción
kyc_test_…Sandbox: gemelo de tu cuenta con datos separados. Ver Sandbox.

Tu cuenta (el tenant) se deduce siempre de la credencial, nunca del cuerpo de la petición. De cada secreto solo se guarda su hash: se muestra una vez, al emitirlo o rotarlo.

Los ejemplos de estas guías usan dos variables:

export KYC_BASE=https://kyc.finoracore.com
export KYC_API_KEY=kyc_test_… # se muestra una sola vez al emitirla

API key​

Envía la clave en la cabecera X-API-Key:

curl -s "$KYC_BASE/v1/eventos" -H "X-API-Key: $KYC_API_KEY"

OAuth 2.0 client credentials​

Recomendado para sistemas centrales. Emite una credencial de tipo OAUTH_CLIENT: su id (cre_…) es el client_id y su secreto (kcs_…) es el client_secret. Envíalos por autenticación básica o en el cuerpo.

curl -s -u "cre_01J9Z3K8Q2W7XPT4M6N5R0B1CQ:kcs_…" \
-d grant_type=client_credentials \
-d scope="casos:escribir casos:leer" \
"$KYC_BASE/oauth2/token"
{
"access_token": "eyJhbGciOiJSUzI1NiJ9…",
"token_type": "Bearer",
"expires_in": 599,
"scope": "casos:escribir casos:leer"
}
curl -s "$KYC_BASE/v1/casos/$CASO" -H "Authorization: Bearer $TOKEN"
  • El token es un JWT RS256 de 10 minutos. Pide uno nuevo antes de que venza.
  • Sin scope, el token lleva todos los alcances del cliente.
  • Los errores de este endpoint siguen RFC 6749 (invalid_client, invalid_scope…), que es lo que esperan las bibliotecas OAuth.

Alcances​

AlcancePermite
casos:escribirCrear casos, subir documentos y selfie, enviar y crear enlaces.
casos:leerConsultar casos y eventos.
screeningScreening suelto y monitoreo.
listas:gestionarListas propias y sus entradas.
webhooks:gestionarDestinos de webhooks, rotación de secreto, pruebas y reenvíos.
credenciales:gestionarEmitir, rotar y revocar credenciales.

Una credencial no puede conceder alcances que no tiene: pedirlos responde 403 ALCANCE_INSUFICIENTE.

Emitir, rotar y revocar​

# Emitir una API key solo para leer casos
curl -s -X POST "$KYC_BASE/v1/credenciales" \
-H "X-API-Key: $KYC_API_KEY" -H "Idempotency-Key: cred-lectura-1" \
-H "Content-Type: application/json" \
-d '{"tipo":"API_KEY","nombre":"Tablero de cumplimiento","alcances":["casos:leer"]}'

# Rotar sin corte: el secreto anterior sigue valiendo 24 h (graciaSegundos, máximo 7 días)
curl -s -X POST "$KYC_BASE/v1/credenciales/$CRED/rotar" \
-H "X-API-Key: $KYC_API_KEY" -H "Idempotency-Key: rotar-$CRED-1" \
-H "Content-Type: application/json" -d '{"graciaSegundos":86400}'

# Revocar de forma irreversible
curl -s -X POST "$KYC_BASE/v1/credenciales/$CRED/revocar" \
-H "X-API-Key: $KYC_API_KEY" -H "Idempotency-Key: revocar-$CRED-1" \
-H "Content-Type: application/json" -d '{"motivo":"Equipo dado de baja"}'

La emisión y la rotación responden con el secreto una sola vez. Una credencial revocada responde 401 al instante, también con un JWT que aún no vence.

Idempotencia​

Toda escritura (POST) exige Idempotency-Key: de 8 a 128 caracteres de [A-Za-z0-9._:-]. Reutiliza la misma clave al reintentar una petición que no sabes si llegó.

SituaciónRespuesta
Misma clave y misma petición (método, ruta y cuerpo) en 24 hLa misma respuesta, con Idempotent-Replayed: true
Misma clave con otra petición409 IDEMPOTENCIA_CONFLICTO
La primera sigue en curso409 IDEMPOTENCIA_EN_CURSO, con Retry-After
Sin la cabecera400 IDEMPOTENCIA_REQUERIDA

Un error 5xx libera la clave para que puedas reintentar.

Errores​

Los errores siguen RFC 9457 (application/problem+json). Ramifica por codigo, que es estable; el texto de title puede cambiar.

{
"type": "urn:finora:kyc:seguridad:no-autenticado",
"title": "Credencial ausente o inválida",
"status": 401,
"codigo": "NO_AUTENTICADO"
}
HTTPcodigoCuándo
400SOLICITUD_INVALIDA, IDEMPOTENCIA_REQUERIDACuerpo o parámetros mal formados; falta Idempotency-Key.
401NO_AUTENTICADOFalta la credencial, no es válida o fue revocada.
403ALCANCE_INSUFICIENTE, TENANT_SUSPENDIDOLa credencial no tiene el alcance; FINORA suspendió la cuenta (la credencial sigue siendo buena y no hace falta rotarla).
404NO_ENCONTRADONo existe o pertenece a otra cuenta: nunca se distingue.
409TRANSICION_INVALIDA, IDEMPOTENCIA_CONFLICTO, IDEMPOTENCIA_EN_CURSOEl estado del caso no admite la operación; conflictos de idempotencia.
422Código del dominio, por ejemplo RIF_INVALIDOUn dato viola una regla. errores[] trae el detalle por campo.
429RITMO_EXCEDIDO, CUOTA_MENSUAL_EXCEDIDARitmo por minuto o cuota mensual del plan. Respeta Retry-After.
503CUSTODIA_NO_DISPONIBLELa custodia criptográfica no está disponible: no se aceptan documentos. Reintenta más tarde.

Límites​

Cada plan fija un ritmo por minuto y cuotas mensuales de casos y de screening. Las respuestas traen X-RateLimit-Limit y X-RateLimit-Remaining; al exceder se responde 429 con Retry-After en segundos.

Versionado​

info.version del contrato sigue SemVer. Un cambio que rompe a un integrador (quitar un campo, cambiar un tipo o un código de error) sube la versión mayor y la ruta pasa a /v2. Añadir campos opcionales, operaciones o valores de enumeración es un cambio menor: tu código debe ignorar lo que no conoce.