Autenticación
La API de KYC utiliza el grant de client-credentials de OAuth 2.0 (RFC 6749 §4.4). Su backend intercambia un client_id y un client_secret por un token Bearer de corta duración, y luego presenta ese token en cada llamada a /v1/*.
Las credenciales son exclusivamente del lado del servidor. Nunca envíe un
client_secret— ni un token de acceso — a un navegador o aplicación móvil. Sus clientes interactúan con el widget, nunca con la API.
Solicitar un Token
Endpoint: POST /oauth/token
Content-Type: application/x-www-form-urlencoded
curl --request POST \
--url https://{FQDN}/oauth/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data grant_type=client_credentials \
--data client_id=$KYC_CLIENT_ID \
--data client_secret=$KYC_CLIENT_SECRET
Las credenciales también pueden enviarse como autenticación HTTP Basic (client_secret_basic) en lugar de en el cuerpo:
curl --request POST \
--url https://{FQDN}/oauth/token \
--user "$KYC_CLIENT_ID:$KYC_CLIENT_SECRET" \
--data grant_type=client_credentials
Respuesta:
{
"access_token": "eyJhbGciOiJSUzI1NiIs…",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "sessions verifications"
}
grant_type debe ser client_credentials — es el único grant que este endpoint admite.
Scopes
Cada endpoint requiere un scope específico. Los tokens se emiten con los scopes otorgados a su cliente; solicite un conjunto más restringido con un parámetro opcional scope cuando un componente de su sistema solo necesite uno de ellos.
| Scope | Otorga acceso a |
|---|---|
sessions | POST /v1/sessions, GET /v1/sessions/{sessionId} |
verifications | POST /v1/verifications, GET /v1/verifications/{verificationId} |
Cada puerta lee en su propia ruta, y solo sus propias filas. Un token sessions lee sesiones de widget; un token verifications lee las verificaciones que creó. Ninguno alcanza los registros del otro, así que un componente de su sistema que solo envía verificaciones server-to-server no necesita más que verifications.
--data scope=sessions
Solicitar un scope desconocido se rechaza en lugar de ignorarse silenciosamente. Un token que carece del scope que un endpoint requiere devuelve 403, no 401 — el token es válido, simplemente no está autorizado para esa llamada.
Uso del Token
Presente el token como credencial Bearer:
curl --request POST \
--url https://{FQDN}/v1/sessions \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data '{"userRef": "user-123"}'
Vida Útil y Renovación del Token
Los tokens son JWT firmados con RS256 y expiran — expires_in le indica cuándo, en segundos. Almacene el token en caché y renuévelo antes de que expire; no solicite un token nuevo por cada llamada a la API, y no codifique un token de forma fija en ningún lugar.
Un cliente robusto:
- Almacena el token en memoria junto con su marca de tiempo de expiración.
- Lo renueva cuando la vida útil restante cae por debajo de un pequeño margen (30-60 segundos).
- Reintenta una vez ante un
401, por si el token expiró entre la verificación y la llamada. - Trata un
503como un fallo transitorio de infraestructura y no de autenticación — aplica backoff y reintenta con el mismo token.
Respuestas de Error
Los errores del endpoint de tokens siguen la RFC 6749 §5.2 — un código error con una error_description legible:
| Estado | error | Causa |
|---|---|---|
400 | unsupported_grant_type | grant_type estaba ausente o no era client_credentials |
400 | invalid_scope | El scope solicitado contiene un valor desconocido |
401 | invalid_client | Credenciales de cliente faltantes, desconocidas o incorrectas. La respuesta incluye un desafío WWW-Authenticate: Basic |
{
"error": "invalid_client",
"error_description": "Missing client credentials"
}
Todo rechazo en una llamada /v1/* — no solo de autenticación — responde con el mismo documento RFC 9457 application/problem+json. Ramifique por errorCode; errors[] nombra los campos a los que se aplica un fallo de validación, y lleva una entrada sin field para un rechazo que no trata de un campo.
{
"type": "docs#/components/schemas/ProblemDetails",
"title": "Unauthorized",
"status": 401,
"errorCode": "unauthorized",
"errors": [
{ "message": "Missing Bearer token (obtain one at POST /oauth/token)", "type": "unauthorized" }
],
"correlationId": "c0d60e879b6d412488ffe83d5213aa8b",
"instance": "/v1/sessions/nope"
}
Cite el correlationId al contactar con soporte — identifica la solicitud exacta en nuestros registros. El endpoint de token es la única excepción: POST /oauth/token sigue la RFC 6749 como se muestra arriba.
Errores en llamadas a /v1/*:
| Estado | Causa | Cómo corregirlo |
|---|---|---|
401 | Falta el encabezado Authorization: Bearer | Envíe el encabezado; obtenga un token en POST /oauth/token |
401 | Token expirado | Renueve el token y reintente |
401 | Token inválido o no verificable | Confirme que está usando el token textualmente y contra el entorno correspondiente |
403 | El token es válido pero carece del scope del endpoint | Solicite un token que incluya el scope requerido |
503 | No se pudo contactar al proveedor de identidad para verificar la firma del token | Reintente con backoff — su token sigue siendo válido |
La respuesta 403 incluye WWW-Authenticate: Bearer error="insufficient_scope" indicando el scope que se requería.
Un 503 es transitorio y no es un fallo de autenticación. Sus credenciales y su token en caché no se ven afectados — Inyo no pudo contactar al proveedor de identidad para verificar la firma del token. Reintente con backoff exponencial y conserve el token que ya tiene: volver a autenticarse no ayuda, y una llamada a POST /oauth/token durante la misma interrupción probablemente también fallará.
{
"errorCode": "service_unavailable",
"errors": [
{ "message": "Identity provider unreachable — cannot verify access tokens", "type": "service_unavailable" }
]
}
Aislamiento de Entornos
Sandbox y producción emiten credenciales separadas, y cada token es válido únicamente en el entorno que lo emitió. Las sesiones están estrictamente limitadas al tenant que las creó: un token nunca puede leer la sesión de otro tenant, y una solicitud por una devuelve 404.
Rotación de su Secreto
Los secretos de cliente son rotados por Inyo a solicitud — contacte a su representante de Inyo en lugar de intentar la rotación a través de la API. Rote de inmediato si un secreto pudo haber sido expuesto.
Próximos Pasos
- Primeros Pasos — ejecute una verificación completa con su nuevo token
- Sesiones de Verificación — todos los campos de
POST /v1/sessions
