Descripción general
Cada informe por función sigue la estructura del serializador V3 definida enservice-didit-verification. El mismo objeto aparece en tres lugares, así que el esquema que ves aquí es la única fuente de verdad para todos ellos:
GET /v3/session/{sessionId}/decision/: cada función se devuelve como un array con nombre en plural (id_verifications[],nfc_verifications[],liveness_checks[],face_matches[],poa_verifications[],phone_verifications[],email_verifications[],aml_screenings[],ip_analyses[],database_validations[],questionnaire_responses[],signatures[],bank_verifications[](consulta Métodos de verificación bancaria) y los equivalentes de KYBregistry_checks[],document_verifications[],key_people_checks[]).- Payloads de webhook (
status.updated,data.updated): la misma estructura dentro del envoltoriodecision. - APIs independientes: las respuestas de un solo objeto (Búsqueda facial, Estimación de edad, Autenticación biométrica) reutilizan el mismo conjunto de campos.
V3 introdujo los flujos de trabajo multiinstancia: cada objeto de función incluye un
node_id que vincula el informe al nodo del grafo del flujo que lo generó. Los endpoints V2 (en singular: kyc, face, aml, etc.) siguen siendo retrocompatibles, pero solo devuelven la primera instancia.Campos comunes
Cada objeto de informe expone lo siguiente:| Campo | Tipo | Descripción |
|---|---|---|
status | string | Estado del ciclo de vida a nivel de función: uno de los valores de Enum de estados. Origen: common/config/choices.py:FeatureStatusChoices (líneas 343-348). El status de nivel superior de la sesión padre usa el enum de sesión, más amplio (StatusChoices, líneas 106-117). |
node_id | string | null | Identificador del nodo del grafo del flujo. Se rellena en los flujos V3 multiinstancia; null en las sesiones heredadas de una sola función. |
warnings | array de objetos de advertencia | Señales de riesgo filtradas para esta función y este node_id. Las devuelve Session.get_logs(...) (sessions/models/session.py:1611). |
portrait_image, front_image, document_file, …) son URLs prefirmadas con un periodo de validez limitado: descárgalos cuanto antes en lugar de guardar la URL. Los ejemplos los muestran como https://<media-host>/....
Objeto de advertencia
Se devuelve en cada arraywarnings[]. Esquema de logs/serializers/log.py:8-65 (LogV3Serializer).
| Campo | Tipo | Admite null | Descripción | Ejemplo |
|---|---|---|---|---|
feature | string (enum) | No | Función que emitió la advertencia. Valores de LogWarningChoices (common/config/choices.py:190-204): ID_VERIFICATION, NFC, LIVENESS, FACEMATCH, PROOF_OF_ADDRESS, PHONE, EMAIL, AML, LOCATION, DATABASE_VALIDATION, QUESTIONNAIRE, KYB_REGISTRY, KYB_DOCUMENTS, KYB_KEY_PEOPLE. | "ID_VERIFICATION" |
risk | string | No | Código de riesgo estable (p. ej., DOCUMENT_EXPIRED, LOW_LIVENESS_SCORE). Valores de logs/choices.py:RiskChoices. Se usa como clave en las tablas de descripciones. | "DOCUMENT_EXPIRED" |
additional_data | object | null | Sí | Contexto específico del riesgo (p. ej., umbrales de puntuación, campos coincidentes). La estructura varía según el código de riesgo. | { "score": 42.1, "threshold": 70 } |
log_type | string (enum) | No | Uno de error, warning, information. De LogTypeChoices (common/config/choices.py:207-210). | "error" |
short_description | string | No | Etiqueta legible del riesgo. De logs/choices.py:RISK_SHORT_DESCRIPTIONS. | "Document expired" |
long_description | string | No | Explicación legible más extensa, adecuada para interfaces dirigidas al usuario final. De logs/choices.py:RISK_LONG_DESCRIPTIONS. | "The document's expiration date has passed, rendering it no longer valid for use." |
node_id | string | null | Sí | Nodo del grafo del flujo para el que se generó la advertencia. null en los registros V2 heredados sin node_id. | "first_id_verification" |
{
"feature": "ID_VERIFICATION",
"risk": "DOCUMENT_EXPIRED",
"additional_data": null,
"log_type": "error",
"short_description": "Document expired",
"long_description": "The document's expiration date has passed, rendering it no longer valid for use.",
"node_id": "first_id_verification"
}
Objetos de informe
Las siguientes secciones describen cada objeto de informe por función. El texto de los encabezados H3 es fijo a propósito, para que otros documentos puedan enlazarlos directamente.Verificación de identidad
Se devuelve para cada documento de KYC o de identidad que envía un usuario. Aparece comoid_verifications[] en GET /v3/session/{sessionId}/decision/ y dentro del campo kyc de las respuestas V2. Fuente: kyc/serializers/kyc.py:383-414 (IDVerificationV3Serializer, que extiende IDVerificationV2Serializer en kyc/serializers/kyc.py:320-380).
| Campo | Tipo | Anulable | Descripción | Ejemplo |
|---|---|---|---|---|
status | cadena | No | Consulta la enumeración de estados. | "Approved" |
document_type | cadena | Sí | Clase de documento en formato legible (Passport, Identity Card, Driver's License, Residence Permit, Health Insurance Card, Tax Card, Social Security Card, Work Permit, Visa, Public Service Card, Birth Certificate, Firearm License, Other). Fuente: DOC_TYPE_MAPPING (common/config/choices.py:1275-1289). | "Passport" |
document_subtype | cadena | Sí | Código de subtipo de documento del registro de documentos de Didit, filtrado según lo que acepta la configuración de documentos del flujo de verificación. Los documentos específicos de una región incluyen la región. Lista completa de códigos: subtipos de documento. | "QUEENSLAND_DRIVER_LICENSE_GENERIC" |
document_number | cadena | Sí | Número de documento extraído por OCR. | "AB1234567" |
personal_number | cadena | Sí | Identificador personal o nacional extraído por OCR. | "99999999R" |
portrait_image | cadena (URL) | Sí | URL prefirmada del recorte del rostro. | "https://<media-host>/.../portrait.jpg?..." |
front_image | cadena (URL) | Sí | URL prefirmada de la imagen limpia del anverso del documento. | "https://<media-host>/.../front.jpg?..." |
front_video | cadena (URL) | Sí | URL prefirmada del vídeo de captura del anverso (cuando esté disponible). | "https://<media-host>/.../front.mp4?..." |
back_image | cadena (URL) | Sí | URL prefirmada de la imagen limpia del reverso del documento. | "https://<media-host>/.../back.jpg?..." |
back_video | cadena (URL) | Sí | URL prefirmada del vídeo de captura del reverso. | null |
full_front_image | cadena (URL) | Sí | Captura del anverso sin recortar (fotograma completo). | "https://<media-host>/.../full_front.jpg?..." |
full_back_image | cadena (URL) | Sí | Captura del reverso sin recortar (fotograma completo). | null |
front_image_camera_front | cadena (URL) | Sí | Imagen de la cámara frontal tomada al mismo tiempo que el anverso del documento. | null |
back_image_camera_front | cadena (URL) | Sí | Imagen de la cámara frontal tomada al mismo tiempo que el reverso del documento. | null |
front_image_camera_front_face_match_score | float (0-100) | Sí | Similitud entre el retrato del documento y la captura de la cámara frontal. | null |
back_image_camera_front_face_match_score | float (0-100) | Sí | Igual que el anterior, pero para la captura del reverso. | null |
document_selfie_face_matches | array | Sí | Sesiones anteriores o entradas de la lista de bloqueo facial que coinciden con la selfie tomada durante la captura del documento. Mismo formato de entrada que liveness_checks[].matches. null cuando la búsqueda no se ejecutó, [] cuando no hubo coincidencias. | null |
front_image_quality_score | objeto | Sí | Métricas de calidad de la imagen del anverso: puntuaciones de 0 a 100 (focus_score, brightness_score, resolution_score, overall_score), además de brightness_issue (ok, too_dark, too_bright) e is_document_fully_visible (booleano). | { "focus_score": 91.0, "overall_score": 88.5 } |
back_image_quality_score | objeto | Sí | Misma estructura que front_image_quality_score. | null |
date_of_birth | cadena (YYYY-MM-DD) | Sí | Fecha de nacimiento extraída por OCR. | "1990-05-12" |
age | entero | Sí | Edad calculada en años en el momento de la extracción. | 35 |
expiration_date | cadena (YYYY-MM-DD) | Sí | Fecha de caducidad del documento. | "2032-05-11" |
date_of_issue | cadena (YYYY-MM-DD) | Sí | Fecha de expedición del documento. | "2022-05-11" |
issuing_state | cadena (ISO 3166-1 alpha-3) | Sí | Código del país emisor. | "ESP" |
issuing_state_name | cadena | Sí | Nombre localizado del país emisor. | "Spain" |
first_name | cadena | Sí | Nombre o nombres de pila extraídos por OCR. | "María" |
last_name | cadena | Sí | Apellido o apellidos extraídos por OCR. | "García López" |
full_name | cadena | Sí | Nombre completo normalizado (proporcionado por el proveedor). | "María García López" |
gender | cadena | Sí | M, F u otro valor proporcionado por el proveedor. | "F" |
address | cadena | Sí | Línea de dirección sin procesar extraída por OCR. | "Calle Mayor 1, 28001 Madrid" |
formatted_address | cadena | Sí | Dirección geocodificada o con formato (cuando se puede interpretar). | "Calle Mayor 1, 28001 Madrid, Spain" |
parsed_address | objeto | Sí | Dirección estructurada y geocodificada: street_1, street_2, city, region, country, postal_code, address_type, formatted_address, document_location ({latitude, longitude}), raw_results, is_best_match. Fuente: kyc/utils/address.py:147-197. | { "street_1": "Calle Mayor 1", "city": "Madrid", "postal_code": "28001", "country": "ES" } |
place_of_birth | cadena | Sí | Lugar de nacimiento extraído por OCR. | "Madrid" |
marital_status | cadena | Sí | Cuando se puede extraer. | null |
nationality | cadena (ISO 3166-1 alpha-3) | Sí | Nacionalidad extraída por OCR. | "ESP" |
extra_fields | objeto | Sí | Campos específicos del tipo de documento que no están cubiertos por el esquema canónico (por ejemplo, las categorías del permiso de conducir). | { "DL Class": "B" } |
mrz | objeto | Sí | Campos de la MRZ analizados cuando están presentes (document_number, birth_date, expiry_date, surname, given_names, …). | { "document_number": "AB1234567", "surname": "GARCIA", "given_names": "MARIA" } |
extra_files | array de cadenas (URL) | No | URL prefirmadas de los archivos adicionales subidos. | [] |
matches | array de objetos | No | Coincidencias de documentos entre sesiones. Cada elemento: { session_id, session_number, vendor_data, verification_date, user_details: { name, document_type, document_number }, status, is_blocklisted, api_service, front_image_url }. front_image_url es una URL prefirmada. | [] |
verification_method | string | No | Método de Verificación de identidad que generó esta fila: document, id_lookup o wallet. Siempre es document para un documento fotografiado, incluidas todas las sesiones creadas antes de que existieran los demás métodos. | "id_lookup" |
assurance | string | No | Nivel de garantía derivado de verification_method: documentary, data_match o cryptographic. | "data_match" |
wallet_provider | string | null | Sí | Id de wallet del catálogo cuando una wallet generó esta fila (mitid, bankid_se, itsme, …). null en los demás casos. | "mitid" |
fallback_from | object | null | Sí | Motivo por el que un método distinto del de documento terminó el paso de identidad: { method, reason, action }. Se establece cuando falló una consulta o un inicio de sesión con wallet: en la fila rechazada cuando el interruptor del país estaba en decline (action: "decline"), y en la verificación de documento con la que continúa el usuario cuando estaba en fallback_to_document (action: "fallback_to_document"). null cuando no hay ningún fallo previo de un método distinto del de documento registrado. | { "method": "id_lookup", "reason": "no_match", "action": "decline" } |
id_lookup | object | null | Sí | Evidencia de la fuente, presente solo cuando verification_method es id_lookup: source (la fuente exacta consultada: un registro gubernamental en la mayoría de los países, o un archivo de una agencia de crédito o de registros residenciales en algunos), checked_at, attempts, max_attempts, outcome (match, partial_match, no_match, provider_error, format_rejected), comparison[] ({ field, label, provided, record, result }; field es uno de identification_number, full_name, date_of_birth, address, y result es match, partial o no_match; las versiones anteriores pueden incluir una fila provider con error), source_errors[] (entorno de preproducción actual: diagnósticos de fuente separados; confirmar el despliegue en producción), registry_portrait (URL prefirmada, solo para las fuentes que devuelven una) y face_match_score. | ver más abajo |
wallet_verification | object | null | Sí | Evidencia de la credencial, presente solo cuando verification_method es wallet: provider, provider_name, issuing_authority, issuing_country, credential_type, level_of_assurance (low, substantial, high), verified_at, signature_valid, attributes (lo que compartió la wallet), portrait (URL prefirmada cuando la wallet comparte una) y face_match_score. | ver más abajo |
document_liveness | object | null | Sí | Puntuaciones de prueba de vida del documento por tipo de fraude (portrait_replace, printed_copy, screen_replay), informadas tanto si se activó una advertencia como si no. Cada una contiene: score (0-100, más alto = más probable que sea genuino; es el valor más bajo, que es el que usó la decisión), front, back, decline_threshold, review_threshold y bucket (approve, review, decline o null). Los umbrales y el bucket se guardan en el momento de la evaluación; los tres son null cuando no hay evidencia histórica de la evaluación, aunque las puntuaciones almacenadas siguen visibles. null cuando la comprobación no se ejecutó. Consulta Puntuaciones de prueba de vida del documento. Solo V3. | { "portrait_replace": { "score": 96.46, "bucket": "approve" } } |
node_id | string | null | Sí | Identificador del nodo del flujo de verificación (V3). | "first_id_verification" |
warnings | array | No | Consulta Objeto de advertencia. | [] |
region | string | Sí | Región o estado del país emisor, cuando el documento lo identifica. | "CA" |
extracted_data | object | Sí | Instantánea de los datos extraídos del documento que se mostró a la persona para que los revisara, junto a los valores confirmados para que puedas compararlos. null cuando no se pidió a la persona que los revisara. | |
barcodes | array de objetos | No | Datos leídos de los códigos de barras del documento, una entrada por código de barras con type, position, data, data_raw y side. [] cuando no hay ninguno. | [] |
{
"status": "Approved",
"document_type": "Passport",
"document_subtype": "PASSPORT_GENERIC",
"document_number": "AB1234567",
"personal_number": "99999999R",
"portrait_image": "https://<media-host>/.../portrait.jpg?signature=...",
"front_image": "https://<media-host>/.../front.jpg?signature=...",
"front_video": null,
"back_image": "https://<media-host>/.../back.jpg?signature=...",
"back_video": null,
"full_front_image": "https://<media-host>/.../full_front.jpg?signature=...",
"full_back_image": null,
"front_image_camera_front": null,
"back_image_camera_front": null,
"front_image_camera_front_face_match_score": null,
"back_image_camera_front_face_match_score": null,
"front_image_quality_score": {
"focus_score": 91.0,
"brightness_score": 88.0,
"brightness_issue": "ok",
"is_document_fully_visible": true,
"resolution_score": 95.0,
"overall_score": 88.5
},
"back_image_quality_score": null,
"date_of_birth": "1990-05-12",
"age": 35,
"expiration_date": "2032-05-11",
"date_of_issue": "2022-05-11",
"issuing_state": "ESP",
"issuing_state_name": "Spain",
"first_name": "María",
"last_name": "García López",
"full_name": "María García López",
"gender": "F",
"address": "Calle Mayor 1, 28001 Madrid",
"formatted_address": "Calle Mayor 1, 28001 Madrid, Spain",
"parsed_address": { "street_1": "Calle Mayor 1", "street_2": null, "city": "Madrid", "region": "Madrid", "postal_code": "28001", "country": "ES", "address_type": "Calle" },
"place_of_birth": "Madrid",
"marital_status": null,
"nationality": "ESP",
"extra_fields": {},
"mrz": {
"document_number": "AB1234567",
"surname": "GARCIA",
"given_names": "MARIA",
"birth_date": "900512",
"expiry_date": "320511"
},
"extra_files": [],
"matches": [],
"node_id": "first_id_verification",
"verification_method": "document",
"assurance": "documentary",
"wallet_provider": null,
"fallback_from": null,
"id_lookup": null,
"wallet_verification": null,
"document_liveness": {
"portrait_replace": {
"score": 96.46,
"front": 96.46,
"back": 98.2,
"decline_threshold": 35,
"review_threshold": 70,
"bucket": "approve"
},
"printed_copy": {
"score": 91.2,
"front": 91.2,
"back": 93.7,
"decline_threshold": 35,
"review_threshold": 77,
"bucket": "approve"
},
"screen_replay": {
"score": 99.9,
"front": 99.9,
"back": 99.5,
"decline_threshold": 30,
"review_threshold": 70,
"bucket": "approve"
}
},
"warnings": []
}
null.
{
"status": "Approved",
"issuing_state": "ZAF",
"first_name": "Thabo",
"last_name": "Mokoena",
"full_name": "Thabo Mokoena",
"date_of_birth": "1991-06-15",
"personal_number": "9106155043088",
"node_id": "first_id_verification",
"verification_method": "id_lookup",
"assurance": "data_match",
"wallet_provider": null,
"fallback_from": null,
"id_lookup": {
"source": "Department of Home Affairs",
"checked_at": "2026-09-04T09:12:44Z",
"attempts": 1,
"max_attempts": 2,
"outcome": "match",
"comparison": [
{ "field": "identification_number", "label": "ID number", "provided": "9106155043088", "record": "9106155043088", "result": "match" },
{ "field": "full_name", "label": "Full name", "provided": "Thabo Mokoena", "record": "Thabo Mokoena", "result": "match" },
{ "field": "date_of_birth", "label": "Date of birth", "provided": "1991-06-15", "record": "1991-06-15", "result": "match" }
],
"registry_portrait": "https://<media-host>/.../registry_portrait.jpg?signature=...",
"face_match_score": 96.4
},
"wallet_verification": null,
"warnings": []
}
{
"status": "Approved",
"issuing_state": "DNK",
"first_name": "Freja",
"last_name": "Nielsen",
"full_name": "Freja Nielsen",
"date_of_birth": "1988-03-02",
"node_id": "first_id_verification",
"verification_method": "wallet",
"assurance": "cryptographic",
"wallet_provider": "mitid",
"fallback_from": null,
"id_lookup": null,
"wallet_verification": {
"provider": "mitid",
"provider_name": "MitID",
"issuing_authority": "Danish Agency for Digital Government",
"issuing_country": "DNK",
"credential_type": "person_identification",
"level_of_assurance": "substantial",
"verified_at": "2026-09-04T09:12:44Z",
"signature_valid": true,
"attributes": {
"full_name": "Freja Nielsen",
"date_of_birth": "1988-03-02",
"cpr_alias": "b0f1c2d3-e4f5-4678-9abc-def012345678"
},
"portrait": null,
"face_match_score": null
},
"warnings": []
}
Verificación NFC
Se devuelve por cada lectura del chip realizada en un documento de identidad: un chip de ePassport o eID según ICAO 9303, o una lectura de la My Number Card de Japón a través de JPKI (chip_protocol: "jpki"). Aparece como nfc_verifications[] en GET /v3/session/{sessionId}/decision/ (una por cada registro KYC principal). Fuente: kyc/serializers/epassport.py:121-139 (NFCV3Serializer, que extiende NFCV2Serializer en kyc/serializers/epassport.py:83-118).
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
status | string | No | Consulta Enumeración de estados. | "Approved" |
portrait_image | string (URL) | Sí | URL prefirmada de la imagen facial extraída del chip. | "https://<media-host>/.../nfc_portrait.jpg?..." |
signature_image | string (URL) | Sí | URL prefirmada de la imagen de la firma extraída del chip (cuando está almacenada en el chip). | null |
chip_data | object | Sí | Datos personales extraídos de los Data Groups del chip, aplanados (kyc/utils/epassport.py:165-212): dgs (Data Groups leídos), surname, name, country, nationality, birth_date (YYYY-MM-DD), expiry_date (YYYY-MM-DD), sex (M/F), document_type (código de documento de la MRZ), document_number, optional_data, dígitos de control de la MRZ (birth_date_hash, expiry_date_hash, document_number_hash, optional_data_hash, final_hash), mrz_string, mrz_type (TD1/TD2/TD3); además place_of_birth y address (y full_name / full_name_non_latin para nombres en escritura no latina) cuando el chip contiene DG11; esas claves no aparecen en los demás casos. null cuando se omitió el paso NFC. | { "document_number": "AB1234567", "name": "MARIA" } |
authenticity | object | Sí | { sod_integrity, dg_integrity }; null en una lectura JPKI. sod_integrity valida que la firma del Document Security Object (SOD) se encadena con una CSCA válida del país emisor (y que la DSC no está revocada ni caducada); dg_integrity valida que los hashes de cada Data Group coinciden con el SOD. Si ambos son true, el chip es genuino y no ha sido manipulado. | { "sod_integrity": true, "dg_integrity": true } |
certificate_summary | objeto | Sí | Resumen del certificado del firmante del documento (kyc/utils/epassport.py:338-348): issuer, subject, serial_number (entero), not_valid_before, not_valid_after (YYYY-MM-DD HH:MM:SS), más un objeto validation { csca_verified, dsc_revoked, dsc_expired, csca_expired } (kyc/views/epassport.py:86). | { "issuer": "Common Name: CSCA SPAIN, Country: ES", "not_valid_after": "2031-02-18 10:21:11" } |
node_id | cadena | null | Sí | Identificador del nodo del flujo de verificación (V3). | "first_nfc" |
is_nfc_skipped | booleano | No | true cuando este paso de NFC se omitió de forma explícita en lugar de leerse; skip_reason indica el motivo. | false |
skip_reason | cadena | Sí | Motivo por el que se omitió el paso; solo se establece cuando is_nfc_skipped es true. Puede ser uno de USER_SKIPPED, DOCUMENT_WITHOUT_CHIP, CHIP_CERTIFICATE_UNAVAILABLE, DEVICE_WITHOUT_NFC, INTEGRATION_WITHOUT_NFC_ACCESS, MRZ_KEY_UNAVAILABLE o JPKI_UNAVAILABLE; véase Motivos de omisión. El payload de la decisión también incluye un nfc_skip_reason a nivel de sesión, con la misma taxonomía, que cubre los pasos de NFC omitidos antes de crear cualquier informe. | null |
chip_protocol | cadena | No | Cómo se lee el chip: icao (chip ICAO 9303 de pasaporte electrónico o de eID) o jpki (My Number Card de Japón). Para jpki, portrait_image, signature_image, chip_data, authenticity y certificate_summary son null. También se establece en los pasos omitidos. | "icao" |
jpki | objeto | Sí | Lo que demostró la lectura de una My Number Card: certificate_types, chain_valid, signature_valid, revocation_status (good, revoked o unchecked), ca_generation, certificate_expires_at, certificates[], attributes (nombre, fecha de nacimiento, sexo y dirección del certificado de firma), attributes_match_ocr y mismatched_attributes. Nunca incluye los certificados, sus números de serie ni las firmas. null en chips ICAO, en pasos omitidos y cuando el paso se cerró sin ninguna lectura de tarjeta. Véase Campos de JPKI. | null |
warnings | array | No | Véase Objeto de advertencia. | [] |
{
"status": "Approved",
"portrait_image": "https://<media-host>/.../nfc_portrait.jpg?signature=...",
"signature_image": null,
"chip_data": {
"dgs": ["DG1", "DG2", "DG11"],
"surname": "GARCIA LOPEZ",
"name": "MARIA",
"country": "ESP",
"nationality": "ESP",
"birth_date": "1990-05-12",
"expiry_date": "2032-05-11",
"sex": "F",
"document_type": "P",
"document_number": "AB1234567",
"optional_data": "",
"birth_date_hash": "4",
"expiry_date_hash": "7",
"document_number_hash": "3",
"optional_data_hash": "",
"final_hash": "8",
"mrz_string": "P<ESPGARCIA<LOPEZ<<MARIA<<<<<<<<<<<<<<<<<<<<AB1234567ESP9005124F3205117<<<<<<<<<<<<<<08",
"mrz_type": "TD3",
"place_of_birth": "MADRID",
"address": "CALLE MAYOR 1, MADRID"
},
"authenticity": { "sod_integrity": true, "dg_integrity": true },
"certificate_summary": {
"issuer": "Common Name: CSCA SPAIN, Organization: DIRECCION GENERAL DE LA POLICIA, Country: ES",
"subject": "Common Name: DS n-eID SPAIN 2, Organizational Unit: PASSPORT, Organization: DIRECCION GENERAL DE LA POLICIA, Country: ES",
"serial_number": 118120836164494130086420187336801405660,
"not_valid_before": "2020-11-18 10:21:11",
"not_valid_after": "2031-02-18 10:21:11",
"validation": {
"csca_verified": true,
"dsc_revoked": false,
"dsc_expired": false,
"csca_expired": false
}
},
"node_id": "first_nfc",
"is_nfc_skipped": false,
"skip_reason": null,
"chip_protocol": "icao",
"jpki": null,
"warnings": []
}
Prueba de vida
Se devuelve por cada sesión de prueba de vida. Aparece comoliveness_checks[] en GET /v3/session/{sessionId}/decision/. Fuente: face/serializers/face.py:301-320 (LivenessV3Serializer, extiende LivenessV2Serializer en face/serializers/face.py:216-298).
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
status | cadena | No | Véase Enumeración de estado. | "Approved" |
method | cadena (enumeración) | Sí | ACTIVE_3D, FLASHING o PASSIVE (LivenessMethodChoices, common/config/choices.py:514-517). La prueba pasiva se ejecuta cuando se permiten las sesiones de escritorio y el usuario está en un dispositivo de escritorio. | "PASSIVE" |
score | flotante (0-100) | Sí | Confianza de la prueba de vida, redondeada a 2 decimales. | 92.41 |
reference_image | cadena (URL) | Sí | URL prefirmada del recorte facial de referencia del usuario. | "https://<media-host>/.../reference.jpg?..." |
video_url | cadena (URL) | Sí | URL prefirmada de la grabación de la prueba de vida cuando la captura la guardó, tanto para la prueba activa como para la pasiva. null cuando la sesión no conservó ninguna grabación. | "https://<media-host>/.../liveness.webm?..." |
age_estimation | flotante | Sí | Edad estimada (en años) del rostro más grande de la imagen de referencia. | 34.2 |
matches | array de objetos | No | Coincidencias faciales entre sesiones. Cada elemento: { session_id, session_number, similarity_percentage, vendor_data, vendor_user_id, biometric_template_id, verification_date, user_details: { full_name, document_type, document_number }, match_image_url, status, is_blocklisted, is_allowlisted, api_service, source }. source es session, imported, list_entry o retained_template. Una coincidencia con plantilla retenida tiene vendor_user_id, vendor_data y biometric_template_id; sus campos de sesión, imagen, datos de identidad, estado y servicio de API son null. | [] |
face_quality | flotante (0-100) | Sí | Puntuación de calidad del rostro de la prueba pasiva (normalizada a un porcentaje). | 87.50 |
face_luminance | flotante (0-100) | Sí | Puntuación de luminancia del rostro de la prueba pasiva (normalizada de 0-255 a un porcentaje). | 54.12 |
node_id | cadena | null | Sí | Identificador del nodo del flujo de verificación (V3). | "first_liveness" |
warnings | array | No | Véase Objeto de advertencia. | [] |
{
"status": "Approved",
"method": "PASSIVE",
"score": 92.41,
"reference_image": "https://<media-host>/.../reference.jpg?signature=...",
"video_url": null,
"age_estimation": 34.2,
"matches": [],
"face_quality": 87.50,
"face_luminance": 54.12,
"node_id": "first_liveness",
"warnings": []
}
null cuando la sesión no conservó ninguna grabación: el ejemplo anterior corresponde a una sesión que no conservó ninguna.
Coincidencia facial
Se devuelve por cada comparación de coincidencia facial (normalmente el rostro de la prueba de vida del usuario frente al retrato del documento). Aparece comoface_matches[] en GET /v3/session/{sessionId}/decision/. Fuente: face/serializers/face.py:367-389 (FaceMatchV3Serializer, extiende FaceMatchV2Serializer en face/serializers/face.py:323-364).
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
status | cadena | No | Véase Enumeración de estado. | "Approved" |
score | flotante (0-100) | Sí | Similitud, redondeada a 2 decimales. Cuando el proveedor solo devuelve un unmatched_faces[].Confidence, se convierte a 100 - confidence. | 97.83 |
source_image_session_id | cadena (UUID) | Sí | La sesión cuyo retrato almacenado aportó la imagen de origen (de referencia). Se establece en los flujos basados en retrato (autenticación biométrica, o un retrato proporcionado al crear la sesión). null cuando la referencia es el retrato del documento de la misma sesión. | null |
source_image | cadena (URL) | Sí | URL prefirmada de la imagen de origen (de referencia): normalmente el retrato del documento, o el retrato almacenado en los flujos de autenticación biométrica. | "https://<media-host>/.../source.jpg?..." |
target_image | cadena (URL) | Sí | URL prefirmada de la imagen objetivo (rostro en vivo) capturada durante la prueba de vida. | "https://<media-host>/.../target.jpg?..." |
node_id | cadena | null | Sí | Identificador del nodo del flujo de verificación (V3). | "first_face_match" |
warnings | array | No | Véase Objeto de advertencia. | [] |
face_coverage | objeto | Sí | Indica si eyes, mouth y face están cubiertos en la imagen capturada. Cada región tiene covered, calibrated y visibility_score; calibrated: false indica que hay evidencia de sombra a la que no se aplica ninguna advertencia. Lo devuelve solo GET /v3/session/{sessionId}/decision/, nunca en los payloads de webhook. | { "eyes": { "covered": false, "calibrated": true, "visibility_score": 0.98 } } |
{
"status": "Approved",
"score": 97.83,
"source_image_session_id": null,
"source_image": "https://<media-host>/.../source.jpg?signature=...",
"target_image": "https://<media-host>/.../target.jpg?signature=...",
"node_id": "first_face_match",
"warnings": []
}
Búsqueda facial
Devuelto por la API independiente de Búsqueda facial (POST /v3/face-search/). La Búsqueda facial nunca aparece como array en plural en /v3/session/{sessionId}/decision/. Cuando se guarda con save_api_request=true, la sesión aparece ahí como una entrada FACE_SEARCH en features[], junto con un elemento liveness_checks[] que contiene los matches almacenados. Fuentes: apis/serializers/face_search.py:8-79 (FaceSearchResponseSerializer que envuelve a FaceSearchDetailsSerializer); los diccionarios de coincidencias se construyen en face/utils/utils.py:869-884.
Respuesta de nivel superior:
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
request_id | cadena (UUID) | No | El id de la sesión guardada cuando save_api_request=true (utilizable con GET /v3/session/{sessionId}/decision/); de lo contrario, un UUID de correlación temporal. | "4a1c2c4e-8b1b-4d6a-91b5-ee9a1f3a2c7f" |
face_search | objeto | No | El payload con los detalles de la búsqueda; ver los campos siguientes. | — |
vendor_data | cadena | Sí | vendor_data de la solicitud, devuelto sin cambios. | null |
metadata | objeto | Sí | metadata de la solicitud, devuelto sin cambios. | null |
created_at | cadena (ISO 8601) | No | Marca de tiempo de la solicitud en el servidor. | "2026-06-12T01:04:42.763237+00:00" |
face_search:
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
status | cadena | No | Declined solo cuando se activa una advertencia FACE_IN_BLOCKLIST o POSSIBLE_FACE_IN_BLOCKLIST; Approved en los demás casos. Las coincidencias duplicadas por sí solas nunca provocan un rechazo (apis/views/face_search.py:242-248). | "Approved" |
total_matches | entero | No | Número de coincidencias devueltas en matches[] (0–5). | 1 |
matches | array de objetos de coincidencia de búsqueda facial | No | Hasta 5 coincidencias por encima del umbral mínimo de similitud, ordenadas por similitud descendente (primero las entradas de la lista de bloqueo, con search_type=blocklisted_or_approved). | […] |
user_image | objeto | No | Resultado de la detección de la imagen enviada: { entities: [{ bbox, confidence }], best_angle }, con una entidad por cada rostro detectado. | { "entities": [{ "bbox": [40, 40, 120, 120], "confidence": 0.73 }], "best_angle": 0 } |
warnings | array de objetos | No | Forma reducida de las advertencias para esta API independiente, sin node_id. El contrato del serializador declara { risk, additional_data, log_type, short_description, long_description } (apis/serializers/face_search.py:49-54). El payload en ejecución también incluye feature, que siempre es "LIVENESS" (apis/views/face_search.py:332-341). | [] |
Objeto de coincidencia de búsqueda facial
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
session_id | cadena (UUID) | Sí | La sesión de verificación coincidente. null cuando source es imported, list_entry o retained_template. | "a3f2a6f1-…" |
session_number | entero | Sí | Número de la sesión coincidente, legible en la consola; null en coincidencias que no son de sesión. | 1024 |
similarity_percentage | float (0-100) | No | Similitud entre el rostro enviado y el rostro coincidente. | 96.42 |
source | cadena (enum) | No | Origen desde el que se registró el rostro coincidente: session (sesión de verificación o llamada independiente guardada), imported (carga directa del rostro en el perfil de usuario), list_entry (rostro asociado a una lista), retained_template (plantilla biométrica sin imagen, conservada después de que se eliminara la sesión de origen). | "session" |
vendor_data | cadena | Sí | El vendor_data de la sesión coincidente, o el del usuario vinculado en las coincidencias imported y retained_template. | "user-12345" |
vendor_user_id | cadena (UUID) | Sí | El usuario vinculado. null en las coincidencias list_entry y en sesiones sin usuario. | "2f7c1a9e-…" |
biometric_template_id | cadena (UUID) | Sí | La plantilla retenida con la que se produjo la coincidencia. Solo se establece en coincidencias retained_template; úsalo con GET/DELETE /v3/biometric-templates/{id}/. | null |
verification_date | cadena (ISO 8601) | Sí | Cuándo se capturó el rostro coincidente, o cuándo se retuvo una retained_template; null en coincidencias list_entry. | "2024-11-04T09:14:02Z" |
user_details | objeto | Sí | { full_name, document_type, document_number } de la verificación de documento de la sesión coincidente. En coincidencias imported solo se establece full_name. null cuando no existen datos de identidad, y siempre null en coincidencias retained_template. | { "full_name": "María García López", "document_type": "Passport", "document_number": "AB1234567" } |
match_image_url | cadena (URL) | Sí | Rostro de referencia del usuario coincidente: URL prefirmada cuando save_api_request=true, o ruta de almacenamiento original en caso contrario. Siempre null en coincidencias retained_template, que no contienen imagen. | "https://<media-host>/.../matched.jpg?..." |
status | cadena | Sí | Estado de verificación de la sesión coincidente (ver enum de estado); null en coincidencias que no son de sesión. | "Approved" |
is_blocklisted | booleano | No | Indica si el rostro coincidente está en tu lista de bloqueo facial. Siempre false en coincidencias retained_template; un rostro en lista de bloqueo se informa por separado como coincidencia list_entry. | false |
is_allowlisted | booleano | No | Indica si el rostro coincidente está en una de tus listas de permitidos. | false |
api_service | cadena (enum) | Sí | Tipo de API independiente, en mayúsculas, de la sesión coincidente (p. ej. PASSIVE_LIVENESS, FACE_MATCH); null en flujos de verificación (workflow) y en coincidencias que no son de sesión. | null |
{
"request_id": "4a1c2c4e-8b1b-4d6a-91b5-ee9a1f3a2c7f",
"face_search": {
"status": "Approved",
"total_matches": 1,
"matches": [
{
"session_id": "a3f2a6f1-1c1c-4eec-8b69-1c1c2f3a2c7f",
"session_number": 1024,
"similarity_percentage": 96.42,
"source": "session",
"vendor_data": "user-12345",
"verification_date": "2024-11-04T09:14:02Z",
"user_details": {
"full_name": "María García López",
"document_type": "Passport",
"document_number": "AB1234567"
},
"match_image_url": "https://<media-host>/.../matched.jpg?signature=...",
"status": "Approved",
"is_blocklisted": false,
"is_allowlisted": false,
"api_service": null
}
],
"user_image": {
"entities": [
{
"bbox": [40, 40, 120, 120],
"confidence": 0.732973
}
],
"best_angle": 0
},
"warnings": []
},
"vendor_data": null,
"metadata": null,
"created_at": "2026-06-12T01:04:42.763237+00:00"
}
Análisis AML
Devuelto por cada entidad analizada. Aparece comoaml_screenings[] en GET /v3/session/{sessionId}/decision/ tanto en sesiones KYC como KYB. Fuente: aml/serializers/aml.py:63-85 (AMLV3Serializer, que extiende AMLV2Serializer en aml/serializers/aml.py:28-60).
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
status | cadena | No | Ver enum de estado. | "Approved" |
total_hits | entero | No | Número de coincidencias del análisis AML (siempre presente, por defecto 0). | 2 |
entity_type | cadena (enum) | Sí | person o company (EntityTypeChoices, common/config/choices.py:675-677). | "person" |
hits | array de objetos | No | Una entrada por coincidencia. Campos clave: id, caption, match (bool), target (bool | null: si la entidad es el objetivo directo del listado), match_score (float 0-100, confianza de identidad), risk_score (float 0-100, riesgo de la entidad), score (obsoleto, float 0-1), datasets[] (p. ej. PEP, PEP Level 1-4, Sanctions, Adverse Media, Warnings and Regulatory Enforcement, Fitness and Probity), properties (nombres, alias, fechas de nacimiento, …), features, url, first_seen, last_seen, rca_name, risk_view, score_breakdown, pep_matches, sanction_matches, warning_matches, adverse_media_matches, adverse_media_details, linked_entities, additional_information y review_status (Unreviewed, Confirmed Match, False Positive, Inconclusive; editable mediante el endpoint de actualización del estado de las coincidencias AML, AMLHitStatusChoices). | […] |
score | float (0-100) | Sí | Puntuación general del análisis: el risk_score más alto entre las coincidencias no marcadas como False Positive (aml/services/aml.py:832-842); 0 cuando todas las coincidencias son falsos positivos. null hasta que se calcule. | 42.7 |
screened_data | object | Sí | Instantánea de los datos enviados al análisis: full_name, nationality, date_of_birth, document_number. | { "full_name": "María García López", "date_of_birth": "1990-05-12" } |
is_ongoing_monitoring_enabled | boolean | No | Si la entidad está suscrita a los nuevos análisis de monitorización continua. | false |
next_ongoing_monitoring_bill_date | string (YYYY-MM-DD) | Sí | Calculada como last_aml_bill_date + 365 days cuando la monitorización continua está habilitada. Una fecha de facturación, no una fecha de análisis. | null |
last_ongoing_screening_at | string (ISO 8601) | Sí | Cuándo la monitorización continua completó por última vez un nuevo análisis de este registro, tanto si el resultado cambió como si no. null si nunca se volvió a analizar; nunca se rellena de forma retroactiva. | "2026-09-12T04:03:11Z" |
last_ongoing_screening_datasets_updated_at | string (ISO 8601) | Sí | Actualización más reciente de los conjuntos de datos AML que el proveedor notificó para ese análisis. null cuando no se notificó ninguna fecha de conjunto de datos; nunca se estima. | null |
node_id | string | null | Sí | Identificador del nodo del flujo de verificación (workflow) (V3). | "first_aml" |
warnings | array | No | Consulte Objeto de advertencia. | [] |
{
"status": "In Review",
"total_hits": 1,
"entity_type": "person",
"hits": [
{
"id": "Q7XW3-aml-hit-1",
"caption": "Maria Garcia Lopez",
"match": true,
"target": true,
"match_score": 86.4,
"risk_score": 42.7,
"datasets": ["PEP Level 2"],
"properties": {
"name": ["María García López", "M. García"],
"alias": ["Maria Garcia"],
"birthDate": ["1990-05-12"]
},
"url": "https://example.org/registry/entities/Q7XW3",
"first_seen": "2023-11-02T00:00:00Z",
"last_seen": "2026-05-01T00:00:00Z",
"review_status": "Unreviewed"
}
],
"score": 42.7,
"screened_data": {
"full_name": "María García López",
"date_of_birth": "1990-05-12",
"nationality": "ES",
"document_number": "AB1234567"
},
"is_ongoing_monitoring_enabled": false,
"next_ongoing_monitoring_bill_date": null,
"last_ongoing_screening_at": null,
"last_ongoing_screening_datasets_updated_at": null,
"node_id": "first_aml",
"warnings": []
}
Análisis de IP
Se devuelve por cada ubicación de red capturada. Aparece comoip_analyses[] en GET /v3/session/{sessionId}/decision/ tanto para sesiones de KYC como de KYB. Fuente: kyc/serializers/location.py:196-243 (IPAnalysisSerializerV3).
| Campo | Tipo | Nulable | Descripción | Ejemplo |
|---|---|---|---|---|
status | string | No | Consulte Enumeración de estados. | "Approved" |
node_id | string | null | Sí | Identificador del nodo del flujo (V3). | "first_ip_analysis" |
device_brand | string | Sí | Marca del dispositivo derivada del agente de usuario. | "Apple" |
device_model | string | Sí | Modelo del dispositivo. | "iPhone" |
browser_family | string | Sí | Familia del navegador. | "Mobile Safari" |
os_family | string | Sí | Familia del sistema operativo. | "iOS" |
platform | string | Sí | Plataforma de alto nivel (mobile, desktop, tablet). | "mobile" |
device_fingerprint | string | Sí | Hash de huella digital del dispositivo, estable por dispositivo. | "f2a3…" |
ip_country | string | Sí | Nombre del país resuelto a partir de la IP. | "Spain" |
ip_country_code | string (ISO 3166-1 alpha-2) | Sí | Código de país resuelto a partir de la IP. | "ES" |
ip_state | string | Sí | Región o estado resuelto a partir de la IP. | "Comunidad de Madrid" |
ip_city | string | Sí | Ciudad resuelta a partir de la IP. | "Madrid" |
latitude | float | Sí | Latitud derivada de la IP. | 40.4168 |
longitude | float | Sí | Longitud derivada de la IP. | -3.7038 |
ip_address | string | Sí | La dirección IP capturada. | "203.0.113.42" |
isp | string | Sí | Nombre del ISP. | "Telefonica de Espana" |
organization | string | Sí | Nombre de la organización (a menudo igual al ISP). | "Telefonica de Espana" |
is_vpn_or_tor | boolean | Sí | true cuando la IP pertenece a una VPN, un proxy o un nodo de salida de Tor. | false |
is_data_center | boolean | Sí | true cuando la IP pertenece a un ASN de alojamiento o de centro de datos conocido. | false |
time_zone | string | Sí | Nombre de la zona horaria IANA. | "Europe/Madrid" |
time_zone_offset | string | Sí | Desfase respecto a UTC. | "+02:00" |
ip | object | No | { location, distance_from_id_document, distance_from_poa_document }. location = { latitude, longitude }. Distancias en km, null cuando falta alguno de los dos extremos. | { "location": { "latitude": 40.4168, "longitude": -3.7038 }, "distance_from_id_document": 3.4, "distance_from_poa_document": 1.1 } |
id_document | object | No | { location, distance_from_ip, distance_from_poa_document }. Ubicación del documento de identidad resuelta a partir de issuing_state y de la dirección analizada. | { "location": { "latitude": 40.4165, "longitude": -3.7026 }, "distance_from_ip": 3.4, "distance_from_poa_document": 4.0 } |
poa_document | object | No | { location, distance_from_ip, distance_from_id_document }. Dirección de la prueba de domicilio, geocodificada. | { "location": { "latitude": 40.4170, "longitude": -3.7040 }, "distance_from_ip": 1.1, "distance_from_id_document": 4.0 } |
matches | array de objetos | No | Coincidencias de IP y dispositivo entre sesiones. Cada elemento: { session_id, session_number, vendor_data, verification_date, match_type, match_source, matched_value, status, is_blocklisted, api_service, source, device_info, location_info, confidence, match_mode }. match_type es ip_address o device_fingerprint; match_source es ip_address, persistent_id, legacy_fp o recovered_high (las coincidencias recuperadas también incluyen recovery_similarity, tls_ja4_corroborated, recovery_gate_reason). Limitado a 5 coincidencias de IP y 5 de dispositivo. | [] |
warnings | array | No | Consulte Objeto de advertencia. | [] |
browser_version, os_version | string | Sí | Versiones del navegador y del sistema operativo según el agente de usuario. | "17.4" |
user_agent, accept_language | string | Sí | La cadena de agente de usuario y el encabezado Accept-Language que envió el navegador. | "en-US,en;q=0.9" |
session_identifier, session_age_ms | string, integer | Sí | La sesión de navegación en la que se ejecutó el paso y su antigüedad en milisegundos. | 48210 |
coords_accuracy | float | Sí | Radio de precisión, en metros, de las coordenadas que informó el dispositivo. | 35.0 |
raw_device_data | object | Sí | Señales sin procesar del dispositivo recopiladas para el paso. | {} |
{
"status": "Approved",
"node_id": "first_ip_analysis",
"device_brand": "Apple",
"device_model": "iPhone",
"browser_family": "Mobile Safari",
"os_family": "iOS",
"platform": "mobile",
"device_fingerprint": "f2a3c1de8b994a3f9e4cdf3a02b1a7c9",
"ip_country": "Spain",
"ip_country_code": "ES",
"ip_state": "Comunidad de Madrid",
"ip_city": "Madrid",
"latitude": 40.4168,
"longitude": -3.7038,
"ip_address": "203.0.113.42",
"isp": "Telefonica de Espana",
"organization": "Telefonica de Espana",
"is_vpn_or_tor": false,
"is_data_center": false,
"time_zone": "Europe/Madrid",
"time_zone_offset": "+02:00",
"ip": {
"location": { "latitude": 40.4168, "longitude": -3.7038 },
"distance_from_id_document": 3.4,
"distance_from_poa_document": 1.1
},
"id_document": {
"location": { "latitude": 40.4165, "longitude": -3.7026 },
"distance_from_ip": 3.4,
"distance_from_poa_document": 4.0
},
"poa_document": {
"location": { "latitude": 40.4170, "longitude": -3.7040 },
"distance_from_ip": 1.1,
"distance_from_id_document": 4.0
},
"matches": [],
"warnings": []
}
Verificación de ubicación
Se devuelve por cada paso de Verificación de ubicación. Aparece comogeolocation_checks[] en GET /v3/session/{sessionId}/decision/: un elemento por paso, correspondiente a su intento aceptado. geolocation_attempts[] enumera todos los intentos de todos los pasos, del más antiguo al más reciente. Ambos son null en un flujo sin el paso. Fuente: GeolocationDecisionSerializer.
| Campo | Tipo | Nulable | Descripción | Ejemplo |
|---|---|---|---|---|
node_id | string | Sí | Nodo del flujo que produjo el resultado. | "geolocation_1" |
status | cadena | No | Ver Enumeración de estados. | "Declined" |
outcome | cadena | Sí | Lo que ocurrió en el intento: verified, low_accuracy, accuracy_undetermined, stale, approximate, denied, restricted, unavailable, timeout, mock_detected, outside_geofence, in_blocked_area, anonymizer_detected, skipped, replay_rejected o unsupported_client. | "outside_geofence" |
permission | cadena | Sí | Lo que concedió el sistema: granted_precise, granted_approximate, denied, restricted, unavailable, timeout, dismissed o not_requested. | "granted_precise" |
latitude, longitude | flotante | Sí | Posición WGS84. null cuando no hay posición. | 48.8566 |
accuracy_m | flotante | Sí | Radio de incertidumbre en metros. | 35.0 |
accuracy_confidence | cadena | Sí | p95, p68 o unspecified. | "p95" |
measured_at, age_seconds | fecha y hora, entero | Sí | Cuándo el dispositivo obtuvo la posición, y los segundos transcurridos hasta que Didit la recibió. | 2 |
source, platform, sdk_version | cadena | Sí | De dónde procede la posición, el cliente que la generó y su versión del SDK. | "browser" |
is_mock, produced_by_accessory | booleano | Sí | Indicios de suplantación que reporta la plataforma. null significa que la plataforma no lo reporta. | null |
integrity | cadena | No | attested, not_attested, failed, unsupported (web) o not_determined. | "unsupported" |
country_code, region_code, city | cadena | Sí | El lugar al que resuelve la posición. | "FR" |
geofence, inside_geofence, geofence_basis, inside_areas, blocked_areas | objeto, booleano, cadena, arreglos | Sí | El resultado de país y área. | { "enabled": true, "result": "outside" } |
position_source, anonymizers | cadena, objeto | Sí | De dónde obtiene la posición el paso, y las señales de VPN, proxy, Tor, suplantación y emulador. | "device_and_ip" |
ip_distance_km, ip_distance_uncertainty_km, ip_consistent, document_distance_km, travel_excused, consecutive_mismatches | número, booleano, entero | Sí | Las comparaciones con la ubicación de la IP y con la dirección registrada. | 12.4 |
attempts | entero | No | El número del intento dentro del paso. | 3 |
consent | objeto | Sí | accepted_at, version y locale del aviso que aceptó la persona. | |
warnings | arreglo de objetos de advertencia | No | Las advertencias LOCATION_* del paso. No aparecen en geolocation_attempts[], que añade received_at y created_at. | [] |
Prueba de domicilio
Se devuelve por cada documento de domicilio enviado. Aparece comopoa_verifications[] en GET /v3/session/{sessionId}/decision/. Fuente: poa/serializers/poa.py:212-227 (POAV3Serializer, extiende POAV2Serializer en poa/serializers/poa.py:173-209).
| Campo | Tipo | Anulable | Descripción | Ejemplo |
|---|---|---|---|---|
status | cadena | No | Ver Enumeración de estados. | "Approved" |
issuing_state | cadena (ISO 3166-1 alfa-3) | Sí | Código de país del emisor del documento. | "ESP" |
document_type | cadena | No | Tipo de alto nivel de PoaDocumentTypeChoices (common/config/choices.py:868-873): UTILITY_BILL, BANK_STATEMENT, GOVERNMENT_ISSUED_DOCUMENT, OTHER_POA_DOCUMENT. Recurre a UNKNOWN, nunca a null. | "UTILITY_BILL" |
document_subtype | cadena | No | Código de subtipo de PoaDocumentSubtypeChoices (p. ej. ELECTRICITY_BILL, WATER_BILL, ACCOUNT_STATEMENT). Recurre a UNKNOWN, nunca a null. | "ELECTRICITY_BILL" |
issuer | cadena | Sí | Nombre de la entidad emisora. | "Iberdrola" |
issue_date | cadena (YYYY-MM-DD) | Sí | Fecha de emisión del documento. | "2026-04-15" |
expiration_date | cadena (YYYY-MM-DD) | Sí | Fecha de caducidad impresa en el documento, cuando está presente. | null |
poa_address | cadena | Sí | Dirección extraída por OCR tal cual. | "Calle Mayor 1, 28001 Madrid" |
poa_formatted_address | cadena | Sí | Dirección geocodificada y formateada. | "Calle Mayor 1, 28001 Madrid, Spain" |
poa_parsed_address | objeto | Sí | Dirección estructurada (street_1, street_2, city, region, postal_code, country (alpha-2), address_type, document_location, …). | { "street_1": "Calle Mayor 1", "city": "Madrid", "postal_code": "28001" } |
document_file | cadena (URL) | Sí | URL prefirmada del documento subido. | "https://<media-host>/.../poa.pdf?..." |
document_language | cadena | Sí | Idioma detectado del documento (ISO 639-1). | "es" |
document_metadata | objeto | Sí | Metadatos filtrados: file_size, content_type, creation_date, modified_date, creator, producer, software, encryption, is_signed, is_tampered, signature_info, exif_original_date, exif_digitized_date, processed_by_known_editor, has_different_creation_mod_date, overlay_manipulation. | { "file_size": 184221, "content_type": "application/pdf", "is_tampered": false } |
extra_fields | objeto | No | Campos de cuenta bancaria (bank_account_number, bank_iban, bank_sort_code, bank_routing_number, bank_swift_bic, bank_branch_name, bank_branch_address), document_phone_number, additional_names, más cualquier clave personalizada guardada en el registro. | { "bank_iban": null, "additional_names": [] } |
name_on_document | cadena | Sí | Nombre tal como aparece en el documento de domicilio. | "María García López" |
expected_details_address | cadena | Sí | Dirección que el cliente escribió durante el registro (literal). | "Calle Mayor 1, Madrid" |
expected_details_formatted_address | cadena | Sí | Dirección esperada geocodificada. | "Calle Mayor 1, 28001 Madrid, Spain" |
expected_details_parsed_address | objeto | Sí | Dirección esperada estructurada. | { "city": "Madrid", "postal_code": "28001" } |
name_match_score_expected_details | flotante (0-100) | Sí | Coincidencia aproximada entre name_on_document y el nombre indicado al crear la sesión. | 94.0 |
name_match_score_id_verification | flotante (0-100) | Sí | Coincidencia aproximada entre name_on_document y el full_name del documento de identidad verificado. | 100.0 |
extra_files | array de cadenas (URL) | No | URL prefirmadas de archivos adicionales subidos. | [] |
detected_codes | array de objetos | No | Códigos QR y de barras detectados en todas las páginas procesadas del documento: type, page_number (empieza en 1), position (polígono), x/y/width/height (cuadro delimitador), page_width/page_height, raw_payload (base64), parsed_payload (valor decodificado; null cuando se localizó un código pero no pudo decodificarse). Array vacío cuando la detección no encuentra nada. | [{ "type": "QR_CODE", "page_number": 1, "parsed_payload": "https://issuer.example/inv/9981" }] |
node_id | cadena | null | Sí | Identificador del nodo del flujo (V3). | "first_poa" |
warnings | array | No | Consulta Objeto de advertencia. | [] |
{
"status": "Approved",
"issuing_state": "ESP",
"document_type": "UTILITY_BILL",
"document_subtype": "ELECTRICITY_BILL",
"issuer": "Iberdrola",
"issue_date": "2026-04-15",
"expiration_date": null,
"poa_address": "Calle Mayor 1, 28001 Madrid",
"poa_formatted_address": "Calle Mayor 1, 28001 Madrid, Spain",
"poa_parsed_address": { "street_1": "Calle Mayor 1", "city": "Madrid", "postal_code": "28001", "country": "ES" },
"document_file": "https://<media-host>/.../poa.pdf?signature=...",
"document_language": "es",
"document_metadata": {
"file_size": 184221,
"content_type": "application/pdf",
"creation_date": "2026-04-15T08:11:32Z",
"modified_date": "2026-04-15T08:11:32Z",
"creator": "Iberdrola Billing",
"producer": "Adobe PDF Library 15.0",
"software": null,
"encryption": null,
"is_signed": true,
"is_tampered": false,
"signature_info": { "signer_name": "Iberdrola Clientes", "date": "2026-04-15T08:11:32Z" },
"exif_original_date": null,
"exif_digitized_date": null,
"processed_by_known_editor": false,
"has_different_creation_mod_date": false,
"overlay_manipulation": null
},
"extra_fields": {
"bank_account_number": null,
"bank_iban": null,
"bank_sort_code": null,
"bank_routing_number": null,
"bank_swift_bic": null,
"bank_branch_name": null,
"bank_branch_address": null,
"document_phone_number": null,
"additional_names": []
},
"name_on_document": "María García López",
"expected_details_address": "Calle Mayor 1, Madrid",
"expected_details_formatted_address": "Calle Mayor 1, 28001 Madrid, Spain",
"expected_details_parsed_address": { "city": "Madrid", "postal_code": "28001", "country": "ES" },
"name_match_score_expected_details": 94.0,
"name_match_score_id_verification": 100.0,
"extra_files": [],
"detected_codes": [
{
"type": "QR_CODE",
"page_number": 1,
"position": [[820, 1120], [1002, 1120], [1002, 1302], [820, 1302]],
"x": 820,
"y": 1120,
"width": 182,
"height": 182,
"page_width": 1190,
"page_height": 1684,
"raw_payload": "aHR0cHM6Ly9pYmVyZHJvbGEuZXMvZmFjdHVyYS85OTgx",
"parsed_payload": "https://iberdrola.es/factura/9981"
},
{
"type": "CODE_128",
"page_number": 1,
"position": [[112, 1480], [560, 1480], [560, 1540], [112, 1540]],
"x": 112,
"y": 1480,
"width": 448,
"height": 60,
"page_width": 1190,
"page_height": 1684,
"raw_payload": "MDA5OTgxMDAwNDI=",
"parsed_payload": "0099810042"
}
],
"node_id": "first_poa",
"warnings": []
}
Verificación de teléfono
Se devuelve por cada intento de verificación de teléfono. Aparece comophone_verifications[] en GET /v3/session/{sessionId}/decision/ tanto para sesiones KYC como KYB. Fuente: phone/serializers/phone.py:251-266 (PhoneV3Serializer, extiende PhoneV2Serializer en phone/serializers/phone.py:103-248).
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
status | cadena | No | Consulta Enumeración de estados. | "Approved" |
phone_number_prefix | cadena | No | Prefijo de país E.164 (con +). | "+34" |
phone_number | cadena | No | Número de abonado sin el prefijo. | "612345678" |
full_number | cadena | No | Número E.164 completo (phone_number_prefix + phone_number). | "+34612345678" |
country_code | cadena (ISO 3166-1 alpha-2) | Sí | País del número. | "ES" |
country_name | cadena | Sí | Nombre del país localizado. | "Spain" |
carrier | objeto | No | { name, type }, donde type es un valor de LineTypeChoices (common/config/choices.py:648-667): mobile, fixed_line, voip, isp, vpn, toll_free, premium_rate, satellite, pager, payphone, voice_mail, unknown y otras clases de línea. | { "name": "Movistar", "type": "mobile" } |
is_disposable | booleano | No | true cuando el operador marca el número como temporal o desechable. | false |
is_virtual | booleano | No | true cuando carrier.type es voip, isp o vpn. | false |
verification_method | cadena | No | Canal usado para entregar el OTP (whatsapp, sms, …). Se toma de actual_channel del último intento de envío (si no existe, usa el channel solicitado y, después, sms). | "whatsapp" |
verification_attempts | entero | No | Total de intentos de envío del OTP (envío inicial más reenvíos). | 1 |
verified_at | cadena (ISO 8601) | Sí | Marca de tiempo en que se introdujo correctamente el OTP. | "2026-05-17T10:14:02Z" |
lifecycle | array de objetos | No | Eventos en orden cronológico: intentos de envío, callbacks de entrega, comprobaciones del código y el evento de estado final. Cada evento es { type, timestamp, details, fee }. Los tipos de evento provienen de PhoneEventChoices. | […] |
matches | array de objetos | No | Coincidencias de número de teléfono entre sesiones. Cada elemento: { session_id, session_number, vendor_data, verification_date, phone_number, status, is_blocklisted, api_service, source }. source es session o list_entry. | [] |
node_id | cadena | null | Sí | Identificador del nodo del flujo (V3). | "first_phone" |
warnings | array | No | Consulta Objeto de advertencia. | [] |
phone_intelligence | objeto | Sí | Señales de inteligencia telefónica. Solo aparece cuando el complemento de inteligencia se ejecutó para el número. | |
phone_social | objeto | Sí | Huella social del número. Solo aparece cuando se ejecutó el complemento de huella social. |
{
"status": "Approved",
"phone_number_prefix": "+34",
"phone_number": "612345678",
"full_number": "+34612345678",
"country_code": "ES",
"country_name": "Spain",
"carrier": { "name": "Movistar", "type": "mobile" },
"is_disposable": false,
"is_virtual": false,
"verification_method": "whatsapp",
"verification_attempts": 1,
"verified_at": "2026-05-17T10:14:02Z",
"lifecycle": [
{
"type": "PHONE_VERIFICATION_MESSAGE_SENT",
"timestamp": "2026-05-17T10:13:51Z",
"details": { "status": "Success", "reason": null, "channel": "whatsapp", "actual_channel": "whatsapp" },
"fee": 0.02
},
{
"type": "PHONE_DELIVERY_DELIVERED",
"timestamp": "2026-05-17T10:13:52Z",
"details": { "channel": "whatsapp", "status": "delivered" },
"fee": 0
},
{
"type": "VALID_CODE_ENTERED",
"timestamp": "2026-05-17T10:14:02Z",
"details": { "code_tried": "482917", "status": "Approved" },
"fee": 0
},
{
"type": "PHONE_VERIFICATION_APPROVED",
"timestamp": "2026-05-17T10:14:02Z",
"details": null,
"fee": 0
}
],
"matches": [],
"node_id": "first_phone",
"warnings": []
}
Verificación de correo electrónico
Se devuelve por cada intento de verificación de correo electrónico. Aparece comoemail_verifications[] en GET /v3/session/{sessionId}/decision/ tanto para sesiones KYC como KYB. Fuente: email_verification/serializers/email.py:149-164 (EmailV3Serializer, extiende EmailV2Serializer en email_verification/serializers/email.py:38-146).
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
status | cadena | No | Consulta Enumeración de estados. | "Approved" |
email | cadena | No | Dirección de correo electrónico enviada. | "maria.garcia@example.com" |
is_breached | booleano | No | true cuando el correo aparece en una filtración de datos conocida. | false |
breaches | array de objetos | No | Detalle por filtración cuando is_breached es true: { name, domain, logo_path, breach_date, description, is_verified, data_classes, breach_emails_count }. | [] |
is_disposable | booleano | No | true cuando el correo pertenece a un proveedor de correo desechable. | false |
is_undeliverable | booleano | No | true cuando la comprobación de entrega SMTP indica que la bandeja de entrada no acepta correo. | false |
verification_attempts | entero | No | Total de intentos de comprobación del OTP. | 1 |
verified_at | cadena (ISO 8601) | Sí | Marca de tiempo en que se introdujo correctamente el OTP. | "2026-05-17T10:15:22Z" |
lifecycle | array de objetos | No | Eventos en orden cronológico: intentos de envío, comprobaciones del código y el evento de estado final. Cada evento es { type, timestamp, details, fee }. Los tipos de evento provienen de EmailEventChoices. | […] |
matches | array de objetos | No | Coincidencias de correo electrónico entre sesiones. Cada elemento: { session_id, session_number, vendor_data, verification_date, email, status, is_blocklisted, api_service, source }. source es session o list_entry. | [] |
node_id | cadena | null | Sí | Identificador del nodo del flujo (V3). | "first_email" |
warnings | array | No | Consulta Objeto de advertencia. | [] |
email_intelligence | objeto | Sí | Señales de inteligencia de correo electrónico. Solo aparece cuando el complemento de inteligencia se ejecutó para la dirección. | |
email_social | objeto | Sí | Huella social de la dirección. Solo aparece cuando se ejecutó el complemento de huella social. |
{
"status": "Approved",
"email": "maria.garcia@example.com",
"is_breached": false,
"breaches": [],
"is_disposable": false,
"is_undeliverable": false,
"verification_attempts": 1,
"verified_at": "2026-05-17T10:15:22Z",
"lifecycle": [
{
"type": "EMAIL_VERIFICATION_MESSAGE_SENT",
"timestamp": "2026-05-17T10:15:11Z",
"details": { "status": "Success", "reason": null },
"fee": 0.02
},
{
"type": "VALID_CODE_ENTERED",
"timestamp": "2026-05-17T10:15:22Z",
"details": { "code_tried": "739204", "status": "Approved" },
"fee": 0
},
{
"type": "EMAIL_VERIFICATION_APPROVED",
"timestamp": "2026-05-17T10:15:22Z",
"details": null,
"fee": 0
}
],
"matches": [],
"node_id": "first_email",
"warnings": []
}
Validación de base de datos
Se devuelve por cada consulta a base de datos realizada con los datos enviados por el usuario. Aparece comodatabase_validations[] en GET /v3/session/{sessionId}/decision/. Fuente: database_validation/serializers/database_validation.py:21-142 (DatabaseValidationV3Serializer, extiende DatabaseValidationV2Serializer).
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
issuing_state | cadena (ISO 3166-1 alfa-3) | Sí | País cuyo registro se consultó. | "ESP" |
validation_type | cadena (enum) | No | Cómo se corroboró el resultado: one_by_one (resultado de un solo servicio), two_by_two (dos o más servicios distintos coincidieron por completo con el número de identificación de forma independiente) o not_enabled (se omitió el validador o ningún proveedor respondió; un no_match definitivo sigue devolviendo one_by_one). Nunca null. Fuente: DatabaseValidationChoices (common/config/choices.py:1097-1100). | "one_by_one" |
screened_data | objeto | No | Los datos enviados al registro. Los campos de archivo (selfie, cnh_qr_code_image, document_image) se firman previamente en el momento de la lectura. | { "document_number": "99999999R", "date_of_birth": "1990-05-12" } |
validations | array de objetos | No | Una entrada por cada servicio del catálogo que produjo una coincidencia. Cada entrada puede incluir service_id, service_name, validation (objeto con el veredicto del proveedor), outcome_code, outcome_detail y source_data (perfil ciudadano depurado: full_name, gender, date_of_birth, photo (URL prefirmada), signature (URL prefirmada), …). | […] |
errors | array de objetos | Sí | Errores por servicio cuando una consulta falló; la clave se omite por completo cuando está vacía. Cada entrada es el objeto de error del servicio de origen más el service_id que lo produjo. | [] |
match_type | cadena (enum) | Sí | Veredicto de coincidencia agregado entre los servicios consultados: full_match, partial_match o no_match (DatabaseValidationMatchTypeChoices, common/config/choices.py:1103-1106). null hasta que se evalúe. | "full_match" |
status | cadena | No | Consulta el Enum de estado. | "Approved" |
node_id | cadena | null | Sí | Identificador del nodo del flujo de verificación (workflow) (V3). | "first_db_validation" |
warnings | array | No | Consulta el Objeto de advertencia. | [] |
{
"issuing_state": "ESP",
"validation_type": "one_by_one",
"screened_data": {
"document_number": "99999999R",
"date_of_birth": "1990-05-12",
"first_name": "María",
"last_name": "García López"
},
"validations": [
{
"service_id": "esp_dni",
"service_name": "Spain - DNI/NIE verification",
"validation": { "is_valid": true, "match_score": 100 },
"outcome_code": "MATCH",
"outcome_detail": "All identifiers match the registry record.",
"source_data": {
"full_name": "María García López",
"gender": "F",
"date_of_birth": "1990-05-12",
"photo": "https://<media-host>/.../registry_photo.jpg?signature=...",
"signature": null
}
}
],
"match_type": "full_match",
"status": "Approved",
"node_id": "first_db_validation",
"warnings": []
}
Respuesta del cuestionario
Se devuelve por cada envío de cuestionario. Aparece comoquestionnaire_responses[] en GET /v3/session/{sessionId}/decision/ tanto para sesiones KYC como KYB. Fuente: questionnaires/serializers/questionnaire.py:591-597 (QuestionnaireResponseV3Serializer, extiende QuestionnaireResponseSerializer en questionnaires/serializers/questionnaire.py:520-588).
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
questionnaire_id | cadena (UUID) | No | Identificador de la versión del cuestionario que se respondió. | "6a0f1c2c-…" |
title | cadena | No | Nombre del cuestionario, tal como se configuró en la Console. | "Customer risk profile" |
description | cadena | Sí | Descripción del cuestionario. | "Short risk-profile questions." |
languages | array de cadenas | No | Códigos de idioma en los que se publica el cuestionario. | ["en", "es"] |
default_language | cadena | No | Código de idioma de reserva. | "en" |
is_active | booleano | No | Indica si esta versión del cuestionario es la activa. | true |
is_simple_questionnaire | booleano | No | true cuando el cuestionario no tiene bifurcaciones (lista plana). | true |
questionnaire_group_id | cadena (UUID) | No | Identificador compartido por las versiones de un mismo cuestionario. | "a7c2c2c2-…" |
version | entero | No | Número de versión de la plantilla activa. | 3 |
status | cadena | No | Uno de Approved, In Review, Not Finished (un rechazo a nivel de cuestionario se asigna a In Review). | "Approved" |
published_at | cadena (ISO 8601) | Sí | Cuándo se publicó la plantilla. | "2026-01-12T11:00:00Z" |
sections | array de objetos | No | Secciones ordenadas tras aplicar el recorrido del grafo y el filtrado por visibilidad. Cada sección es { title, description, items[] } (title y description provienen del SECTION_HEADER de apertura, ya traducidos). Cada elemento es un elemento de formulario (uuid, value (id del nodo), element_type, is_required, title, description, placeholder, choices, max_files, required_if, repeatable_config, más un campo answer: null si no se respondió, omitido en los elementos de diseño HEADING/PARAGRAPH/SEPARATOR). Las respuestas de archivo contienen { files: [<presigned URL>, …] }. | […] |
node_id | cadena | null | Sí | Identificador del nodo del flujo (V3). | "first_questionnaire" |
{
"questionnaire_id": "6a0f1c2c-3b7d-4d2c-9eb6-fdc6c7c92ef9",
"title": "Customer risk profile",
"description": "Short risk-profile questions.",
"languages": ["en", "es"],
"default_language": "en",
"is_active": true,
"is_simple_questionnaire": true,
"questionnaire_group_id": "a7c2c2c2-1111-4d2c-9eb6-fdc6c7c92ef9",
"version": 3,
"status": "Approved",
"published_at": "2026-01-12T11:00:00Z",
"sections": [
{
"title": "Source of funds",
"description": null,
"items": [
{
"uuid": "4f1d5e2c-aaaa-4d2c-9eb6-fdc6c7c92ef9",
"value": "q_source_of_funds",
"element_type": "SINGLE_CHOICE",
"is_required": true,
"title": "What is your main source of funds?",
"description": null,
"placeholder": null,
"choices": [
{ "label": "Salary", "value": "salary" },
{ "label": "Business income", "value": "business" },
{ "label": "Investments", "value": "investments" }
],
"max_files": 1,
"required_if": null,
"repeatable_config": null,
"answer": { "value": "salary" }
}
]
}
],
"node_id": "first_questionnaire"
}
Firma electrónica
Se devuelve por cada firmante de un paso de Firma electrónica. Aparece comosignatures[] en GET /v3/session/{sessionId}/decision/ tanto para sesiones KYC como KYB, solo cuando el flujo tiene el paso. A diferencia de los demás objetos de informe, su status es la etapa de firma y su resultado está en verdict, y los elementos de warnings[] son { code, node_id } en lugar de objetos de advertencia.
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
id | cadena (UUID) | No | La firma del firmante. Úsala como signature_id en las rutas de evidencia y de validación. | "0e6c2a8e-…" |
node_id | cadena | No | Identificador del nodo del flujo. | "feature_signature" |
status | cadena | No | Etapa de firma: intro, review, code, signing, signed o declined. Solo signed significa que los documentos están firmados. | "signed" |
verdict | cadena | No | Not Finished, Approved, In Review o Declined. | "Approved" |
level | cadena | No | simple (predeterminado), aes o qes (cualificada; es un complemento). | "aes" |
format | cadena | No | pdf para una firma Simple, pades para Avanzada (AES) y Cualificada (QES). | "pades" |
profile | cadena | Sí | PAdES-B-LT una vez que se ha firmado una firma Avanzada (AES) o Cualificada (QES); en otro caso, null. | "PAdES-B-LT" |
signer | objeto | No | { name, capacity, company, role, roles, identity_session_id }. capacity es self (KYC) o company (KYB). | { "name": "Jane Doe", "capacity": "self", … } |
identity_used | objeto | No | { session_id, kyc_id, verified, expected_name }: la identidad verificada en la que se apoya la firma. Vacío para una firma Simple sin identidad verificada. | { "verified": true, … } |
certificate | objeto | Sí | { issuer, issued_to, serial, valid_from, valid_until }. null hasta que se firme, y siempre null para una firma Simple. | { "serial": "5A3F9C21", … } |
confirmation | objeto | No | { channel, destination, confirmed_at, attempts }. destination está enmascarado; attempts cuenta los códigos introducidos, incluido el correcto. Una firma simple no tiene código, así que channel y destination son null. | { "channel": "email", … } |
timestamp | objeto | Sí | { time, qualified, valid }. qualified es siempre false en AES, donde Didit emite la marca de tiempo; en QES la emite el prestador cualificado de servicios de confianza. null hasta que se firma, y siempre null en una firma simple. | { "qualified": false, … } |
documents | array de objetos | No | { id, uuid, title, language, source_revision, translation_id, file_name, pages, size_bytes, sha256_original, sha256_signed, status, opened_at, read_at, read_to_end, consented_at, consent, signed_file, mode, source_format, conversion, fields }. status es signed, declined, not_signed o not_reached. mode es fields o read_and_agree. source_format es pdf o docx; conversion describe el archivo Word original, o es null para un PDF. | […] |
documents[].language | cadena | Sí | Idioma de la versión seleccionada cuando se inició el intento, o null si no se ha definido. Se usa una traducción completa y coincidente; si no, el original. Una vez firmado, es el idioma que se firmó realmente. | "en" |
documents[].source_revision | cadena (UUID) | No | Revisión de origen copiada en el intento, incluso cuando se selecciona una traducción. Es distinta del id del documento del firmante. | "22222222-2222-4222-8222-222222222222" |
documents[].translation_id | cadena (UUID) | Sí | Traducción seleccionada, o null para el original. La copia del documento y su selección de idioma permanecen fijas una vez iniciado el intento. | null |
documents[].fields | array de objetos | No | { key, type, role, label, page, x, y, width, height, required, value, display_value, value_source, filled_at, image_url, value_unavailable_reason } por cada campo del documento. value es una cadena, un booleano en el caso de una casilla, o true para una firma o unas iniciales aplicadas. Vacío en un documento sin campos. | […] |
adopted_signature | objeto | Sí | { method, font, adopted_at }: la firma y las iniciales que adoptó el firmante. method es typed o drawn; font es el estilo de escritura manuscrita de una firma mecanografiada. null hasta que se adopte. | { "method": "drawn", … } |
electronic_signature_consent_at | cadena (ISO 8601) | Sí | Cuándo el firmante aceptó firmar los documentos electrónicamente. Se establece cuando algún documento tiene campos. | "2026-11-03T10:41:40Z" |
evidence_file | cadena | Sí | Ruta del PDF de evidencias, una vez firmado. | "/v3/session/…/evidence/?signature_id=…" |
warnings | array de objetos | No | { code, node_id }, con code uno de SIGNATURE_DECLINED, SIGNATURE_OTP_FAILED, SIGNATURE_NAME_MISMATCH, SIGNATURE_IDENTITY_NOT_VERIFIED, SIGNATURE_DOCUMENT_CHANGED. | [] |
validation | objeto | Sí | { valid, checked_at, documents[] }: la última comprobación criptográfica de los documentos firmados. null hasta que se firme. { valid: null, reason: "signature_provider_outcome_unknown", checked_at } cuando no se pudo confirmar el resultado de la firma. | { "valid": true, … } |
declined_at | cadena (ISO 8601) | Sí | Cuándo el firmante rechazó la firma. | null |
declined_action | cadena | No | El signature_declined_action del paso. | "REVIEW" |
signed_at | cadena (ISO 8601) | Sí | Cuándo se firmaron los documentos. | "2026-11-03T10:42:24Z" |
expires_at | cadena (ISO 8601) | No | Cuándo deja de funcionar el enlace de firma. | "2026-11-10T10:30:00Z" |
email_sent_at | cadena (ISO 8601) | Sí | Cuándo se envió al firmante por correo electrónico una copia firmada. | "2026-11-03T10:42:30Z" |
email_unavailable_reason | cadena | Sí | Por qué no se envió ninguna copia por correo electrónico, cuando se solicitó una. | null |
ip_address | cadena | Sí | La dirección IP del firmante cuando solicitó su código. | "203.0.113.10" |
place | cadena | Sí | No se recoge: siempre null. | null |
place_unavailable_reason | cadena | Sí | not_collected. | "not_collected" |
Estimación de edad
Devuelto por la API independiente de Estimación de edad (POST /v3/age-estimation/). La respuesta incluye un subconjunto de la forma de Liveness check bajo un sobre age_estimation: status, method, score, age_estimation, warnings, más un bloque user_image de detección facial exclusivo de la API independiente. No incluye reference_image, video_url, matches, face_quality ni face_luminance. En sesiones de flujo no hay un array aparte: la edad estimada aparece como liveness_checks[].age_estimation en GET /v3/session/{sessionId}/decision/. Fuente: apis/serializers/age_estimation.py:50-55 (AgeEstimationResponseSerializer), el sobre se ensambla en apis/views/age_estimation.py:138-174.
| Campo | Tipo | Nulable | Descripción | Ejemplo |
|---|---|---|---|---|
request_id | cadena (UUID) | No | ID de sesión persistido cuando save_api_request=true (el valor por defecto); en caso contrario, un UUID de correlación temporal. | "3b1f1e2c-…" |
age_estimation | objeto | No | Sobre del resultado: status (Approved / Declined), method (siempre PASSIVE), score (prueba de vida de 0-100, que puede ser nulo), age_estimation (edad estimada en años del rostro más grande, que puede ser nula), user_image (entities[] con age, bbox [x_min, y_min, x_max, y_max], confidence y gender por cada rostro; además best_angle), warnings[]. | { … } |
vendor_data | cadena | Sí | vendor_data de la solicitud, devuelto tal cual. | null |
metadata | objeto | Sí | metadata de la solicitud, devuelto tal cual. | null |
created_at | cadena (ISO 8601) | No | Marca de tiempo de la solicitud en el servidor. | "2026-05-17T10:22:13.512941+00:00" |
{
"request_id": "3b1f1e2c-7777-4d2c-9eb6-fdc6c7c92ef9",
"age_estimation": {
"status": "Approved",
"method": "PASSIVE",
"score": 94.10,
"age_estimation": 28.7,
"user_image": {
"entities": [
{ "age": 28.7, "bbox": [40, 40, 100, 100], "confidence": 0.72, "gender": "male" }
],
"best_angle": 0
},
"warnings": []
},
"vendor_data": null,
"metadata": null,
"created_at": "2026-05-17T10:22:13.512941+00:00"
}
Autenticación biométrica
La autenticación biométrica ejecuta el mismo proceso de prueba de vida y coincidencia facial que se usa en la KYC estándar, pero configurado para comparar el rostro capturado con la imagen de referencia de un usuario existente, en lugar de con un retrato de documento recién obtenido mediante OCR. No hay un serializador específico:GET /v3/session/{sessionId}/decision/ devuelve los objetos estándar Prueba de vida y Coincidencia facial bajo liveness_checks[] y face_matches[]. El flujo de la sesión se configura con workflow_type = "biometric_authentication" (WorkflowTypeChoices, common/config/choices.py:636).
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
liveness_checks | array de Prueba de vida | No | Resultado de la prueba de vida del intento de autenticación. | [ { "status": "Approved", … } ] |
face_matches | array de Coincidencia facial | No | Resultado de la comparación con la referencia registrada. source_image_session_id se establece en el session_id propio de la sesión: la cara de referencia (el portrait_image proporcionado, o el rostro almacenado reutilizado mediante vendor_data cuando se omite portrait_image) se registra en la propia sesión de autenticación (face/views/face.py:656-659). | [ { "status": "Approved", "source_image_session_id": "…", … } ] |
status | cadena | No | Estado de la sesión a nivel superior (véase Enumeración de estados). | "Approved" |
{
"session_id": "9b1f1e2c-8888-4d2c-9eb6-fdc6c7c92ef9",
"status": "Approved",
"liveness_checks": [
{
"status": "Approved",
"method": "PASSIVE",
"score": 95.10,
"reference_image": "https://<media-host>/.../reference.jpg?signature=...",
"video_url": null,
"age_estimation": null,
"matches": [],
"face_quality": 91.20,
"face_luminance": 53.10,
"node_id": "biometric_auth_liveness",
"warnings": []
}
],
"face_matches": [
{
"status": "Approved",
"score": 98.42,
"source_image_session_id": "9b1f1e2c-8888-4d2c-9eb6-fdc6c7c92ef9",
"source_image": "https://<media-host>/.../source.jpg?signature=...",
"target_image": "https://<media-host>/.../target.jpg?signature=...",
"node_id": "biometric_auth_face_match",
"warnings": []
}
]
}
Registro KYB
Se devuelve por cada empresa confirmada en el registro dentro de un flujo de verificación KYB (workflow). Aparece comoregistry_checks[] en GET /v3/session/{sessionId}/decision/ para sesiones de empresa. Fuente: kyb/serializers/kyb.py:939-964 (RegistryCheckV3Serializer).
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
status | cadena | No | Véase Enumeración de estados. | "Approved" |
node_id | cadena | null | Sí | Identificador del nodo del flujo (V3). | "first_registry" |
data_resolved | booleano | No | true cuando la consulta al registro ha finalizado (o cuando is_from_registry es false, lo que significa que los datos se introdujeron manualmente). | true |
company | objeto | No | Payload completo de la empresa: véase Objeto de empresa más abajo. | { … } |
ownership_structure | objeto | Sí | La tabla de capitalización que comprobó el registro: shareholders[] y beneficial_owners[], donde cada titular incluye su identidad en el registro, su participación y el shareholding canónico. | { "shareholders": [...], "beneficial_owners": [] } |
warnings | array | No | Véase Objeto de advertencia. | [] |
Objeto de empresa
Procede dekyb/serializers/kyb.py:220-321 (KYBCompanyResponseSerializer).
| Campo | Tipo | Nulo | Descripción |
|---|---|---|---|
uuid | cadena (UUID) | No | Identificador interno de la empresa. |
node_id | cadena | null | Sí | Identificador del nodo del flujo. |
status | cadena | No | Estado de la función (FeatureStatusChoices). |
registry_status | cadena | Sí | Estado de la empresa en el registro (active, dissolved, …). |
data_resolved | booleano | No | Misma definición que en el objeto padre. |
company_name | cadena | Sí | Nombre registrado de la empresa. |
registration_number | cadena | Sí | Identificador en el registro. |
country_code | cadena (ISO 3166-1 alpha-2) | Sí | País de constitución. |
region | cadena | Sí | Subdivisión ISO 3166-2, cuando corresponda (p. ej. US-CA). |
company_type | cadena | Sí | Forma jurídica (LLC, SL, …). |
incorporation_date | cadena (AAAA-MM-DD) | Sí | Fecha de constitución. |
registered_address | cadena | Sí | Domicilio social legal registrado. |
tax_number | cadena | Sí | Identificador fiscal o de IVA. |
risk_level | cadena | Sí | Nivel de riesgo proporcionado por el proveedor. |
verification_status | cadena | Sí | Enumeración interna del estado de verificación. |
is_from_registry | booleano | No | true cuando procede del registro (frente a la introducción manual). |
fetch_status | cadena | Sí | pending, resolved, failed. |
alternative_names | cadena | Sí | Nombres comerciales alternativos separados por comas. |
nature_of_business | cadena | Sí | Descripción en texto libre de la actividad empresarial. |
registered_capital | cadena | Sí | Capital social registrado, como cadena legible. |
registered_capital_amount | cadena (decimal) | Sí | Importe procesado del capital social registrado. |
registered_capital_currency | cadena (ISO 4217) | Sí | Código de moneda. |
website | cadena (URL) | Sí | Sitio web de la empresa. |
email | cadena | Sí | Correo electrónico de contacto público. |
phone | cadena | Sí | Teléfono de contacto público. |
legal_entity_identifier | cadena | Sí | LEI, cuando esté disponible. |
location_of_registration | cadena | Sí | Oficina o región del registro. |
vat_number | cadena | Sí | Número de IVA presentado para la empresa. |
vat_validation_status | cadena | No | Resultado de validar el número de IVA, o del tax_number cuando no hay ninguno: valid, invalid, format_valid, invalid_format, could_not_validate o not_applicable. Véase Validación de IVA e identificación fiscal. |
vat_validated_number | cadena | Sí | El número que se comprobó, tal como lo conoce la fuente. |
vat_validation_source | cadena | Sí | Fuente que determinó el estado: eu_vies, pl_vat_white_list, no_brreg, ch_uid_register, br_receita_federal, co_rues, cr_hacienda, ec_sri, py_dnit o format_rules. |
vat_validated_name | cadena | Sí | Nombre registrado en la fuente (vacío cuando no lo revela). |
vat_validated_address | cadena | Sí | Dirección registrada en la fuente (vacía cuando no se revela). |
vat_checked_at | cadena (ISO 8601) | Sí | Marca temporal de la comprobación; null cuando no se realizó ninguna. |
financial_summary | objeto | Sí | Instantánea de los datos financieros más recientes y destacados, cuando los facilita el registro. |
officers | array de objetos | No | Lista de administradores apta para B2C: { uuid, name, designation, role, nationality, is_active, kyc_status, kyc_session_url }. |
beneficial_owners | array de objetos | No | Lista de beneficiarios finales (UBO) apta para B2C: { uuid, name, first_name, last_name, entity_type, roles, ownership_min_shares, ownership_max_shares, is_active, kyc_status, kyc_session_url, effective_ownership_percent }. |
addresses | array de objetos | Sí | Detalle de cada dirección procedente del registro. |
industries | array de objetos | Sí | Clasificaciones de tipo SIC/NAICS. |
accounts | array de objetos | Sí | Metadatos de las cuentas presentadas. |
registry_data | objeto | Sí | Detalle normalizado del registro de Didit (resultado de la estructura de propiedad, correcciones hechas en la consola y datos del registro que no tienen campo propio). No es un contrato estable. |
user_provided_data | objeto | Sí | Instantánea de los campos editados por el usuario. |
confirmed_by_user_at | cadena (ISO 8601) | Sí | Marca temporal en la que el usuario confirmó los datos extraídos. |
last_console_edit_at | cadena (ISO 8601) | Sí | Marca de tiempo de la última edición en la consola. |
is_editable | booleano | No | true mientras el usuario final todavía puede editar los datos obtenidos del registro. |
{
"status": "Approved",
"node_id": "first_registry",
"data_resolved": true,
"company": {
"uuid": "b1f1e2c2-9999-4d2c-9eb6-fdc6c7c92ef9",
"node_id": "first_registry",
"status": "Approved",
"registry_status": "active",
"data_resolved": true,
"company_name": "Sante Clinics SL",
"registration_number": "B12345678",
"country_code": "ES",
"region": null,
"company_type": "SL",
"incorporation_date": "2018-03-22",
"registered_address": "Calle Mayor 1, 28001 Madrid, Spain",
"tax_number": "B12345678",
"risk_level": "low",
"verification_status": "verified",
"is_from_registry": true,
"fetch_status": "resolved",
"alternative_names": "Sante Clinics",
"nature_of_business": "Medical clinic operations",
"registered_capital": "EUR 50,000",
"registered_capital_amount": "50000.00",
"registered_capital_currency": "EUR",
"website": "https://santeclinics.com",
"email": "info@santeclinics.com",
"phone": "+34911223344",
"legal_entity_identifier": null,
"location_of_registration": "Registro Mercantil de Madrid",
"vat_number": "ESB12345678",
"vat_validation_status": "valid",
"vat_validated_name": "SANTE CLINICS SL",
"vat_validated_address": "CALLE MAYOR 1, 28001 MADRID",
"vat_checked_at": "2026-05-17T10:11:05Z",
"financial_summary": null,
"officers": [
{
"uuid": "c1f1e2c2-aaaa-4d2c-9eb6-fdc6c7c92ef9",
"name": "María García López",
"designation": "Administrador único",
"role": "Director",
"nationality": "ESP",
"is_active": true,
"kyc_status": "Approved",
"kyc_session_url": "https://verify.didit.me/s/…"
}
],
"beneficial_owners": [
{
"uuid": "d1f1e2c2-bbbb-4d2c-9eb6-fdc6c7c92ef9",
"name": "María García López",
"first_name": "María",
"last_name": "García López",
"entity_type": "person",
"roles": ["UBO"],
"ownership_min_shares": "75.00",
"ownership_max_shares": "75.00",
"is_active": true,
"kyc_status": "Approved",
"kyc_session_url": "https://verify.didit.me/s/…",
"effective_ownership_percent": 75.0
}
],
"addresses": [],
"industries": [],
"accounts": [],
"registry_data": {},
"user_provided_data": {},
"confirmed_by_user_at": "2026-05-17T10:11:02Z",
"last_console_edit_at": null,
"is_editable": false
},
"ownership_structure": null,
"warnings": []
}
Documento KYB
Se devuelve por cada nodo que recopila documentos de respaldo KYB. Aparece comodocument_verifications[] en GET /v3/session/{sessionId}/decision/ en las sesiones de empresa: una entrada por node_id, con items[] que enumera cada documento cargado. Fuente: kyb/serializers/kyb.py:1053-1068 (DocumentVerificationV3Serializer); cada elemento sigue kyb/serializers/kyb.py:811-851 (KYBDocumentResponseSerializer).
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
status | string | No | Estado agregado de los documentos de este nodo: Approved solo cuando todos los documentos del flujo están aprobados; Declined si alguno está rechazado; In Review en cualquier otro caso; Not Finished mientras esté pendiente. Consulta la enumeración de estados. | "Approved" |
node_id | string | null | Sí | Identificador del nodo del flujo (V3). | "first_kyb_documents" |
items | array de objetos de elemento de documento KYB | No | Una entrada por cada documento cargado o solicitado. | […] |
groups | objeto | No | Recuentos por grupo de documentos: { <group_name>: { total, approved, pending, declined, in_review, other, missing } }. | { "incorporation_certificate": { "total": 1, "approved": 1, "pending": 0, "declined": 0, "in_review": 0, "other": 0, "missing": 0 } } |
required_groups | array de strings | No | Grupos de documentos que exige la configuración del flujo. | ["incorporation_certificate", "shareholder_register"] |
warnings | array | No | Consulta el objeto de advertencia. | [] |
Objeto de documento KYB
| Campo | Tipo | Nulo | Descripción |
|---|---|---|---|
uuid | string (UUID) | No | Identificador interno del documento. |
document_type | string | Sí | Grupo de nivel superior (incorporation_certificate, shareholder_register, …). |
document_subtype | string | Sí | Subtipo específico del proveedor. |
document_group | string | Sí | Equivalente de document_type (alias que se mantiene por claridad). |
file_url | string (URL) | Sí | URL prefirmada del archivo limpio. |
original_filename | string | Sí | Nombre de archivo tal como se cargó. |
file_size | integer | Sí | Tamaño del archivo en bytes. |
status | string | No | Estado del documento (FeatureStatusChoices). |
created_at | string (ISO 8601) | No | Marca de tiempo de la carga. |
cross_check_result | object | Sí | Veredicto de la comparación cruzada con el registro u otros documentos. |
document_metadata | object | Sí | Misma estructura filtrada de metadatos que document_metadata de la prueba de domicilio (POA). |
description | string | Sí | Descripción proporcionada por el revisor o por el sistema. |
is_requested | boolean | No | true cuando el flujo esperaba este documento. |
ocr_data | object | Sí | Campos extraídos por OCR, cuando están disponibles. |
is_console_upload | boolean | No | true cuando el documento lo cargó un revisor desde la consola (se excluye del veredicto agregado). |
is_confirmed | boolean | No | true cuando el revisor ha confirmado explícitamente el documento. |
{
"status": "Approved",
"node_id": "first_kyb_documents",
"items": [
{
"uuid": "e1f1e2c2-cccc-4d2c-9eb6-fdc6c7c92ef9",
"document_type": "incorporation_certificate",
"document_subtype": "registro_mercantil_extract",
"document_group": "incorporation_certificate",
"file_url": "https://<media-host>/.../incorporation.pdf?signature=...",
"original_filename": "incorporation_certificate.pdf",
"file_size": 256412,
"status": "Approved",
"created_at": "2026-05-17T10:08:00Z",
"cross_check_result": { "matches_registry_name": true, "matches_registration_number": true },
"document_metadata": {
"file_size": 256412,
"content_type": "application/pdf",
"is_signed": true,
"is_tampered": false
},
"description": null,
"is_requested": true,
"ocr_data": { "company_name": "Sante Clinics SL", "registration_number": "B12345678" },
"is_console_upload": false,
"is_confirmed": true
}
],
"groups": {
"incorporation_certificate": { "total": 1, "approved": 1, "pending": 0, "declined": 0, "in_review": 0, "other": 0, "missing": 0 }
},
"required_groups": ["incorporation_certificate", "shareholder_register"],
"warnings": []
}
Persona clave KYB
Se devuelve por cada nodo de personas clave de un flujo KYB. Aparece comokey_people_checks[] en GET /v3/session/{sessionId}/decision/ en las sesiones de empresa. Fuente: kyb/serializers/kyb.py:967-1050 (KeyPeopleCheckV3Serializer).
| Campo | Tipo | Nulo | Descripción | Ejemplo |
|---|---|---|---|---|
status | string | No | Consulta la enumeración de estados. | "Approved" |
node_id | string | null | Sí | Identificador del nodo del flujo (V3). | "first_key_people" |
registry | object | No | { officers[], beneficial_owners[] } extraídos del registro. Los directivos siguen KYBPersonResponseSerializer (kyb/serializers/kyb.py:533-645); los beneficiarios finales siguen KYBBeneficialOwnerResponseSerializer (kyb/serializers/kyb.py:648-788), que añade date_of_birth, country_of_birth, email, company_name, registration_number, entity_type, roles, ownership_min_shares, ownership_max_shares, child_beneficial_owners y effective_ownership_percent. Ambos incluyen el enriquecimiento AML y KYC para cada parte: aml_status, kyc_status, kyc_session_url, kyc_session_id, verification_workflow_type, verification_workflow_id, verification_workflow_label, verification_workflow_features, didit_internal_id, kyc_document_type, kyc_nationality, kyc_liveness_passed, kyc_verified_at, kyc_aml_categories y kyc_notification_sent_at. | { "officers": [...], "beneficial_owners": [...] } |
submitted | object | No | { parties[] }: entradas que la empresa confirmó o envió mediante el flujo de personas clave (filas de BusinessParty con source=USER). Cada parte sigue BusinessPartySubmissionResponseSerializer (kyb/serializers/party.py:146-194): uuid, entity_type, source, name, first_name, last_name, company_name, registration_number, email, nationality, phone_number, date_of_birth, position, custom_fields, is_active, is_skipped, requires_verification, roles[] ({ role, ownership_percent, voting_percent }), kyc_session_id, kyc_session_status, kyc_session_url, kyc_session_deleted, kyb_sub_session_id, kyb_sub_session_status, kyb_sub_session_url, kyb_sub_session_deleted, verification_workflow_type, verification_workflow_id, verification_workflow_label, verification_workflow_features y didit_internal_id. kyc_session_deleted y kyb_sub_session_deleted marcan una sesión hija que fue eliminada: su estado se queda congelado en el último valor, el *_session_url correspondiente vuelve como null porque el enlace ya no se resuelve, y la parte deja de bloquear a la sesión padre (la comprobación pasa a In Review). Para quitar la marca, usa PATCH /v3/session/{id}/kyb/parties/{party_uuid}/. | { "parties": [...] } |
ubo_kyc_summary | object | Sí | Recuentos de los UBO activos con KYC vinculado: { total, approved, flagged, pending }. null cuando ningún UBO activo tiene KYC vinculado. | { "total": 2, "approved": 2, "flagged": 0, "pending": 0 } |
warnings | array | No | Ver Objeto de advertencia. | [] |
{
"status": "Approved",
"node_id": "first_key_people",
"registry": {
"officers": [
{
"uuid": "c1f1e2c2-aaaa-4d2c-9eb6-fdc6c7c92ef9",
"name": "María García López",
"designation": "Administrador único",
"role": "Director",
"nationality": "ESP",
"appointment_date": "2018-03-22",
"termination_date": null,
"is_active": true,
"address": "Calle Mayor 1, 28001 Madrid",
"aml_status": "Approved",
"kyc_status": "Approved",
"kyc_session_url": "https://verify.didit.me/s/…",
"kyc_session_id": "9b1f1e2c-8888-4d2c-9eb6-fdc6c7c92ef9",
"verification_workflow_type": "kyc",
"verification_workflow_id": "11111111-1111-1111-1111-111111111111",
"verification_workflow_label": "KYB officer KYC",
"verification_workflow_features": [
{ "feature": "ID_VERIFICATION", "status": "Approved" },
{ "feature": "LIVENESS", "status": "Approved" },
{ "feature": "FACE_MATCH", "status": "Approved" }
],
"didit_internal_id": "user-12345",
"kyc_document_type": "Passport",
"kyc_nationality": "ESP",
"kyc_liveness_passed": true,
"kyc_verified_at": "2026-05-17T10:10:11Z",
"kyc_aml_categories": [],
"kyc_notification_sent_at": "2026-05-15T08:00:00Z"
}
],
"beneficial_owners": []
},
"submitted": {
"parties": [
{
"uuid": "d1f1e2c2-bbbb-4d2c-9eb6-fdc6c7c92ef9",
"entity_type": "person",
"source": "USER",
"name": "María García López",
"first_name": "María",
"last_name": "García López",
"company_name": null,
"registration_number": null,
"email": "maria.garcia@example.com",
"nationality": "ESP",
"phone_number": null,
"date_of_birth": "1990-05-12",
"position": "Administrador único",
"custom_fields": {},
"is_active": true,
"is_skipped": false,
"requires_verification": true,
"roles": [
{ "role": "UBO", "ownership_percent": 75.0, "voting_percent": null }
],
"kyc_session_id": "9b1f1e2c-8888-4d2c-9eb6-fdc6c7c92ef9",
"kyc_session_status": "Approved",
"kyc_session_url": "https://verify.didit.me/s/…",
"kyb_sub_session_id": null,
"kyb_sub_session_status": null,
"kyb_sub_session_url": null,
"verification_workflow_type": "kyc",
"verification_workflow_id": "11111111-1111-1111-1111-111111111111",
"verification_workflow_label": "KYB officer KYC",
"verification_workflow_features": [
{ "feature": "ID_VERIFICATION", "status": "Approved" },
{ "feature": "LIVENESS", "status": "Approved" }
],
"didit_internal_id": "user-12345"
}
]
},
"ubo_kyc_summary": { "total": 1, "approved": 1, "flagged": 0, "pending": 0 },
"warnings": []
}
Campos a nivel de decisión
Estas claves están junto a los arrays de cada función enGET /v3/session/{sessionId}/decision/ y dentro del objeto decision de un webhook.
| Campo | Tipo | Admite nulo | Descripción |
|---|---|---|---|
status_override | objeto | Sí | { overridden_at, automatic_status } después de que un revisor haya establecido status manualmente; null cuando el estado es el automático. |
decision_trace | objeto | No | Cómo se llegó al estado: status, decided_by (manual, automatic o investigator), decided_at, automatic_status, terminal_node_id, actor, warning_counts y status_warnings. |
linked_records | objeto | Sí | Resúmenes de same_face, earlier_verifications y networks; null cuando no hay nada que mostrar. |
biometric_retention | objeto | No | { jurisdictions, deletes_at }. deletes_at es la fecha en la que se eliminan los datos biométricos de la sesión capturados en directo, y null cuando aún no hay una fecha aplicable. |
database_validation_not_performed_reason | objeto | Sí | { code, message } que explica por qué una validación de base de datos configurada no produjo ningún resultado. |
assignee, waiting_since, sla_due_at | objeto, datetime | Sí | El revisor de la Console que tiene asignada la sesión y su temporizador de revisión; el reloj es null salvo que la sesión esté en In Review. |
shared_from_session, shared_from_session_number | UUID, entero | Sí | La sesión de origen de una sesión importada. |
sandbox_scenario | cadena | Sí | El escenario con el que se creó una sesión de sandbox. |
fraud_check | objeto | Sí | El resultado de la Fraud Check API; null en cualquier otra sesión. |
full_session_video, full_session_video_recorded_at | URL, datetime | Sí | La grabación y el momento en que se realizó. Solo se devuelve cuando tu organización graba el video de la sesión completa. |
Consentimiento biométrico
Cada decisión y webhook de sesión de Verificación de usuarios incluye un único objetobiometric_consent (no un array): si la sesión requería consentimiento biométrico explícito, por qué y la evidencia de la respuesta. Es null cuando la sesión nunca se evaluó, por ejemplo en un flujo de verificación (workflow) sin captura facial. Origen: BiometricConsentDecisionSerializer (sessions/serializers/biometric_consent.py). Cuándo aparece el paso y qué significa cada caso se explica en Consentimiento biométrico.
Los campos sin valor registrado son null, nunca una cadena vacía.
| Campo | Tipo | Descripción |
|---|---|---|
required | boolean | Si la sesión debe recoger consentimiento biométrico explícito. Nunca vuelve a false. |
trigger | string (enum) | null | Por qué se requiere el consentimiento, o cómo se cumplió: declared_state, ip_state, ip_unknown, document_issuer, forced (el modo de la aplicación es Siempre), customer_collected (enviaste biometric_consent al crear la sesión). null mientras no se requiera. |
status | string (enum) | not_required, pending (requerido, no otorgado), given, declined (se registró un rechazo; hoy ninguna pantalla de Didit ofrece rechazar). |
given_at | string (ISO 8601) | null | Cuándo se otorgó el consentimiento. Para customer_collected, el given_at que enviaste. |
declined_at | string (ISO 8601) | null | Cuándo se registró un rechazo. |
text_version | string | null | ID de versión del texto de consentimiento al que respondió la persona, o el que enviaste. |
text_hash | string | null | SHA-256 (hex) del texto exacto mostrado, en el idioma en que se mostró. |
locale | string | null | Idioma en que se mostró el texto. |
policy_url | string | null | La política de datos biométricos a la que enlazaba el paso. |
step | string | null | Paso del flujo en el que estaba la sesión cuando la persona respondió (por ejemplo, LIVENESS). |
node_id | string | null | Nodo del grafo del flujo en el que estaba la sesión cuando la persona respondió. |
ip_address | string | null | IP desde la que llegó la respuesta. |
ip_country_code | string | null | País ISO 3166-1 alfa-2 de la IP de la respuesta. |
ip_state | string | null | Subdivisión ISO 3166-2 de la IP de la respuesta (por ejemplo, US-IL). |
ip_city | string | null | Ciudad de la IP de la respuesta. |
user_agent | string | null | User agent de la solicitud de la respuesta. |
detected_ip_address | string | null | La IP de la persona desde la que se evaluó el requisito por última vez. Puede diferir de ip_address cuando la persona respondió en otro dispositivo. |
detected_country_code | string | null | País ISO 3166-1 alfa-2 de la IP detectada. |
detected_state | string | null | Subdivisión ISO 3166-2 de la IP detectada. |
detected_city | string | null | Ciudad de la IP detectada. |
declared_state | string | null | Subdivisión ISO 3166-2 que declaraste: user_state, o el estado de una dirección de EE. UU. en expected_details. |
document_state | string | null | Subdivisión ISO 3166-2 que emitió el documento de identidad, leída en la captura del documento. |
jurisdictions | array of string | Estados de EE. UU. (códigos USPS, por ejemplo IL) cuya legislación biométrica se aplica a la persona. US cuando la evidencia sitúa a la persona en EE. UU. pero no se conoce el estado. Vacío cuando no aplica ninguno. |
retention_months | integer | null | El límite de retención biométrica más corto, en meses, entre jurisdictions. null cuando no aplica ninguno. |
reason | string (enum) | null | BIOMETRIC_CONSENT_UNSUPPORTED_SDK: se requería consentimiento y un SDK nativo anterior a 4.10.0, o uno que no informó su versión, capturó un rostro sin el paso; status se queda en pending, o en given si la persona aceptó después en el flujo alojado. BIOMETRIC_CONSENT_DECLINED: se registró un rechazo (sustituye al motivo del SDK). null en los demás casos, y siempre null cuando la sesión no requería consentimiento. |
decline_reason | string | null | BIOMETRIC_CONSENT_DECLINED cuando un rechazo registrado terminó la sesión; en caso contrario, null. |
face_data_deleted_at | string (ISO 8601) | null | Cuándo el rechazo eliminó las imágenes faciales, los vídeos y las plantillas faciales de la sesión. null salvo que se haya registrado un rechazo. |
{
"required": true,
"trigger": "ip_state",
"status": "pending",
"given_at": null,
"declined_at": null,
"text_version": null,
"text_hash": null,
"locale": null,
"policy_url": null,
"step": null,
"node_id": null,
"ip_address": null,
"ip_country_code": null,
"ip_state": null,
"ip_city": null,
"user_agent": null,
"detected_ip_address": "203.0.113.42",
"detected_country_code": "US",
"detected_state": "US-IL",
"detected_city": "Chicago",
"declared_state": null,
"document_state": null,
"jurisdictions": ["IL"],
"retention_months": 36,
"reason": "BIOMETRIC_CONSENT_UNSUPPORTED_SDK",
"decline_reason": null,
"face_data_deleted_at": null
}
{
"required": true,
"trigger": "declared_state",
"status": "given",
"given_at": "2026-10-13T18:31:07.412000Z",
"declined_at": null,
"text_version": "bio-consent-2026-10-12",
"text_hash": "9b2f0c5e4d8a7f61c3e2b4a5d6f7081923a4b5c6d7e8f90a1b2c3d4e5f6a7b8c",
"locale": "en",
"policy_url": "https://didit.me/legal/biometric-data-policy",
"step": "LIVENESS",
"node_id": "feature_liveness_1",
"ip_address": "198.51.100.23",
"ip_country_code": "ES",
"ip_state": "ES-M",
"ip_city": "Madrid",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
"detected_ip_address": "198.51.100.23",
"detected_country_code": "ES",
"detected_state": "ES-M",
"detected_city": "Madrid",
"declared_state": null,
"document_state": null,
"jurisdictions": ["IL"],
"retention_months": 36,
"reason": null,
"decline_reason": null,
"face_data_deleted_at": null
}
Referencia de los valores de estado
Dos conjuntos de valores relacionados comparten el nombre de campostatus. Todos los objetos de informe por función de esta página usan el enum de nivel de función; el status de nivel superior de la sesión principal usa el enum de sesión, más amplio.
Estados de nivel de función
Los usa el campostatus de todos los objetos de informe. Origen: common/config/choices.py:343-348 (FeatureStatusChoices).
| Valor | Significado |
|---|---|
Not Finished | La función se ha habilitado, pero el usuario aún no la ha completado. |
Approved | La función superó todas las comprobaciones. |
Declined | La función no superó al menos una comprobación estricta (consulta warnings[] con log_type: "error"). |
In Review | La función activó señales de fallo leve y está pendiente de revisión manual (consulta warnings[] con log_type: "warning"). |
Resub Requested | Un revisor solicitó que el usuario vuelva a enviar la información de esta función. |
Expired cuando se agota el tiempo de su paso (PhoneStatusChoices en common/config/choices.py:377-382, EmailStatusChoices en common/config/choices.py:434-439).
Estados de nivel de sesión
Los usa elstatus de nivel superior de la sesión principal. Origen: common/config/choices.py:106-117 (StatusChoices).
| Valor | Significado |
|---|---|
Not Started | La sesión se ha creado, pero el usuario no la ha iniciado. |
In Progress | El usuario ha iniciado el flujo; el resultado aún no es definitivo. |
Approved | La sesión superó todas las comprobaciones. |
Declined | La sesión no superó al menos una comprobación estricta. |
In Review | La sesión está pendiente de revisión manual. |
Expired | La sesión expiró antes de completarse. |
Abandoned | El usuario abandonó el flujo sin completarlo. |
Kyc Expired | Venció el periodo de validez del KYC (se usa en flujos de reverificación). |
Resubmitted | El usuario volvió a enviar la verificación tras un rechazo previo; una sesión más reciente reemplaza a esta. |
Awaiting User | El sistema está esperando una acción del usuario (por ejemplo, introducir un OTP). |
Los valores finales de sesión son
Approved, Declined, In Review, Expired, Kyc Expired y Abandoned. Una sesión puede alcanzar su decisión global mientras una función concreta sigue en In Review.