Verificación de identidad
Antes de firmar con un certificado que emite Datil, cada firmante verifica su identidad en intentos. Cada intento ejecuta, en orden, todos los controles que exige el flujo (
identity_checks
): un intento aprueba solo si aprueban todos, y el primer control que falla termina el intento. Un control que no pudo ejecutarse porque un servicio externo no respondió (
not_run
) no consume el intento: la persona repite ese paso. Sin
max_attempts
(
null
, el valor por defecto) los intentos no tienen límite y ningún caso pasa a revisión. Con
max_attempts
intentos fallidos, más los que conceda una revisión, el caso pasa a revisión: la página de firma se detiene, se avisa a
review_emails
y el caso espera una decisión. La revisión aprueba (solo si un intento probó una persona real con AWS Face Liveness; la persona firma con esa evidencia), concede de 1 a 10 intentos más o rechaza (la persona no puede seguir con ese enlace). Estas rutas nunca devuelven imágenes ni datos biométricos.
Consultar la verificación de un firmante#
/api/v1/signature-requests/:reference_id/signers/:national_id/identity
Bearer
El resumen de la verificación de una persona y cada uno de sus intentos, del más reciente al más antiguo, con el veredicto, el motivo y las mediciones de cada control.
reference_id
string
requerido
Tu número de trámite.
national_id
string
requerido
La cédula del firmante.
environment
string
production
por defecto;
test
consulta una prueba.
productiontest
Devuelve
·
200
con el resumen y los intentos ·
404 not_found
·
401
sin llave válida.
curl "https://edge.datil.com/api/v1/signature-requests/CRED-2026-0001/signers/:national_id/identity" \
-H "Authorization: Bearer $DATIL_API_KEY"
{
"ok": true,
"reference_id": "CRED-2026-0001",
"national_id": "0919372607",
"identity": {
"status": "in_review",
"attempts_used": 3,
"attempts_allowed": 3,
"attempts_remaining": 0,
"required_checks": [
"registry",
"environment",
"liveness",
"face_match"
],
"review": {
"state": "pending",
"note": null,
"reviewed_by": null,
"at": "2026-08-25T14:20:00Z"
}
},
"attempts": [
{
"id": "7e2a4c6f-1b3d-4f5a-9c7e-2d4f6a8c0e1b",
"number": 3,
"ceremony_revision": 0,
"status": "failed",
"started_at": "2026-08-25T14:18:00Z",
"finished_at": "2026-08-25T14:19:30Z",
"failed_check": "face_match",
"failure_reason": "La similitud no alcanzó el umbral del flujo.",
"required_checks": [
"registry",
"environment",
"liveness",
"face_match"
],
"policy": {
"id_card": "off",
"active_challenge": false,
"face_quality": false,
"face_match_threshold": 90.0,
"environment": "record",
"signature_graphic": false,
"max_attempts": 3,
"review_emails": [
"cumplimiento@example.com"
]
},
"checks": [
{
"key": "liveness",
"verdict": "passed",
"reason": "AWS confirmó una persona real frente a la cámara.",
"measurements": {
"confidence": 98.4,
"session_id": "a1b2c3d4"
},
"at": "2026-08-25T14:19:10Z"
}
]
}
]
}
Decidir un caso en revisión#
/api/v1/signature-requests/:reference_id/signers/:national_id/identity/review
Bearer
La decisión sobre un caso que agotó sus intentos. Queda registrada con la llave como revisora (
review.reviewed_by
) y avisa al firmante cuando aprueba o concede intentos, igual que la cola de revisión de la consola.
Content-Type: application/json
reference_id
string
requerido
Tu número de trámite.
national_id
string
requerido
La cédula del firmante.
decision
string
requerido
approve
: la persona continúa a la firma con la evidencia del último intento en el que AWS Face Liveness aprobó.
grant_attempts
: concede
attempts
intentos más.
reject
: la persona no puede continuar con este enlace.
approvegrant_attemptsreject
attempts
integer
Con
grant_attempts
: cuántos intentos se conceden, de 1 a 10.
note
string
Nota de la decisión. Hasta 2000 caracteres.
environment
string
production
por defecto;
test
decide sobre una prueba.
productiontest
Devuelve
·
200
con el resumen actualizado ·
409 not_in_review
si el caso no está en revisión ·
409 no_live_attempt
al aprobar sin un intento con prueba de vida aprobada ·
422
con
invalid_value:decision
,
required:attempts
,
out_of_range:attempts
o
too_long:note
·
404 not_found
.
curl -X POST https://edge.datil.com/api/v1/signature-requests/CRED-2026-0001/signers/:national_id/identity/review \
-H "Authorization: Bearer $DATIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"decision": "grant_attempts",
"attempts": 2,
"note": "La luz del primer intento era insuficiente."
}'
{
"ok": true,
"reference_id": "CRED-2026-0001",
"national_id": "0919372607",
"identity": {
"status": "failed",
"attempts_used": 3,
"attempts_allowed": 5,
"attempts_remaining": 2,
"required_checks": [
"registry",
"environment",
"liveness",
"face_match"
],
"review": {
"state": null,
"note": "La luz del primer intento era insuficiente.",
"reviewed_by": "API · Core bancario (dtl_a1b2c3d4…)",
"at": "2026-08-25T14:20:00Z"
}
}
}
Listar los casos en revisión#
/api/v1/identity-reviews
Bearer
Los firmantes de tu organización cuyo caso espera una decisión, del más antiguo al más reciente.
Devuelve
·
200
con los casos ·
401
sin llave válida.
curl "https://edge.datil.com/api/v1/identity-reviews" \
-H "Authorization: Bearer $DATIL_API_KEY"
{
"ok": true,
"reviews": [
{
"signer_id": "3c1f7a9e-2b4d-4e6f-8a1c-5d7b9e1f3a5c",
"reference_id": "CRED-2026-0001",
"environment": "production",
"national_id": "0919372607",
"name": "Juan Pérez",
"email": "juan@example.com",
"review_requested_at": "2026-08-25T14:20:00Z",
"identity": {
"status": "in_review",
"attempts_used": 3,
"attempts_allowed": 3,
"attempts_remaining": 0,
"required_checks": [
"registry",
"environment",
"liveness",
"face_match"
],
"review": {
"state": "pending",
"note": null,
"reviewed_by": null,
"at": "2026-08-25T14:20:00Z"
}
}
}
]
}
El resumen de verificación#
identity
en la consulta de la solicitud, en el webhook final, en los eventos
signer.*
y en las rutas de esta sección.
status
string
failed
: el último intento falló y quedan intentos.
in_review
: se agotaron y el caso espera una decisión.
approved
y
rejected
son decisiones de revisión.
not_startedin_progresspassedfailedin_reviewapprovedrejected
attempts_used
integer
Intentos fallidos en el enlace vigente. Un intento abandonado no cuenta.
attempts_allowed
integer | null
max_attempts
del flujo más los intentos que concedió una revisión;
null
cuando el flujo no fija un límite.
attempts_remaining
integer | null
Intentos que la persona puede iniciar;
null
sin límite.
required_checks
array
Los controles que exige el flujo, en orden. En un dispositivo de riesgo,
environment: adapt
agrega
active_challenge
y
face_quality
al intento.
review.state
string
null
mientras el caso no pasó por revisión.
pendingapprovedrejected
review.note
string
La nota de la última decisión.
review.reviewed_by
string
Quién decidió: el correo del revisor o la llave de API.
review.at
string
Cuándo cambió la revisión.
El intento y sus controles#
Cada intento lista sus controles en el orden en que corren.
measurements
lleva solo números, banderas y textos cortos (similitud, confianza, identificadores de sesión, resúmenes criptográficos); nunca imágenes. Claves de control, en orden:
registry
,
environment
,
id_card_front
,
id_card_back
,
active_challenge
,
liveness
,
face_quality
,
face_match
,
signature_graphic
.
status
string
abandoned
: la persona recargó o abrió otra pestaña. No cuenta como intento.
in_progresspassedfailedabandoned
number
integer
Número del intento en el enlace.
ceremony_revision
integer
Versión del enlace de firma; un enlace nuevo empieza su propia cuenta.
failed_check
string
El control que terminó el intento.
failure_reason
string
Por qué falló, en español.
required_checks
array
Los controles que exigió el intento.
policy
objeto
La configuración
identity_checks
con la que corrió.
checks[].key
string
La clave del control.
checks[].verdict
string
not_run
: un servicio externo no respondió; no consume el intento.
passedfailednot_runpending
checks[].reason
string
El motivo del veredicto, en español.
checks[].measurements
objeto
Las mediciones del control.
checks[].at
string
Cuándo se registró el resultado.
La configuración identity_checks#
La verificación que exige un flujo (
flows[].identity_checks
). Todo flujo ejecuta la base:
registry
(cédula y código dactilar contra el Registro Civil),
environment
(clasifica el dispositivo),
liveness
(AWS Face Liveness) y
face_match
(la captura contra la foto del Registro Civil). Estos campos agregan controles y fijan cómo se aplican. La configuración queda congelada en cada solicitud al crearse.
id_card
string
Foto de la cédula física, tomada en la página.
front
: se verifican el NUI, los apellidos y la foto contra el Registro Civil, y que no sea una foto de una pantalla.
front_and_back
: además el código dactilar impreso, que no esté caducada y que sea la cédula vigente. Por defecto
off
.
offfrontfront_and_back
active_challenge
boolean
Prueba de vida guiada antes de AWS: centrar el rostro, parpadear, girar la cabeza a un lado al azar y abrir la boca. No se graba video. Por defecto
false
.
face_quality
boolean
La captura debe tener un solo rostro, de frente, nítido, con buena luz y sin partes cubiertas antes de compararse. Por defecto
false
.
face_match_threshold
number
Similitud mínima, en porcentaje, entre la captura y la foto del Registro Civil. De 90 (el mínimo de la plataforma) a 99.5. Por defecto 90.
environment
string
record
: clasifica y guarda el dispositivo y la cámara.
adapt
: además rechaza entornos automatizados o con cámara virtual, y en un computador o un navegador dentro de otra app exige
active_challenge
y
face_quality
. Por defecto
record
.
recordadapt
signature_graphic
boolean
Dibuja en cada sello visible la firma manuscrita que guarda el Registro Civil; si no la tiene, el sello muestra «NO FIRMA». Por defecto
false
.
max_attempts
integer | null
Intentos antes de que el caso pase a revisión, de 1 a 10.
null
(por defecto): sin límite de intentos y sin revisión.
review_emails
array
Correos que reciben un aviso cuando un caso pasa a revisión. Por defecto
[]
.