> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Referencia de la API de configuración de funciones

> Todos los campos de configuración que aceptan POST y PATCH /v3/workflows/ de Didit para crear flujos lineales simples con el array features.

Usa estos campos de `config` dentro de cada elemento del array `features` para [`POST /v3/workflows/`](https://docs.didit.me/es/management-api/workflows/create) y [`PATCH /v3/workflows/{settings_uuid}/`](https://docs.didit.me/es/management-api/workflows/update).

```json theme={null}
{
  "workflow_label": "Standard KYC",
  "features": [
    {
      "feature": "OCR",
      "config": {
        "documents_allowed": {
          "USA": {
            "DL": {
              "enabled": 1,
              "sides": 2
            }
          }
        }
      }
    }
  ]
}
```

La API de workflows v3 construye un workflow lineal basado en nodos a partir del array ordenado `features`. Envía las funciones en el orden exacto de ejecución.

> [!NOTE]
>
> Qué motor ejecuta una función (el de Didit o el de un proveedor externo) no es uno de los campos de configuración que se indican a continuación. Se gestiona desde el [Marketplace](https://docs.didit.me/es/console/marketplace.md) de la consola, que define por ti `provider_key` y `fallback_to_native` en el objeto `config` de la función.

## Reglas de validación

* `OCR` incluye de forma predeterminada todos los países y tipos de documento compatibles cuando `config.documents_allowed` se omite o vale `null` o `{}`. Si envías un objeto `documents_allowed` personalizado, debe contener al menos un país válido y un tipo de documento habilitado. Cada configuración de documento puede establecer `sides` en `1` para capturar solo el anverso o en `2` para capturar el anverso y el reverso.
* `QUESTIONNAIRE` requiere `config.questionnaire_uuid`.
* `KYB_DOCUMENTS` requiere `config.kyb_required_document_groups`.
* `SIGNATURE` rechaza `signature_level: "qes"` con `qes_not_available` hasta que las firmas cualificadas estén disponibles, y rechaza un paso nuevo con `signature_level: "aes"` con `aes_not_available` mientras `signature_availability.aes` sea `false` en el flujo. Sus documentos deben existir cuando se crea una sesión: con `signature_documents_source` establecido en `workflow`, el paso necesita documentos subidos en la consola, y un paso sin documentos puede quedarse como borrador, pero no puede pasar a producción; con `session`, cada llamada de creación debe enviar `sign.documents`.
* `FACE_MATCH` debe ir después de `OCR` en las solicitudes de flujos simples.
* `NFC` y `DATABASE_VALIDATION` requieren `OCR` cuando aparecen en el mismo flujo. `AML` necesita uno de `OCR`, `KYB_REGISTRY` o `DOCUMENT_AI` antes que él; si solo tiene `DOCUMENT_AI` delante, el `full_name` analizado tiene que poder completarse, ya sea a partir de un campo de Document AI anterior con la clave `full_name`, que se asigna automáticamente, o a partir de una entrada explícita en `config.aml_field_sources` (consulta [AML](#aml)).
* Las subfunciones de KYB como `KYB_DOCUMENTS` y `KYB_KEY_PEOPLE` requieren `KYB_REGISTRY` antes en el flujo.
* Un flujo es de personas (KYC) o de empresas (KYB), nunca ambas cosas. Un flujo que usa cualquier función de KYB (`KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`) solo puede combinarla con `AML`, `DOCUMENT_AI`, `QUESTIONNAIRE`, `PHONE_VERIFICATION`, `EMAIL_VERIFICATION`, `IP_ANALYSIS` y `SIGNATURE`. No puede incluir funciones exclusivas de personas como `OCR`, `LIVENESS`, `FACE_MATCH`, `NFC`, `PROOF_OF_ADDRESS`, `DATABASE_VALIDATION` o `AGE_ESTIMATION`, y un flujo de personas no puede incluir funciones de KYB. En un flujo de empresas, `DOCUMENT_AI` compara cualquier campo marcado con `is_full_name` con la empresa verificada en lugar de con una persona. Para verificar a las personas detrás de una empresa, crea un flujo de KYC independiente y haz referencia a él desde el nodo `KYB_KEY_PEOPLE` mediante `kyb_ubo_verification_workflow`, `kyb_officer_verification_workflow` o `kyb_shareholder_verification_workflow`.
* Los campos de acción usan `DECLINE`, `REVIEW` o `NO_ACTION`, salvo que a continuación se indique que el campo está restringido.
* Los campos de puntuación y de umbral son números de `0` a `100`, salvo que se indique un rango más estrecho.

## Reglas de estado comunes

Todas las funciones admiten un array opcional `status_rules`. Úsalo para sobrescribir el estado de la función cuando se cumple una condición sobre un campo.

```json theme={null}
{
  "status_rules": [
    {
      "field": "kyc.issuing_state",
      "operator": "in",
      "value": ["VEN", "IRN"],
      "status": "In Review",
      "value_type": "literal"
    },
    {
      "field": "kyc.extra_fields.profession",
      "operator": "fuzzy_match",
      "value": "Soft. Engineer",
      "score": 80,
      "status": "Declined",
      "value_type": "literal"
    },
    {
      "field": "kyc.extra_fields.dl_class_code_b_to",
      "operator": "less_than",
      "value": "2030-01-01",
      "status": "In Review",
      "value_type": "literal"
    },
    {
      "field": "kyc.extra_fields.dl_class_code_b_from",
      "operator": "less_than",
      "value": { "direction": "past", "amount": 3, "unit": "years" },
      "status": "Declined",
      "value_type": "relative_date"
    }
  ]
}
```

| Campo | Tipo | Descripción |
| - | - | - |
| `field` | string | Ruta del campo que se comprueba, como `kyc.issuing_state` o `kyc.document_type`. |
| `operator` | string | Uno de `equals`, `not_equals`, `greater_than`, `greater_than_or_equals`, `less_than`, `less_than_or_equals`, `contains`, `not_contains`, `in`, `not_in`, `is_empty`, `is_not_empty`, `regex` o `fuzzy_match`. |
| `value` | any | Valor de comparación. Omítelo o envía `null` en los operadores que no necesitan un valor. |
| `status` | string | Uno de `Approved`, `Declined`, `In Review` o `No Action`. |
| `value_type` | string | Opcional. `literal` por defecto. Usa `field` para comparar con otro campo, `list` para resolver el UUID de una lista de Didit en tiempo de ejecución, o `relative_date` para comparar un campo de fecha con la fecha de hoy más o menos una duración. |
| `score` | number | Obligatorio para `fuzzy_match`. Puntuación mínima de similitud, de `0` a `100`. La regla se cumple cuando la similitud calculada es mayor o igual que este valor (`similarity >= score`). Por ejemplo, `Software Engineer` puede coincidir con `Soft. Engineer` cuando la similitud es de al menos `80`. |

El ejemplo anterior se lee así: `kyc.extra_fields.profession` coincide de forma aproximada con `Soft. Engineer` con una puntuación mínima de `80` → se establece el estado de la función en `Declined`.

En Verificación de identidad, apunta a valores extraídos de `extra_fields`, como `kyc.extra_fields.profession`, a fechas de validez de las categorías del permiso de conducir, como `kyc.extra_fields.dl_class_code_b_from` y `kyc.extra_fields.dl_class_code_b_to`, o a códigos de restricción o información por categoría, como `kyc.extra_fields.dl_class_code_b_notes` (columna 12 de los permisos del Reino Unido). Estos valores proceden del objeto `extra_fields` del resultado del OCR; no forman parte de `expected_details`.

> [!NOTE]
>
> `dl_class_code_*_from` y `dl_class_code_*_to` son siempre una fecha ISO válida o no aparecen en `extra_fields`: Didit nunca devuelve texto de OCR ilegible en un campo de fecha. Si la celda de la tabla de categorías no se puede leer, el campo se omite en lugar de enviarse como una cadena sin procesar, así que usa el operador `is_empty` para tratar las fechas de categoría ilegibles en lugar de dar por hecho que el campo siempre está presente.

Para los campos de fecha, usa `value_type: "relative_date"` con un objeto de valor con la forma `{ "direction": "past" | "future", "amount": number, "unit": "days" | "months" | "years" }`. Por ejemplo, `operator: "less_than"` con `{ "direction": "past", "amount": 3, "unit": "years" }` coincide con fechas de hace más de tres años respecto a hoy.

### Comparar con un paso concreto

Un flujo de verificación (workflow) en forma de grafo puede ejecutar la misma función más de una vez, por ejemplo, tres pasos de Verificación de identidad.
Con `value_type: "field"`, añade `@<node_id>` al valor para leerlo de un paso concreto.
El nodo referenciado debe ser un paso de una función que se ejecute siempre antes del paso de la propia regla, en todas las rutas que llegan a él, o bien el propio paso de la regla.
Un valor sin el sufijo se lee del paso de la propia regla.

```json theme={null}
{
  "status_rules": [
    {
      "field": "kyc.full_name",
      "operator": "fuzzy_match",
      "value": "kyc.full_name@ocr_1",
      "value_type": "field",
      "score": 80,
      "status": "Declined"
    }
  ]
}
```

Esta regla, configurada en el tercer paso de Verificación de identidad, se lee así: el `kyc.full_name` de este paso coincide de forma aproximada con el nombre completo leído por el paso `ocr_1` con una puntuación mínima de `80` → se establece el estado de la función en `Declined`.
En la consola, el selector de variables muestra cada paso elegible con su número en el lienzo y guarda el sufijo por ti.

## OCR / Verificación de identidad

Valor de la función: `OCR`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `documents_allowed` | object | Opcional. Omítelo, envía `null` o envía `{}` para permitir todos los países y tipos de documento compatibles. Envía un objeto que asocie códigos de país ISO3 a la configuración de tipos de documento solo cuando quieras restringir los documentos permitidos. Al menos un documento personalizado debe tener `enabled: 1`. Las configuraciones de documento pueden incluir `sides: 1` para capturar solo el anverso o `sides: 2` para capturar anverso y reverso. Los tipos de documento incluyen `P`, `ID`, `DL`, `RP`, `HIC`, `TC`, `SSC` y otros valores admitidos por cada país. |
| `methods` | object | Cuál de los tres [métodos de Verificación de identidad](https://docs.didit.me/es/core-technology/id-verification/verification-methods.md) puede usar cada país: captura de documento, consulta sin documento contra una fuente gubernamental u otra fuente oficial, y wallets de identidad digital. Si omites la clave, un país o un método dentro de un país, ese país usa solo captura de documento. Cada método y cada wallet deben figurar como disponibles para el país en el catálogo de capacidades; de lo contrario, se rechaza el guardado. Consulta [Métodos por país](#métodos-por-país) más abajo. |
| `document_blur_fields_by_country` | object | Asocia un código de país ISO3 a los nombres de los campos que se difuminan para ocultarlos en las imágenes del documento. |
| `image_capture_methods_allowed` | string\[] | Métodos de captura permitidos. Los valores incluyen `CAMERA_SCAN` y `UPLOAD`. |
| `duplicated_user_action` | action | Acción para un usuario duplicado. |
| `is_age_restrictions_enabled` | boolean | Activa las comprobaciones de edad mínima y máxima. |
| `age_restrictions_by_country` | object | Asocia un código de país ISO3 a una configuración de edad con `minimum_age`, `maximum_age` opcional y `states` opcional. |
| `minimum_age` | integer | Edad mínima global, de `1` a `120`. |
| `minimum_age_action` | action | Acción cuando el usuario tiene menos de `minimum_age`. |
| `maximum_age` | integer | Edad máxima global, de `1` a `120`. |
| `maximum_age_action` | action | Acción cuando el usuario supera `maximum_age`. |
| `expiration_date_not_detected_action` | action | Acción cuando falta la fecha de caducidad del documento. |
| `invalid_code_action` | action | Acción cuando un código de barras o un código legible por máquina no es válido. |
| `invalid_mrz_action` | action | Acción cuando la MRZ no es válida. |
| `inconsistent_data_action` | action | Acción cuando los campos extraídos del documento se contradicen. |
| `invalid_validation_action` | action | Acción cuando falla la validación del documento. |
| `expected_details_mismatch_action` | action | Acción cuando los datos esperados del usuario no coinciden con el documento. |
| `image_too_blurry_action` | action | Acción para imágenes del documento borrosas. |
| `image_too_dark_action` | action | Acción para imágenes del documento oscuras. |
| `image_too_bright_action` | action | Acción para imágenes del documento sobreexpuestas. |
| `unparsed_address_action` | action | Acción cuando no se puede interpretar la dirección del documento. |
| `address_validation_enabled` | boolean | Valida la dirección que lee este paso (impresa en el documento de identidad) contra datos postales de referencia: confirma que la dirección existe y la normaliza, y nunca la vincula a una persona. El resultado es el objeto `address_validation` del paso en la decisión. **Se cobran \$0.10 por dirección validada**; una validación que no se pudo ejecutar (`unavailable`) es gratuita. Desactivado de forma predeterminada. |
| `address_not_verified_action` | action | Acción cuando la validación de direcciones no pudo confirmar la dirección hasta el nivel del edificio (`ADDRESS_NOT_VERIFIED`: `partially_verified` o `not_verified`). Solo se aplica mientras `address_validation_enabled` está activado. El valor predeterminado es `NO_ACTION`, que solo registra la advertencia. |
| `document_or_personal_number_format_mismatch_action` | action | Acción cuando el formato del número de documento o del número personal no coincide con el patrón esperado. |
| `critical_field_occlusion_action` | action | Acción cuando la comprobación de oclusión indica que un campo impreso crítico (un número de identidad, un nombre, la fecha de nacimiento o la fecha de caducidad) estaba tapado físicamente en el documento capturado. Tapar un número de identidad es una señal de manipulación y no de calidad de captura, por lo que el valor predeterminado es `REVIEW`; en cualquier caso, el valor leído de un campo tapado se elimina de la extracción. Súbelo a `DECLINE` cuando un documento con datos ocultos nunca deba llegar a un revisor. |
| `document_without_portrait_action` | action | Acción cuando el tipo de documento reconocido nunca lleva foto de retrato en ninguna de sus caras (algunos permisos de residencia, tarjetas sanitarias, certificados de registro y otras familias de documentos sin retrato conocidas en el catálogo). El valor predeterminado es `REVIEW`. Considera `DECLINE` cuando la Coincidencia facial sea la base de la comprobación de identidad del flujo. |
| `is_document_selfie_portrait_match_enabled` | boolean | Activa la comparación entre el retrato del documento y la selfie. |
| `document_selfie_portrait_match_decline_threshold` | integer | Umbral de rechazo para la coincidencia entre el retrato del documento y la selfie. |
| `document_selfie_portrait_match_review_threshold` | integer | Umbral de revisión para la coincidencia entre el retrato del documento y la selfie. |
| `document_selfie_face_search_enabled` | boolean | Ejecuta la [Búsqueda facial 1:N](https://docs.didit.me/es/core-technology/face-search/overview.md#el-selfie-tomado-durante-la-captura-del-documento) sobre la selfie tomada durante la captura del documento (requiere `is_document_selfie_portrait_match_enabled`): la compara con la lista de bloqueo de rostros y con usuarios verificados anteriormente. La selfie solo se compara; su plantilla nunca se almacena. Activado de forma predeterminada. `false` omite la búsqueda y deja las acciones de rostro duplicado de la selfie del documento sin nada sobre lo que actuar; `face_search_enabled: false` en el paso de Prueba de vida también la omite, ya que esa exclusión abarca todas las selfies de la sesión. |
| `document_selfie_duplicated_face_action` | action | Veredicto cuando la selfie de la captura del documento coincide, o posiblemente coincide, con el rostro de un usuario ya verificado en esta aplicación. El valor predeterminado es `NO_ACTION`. |
| `document_selfie_duplicated_face_name_mismatch_action` | action | Veredicto cuando la selfie de la captura del documento coincide con un usuario ya verificado con otro nombre. Solo puede endurecer `document_selfie_duplicated_face_action`. El valor predeterminado es `REVIEW`. |
| `document_selfie_duplicated_face_document_mismatch_action` | action | Veredicto cuando la selfie de la captura del documento coincide con un usuario ya verificado con una fecha de nacimiento distinta en su documento de identidad. No se marca a la misma persona con un documento distinto o renovado. Solo puede endurecer `document_selfie_duplicated_face_action`. El valor predeterminado es `REVIEW`. |
| `id_verification_name_match_score_threshold` | integer | Umbral de coincidencia de nombre entre varias verificaciones de identidad. |
| `id_verification_max_retry_attempts` | integer | Límite de reintentos para la verificación de identidad, de `2` a `5`. |
| `id_document_quality_threshold` | integer | Puntuación mínima de calidad de captura (de `0` a `100`) que debe alcanzar la imagen de un documento para ser aceptada. La comprobación de calidad se ejecuta siempre; solo este umbral es configurable. El valor predeterminado es `20`, ajustado para rechazar las capturas degradadas o dudosas (desenfoque, movimiento, texto ilegible) y aceptar los documentos legibles; súbelo si necesitas requisitos de captura más estrictos. La consola muestra este valor en un control deslizante perceptual en el que el valor predeterminado de `20` aparece como un 50% equilibrado. |
| `cross_org_fraud_document_action` | action | Veredicto cuando otra organización de la red marcó este documento como fraudulento. |
| `document_audio_recording_enabled` | boolean | Graba el micrófono durante la captura del documento, para que un revisor pueda escuchar la sesión. Desactivado de forma predeterminada. |
| `document_liveness_portrait_replace_decline_threshold` | integer | Puntuación de sustitución de retrato (de `0` a `100`; cuanto más alta, más probable es que sea auténtico) por debajo de la cual se rechaza la sesión. El valor predeterminado es `35`. Consulta [umbrales de prueba de vida del documento](https://docs.didit.me/es/core-technology/id-verification/warnings-id-verification.md#configurar-los-umbrales-de-prueba-de-vida-del-documento). |
| `document_liveness_portrait_replace_review_threshold` | integer | Puntuación de sustitución de retrato por debajo de la cual la sesión pasa a En revisión, cuando no se ha rechazado ya. Con `100`, se retienen casi todas las sesiones. El valor predeterminado es `70`. Consulta [umbrales de prueba de vida del documento](https://docs.didit.me/es/core-technology/id-verification/warnings-id-verification.md#configurar-los-umbrales-de-prueba-de-vida-del-documento). |
| `document_liveness_printed_copy_decline_threshold` | integer | Puntuación de copia impresa (de `0` a `100`; cuanto más alta, más probable es que sea auténtico) por debajo de la cual se rechaza la sesión. El valor predeterminado es `35`. Consulta [umbrales de prueba de vida del documento](https://docs.didit.me/es/core-technology/id-verification/warnings-id-verification.md#configurar-los-umbrales-de-prueba-de-vida-del-documento). |
| `document_liveness_printed_copy_review_threshold` | integer | Puntuación de copia impresa por debajo de la cual la sesión pasa a En revisión, cuando no se ha rechazado ya. Con `100`, se retienen casi todas las sesiones. El valor predeterminado es `77`. Consulta [umbrales de prueba de vida del documento](https://docs.didit.me/es/core-technology/id-verification/warnings-id-verification.md#configurar-los-umbrales-de-prueba-de-vida-del-documento). |
| `document_liveness_screen_replay_decline_threshold` | integer | Puntuación de captura de pantalla (de `0` a `100`; cuanto más alta, más probable es que sea auténtico) por debajo de la cual se rechaza la sesión. El valor predeterminado es `30`. Consulta [umbrales de prueba de vida del documento](https://docs.didit.me/es/core-technology/id-verification/warnings-id-verification.md#configurar-los-umbrales-de-prueba-de-vida-del-documento). |
| `document_liveness_screen_replay_review_threshold` | integer | Puntuación de captura de pantalla por debajo de la cual la sesión pasa a En revisión, cuando no se ha rechazado ya. Con `100`, se retienen casi todas las sesiones. El valor predeterminado es `70`. Consulta [umbrales de prueba de vida del documento](https://docs.didit.me/es/core-technology/id-verification/warnings-id-verification.md#configurar-los-umbrales-de-prueba-de-vida-del-documento). |
| `id_verification_injection_attack_action` | action | Veredicto cuando el documento, o la selfie tomada para una consulta de identidad, se inyectó en lugar de capturarse con la propia cámara del dispositivo (`INJECTION_ATTACK_DETECTED`): una cámara virtual por software, una señal de cámara generada por la página o por automatización del navegador, una cámara interceptada o una herramienta de instrumentación conectada a la aplicación. Valores: `DECLINE`, `REVIEW`, `NO_ACTION`. El valor predeterminado es `DECLINE`. Las señales que puede producir una persona real nunca lo activan. En la prueba de vida y la coincidencia facial, el riesgo se rige por `frame_injection_action`. |
| `image_quality_too_low_action` | action | Veredicto cuando la calidad general de la imagen del documento no alcanza el mínimo exigido. |
| `is_image_capture_review_screen_enabled` | boolean | Muestra al usuario una pantalla de revisión después de cada captura del documento, para que pueda repetir la foto antes de enviarla. Desactivado de forma predeterminada. |
| `is_ocr_id_verification_data_review_enabled` | boolean | Permite al usuario revisar y corregir los datos de identidad extraídos antes de que se complete el paso. Desactivado de forma predeterminada. Cada corrección se evalúa con `ocr_id_verification_data_review_critical_fields`, y una discrepancia aplica la acción crítica o la menor según corresponda. La revisión se ejecuta igualmente cuando el flujo incluye NFC: una lectura posterior del chip simplemente la reemplaza. |
| `ocr_id_verification_data_review_critical_fields` | string\[] | Qué campos de identidad extraídos se consideran críticos cuando el usuario edita el resultado del OCR, de modo que una discrepancia aplica la acción crítica en lugar de la menor. Formato: `["first_name" \| "last_name" \| "date_of_birth" \| ...]`. |
| `ocr_id_verification_data_review_critical_mismatch_action` | restricted action | Veredicto cuando la edición del usuario no coincide con el OCR en un campo crítico. |
| `ocr_id_verification_data_review_minor_mismatch_action` | action | Veredicto cuando la edición del usuario no coincide con el OCR en un campo no crítico. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

> [!NOTE]
>
> La prueba de vida del documento se configura con los seis umbrales `document_liveness_*` anteriores, no con
> campos de acción por señal. `portrait_replacement_action`, `printed_copy_action` y
> `screen_capture_action` son parte de la configuración a nivel de cuenta y **no** se aceptan en la configuración
> de funciones de un flujo: la API elimina las claves de configuración desconocidas al guardar, por lo que enviarlas ahí no tiene
> ningún efecto. Cada señal tiene un umbral de rechazo y un umbral de revisión en una escala de `0` a `100` en la que
> una puntuación más alta indica que es más probable que el documento sea auténtico.

Ejemplo:

```json theme={null}
{
  "feature": "OCR",
  "config": {
    "documents_allowed": {
      "USA": {
        "DL": {
          "enabled": 1,
          "sides": 2
        }
      }
    },
    "duplicated_user_action": "REVIEW",
    "image_capture_methods_allowed": ["CAMERA_SCAN", "UPLOAD"]
  }
}
```

### Métodos por país

`methods` usa como clave el código de país [ISO 3166-1 alpha-3](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3). Cada país admite hasta tres objetos de método; todo lo que omitas toma su valor predeterminado.

```json theme={null}
{
  "feature": "OCR",
  "config": {
    "methods": {
      "ZAF": {
        "document": { "enabled": true },
        "id_lookup": {
          "enabled": true,
          "max_attempts": 2,
          "skip_liveness_and_face_match": true,
          "on_partial_match": "fallback_to_document",
          "on_no_match": "fallback_to_document",
          "on_provider_error": "fallback_to_document"
        },
        "wallet": { "enabled": false, "providers": [], "on_failure": "fallback_to_document" }
      },
      "DNK": {
        "document": { "enabled": true },
        "id_lookup": { "enabled": true, "on_no_match": "decline" }
      }
    }
  }
}
```

Para que los documentos no aparezcan en la primera pantalla y solo se ofrezcan cuando una wallet o una consulta no da resultado, configura `document.fallback_only`. El ejemplo usa Finlandia, donde primero se ofrece la Finnish Trust Network y la captura del documento es la alternativa. Finlandia también necesita sus tipos de documento habilitados en `documents_allowed` (por ejemplo, pasaporte y documento de identidad) para que la alternativa tenga documentos que ofrecer.

```json theme={null}
{
  "FIN": {
    "document": { "enabled": true, "fallback_only": true },
    "wallet": { "enabled": true, "providers": ["ftn"], "on_failure": "fallback_to_document" }
  }
}
```

Las dos consultas anteriores están `available` en el catálogo actual, así que esa configuración se guarda tal cual. El bloque de wallet está desactivado a propósito: **todavía no hay ninguna wallet activa en producción**, por lo que `wallet.enabled: true` se rechaza y hace fallar todo el guardado, incluida la configuración de las consultas. Cuando el catálogo marque una wallet como `available` en un país, añádela a ese país:

```json theme={null}
{
  "DNK": {
    "document": { "enabled": true },
    "wallet": { "enabled": true, "providers": ["mitid"], "on_failure": "fallback_to_document" }
  }
}
```

| Clave | Tipo | Valor predeterminado | Descripción |
| - | - | - | - |
| `<ISO3>.document.enabled` | boolean | `true` | Indica si se acepta un documento fotografiado en este país. Qué documentos se aceptan se sigue definiendo en `documents_allowed`. |
| `<ISO3>.document.fallback_only` | boolean | `false` | Mantiene habilitada la captura de documento, pero no la ofrece en la primera pantalla. Los usuarios empiezan con la wallet o la consulta de identidad del país, y solo pasan a la captura de documento los usuarios cuyo inicio de sesión con la wallet falla, se cancela o agota el tiempo, o cuya consulta no coincide (según los interruptores `on_failure`, `on_partial_match`, `on_no_match` y `on_provider_error` configurados en `fallback_to_document`). Con una sola wallet, el usuario llega directamente a esa wallet. Sin esta opción, la wallet o la consulta se muestran junto a la captura de documento. Se rechaza con HTTP 400 salvo que `document.enabled` sea `true` y al menos una wallet o consulta de identidad del país recurra a la captura de documento. |
| `<ISO3>.id_lookup.enabled` | boolean | `false` | Ofrece la consulta sin documento contra la fuente gubernamental u otra fuente oficial de este país. Se rechaza cuando el catálogo no marca la fuente del país como `available`. |
| `<ISO3>.id_lookup.max_attempts` | integer | `1` | De `1` a `5`. Cuántas consultas **respondidas** tiene el usuario antes de que se active el interruptor de alternativa. Un número que no supera la comprobación de formato en el cliente nunca llega al registro, así que ni cuenta ni se factura. |
| `<ISO3>.id_lookup.skip_liveness_and_face_match` | boolean | `true` | Tras una coincidencia contra un registro que devuelve un retrato, omite los pasos propios de Prueba de vida y Coincidencia facial del flujo: la consulta ya ejecutó una prueba de vida pasiva sobre la selfie y la comparó con ese retrato. Se normaliza a `false` al guardar para una fuente que no devuelve retrato, donde el interruptor no tendría sentido. |
| `<ISO3>.id_lookup.on_partial_match` | `fallback_to_document` \| `decline` | `fallback_to_document` | Qué ocurre cuando el registro respondió, pero algunos campos no coincidieron. |
| `<ISO3>.id_lookup.on_no_match` | `fallback_to_document` \| `decline` | `fallback_to_document` | Qué ocurre cuando el registro respondió y no contiene ningún registro coincidente. |
| `<ISO3>.id_lookup.on_provider_error` | `fallback_to_document` \| `decline` | `fallback_to_document` | Qué ocurre cuando no se pudo acceder al registro. Nunca se factura. |
| `<ISO3>.id_lookup.response_fields` | string\[] \| null | `null` | Subconjunto opcional de las claves de campo de respuesta de la fuente. Las claves desconocidas se rechazan y los campos obligatorios de la fuente se vuelven a añadir siempre, de modo que el valor guardado es siempre una selección válida. La implementación actual en staging aplica esta selección a la salida de la comparación, al género opcional y a los retratos del registro que se conservan. Los campos de identidad obligatorios se mantienen. Consulta la nota sobre despliegue y retención más abajo. |
| `<ISO3>.wallet.enabled` | boolean | `false` | Ofrece el inicio de sesión con wallet de identidad digital en este país. |
| `<ISO3>.wallet.providers` | string\[] | `[]` | IDs de wallet del catálogo que acepta este país: una lista de aceptación, nunca una clasificación. El orden que envíes se normaliza al orden del catálogo. Se requiere al menos una wallet cuando `enabled` es `true`. Se rechaza una wallet que no se ofrece en el país o que todavía está marcada como próximamente. |
| `<ISO3>.wallet.on_failure` | `fallback_to_document` \| `decline` | `fallback_to_document` | Qué ocurre cuando el inicio de sesión se cancela, agota el tiempo o falla. |

Validación que aplica la API al guardar:

* Se rechaza un código de país desconocido, una clave desconocida dentro de un país o una clave desconocida dentro de un método: nada se descarta en silencio.
* Se rechaza un país sin ningún método habilitado: nadie allí podría verificarse.
* Una wallet o una consulta solo puede recurrir a la captura de documento cuando la captura de documento está habilitada para ese país. `fallback_to_document` en un país donde `document.enabled` es `false` rechaza en tiempo de ejecución, porque no hay ninguna alternativa a la que recurrir.
* `document.fallback_only: true` se rechaza con HTTP 400 salvo que `document.enabled` sea `true` y al menos una wallet o consulta de identidad de ese país recurra a la captura de documento.

> [!WARNING]
>
> La implementación actual en staging aplica `id_lookup.response_fields` a la salida de la comparación, al género opcional y a los retratos del registro que se conservan. Los campos de identidad obligatorios siguen formando parte del registro de verificación. Esto no garantiza que todos los payloads intermedios del proveedor queden excluidos del procesamiento. El despliegue en producción de este cambio no se ha verificado; confirma el comportamiento en tu entorno de destino antes de confiar en la selección de campos para requisitos de retención.

Lee el catálogo de capacidades antes de escribir `methods`: en la pestaña **Países** de la consola o con la herramienta MCP [`didit_workflow_get_id_verification_methods_catalog`](https://docs.didit.me/es/integration/mcp/tools). El comportamiento, la cobertura y la facturación se describen en [Métodos de verificación de identidad](https://docs.didit.me/es/core-technology/id-verification/verification-methods.md).

## NFC / pasaporte electrónico

Valor de la función: `NFC`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `allow_nfc_skip` | boolean | Permite a los usuarios omitir el NFC cuando su documento admite la lectura del chip. |
| `skip_nfc_action` | action | Acción cuando el usuario omite el NFC. |
| `unverified_chip_action` | action | Acción cuando falla la verificación del chip. |
| `trust_anchor_missing_action` | action | Veredicto cuando los hashes de los grupos de datos del chip están intactos, pero la cadena de certificados no se puede verificar porque el ancla de confianza de la CSCA del país emisor no está cargada. |
| `jpki_request_attributes` | boolean | Tarjeta My Number de Japón ([JPKI](https://docs.didit.me/es/core-technology/nfc-verification/overview.md#my-number-card-de-japón-jpki), solo SDK nativos): lee también el certificado de firma, que requiere el PIN de firma de la tarjeta e incluye el nombre, la fecha de nacimiento, el sexo y la dirección del titular, que se comparan con los datos de la verificación de identidad. Valor predeterminado: `true`. Con `false` solo se lee el certificado de autenticación del usuario (PIN de 4 dígitos), que acredita la tarjeta y el PIN, pero no incluye datos del titular. |
| `jpki_certificate_invalid_action` | action | Veredicto cuando un certificado de la tarjeta My Number no se encadena a la autoridad de certificación JPKI, está fuera de su periodo de validez o no es un certificado de tarjeta del tipo solicitado (`JPKI_CERTIFICATE_INVALID`). Valor predeterminado: `DECLINE`. |
| `jpki_signature_invalid_action` | action | Veredicto cuando la firma de la tarjeta My Number sobre el desafío de un solo uso no se verifica, por lo que no quedan acreditadas la posesión de la tarjeta ni el conocimiento de su PIN (`JPKI_SIGNATURE_INVALID`). Valor predeterminado: `DECLINE`. |
| `jpki_certificate_revoked_action` | action | Veredicto cuando la comprobación de revocación indica que un certificado de la tarjeta My Number está revocado (`JPKI_CERTIFICATE_REVOKED`). Valor predeterminado: `DECLINE`. |
| `jpki_revocation_unchecked_action` | action | Veredicto cuando la tarjeta My Number se verificó, pero no se obtuvo respuesta sobre su revocación, por lo que no se puede descartar que la tarjeta esté revocada (`JPKI_REVOCATION_UNCHECKED`). Valor predeterminado: `REVIEW`. |
| `jpki_inconsistent_data_action` | action | Veredicto cuando el nombre, la fecha de nacimiento, el sexo o la dirección del certificado de firma de la tarjeta My Number difieren de los datos de la verificación de identidad de la misma tarjeta (`JPKI_AND_OCR_DATA_NOT_SAME`). Valor predeterminado: `REVIEW`. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

## Prueba de vida

Valor de la función: `LIVENESS`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `face_liveness_method` | string | Uno de `ACTIVE_3D`, `FLASHING` o `PASSIVE`. |
| `face_liveness_mode` | string | Anulación del modo de prueba de vida. |
| `face_liveness_flash_mode` | string | Modo de destello para los métodos `ACTIVE_3D` y `FLASHING`. `"0"` (no estricto, predeterminado) verifica que los colores que destellan en la pantalla se reflejen en el rostro del usuario; `"1"` (estricto) exige además que los reflejos coincidan con la secuencia exacta de colores mostrada. Así protege mejor frente a ataques de repetición y de inyección de video, pero produce más rechazos falsos. |
| `face_liveness_score_decline_threshold` | integer | Umbral de rechazo. |
| `face_liveness_score_review_threshold` | integer | Umbral de revisión. |
| `face_liveness_possible_duplicated_face_action` | action | Acción cuando el rostro puede estar duplicado. |
| `face_liveness_multiple_faces_action` | action | Acción cuando se detectan varios rostros. |
| `face_liveness_video_anomaly_action` | action | Acción cuando la grabación almacenada contiene una secuencia en movimiento repetida. Valor predeterminado: `NO_ACTION`. `REVIEW` y `DECLINE` pueden escalar de forma asíncrona una verificación ya decidida. Los fotogramas estáticos escasos o repetidos no bastan por sí solos para activarla. |
| `face_liveness_attack_face_match_action` | action | Acción cuando el rostro de la prueba de vida coincide con el rostro de una sesión anterior de esta aplicación que pertenece a otro usuario y cuya captura se consideró, con alta confianza, un ataque a la prueba de vida (advertencia `FACE_MATCHES_LIVENESS_ATTACK`). Acepta `NO_ACTION` o `REVIEW`. `DECLINE` se acepta, pero se aplica como `REVIEW`, porque un usuario legítimo puede ser rechazado una vez por error y superar la verificación después. Valor predeterminado: `NO_ACTION`. |
| `race_map_similarity_thresholds` | object | Umbrales de similitud por grupo demográfico. |
| `face_privacy_mode_enabled` | boolean | Activa el modo de privacidad para los recursos faciales. |
| `face_quality_review_threshold` | integer | Umbral de revisión para la calidad de la imagen facial. |
| `face_quality_decline_threshold` | integer | Umbral de rechazo para la calidad de la imagen facial. Debe ser menor o igual que el umbral de revisión. |
| `face_luminance_min_threshold` | integer | Umbral mínimo de luminancia. Debe ser inferior a `face_luminance_max_threshold`. |
| `face_luminance_min_action` | action | Acción cuando la luminancia es demasiado baja. |
| `face_luminance_max_threshold` | integer | Umbral máximo de luminancia. |
| `face_luminance_max_action` | action | Acción cuando la luminancia es demasiado alta. |
| `face_liveness_max_attempts` | integer | Número total de envíos de prueba de vida por sesión, de `1` a `3`. El valor predeterminado, `3`, equivale a un intento inicial más dos reintentos. Establecer `1` no desactiva los reintentos por fallos de calidad de captura: cuando todas las advertencias del intento son ambientales (`LOW_FACE_LUMINANCE`, `HIGH_FACE_LUMINANCE`, `LOW_FACE_QUALITY`, `HIGH_FACE_OCCLUSION`, `NO_FACE_DETECTED`), el usuario siempre obtiene un segundo intento con indicaciones para corregir la captura. |
| `cross_org_fraud_face_action` | action | **Obsoleto y ya no se aplica.** Trataba un rostro como si tuviera asociado un veredicto de fraude, algo que una identidad biométrica estable no puede tener. Se sigue aceptando para que los flujos de verificación (workflows) existentes continúen superando la validación. Usa `cross_org_identity_claim_pattern_action`. |
| `cross_org_identity_claim_pattern_action` | action | Veredicto cuando otras organizaciones de la red registraron, para esta misma persona, eventos de declaración de identidad en los que la identidad reclamada no coincidía. Solo admite revisión o sin acción: un rechazo configurado aquí se rebaja a revisión. Consulta [Declaraciones de identidad entre organizaciones](https://docs.didit.me/es/core-technology/liveness/cross-organization-identity-claims.md). |
| `external_capture_device_action` | action | Veredicto cuando se detecta un dispositivo de captura externo. |
| `face_audio_recording_enabled` | boolean | Graba el micrófono durante la captura de la selfie para que un revisor pueda escuchar la sesión. Desactivado por defecto. |
| `face_search_enabled` | boolean | Ejecuta la [Búsqueda facial 1:N](https://docs.didit.me/es/core-technology/face-search/overview.md#desactivar-la-búsqueda-facial-automática) automática sobre la selfie: la compara con usuarios verificados previamente y con las listas de bloqueo y de permitidos de rostros, y almacena su plantilla biométrica para coincidencias posteriores. Activado por defecto. Con `false` se omite la búsqueda, no se conserva ninguna plantilla facial para este paso y las acciones de rostro duplicado quedan sin datos sobre los que actuar. |
| `face_liveness_uncertain_retry_enabled` | boolean | Solo para la prueba de vida activa del SDK nativo. Si está activado, una captura cuya puntuación de prueba de vida quede estrictamente entre `face_liveness_score_decline_threshold` y `face_liveness_score_review_threshold` nunca recibe una decisión, sea cual sea el veredicto que le haya asignado el motor. Se le indica a la persona que el resultado no fue claro y se le pide que repita la captura, cada vez que ocurra, fuera del límite de `face_liveness_max_attempts`, que sigue aplicándose a las capturas que el motor no pudo puntuar. Desactivado por defecto; el flujo web lo ignora. |
| `face_liveness_duplicated_face_name_mismatch_action` | action | Veredicto cuando se encuentra un rostro duplicado con un nombre distinto. |
| `face_liveness_duplicated_face_document_mismatch_action` | action | Veredicto cuando se encuentra un rostro duplicado y el documento de identidad del usuario coincidente muestra una fecha de nacimiento distinta. No se marca a la misma persona con un documento distinto o renovado. Valor predeterminado: `REVIEW`. |
| `frame_injection_action` | action | Veredicto cuando se detectan fotogramas de video inyectados. |
| `screen_capture_action` | action | Veredicto cuando la selfie es una foto de una pantalla. |
| `virtual_camera_action` | action | Veredicto cuando se detecta la señal de una cámara virtual. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

## Coincidencia facial

Valor de la función: `FACE_MATCH`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `face_match_score_decline_threshold` | entero | Umbral de rechazo. |
| `face_match_score_review_threshold` | entero | Umbral de revisión. |
| `face_match_max_attempts` | entero | Número total de envíos de coincidencia facial por sesión, de `1` a `3`. El valor predeterminado `3` equivale a un intento inicial más dos reintentos. |
| `face_match_not_computed_action` | acción restringida | Veredicto cuando no se pudo obtener una puntuación de coincidencia facial (falta el retrato o la selfie). |
| `face_match_eyes_covered_action` | acción | Veredicto cuando la zona de los ojos está cubierta en la selfie. El valor predeterminado es `NO_ACTION`, que registra la evidencia sin cambiar el resultado de Coincidencia facial. Esta señal aún se está calibrando, por lo que funciona solo en modo de observación hasta que la región figure como calibrada: si configuras `REVIEW` o `DECLINE` ahora, surtirá efecto cuando la región figure como calibrada. |
| `face_match_mouth_covered_action` | acción | Veredicto cuando la zona de la boca está cubierta en la selfie. Tiene el mismo valor predeterminado `NO_ACTION` y la misma salvedad sobre la calibración que `face_match_eyes_covered_action`. |
| `face_match_face_covered_action` | acción | Veredicto cuando el rostro completo está cubierto en la selfie. Tiene el mismo valor predeterminado `NO_ACTION` y la misma salvedad sobre la calibración que `face_match_eyes_covered_action`. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

## Estimación de edad

Valor de la función: `AGE_ESTIMATION`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `enable_id_verification_fallback` | boolean | Ejecuta la Verificación de identidad cuando la estimación de edad cae en el rango límite. |
| `minimum_age_threshold` | integer | Edad mínima aceptada, de `1` a `100`. |
| `borderline_minimum_age_threshold` | integer | Límite inferior del rango límite, de `1` a `100`. |
| `borderline_maximum_age_threshold` | integer | Límite superior del rango límite, de `1` a `100`. |
| `face_liveness_method` | string | Uno de `ACTIVE_3D`, `FLASHING` o `PASSIVE`. |
| `face_liveness_flash_mode` | string | Modo de destellos para los métodos `ACTIVE_3D` y `FLASHING`. `"0"` (no estricto, valor predeterminado) verifica que los colores que destellan en la pantalla se reflejen en el rostro del usuario; `"1"` (estricto) exige además que los reflejos coincidan con la secuencia exacta de colores emitida. |
| `face_liveness_score_decline_threshold` | number | Umbral de rechazo de la prueba de vida que usa la estimación de edad. |
| `face_liveness_score_review_threshold` | number | Umbral de revisión de la prueba de vida que usa la estimación de edad. |
| `face_liveness_possible_duplicated_face_action` | action | Acción cuando el rostro puede estar duplicado. |
| `face_liveness_multiple_faces_action` | action | Acción cuando se detectan varios rostros. |
| `face_liveness_video_anomaly_action` | action | Acción cuando la grabación almacenada contiene una secuencia en movimiento repetida. Valor predeterminado: `NO_ACTION`; `REVIEW` y `DECLINE` pueden escalar de forma asíncrona una verificación ya decidida. Los fotogramas fijos escasos o repetidos no la activan por sí solos. |
| `face_liveness_attack_face_match_action` | action | Acción cuando el rostro de la prueba de vida coincide con el rostro de una sesión anterior de esta aplicación de otro usuario cuya captura se consideró, con alta confianza, un ataque a la prueba de vida (advertencia `FACE_MATCHES_LIVENESS_ATTACK`). Acepta `NO_ACTION` o `REVIEW`; `DECLINE` se acepta, pero se aplica como `REVIEW`, porque un usuario legítimo puede ser rechazado una vez por error y luego superar la verificación. Valor predeterminado: `NO_ACTION`. |
| `face_privacy_mode_enabled` | boolean | Activa el modo de privacidad para los recursos faciales. |
| `face_quality_review_threshold` | integer | Umbral de revisión de la calidad del rostro. |
| `face_quality_decline_threshold` | integer | Umbral de rechazo de la calidad del rostro. |
| `face_luminance_min_threshold` | integer | Umbral mínimo de luminancia. |
| `face_luminance_min_action` | action | Acción cuando la luminancia es demasiado baja. |
| `face_luminance_max_threshold` | integer | Umbral máximo de luminancia. |
| `face_luminance_max_action` | action | Acción cuando la luminancia es demasiado alta. |
| `face_liveness_max_attempts` | integer | Total de envíos de prueba de vida por sesión, de `1` a `3`. El valor predeterminado `3` equivale a un intento inicial más dos reintentos. Configurar `1` no desactiva los reintentos por fallos de calidad de captura: cuando todas las advertencias del intento son ambientales (`LOW_FACE_LUMINANCE`, `HIGH_FACE_LUMINANCE`, `LOW_FACE_QUALITY`, `HIGH_FACE_OCCLUSION`, `NO_FACE_DETECTED`), el usuario siempre obtiene un segundo intento con indicaciones para corregir el problema. |
| `external_capture_device_action` | action | Veredicto cuando se detecta un dispositivo de captura externo. |
| `face_audio_recording_enabled` | boolean | Graba el audio del micrófono durante la captura del selfie para que un revisor pueda escuchar la sesión. Desactivado de forma predeterminada. |
| `face_search_enabled` | boolean | Ejecuta la [Búsqueda facial 1:N](https://docs.didit.me/es/core-technology/face-search/overview.md#desactivar-la-búsqueda-facial-automática) automática sobre el selfie: lo compara con los usuarios verificados anteriormente, con la lista de bloqueo y la lista de permitidos de rostros, y almacena su plantilla biométrica para comparaciones posteriores. Activado de forma predeterminada. `false` omite la búsqueda, no conserva ninguna plantilla facial para este paso y deja las acciones de rostro duplicado sin ningún caso al que aplicarse. |
| `face_liveness_uncertain_retry_enabled` | boolean | Solo para la prueba de vida activa del SDK nativo. Si está activado, una captura cuya puntuación de prueba de vida quede estrictamente entre `face_liveness_score_decline_threshold` y `face_liveness_score_review_threshold` nunca recibe una decisión, sea cual sea el veredicto que le haya asignado el motor: se informa a la persona de que el resultado no fue concluyente y se le pide que realice otra captura, siempre fuera del límite de `face_liveness_max_attempts` (que sigue aplicándose a las capturas que el motor no pudo puntuar). Desactivado de forma predeterminada; el flujo web lo ignora. |
| `face_liveness_duplicated_face_name_mismatch_action` | action | Veredicto cuando se encuentra un rostro duplicado con un nombre distinto. |
| `face_liveness_duplicated_face_document_mismatch_action` | action | Veredicto cuando se encuentra un rostro duplicado y el documento de identidad del usuario coincidente muestra una fecha de nacimiento distinta. No se marca a una persona como duplicada si presenta un documento diferente o renovado. Valor predeterminado: `REVIEW`. |
| `frame_injection_action` | action | Veredicto cuando se detectan fotogramas de video inyectados. |
| `screen_capture_action` | action | Veredicto cuando el selfie es una foto de una pantalla. |
| `virtual_camera_action` | action | Veredicto cuando se detecta la señal de una cámara virtual. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

## Verificación de teléfono

Valor de la función: `PHONE_VERIFICATION`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `code_size` | entero | Longitud del OTP, de `4` a `8`. |
| `phone_max_retries` | entero | Número máximo de reintentos de envío, de `1` a `5`. |
| `phone_max_check_attempts` | entero | Número máximo de intentos de comprobación del OTP, de `1` a `5`. |
| `phone_verification_countries` | objeto | Código de país ISO2 asociado a la configuración de canales. Ejemplo: `{ "US": { "sms": { "enabled": true } } }`. |
| `disposable_number_action` | acción | Acción para números desechables. |
| `voip_number_action` | acción | Acción para números VoIP. |
| `duplicated_phone_number_action` | acción | Acción para números de teléfono duplicados. |
| `high_risk_phone_action` | acción | Acción cuando el proveedor de entrega bloquea el envío del OTP. Solo `DECLINE` o `REVIEW`; valor predeterminado `DECLINE`. Se aplica solo cuando todos los bloqueos del paso tienen `risk_factors` exactamente igual a `["device_attribute"]`; cualquier otro factor de riesgo, cualquier combinación que lo incluya o la ausencia de factores de riesgo provoca el rechazo, independientemente de esta configuración. |
| `phone_shared_device_mode` | booleano | Permite el modo de verificación de teléfono con dispositivo compartido. |
| `phone_enrichment_enabled` | booleano | Activa el enriquecimiento con inteligencia telefónica (riesgo por tipo de línea, índice de confianza, operador, historial de portabilidad / SIM swap, puntuación de riesgo de fraude). **Se cobra \$0.05 por verificación** además del precio de la verificación de teléfono. |
| `phone_intelligence_score_action` | acción | Acción cuando la puntuación de riesgo de fraude del teléfono es igual o superior a `phone_intelligence_score_threshold`. |
| `phone_intelligence_score_threshold` | entero | Puntuación de riesgo de fraude (`0`–`100`, cuanto más alta, más riesgo) que activa `phone_intelligence_score_action`. Valor predeterminado `80`. |
| `phone_type_risk_action` | acción | Acción cuando el número se marca como un tipo de teléfono de alto riesgo. |
| `recent_port_action` | acción | Acción cuando el número se ha portado recientemente (señal de SIM swap / portabilidad). |
| `low_phone_trust_action` | acción | Acción cuando el índice de confianza del teléfono es igual o inferior a `phone_trust_index_threshold`. |
| `phone_trust_index_threshold` | entero | Índice de confianza (`0`–`100`, cuanto más bajo, más riesgo) igual o por debajo del cual se aplica `low_phone_trust_action`. Valor predeterminado `30`. |
| `phone_social_enabled` | booleano | Activa la comprobación de huella social: en qué plataformas de mensajería, redes sociales, comercio electrónico y servicios profesionales está registrado el número verificado. **Se cobra \$0.05 por verificación** además del precio de la verificación de teléfono, con independencia de `phone_enrichment_enabled`. |
| `phone_no_social_presence_action` | acción | Acción cuando la comprobación de huella social determina que el número no está registrado en ninguna de las plataformas que cubre, una señal habitual de identidad sintética. Valor predeterminado `NO_ACTION`. |
| `cross_org_fraud_phone_action` | acción | Veredicto cuando otra organización de la red ha marcado este número como fraudulento. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

La Verificación de teléfono está desactivada hasta que la organización realice su primera recarga.

> [!NOTE]
>
> El enriquecimiento con inteligencia telefónica es un complemento opcional. Cuando `phone_enrichment_enabled` es `true`, cada verificación de teléfono completada se enriquece con inteligencia telefónica y **se factura a \$0.05 por solicitud**, además del coste estándar de la verificación de teléfono. Las acciones basadas en la puntuación solo surten efecto cuando la puntuación de enriquecimiento está disponible; las acciones de índice de confianza, tipo de teléfono y portabilidad se aplican en cuanto se ejecuta el enriquecimiento.
>
> La comprobación de huella social es un segundo complemento independiente. Cuando `phone_social_enabled` es `true`, cada verificación de teléfono completada indica también en qué plataformas en línea está registrado el número (mensajería, redes sociales, comercio electrónico y servicios profesionales) y **se factura a \$0.05 por solicitud**. Puede activarse con o sin `phone_enrichment_enabled`: los dos complementos tienen precios y facturación independientes. Una consulta que no encuentra el número en ninguna de las plataformas que cubre es una respuesta válida y facturable, y activa `phone_no_social_presence_action`. Usa `phone.social_profiles_registered` (el número de plataformas en las que está registrado el número) para crear ramas según el resultado en el grafo de un flujo.

## Verificación de correo electrónico

Valor de la función: `EMAIL_VERIFICATION`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `email_code_size` | integer | Longitud del OTP, de `4` a `8`. |
| `email_max_retries` | integer | Número máximo de reintentos de envío, de `1` a `5`. |
| `email_max_check_attempts` | integer | Número máximo de intentos de comprobación del OTP, de `1` a `5`. |
| `email_alphanumeric_code` | boolean | Usa códigos de correo electrónico alfanuméricos. |
| `breached_email_action` | action | Acción para correos electrónicos afectados por brechas de datos. |
| `disposable_email_action` | action | Acción para correos electrónicos desechables. |
| `duplicated_email_action` | action | Acción para correos electrónicos duplicados. |
| `only_corporate_emails_allowed` | boolean | Rechaza las direcciones de correo electrónico que no son corporativas. |
| `email_enrichment_enabled` | boolean | Activa el enriquecimiento con inteligencia de correo electrónico (entregabilidad, reputación del dominio, exposición en brechas de datos y puntuación de riesgo de fraude). **Se cobra \$0.05 por verificación**, además del precio de la verificación de correo electrónico. |
| `email_intelligence_score_action` | action | Acción cuando la puntuación de riesgo de fraude del correo electrónico es igual o superior a `email_intelligence_score_threshold`. |
| `email_intelligence_score_threshold` | integer | Puntuación de riesgo de fraude (`0`–`100`; cuanto más alta, más riesgo) que dispara `email_intelligence_score_action`. Valor predeterminado: `80`. |
| `recent_email_breach_action` | action | Acción cuando el correo electrónico aparece en una brecha de datos conocida reciente. |
| `frequent_email_breach_action` | action | Acción cuando el correo electrónico aparece en muchas brechas de datos conocidas. |
| `email_social_enabled` | boolean | Activa la comprobación de huella social: en qué plataformas de correo electrónico, redes sociales, servicios profesionales, comercio electrónico y entretenimiento está registrada la dirección verificada. **Se cobra \$0.05 por verificación**, además del precio de la verificación de correo electrónico, con independencia de `email_enrichment_enabled`. |
| `email_no_social_presence_action` | action | Acción cuando la comprobación de huella social no encuentra la dirección registrada en ninguna de las plataformas que cubre, una señal habitual de identidad sintética. Valor predeterminado: `NO_ACTION`. |
| `cross_org_fraud_email_action` | action | Veredicto cuando otra organización de la red marcó esta dirección como fraudulenta. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

> [!NOTE]
>
> El enriquecimiento con inteligencia de correo electrónico es un complemento opcional. Cuando `email_enrichment_enabled` es `true`, cada verificación de correo electrónico completada se enriquece con inteligencia de correo electrónico y **se factura a \$0.05 por solicitud**, además del coste estándar de la verificación de correo electrónico. La acción basada en la puntuación se aplica en cuanto la puntuación de enriquecimiento está disponible; las acciones de brechas de datos se aplican en cuanto se ejecuta el enriquecimiento.
>
> La comprobación de huella social es un segundo complemento, independiente del anterior. Cuando `email_social_enabled` es `true`, cada verificación de correo electrónico completada también indica en qué plataformas en línea está registrada la dirección (proveedores de correo electrónico, redes sociales y servicios profesionales, de comercio electrónico y de entretenimiento) y **se factura a \$0.05 por solicitud**. Puede activarse con o sin `email_enrichment_enabled`: los dos complementos tienen precios propios y se facturan por separado. Una consulta que no encuentra la dirección en ninguna de las plataformas que cubre es una respuesta válida y facturable, y dispara `email_no_social_presence_action`. Usa `email.social_profiles_registered` (el número de plataformas en las que está registrada la dirección) para crear una rama según el resultado en un grafo de workflow.

## Validación de base de datos

Valor de la función: `DATABASE_VALIDATION`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `database_validation_countries` | objeto | Código de país ISO3 asociado a `{ "services": ["service_id"] }`. Usa los ID de servicio del catálogo de Validación de base de datos. |
| `database_validation_partial_match_action` | acción | Acción que se aplica cuando la validación de base de datos devuelve una coincidencia parcial. |
| `database_validation_no_match_action` | acción | Acción que se aplica cuando la validación de base de datos no devuelve ninguna coincidencia. |
| `database_validation_not_applicable_action` | acción | Acción que se aplica cuando la validación de base de datos no puede ejecutarse porque el documento no incluye el identificador que requieren los servicios configurados (por ejemplo, un pasaporte sin número de identificación nacional). El valor predeterminado es `NO_ACTION`. |
| `database_validation_field_sources` | objeto | De dónde leer un dato de entrada de la base de datos que ningún paso anterior del grafo puede completar. `source` indica el origen del dato y `key` indica el valor dentro de él: una clave de campo de Document AI para `document_ai`, un id de nodo del cuestionario para `questionnaire`, y `expected_details.<field>` o `metadata.<key>` para `expected_data`. Las coincidencias exactas de clave con un paso anterior se resuelven automáticamente y, de forma intencionada, no se guardan, de modo que cambiar el nombre de un campo de Document AI nunca deja fijado en la configuración un mapeo obsoleto. Una entrada mal formada se rechaza con un `400` que indica su campo de entrada. Estructura: `{"<db_validation_input_field>": {"source": "document_ai"\|"questionnaire"\|"expected_data", "key": "<docai field key>\|<questionnaire node id>\|expected_details.<field>\|metadata.<key>"}}`. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

Ejemplo:

```json theme={null}
{
  "feature": "DATABASE_VALIDATION",
  "config": {
    "database_validation_countries": {
      "BRA": {
        "services": ["SERVICE_ID_FROM_CATALOG"]
      }
    },
    "database_validation_field_sources": {
      "tax_id": {
        "source": "expected_data",
        "key": "expected_details.document_number"
      }
    },
    "database_validation_no_match_action": "REVIEW",
    "database_validation_partial_match_action": "REVIEW"
  }
}
```

> [!WARNING]
>
> `database_validation_countries` es lo que hace que este paso haga algo. Una función `DATABASE_VALIDATION`
> guardada sin este campo se acepta, pero luego no ejecuta ninguna comprobación, así que envía siempre al menos un
> país con al menos un ID de servicio.

Un ID de servicio que el paso no puede ejecutar se rechaza con un `400` que lo identifica y explica el motivo, y no se guarda nada.
Esto incluye un ID que no está en el catálogo, un ID que pertenece a otro país, un servicio que todavía no está disponible y un servicio que solo se ofrece a través del endpoint independiente [`POST /v3/database-validation/`](https://docs.didit.me/es/core-technology/database-validation/overview).
Un servicio cuyos datos de entrada no proporciona ningún paso anterior se rechaza del mismo modo, con la lista de los datos de entrada que faltan.
Un servicio que el flujo guardado ya incluye pero que ya no puede ejecutarse se elimina cuando vuelves a guardarlo.

Por ejemplo, este flujo de Argentina lee el número de DNI y el género desde Verificación de identidad y los comprueba con RENAPER sin selfie:

```json theme={null}
{
  "workflow_label": "Argentina DNI check",
  "features": [
    {"feature": "OCR"},
    {
      "feature": "DATABASE_VALIDATION",
      "config": {"database_validation_countries": {"ARG": {"services": ["arg_renaper_data"]}}}
    }
  ]
}
```

Usa `arg_renaper` en su lugar, después de un paso `LIVENESS`, para comparar además la selfie con la foto que tiene RENAPER.
Consulta [RENAPER](https://docs.didit.me/es/api-reference/database-validation/argentina/renaper.md) para conocer su puntuación de coincidencia facial y su umbral.

## Verificación bancaria

Valor de la función: `BANK_VERIFICATION`.

> [!WARNING]
>
> La Verificación bancaria todavía no está habilitada en producción.
> Hasta que lo esté, se rechaza guardar un flujo de producción que incluya este nodo.

El usuario verifica una cuenta bancaria, y el titular de la cuenta que informa el banco se compara con la identidad que estableció un paso anterior del flujo. El usuario lo hace mediante uno de dos métodos: el inicio de sesión bancario (`open_banking`), en el que inicia sesión en su banco, o la comprobación de cuenta (`account_lookup`), en la que escribe los datos de la cuenta y el banco confirma el nombre que figura en ella. `bank_method_order` y los `methods` de cada país determinan qué métodos ofrece un país y cuál va primero; consulta [Métodos de verificación bancaria](https://docs.didit.me/es/core-technology/bank-verification/verification-methods.md). El paso genera evidencias (una puntuación del nombre del titular, la comparación que la produjo y códigos de motivo) y las claves `bank_*_action` convierten esas evidencias en un estado.

Dos cosas deciden si el nodo hace algo. `bank_countries` es una lista de permitidos, así que un mapa vacío no ofrece ningún banco ni ejecuta ninguna comprobación. Además, el titular necesita algo con lo que compararse: coloca antes un paso `OCR`, `DATABASE_VALIDATION` o `QUESTIONNAIRE`, envía `expected_details` al crear la sesión o asigna tú mismo los campos con `bank_field_sources`. Sin ninguno de ellos, la propiedad solo puede ser `unknown`, y eso es lo que decide `bank_reference_identity_missing_action`.

> [!NOTE]
>
> La Verificación bancaria todavía se está desplegando, por lo que un nodo `BANK_VERIFICATION` solo se acepta en una cuenta en la que se haya habilitado. En cualquier otra, el guardado se rechaza con un mensaje que lo indica. Tampoco se configura aquí qué ruta ejecuta el paso: lo determina el par `provider_key` y `fallback_to_native` que el [Marketplace](https://docs.didit.me/es/console/marketplace.md) de la consola establece por ti.

### Conectar una cuenta

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `bank_countries` | object | En qué países puede un usuario conectar un banco. Es una lista de permitidos: un mapa vacío significa que el nodo no ofrece nada ni ejecuta nada. `institutions` limita el selector a ID de instituciones concretas; `"all"` ofrece todos los bancos del país que admiten verificación de identidad. Un país que no atiende ninguna ruta del nodo se mantiene: solo ofrece sus alternativas y Continuar sin tu banco; consulta [Cuando la persona no puede verificar su banco](https://docs.didit.me/es/core-technology/bank-verification/fallbacks.md). Un código que no corresponde a ningún país se rechaza al guardar. `methods` establece cuáles de los métodos, inicio de sesión bancario (`open_banking`) y comprobación de cuenta (`account_lookup`), ofrece el país y en qué orden, por encima de `bank_method_order`: el usuario empieza por el primero y se le ofrece el segundo como respaldo. Se rechaza al guardar un país habilitado cuyos `methods` nombren un método que ninguna ruta del nodo atiende allí, y también un país que atiende una ruta y al que `methods` deja sin ninguno. Forma: `{"<ISO3>": {"enabled": true\|false, "institutions": ["<institution_id>", ...]\|"all", "methods"?: ["open_banking"\|"account_lookup", ...]}}`. |
| `bank_method_order` | string\[] | Cuáles de los dos métodos ofrece el paso, y en qué orden, en todos los países que no establecen sus propios `methods`: `open_banking` (inicio de sesión bancario: el usuario inicia sesión en su banco, y solo este método lee saldos, transacciones e ingresos) y `account_lookup` (comprobación de cuenta: sin inicio de sesión, solo propiedad). En cada país, el usuario empieza por el primer método que atiende allí una ruta y se le ofrece el otro como respaldo; un método que ninguna ruta atiende en un país se omite allí. Al menos un método. Un guardado que no envía ninguno recibe `["open_banking", "account_lookup"]`, salvo que envíe `bank_open_banking_enabled` o `bank_account_lookup_enabled`, que en ese caso lo establecen. |
| `bank_scopes` | object | Qué se pide al usuario que consienta compartir. `ownership` es lo que verifica el producto y no se puede desactivar. `identifiers` muestra sin enmascarar el IBAN o el número de cuenta; `balances`, `transactions` e `income` leen datos financieros reales, se facturan cada uno por separado y se rechazan al guardar salvo que tu aplicación tenga el derecho de acceso a datos financieros. Solo el inicio de sesión bancario lee datos: un país que ofrece la comprobación de cuenta no se rechaza, y un usuario que verifica mediante comprobación de cuenta se aprueba sin los datos, que el resultado enumera en `financial_data.not_collected`. Un ámbito desactivado nunca se solicita, así que el banco nunca lo muestra en su pantalla de consentimiento. El valor predeterminado es solo `ownership`. Forma: `{"ownership": true, "identifiers": true\|false, "balances": true\|false, "transactions": true\|false, "income": true\|false}`. |
| `bank_eligible_account_types` | string\[] | Qué tipos de cuenta puede elegir el usuario: `checking`, `current`, `savings`, `business` u `other`. Las tarjetas de crédito, los préstamos y las cuentas de inversión nunca son elegibles, porque no acreditan la propiedad de una cuenta de pago. El valor predeterminado es cuenta corriente y cuenta de cheques. |
| `bank_account_selection` | string | `user` permite al usuario elegir cuál de las cuentas conectadas se verifica; `auto` toma la primera elegible. |
| `bank_require_oauth_only` | boolean | Ofrece solo instituciones accesibles mediante OAuth o de aplicación a aplicación, nunca una pantalla heredada de captura de credenciales. En los mercados donde el open banking ya hace de OAuth la única ruta, esto no cambia nada. |
| `bank_max_attempts` | integer | Cuántos intentos de inicio de sesión bancario tiene el usuario, de `1` a `5`; un microdepósito o la carga de un extracto también consume uno. La comprobación de cuenta tiene su propio `bank_account_check_max_attempts`. Cuando todas las formas de verificar que aún se ofrecen al usuario, incluida la carga de un extracto, han agotado sus intentos sin una conexión exitosa, decide `bank_attempts_exhausted_action`. |
| `bank_connection_timeout_minutes` | integer | Cuánto tiempo permanece abierta una conexión iniciada antes de que el intento se dé por abandonado, de `5` a `60` minutos. |
| `bank_allow_skip` | boolean | Sustituido por `bank_continue_without_bank`: ahora el usuario siempre puede continuar sin un banco. Se lee durante una versión a partir de un guardado que no envía `bank_continue_without_bank`: `true` establece `from_start` y cualquier otro valor, `when_needed`. Cada guardado lo vuelve a escribir: `true` para `from_start` y `false` para `when_needed`. |

### Cuando el usuario no puede verificar

El usuario siempre puede continuar sin un banco, y el paso nunca lo deja bloqueado. Consulta [Cuando la persona no puede verificar su banco](https://docs.didit.me/es/core-technology/bank-verification/fallbacks.md).

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `bank_continue_without_bank` | string | Cuándo muestra el paso **Continue without your bank**. `when_needed`, el valor por defecto, lo muestra cuando ningún método funciona para el país o el banco del usuario, cuando no se puede contactar con su banco y ningún otro método pudo verificarlo (por ejemplo, porque la comprobación de cuenta tampoco pudo contactar con el banco) o cuando el usuario indica que no tiene banca en línea. `from_start` también lo muestra en la primera pantalla. No se puede desactivar. Un guardado que no envía ni esta clave ni `bank_allow_skip` recibe `when_needed`. |
| `bank_statement_standalone_enabled` | boolean | Junto con `bank_statement_enabled`, ofrece también la subida de extractos cuando no hubo ningún intento bancario, en cualquier país, incluido uno que no cubre ninguna vía de inicio de sesión bancario ni de comprobación de cuenta. En ese caso se factura por separado, como `bank_statement_upload`, a USD 0.20 por extracto evaluado antes de aplicar tu tarifa contractual o precio especial: consulta [Precios](https://docs.didit.me/es/core-technology/bank-verification/fallbacks.md#precios). Las sesiones de sandbox pueden probarlo sin facturación. Activado por defecto. |

Lo que significa continuar para la sesión lo determina `bank_unsupported_action`, `bank_attempts_exhausted_action` o `bank_skipped_action`, según el motivo por el que el usuario continuó, salvo que un intento evaluado antes ya haya decidido el paso: consulta [Acciones de veredicto](#acciones-de-veredicto).

### Comparación del titular

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `bank_reference_identity` | string | Qué paso anterior aporta la identidad con la que se compara al titular: `kyc` (Verificación de identidad), `database_validation`, `expected_details` (lo que enviaste al crear la sesión), `questionnaire` o `auto` para usar el que haya producido el flujo. El paso que realmente la aportó se devuelve en el resultado como `reference_identity_source`. |
| `bank_field_sources` | object | De dónde leer un campo de la identidad de referencia cuando ningún paso anterior del grafo puede rellenarlo. La CLAVE del mapa es una de `full_name`, `first_name`, `last_name`, `address`; `source` indica el productor y `key` indica el valor dentro de él: una clave de campo de Document AI para `document_ai`, un id de nodo del cuestionario para `questionnaire`, y `expected_details.<field>` o `metadata.<key>` para `expected_data`. Un valor bajo `expected_details.` solo puede indicar un campo que el payload de creación de sesión realmente contenga: `address`, `country`, `date_of_birth`, `first_name`, `gender`, `id_country`, `identification_number`, `ip_address`, `last_name`, `nationality` o `poa_country`. Una entrada mal formada se rechaza al guardar, no se descarta. Estructura: `{"full_name"\|"first_name"\|"last_name"\|"address": {"source": "document_ai"\|"questionnaire"\|"expected_data", "key": "<docai field key>\|<questionnaire node id>\|expected_details.<field>\|metadata.<key>"}}`. |
| `bank_name_match_threshold` | integer | A partir de esta puntuación, inclusive, el nombre del titular coincide. De `50` a `100`, por defecto `85`. |
| `bank_partial_match_floor` | integer | Por debajo de esta puntuación, el nombre del titular no coincide. De `0` a `99`, por defecto `70`. La franja entre el mínimo y el umbral es la coincidencia parcial, por lo que el mínimo debe ser estrictamente inferior al umbral o se rechaza el guardado. Aquí, un `null` explícito significa "usar el valor por defecto", y por eso se rechaza un umbral de `50` sin mínimo: se comprueba como `50` frente al mínimo por defecto de `70`. |
| `bank_require_address_match` | boolean | Exige además que la dirección del titular coincida. Un nombre que alcanzó el umbral pero cuya dirección puntúa por debajo de él baja a coincidencia parcial. Una entidad que no devuelve dirección anula el requisito; una sesión sin dirección propia con la que comparar no lo anula, y termina en coincidencia parcial. Desactivado por defecto. |
| `bank_use_provider_score` | boolean | Lee también la puntuación del nombre del titular de la propia entidad y deja que decida cuando es mayor que la de Didit o cuando Didit no tenía ningún nombre de titular que puntuar. Un resultado decidido así indica `provider_only` como método de coincidencia, y una conexión que no devolvió esa puntuación registra una advertencia `provider_score_unavailable`. Activado por defecto. |
| `bank_show_match_result_to_user` | boolean | Muestra el resultado de propiedad al usuario dentro del flujo de verificación. Si está desactivado, se registra en la sesión pero nunca se le muestra. |

### Comprobación de cuenta

Estas claves solo se aplican a la comprobación de cuenta. El inicio de sesión bancario conserva sus coincidencias aproximadas y su propio `bank_max_attempts`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `bank_account_check_accept_close_match` | boolean | Si está activado (por defecto), un nombre que el banco puntúa entre `bank_partial_match_floor` y `bank_name_match_threshold` es una coincidencia aproximada: el usuario confirma el nombre que tiene el banco cuando `bank_suggest_holder_name` está activado, y decide `bank_partial_match_action`. Si está desactivado, esa coincidencia aproximada es una no coincidencia (`OWNER_NAME_MISMATCH`, decidida por `bank_no_match_action`) y consume el intento. |
| `bank_account_check_max_attempts` | integer | Cuántas comprobaciones de cuenta tiene el usuario, de `1` a `5`, `3` si no se define: cuántas veces puede introducir los datos de la cuenta para una comprobación que el banco responde. Es un recuento independiente de `bank_max_attempts`. Una comprobación rechazada tal como se introdujo (un IBAN no válido) o una que el banco no pudo responder no consume ninguno. |

### Datos financieros

`bank_expected_currencies` funciona solo con el consentimiento `ownership` por defecto. Las otras tres claves leen datos financieros reales, por lo que cada una necesita el alcance de consentimiento correspondiente en `bank_scopes`, y sin él se rechaza el guardado.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `bank_expected_currencies` | string\[] | Monedas ISO 4217 en las que se espera que esté la cuenta. Vacío significa cualquiera; una discrepancia se notifica mediante `bank_currency_mismatch_action`. |
| `bank_min_balance` | number | Saldo disponible mínimo, en la moneda propia de la cuenta. Por debajo de él, se dispara `bank_low_balance_action`. Necesita el alcance `balances`. `0` es un límite real y no equivale a omitir la clave: una cuenta en descubierto dispara la acción. Esa acción tiene `NO_ACTION` por defecto, que deja el veredicto sin cambios, así que rechazar una cuenta en descubierto también requiere `bank_low_balance_action: "DECLINE"`. |
| `bank_transactions_history_days` | entero | Hasta cuántos días atrás se lee el historial de transacciones, de `30` a `365` días. El valor predeterminado es `90`. Requiere el alcance `transactions`. |
| `bank_refresh_enabled` | booleano | Vuelve a obtener los datos financieros de la cuenta después de que el paso ya se haya decidido, mientras dure el consentimiento bancario. Requiere al menos uno de los alcances `balances`, `transactions` o `income`. Un consentimiento que caduque después se rige por `bank_consent_expired_action`. |

### Qué se almacena

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `bank_store_full_identifiers` | booleano | Almacena los identificadores de la cuenta sin enmascarar en lugar de enmascarados. Requiere el alcance `identifiers`. Aun así, la forma sin enmascarar solo se devuelve a quien llama con el permiso de lectura de verificación bancaria. |
| `bank_store_raw_owner_data` | booleano | Conserva los datos del titular que devolvió la entidad junto a la prueba de propiedad. Si está desactivado, solo se conserva la comparación en sí: puntuaciones, método de coincidencia y códigos de motivo. |

### Acciones de veredicto

Cada clave de esta sección admite `DECLINE`, `REVIEW` o `NO_ACTION`, salvo que esté marcada como restringida, y recurre al valor predeterminado indicado si la omites o envías `null`. Por defecto, nada que no sea una prueba positiva de propiedad aprueba, y solo una prueba demostrable en contra del usuario rechaza.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `bank_no_match_action` | acción restringida | Veredicto cuando el titular de la cuenta demostrablemente no es la persona verificada: la mejor puntuación de nombre está por debajo de `bank_partial_match_floor`. Usa `DECLINE` o `REVIEW`. El valor predeterminado es `DECLINE`. |
| `bank_partial_match_action` | acción | Veredicto cuando el nombre del titular queda entre `bank_partial_match_floor` y `bank_name_match_threshold`. El valor predeterminado es `REVIEW`, y por defecto nunca aprueba. |
| `bank_not_verifiable_action` | acción | Veredicto cuando la entidad se conectó pero no devolvió ninguna identidad del titular que comparar. El valor predeterminado es `REVIEW`. |
| `bank_unknown_action` | acción | Veredicto cuando no se pudo obtener la prueba tras los reintentos, es decir, un fallo transitorio. El valor predeterminado es `REVIEW`. |
| `bank_reference_identity_missing_action` | acción | Veredicto cuando ningún paso anterior generó una identidad con la que comparar al titular, por lo que la propiedad solo puede ser `unknown`. El valor predeterminado es `REVIEW`. |
| `bank_joint_account_action` | acción | Veredicto cuando la cuenta tiene más de un titular. El valor predeterminado es `NO_ACTION`. |
| `bank_business_account_action` | acción | Veredicto cuando la entidad clasifica al titular como empresa en lugar de como persona. El valor predeterminado es `REVIEW` en un flujo de personas, y `NO_ACTION` en un flujo de empresas (KYB), donde un titular empresarial es lo que la sesión espera encontrar. |
| `bank_unsupported_action` | acción | Veredicto cuando el usuario continúa sin banco porque ningún método podía verificar su país o su banco: ninguna vía de inicio de sesión en el banco ni de comprobación de cuenta da servicio al país, o el banco que eligió no se puede usar en este paso. En ese caso, el resultado tiene `continued_without_bank` en true y `NOT_COVERED` entre sus códigos de motivo. El valor predeterminado es `REVIEW`. |
| `bank_skipped_action` | acción restringida | Veredicto cuando el usuario eligió Continuar sin tu banco aunque había una forma de verificar. En ese caso, el resultado tiene `continued_without_bank` en true y `SKIPPED` entre sus códigos de motivo. Usa `DECLINE` o `REVIEW`. El valor predeterminado es `REVIEW`. |
| `bank_attempts_exhausted_action` | acción restringida | Veredicto cuando el usuario agotó los intentos de todas las formas de verificar que aún se le ofrecen, incluida la carga de un extracto bancario (`bank_max_attempts`, y `bank_account_check_max_attempts` donde el país ofrece la comprobación de cuenta), sin lograr una conexión exitosa, también cuando después continúa sin banco. Usa `DECLINE` o `REVIEW`. El valor predeterminado es `DECLINE`. |
| `bank_consent_expired_action` | acción | Veredicto cuando el consentimiento bancario caduca después de que el paso ya se haya decidido. Solo tiene sentido con `bank_refresh_enabled`. El valor predeterminado es `NO_ACTION`. |
| `bank_currency_mismatch_action` | acción | Veredicto cuando la moneda de la cuenta no está en `bank_expected_currencies`. El valor predeterminado es `NO_ACTION`. |
| `bank_country_mismatch_action` | acción | Veredicto cuando el país de la entidad difiere del país esperado o del país del documento. El valor predeterminado es `NO_ACTION`. |
| `bank_low_balance_action` | acción | Veredicto cuando el saldo disponible está por debajo de `bank_min_balance`. Requiere el alcance `balances`. El valor predeterminado es `NO_ACTION`. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

### Más controles

Estas claves son opcionales. Cada clave de acción admite `DECLINE`, `REVIEW` o `NO_ACTION`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `bank_abandoned_action` | acción | Veredicto cuando el paso termina sin coincidencia después de que la persona se fuera a su banco y nunca volviera (un intento agotó el tiempo de espera). |
| `bank_account_age_action` | acción | Veredicto cuando la cuenta es más reciente que `bank_account_age_days`, un patrón habitual de cuentas mula. |
| `bank_account_age_days` | entero | Una cuenta cuyo historial empieza hace menos de este número de días se considera nueva, de 1 a 365, con 30 como valor predeterminado. Se lee del historial de transacciones, por lo que solo funciona con el alcance `transactions`. |
| `bank_account_lookup_enabled` | booleano | Retirado: usa `bank_method_order` y `bank_countries.<ISO3>.methods`. Se sigue leyendo durante una versión en un guardado que no envía `bank_method_order`: junto con `bank_open_banking_enabled`, define el orden, con la comprobación de cuenta después del inicio de sesión en el banco cuando está activado, y sin ella cuando está desactivado o sin definir. Cada guardado lo vuelve a escribir indicando si algún país ofrece la comprobación de cuenta. |
| `bank_account_type_action` | acción | Veredicto cuando la cuenta verificada es una cuenta de ahorro. |
| `bank_address_match_threshold` | entero | A partir de esta puntuación, la dirección del titular coincide, de 50 a 100, con 70 como valor predeterminado. Solo se lee con `bank_require_address_match`. |
| `bank_address_mismatch_action` | acción | Veredicto cuando la dirección del titular difiere, lo que convierte una coincidencia en una coincidencia cercana. Solo con `bank_require_address_match`. |
| `bank_auto_add_countries` | booleano | Ofrece todos los países a los que puede dar servicio alguna vía de este nodo, también los que se añadan después de guardar el nodo, salvo los países que `bank_countries` desactiva. Está desactivado cuando la clave no existe, de modo que un nodo existente nunca se amplía por sí solo. |
| `bank_cash_flow_action` | action | Veredicto cuando el dinero entra y vuelve a salir de inmediato, o cuando entran muchas transferencias pequeñas (flujo de caja de paso). Requiere el scope `transactions`. |
| `bank_dob_match_enabled` | boolean | Compara la fecha de nacimiento del titular, cuando el banco la comparte, con la verificada. Una discrepancia nunca cambia el resultado de propiedad: dispara `bank_dob_mismatch_action`. Activado de forma predeterminada. |
| `bank_dob_match_threshold` | integer | A partir de esta puntuación, la fecha de nacimiento coincide; de 50 a 100, con 70 como valor predeterminado. Una fecha es el mismo día o no lo es, así que puntúa 100 o 0. |
| `bank_dob_mismatch_action` | action | Veredicto cuando la fecha de nacimiento del titular es distinta. Solo con `bank_dob_match_enabled`. |
| `bank_email_match_enabled` | boolean | Compara el correo electrónico registrado en el banco con el correo electrónico verificado de la sesión. Una discrepancia dispara `bank_email_mismatch_action`. Desactivado de forma predeterminada. |
| `bank_email_match_threshold` | integer | A partir de esta puntuación, el correo electrónico coincide; de 50 a 100, con 70 como valor predeterminado. |
| `bank_email_mismatch_action` | action | Veredicto cuando el correo electrónico del titular es distinto. Solo con `bank_email_match_enabled`. |
| `bank_evidence_retention_days` | integer | Elimina la evidencia bancaria esta cantidad de días después del veredicto: 30, 90, 365 o 1825. Con null se conserva junto con la sesión. Se eliminan: los datos del titular, la identidad con la que se compararon, los identificadores de cuenta, los datos financieros y un extracto subido; una conexión que siga activa se revoca. El veredicto, las puntuaciones y los códigos de motivo se conservan. Eliminar la sesión elimina todo, lo que ocurra primero. |
| `bank_fallback_used_action` | action | Veredicto cuando la cuenta se verificó con microdepósitos o con la subida de un extracto. |
| `bank_match_any_holder` | boolean | Una cuenta conjunta o en copropiedad coincide cuando CUALQUIERA de los titulares indicados coincide con la persona. Desactivado: solo puede coincidir el primer titular que indica el banco. Activado de forma predeterminada. |
| `bank_microdeposits_enabled` | boolean | Ofrece microdepósitos como alternativa: llegan dos depósitos pequeños a la cuenta y la persona introduce los importes. Solo se ofrece en un país cuya ruta pueda enviarlos, después de un intento de verificación bancaria cobrado en la misma sesión. Incluido sin cargo adicional; el cliente paga el precio de la ruta una sola vez. Las sesiones de sandbox pueden probarlo sin facturación. El titular es el nombre que verificó la sesión, a cuyo nombre la persona declara que está la cuenta, por lo que una cuenta verificada registra una advertencia `holder_declared`. Activado de forma predeterminada. |
| `bank_mule_score_action` | action | Veredicto cuando la puntuación de mula es igual o superior a `bank_mule_score_threshold`. |
| `bank_mule_score_threshold` | integer | A partir de esta puntuación de mula, de 0 a 100, se dispara `bank_mule_score_action`; el valor predeterminado es 70. La puntuación combina una cuenta nueva, flujo de caja de paso, un saldo vaciado y muchas transferencias pequeñas entrantes, a partir del historial de transacciones (el scope `transactions`). |
| `bank_open_banking_enabled` | boolean | Retirado: usa `bank_method_order` y `bank_countries.<ISO3>.methods`. Se lee durante una versión en un guardado que no envía `bank_method_order`: junto con `bank_account_lookup_enabled`, define el orden, con el inicio de sesión en el banco cuando está activado o sin definir. Cada guardado lo vuelve a escribir indicando si algún país ofrece inicio de sesión en el banco. |
| `bank_phone_match_enabled` | boolean | Compara el teléfono registrado en el banco con el teléfono verificado de la sesión. Una discrepancia dispara `bank_phone_mismatch_action`. Desactivado de forma predeterminada. |
| `bank_phone_match_threshold` | integer | A partir de esta puntuación, el teléfono coincide; de 50 a 100, con 70 como valor predeterminado. |
| `bank_phone_mismatch_action` | action | Veredicto cuando el teléfono del titular es distinto. Solo con `bank_phone_match_enabled`. |
| `bank_popular_mode` | string | `auto` (el valor predeterminado) ordena los bancos populares según los que más conecta la gente en el país; `manual` muestra en su lugar las `popular_institutions` de cada país definidas en `bank_countries`, en su orden. |
| `bank_statement_document_checks_action` | action | Veredicto cuando un extracto subido presenta indicios de edición o manipulación. El valor predeterminado es `REVIEW`. |
| `bank_statement_enabled` | boolean | Ofrece la subida de un extracto bancario como alternativa: un extracto de los últimos 3 meses, revisado para detectar manipulaciones, cuyo nombre de titular se compara igual que el de un banco. Incluido sin cargo adicional tras un intento de verificación bancaria cobrado en la misma sesión. Con `bank_statement_standalone_enabled` también se ofrece sin un intento bancario previo, en cualquier país, y en ese caso se factura por separado. Las sesiones de sandbox pueden probarlo sin facturación. Desactivado de forma predeterminada. |
| `bank_suggest_holder_name` | boolean | Ante una coincidencia cercana, muestra a la persona el nombre a cuyo nombre el banco tiene la cuenta y le pide que confirme que es el suyo o que conecte otra cuenta. Su respuesta se registra como `holder_confirmation`; confirmar termina el paso con `bank_partial_match_action`. Activado de forma predeterminada. |
| `fallback_to_native` | boolean | Indica si una conexión de marketplace que no se puede establecer recurre a la ruta nativa de Didit. Desactivado de forma predeterminada: un respaldo silencioso gastaría tu saldo de Didit en una sesión que esperabas ejecutar con tu propio contrato de proveedor. Una conexión de respaldo se registra como `credential_source = native` y se factura al precio nativo. |
| `provider_key` | string | Qué ruta ejecuta el paso. Vacío (el valor predeterminado) es la Verificación bancaria nativa de Didit, un producto independiente del proveedor que Didit enruta al proveedor regional de open banking que da servicio al país y a la institución del usuario, con los contratos y la facturación de Didit. Un valor nombra un proveedor del MARKETPLACE cuyas propias credenciales ha conectado esta aplicación: la sesión se ejecuta, se factura y se revoca entonces en tu cuenta del proveedor, y Didit cobra solo la tarifa de plataforma del marketplace. Un proveedor que no está conectado se rechaza al guardar. |

Objeto `config` de ejemplo, para una cuenta en la que la Verificación bancaria está habilitada y la ruta que seleccionaste cubre el país que indicas:

```json theme={null}
{
  "bank_method_order": ["open_banking", "account_lookup"],
  "bank_countries": {
    "ESP": { "enabled": true, "institutions": "all" }
  },
  "bank_scopes": { "ownership": true },
  "bank_eligible_account_types": ["checking", "current"],
  "bank_name_match_threshold": 85,
  "bank_partial_match_floor": 70,
  "bank_partial_match_action": "REVIEW",
  "bank_no_match_action": "DECLINE"
}
```

> [!WARNING]
>
> `bank_countries` es lo que hace que este paso tenga algún efecto, y se comprueba contra la ruta en la que se
> ejecuta el nodo, no contra una lista global. Un país en el que esa ruta no puede establecer la propiedad
> de la cuenta se rechaza al guardar y se nombra en el error, así que lee el error en lugar de suponer
> que el país se aceptó y se omitirá durante la ejecución.

## AML

Valor de la función: `AML`.

Para el análisis AML de personas (KYC), usa estos campos:

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `is_aml_ongoing_monitoring_enabled` | boolean | Activa la monitorización AML continua. |
| `aml_score_approve_threshold` | integer | Umbral de aprobación. |
| `aml_score_review_threshold` | integer | Umbral de revisión. |
| `aml_match_score_threshold` | integer | Umbral de puntuación de coincidencia para posibles coincidencias. |
| `aml_name_weight` | integer | Peso del nombre. Si se proporciona algún peso AML, los pesos del nombre, la fecha de nacimiento y el país deben sumar `100`. |
| `aml_dob_weight` | integer | Peso de la fecha de nacimiento. |
| `aml_country_weight` | integer | Peso del país. |
| `create_cases_on_hit` | boolean | Abre un caso automáticamente cuando el análisis devuelve una coincidencia (hit), en lugar de dejar que la coincidencia se clasifique desde la sesión. Desactivado por defecto. |
| `case_blueprint` | uuid | Plantilla de caso a partir del cual se crea el caso automático. Solo tiene sentido con `create_cases_on_hit`; si no se define, se usa el valor por defecto de la cuenta. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

Para el análisis AML de empresas (KYB), usa estos campos:

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `kyb_score_approve_threshold` | integer | Umbral de aprobación AML de la empresa. |
| `kyb_score_review_threshold` | integer | Umbral de revisión AML de la empresa. |
| `kyb_enable_ongoing_monitoring` | boolean | Activa la monitorización AML continua de KYB. |
| `kyb_company_aml_match_score_threshold` | integer | Umbral de puntuación de coincidencia AML de la empresa. |
| `kyb_company_aml_name_weight` | integer | Peso del nombre de la empresa. Cuando se proporcionan, los pesos AML de la empresa deben sumar `100`. |
| `kyb_company_aml_dob_weight` | integer | Peso de la fecha de constitución o de la fecha de nacimiento. |
| `kyb_company_aml_country_weight` | integer | Peso del país. |

### Analizar una entidad extraída por un paso de Document AI

Normalmente, un paso AML obtiene a quién analiza del paso `OCR` (una persona) o del paso `KYB_REGISTRY` (una empresa). Un flujo cuyo único paso de extracción es `DOCUMENT_AI` (documentos no estandarizados, como un certificado fiscal o una escritura de constitución) no tiene ninguno de los dos, así que debe indicar de dónde procede cada dato de entrada del análisis.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `aml_field_sources` | object | De dónde leer la entidad que analiza este paso. `source` indica el origen del dato y `key` indica el valor dentro de él: una clave de campo de Document AI para `document_ai`, un id de nodo del cuestionario para `questionnaire`, y `expected_details.<field>` o `metadata.<key>` para `expected_data`. La CLAVE del mapa es uno de los cuatro datos de entrada del análisis (`full_name`, `date_of_birth`, `nationality`, `document_number`), que para una empresa se interpretan como razón social, fecha de constitución, país y número de registro. Un campo de Document AI cuya clave ya es una de esas cuatro se asigna automáticamente y, de forma deliberada, no se guarda, de modo que renombrarlo nunca deja fijada una asignación obsoleta. Una asignación explícita prevalece tanto sobre la asignación automática como sobre el documento de identidad, y si no se resuelve en ningún valor durante la ejecución, el dato de entrada queda vacío en lugar de recurrir a otra fuente. En un flujo de empresas (KYB), la empresa devuelta por un paso `KYB_REGISTRY` es la fuente de referencia: solo una asignación explícita sustituye uno de sus datos de entrada, la asignación automática no se aplica sobre un registro del registro de empresas y, si no hay paso de registro, la asignación constituye toda la identidad. Formato: `{"full_name"\|"date_of_birth"\|"nationality"\|"document_number": {"source": "document_ai"\|"questionnaire"\|"expected_data", "key": "<docai field key>\|<questionnaire node id>\|expected_details.<field>\|metadata.<key>"}}`. |
| `aml_entity_type` | string | `person` o `company`. Por defecto es `person` en un flujo de personas (KYC) y `company` en un flujo de empresas (KYB). Define `company` para analizar la empresa que figura en un documento subido sin un paso `KYB_REGISTRY`: el proveedor busca en registros de empresas y la puntuación de coincidencia se evalúa como la de una empresa. |
| `aml_incomplete_data_action` | action | Decisión cuando el análisis se ejecutó con una identidad incompleta (nombre, fecha de nacimiento y país). `REVIEW` es el valor por defecto. `NO_ACTION` permite continuar con datos reducidos en un flujo que, a sabiendas, solo dispone de un nombre. El análisis se ejecuta en ambos casos y el registro de datos parciales se guarda en ambos casos: esto solo decide cómo afecta al estado. |

Ejemplo: análisis de la empresa que figura en un *acta constitutiva* mexicana, sin ningún documento de identidad en todo el flujo:

```json theme={null}
{
  "feature": "AML",
  "config": {
    "aml_entity_type": "company",
    "aml_field_sources": {
      "full_name": { "source": "document_ai", "key": "razon_social" },
      "document_number": { "source": "document_ai", "key": "rfc" },
      "date_of_birth": { "source": "document_ai", "key": "fecha_constitucion" },
      "nationality": { "source": "document_ai", "key": "pais" }
    },
    "aml_incomplete_data_action": "REVIEW"
  }
}
```

> [!WARNING]
>
> Sin un paso `OCR` ni un paso `KYB_REGISTRY` antes, un paso `AML` debe poder rellenar
> `full_name`: sin un nombre, el proveedor no realiza ninguna búsqueda. Un flujo que no asigna nada, o que asigna
> una clave de Document AI que ningún paso anterior extrae, se rechaza al guardarlo en lugar de guardarse y quedarse
> sin analizar nada. La precisión del análisis AML depende directamente de cuántos identificadores proporciones: un
> análisis solo por nombre es lo que genera un gran volumen de falsos positivos.

## Análisis de dispositivo e IP

Valor de la función: `IP_ANALYSIS`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `ip_mismatch_action` | action | Acción cuando la geolocalización de la IP no coincide con los datos esperados. |
| `ip_location_not_determined_action` | action | Veredicto cuando no se registró ninguna dirección IP que identifique al usuario final, por lo que la sesión no tiene ninguna ubicación IP: el país, la ciudad, el ISP, las coordenadas y la zona horaria no están disponibles, y no pueden ejecutarse `ip_geofencing_by_country`, la comparación con el país del documento ni las comprobaciones de VPN o centro de datos. El valor predeterminado es `NO_ACTION`, que mantiene visible la advertencia `IP_LOCATION_NOT_DETERMINED` en la sesión sin cambiar su veredicto; configura `REVIEW` o `DECLINE` si una sesión sin ubicación no debe aprobarse. |
| `vpn_detection_action` | action | Acción cuando se detecta el uso de una VPN o un proxy. |
| `expected_ip_mismatch_action` | action | Acción cuando la IP no coincide con la IP esperada. |
| `duplicated_ip_action` | action | Acción cuando la IP se reutiliza de forma sospechosa. |
| `duplicated_device_action` | action | Acción cuando la misma huella persistente del dispositivo se reutiliza en sesiones con distintos valores de `vendor_data`. |
| `recovered_device_action` | action | Acción cuando la recuperación de huella v2 vincula la sesión con alta confianza a un dispositivo ya visto después de que cambiara el ID persistente del dispositivo. |
| `is_ip_geofencing_enabled` | boolean | Activa las restricciones de geovallas por IP. Cuando es `false`, `ip_geofencing_by_country` se conserva, pero no se aplica. |
| `ip_geofencing_by_country` | object | Reglas de ubicación IP por país, indexadas por código de país ISO-3: `{"USA": {"allowed": true, "states": {"California": {"allowed": false}}}}`. Las entradas de estado o región prevalecen sobre el indicador del país; los países que no figuran en la lista están permitidos. |
| `ip_geofencing_action` | action | Acción cuando la IP de la sesión se ubica en un país o estado/región no permitido. El valor predeterminado es `DECLINE`. |
| `automation_detected_action` | action | Veredicto cuando la sesión parece estar controlada por automatización en lugar de por una persona. |
| `cross_org_fraud_device_action` | action | Veredicto cuando otra organización de la red marcó este dispositivo como fraudulento. |
| `cross_org_fraud_ip_action` | action | Veredicto cuando otra organización de la red marcó esta IP como fraudulenta. |
| `device_app_tampered_action` | action | Veredicto cuando el binario de la aplicación anfitriona parece manipulado. |
| `device_blocklist_action` | action | Veredicto cuando el dispositivo está en la lista de bloqueo de la organización. |
| `device_debugger_action` | action | Veredicto cuando hay un depurador conectado a la aplicación anfitriona. |
| `device_emulator_action` | action | Veredicto cuando el dispositivo es un emulador y no hardware real. |
| `device_hooking_action` | action | Veredicto cuando se detecta hooking o instrumentación en tiempo de ejecución. |
| `device_integrity_missing_action` | action | Veredicto cuando no se devolvió ninguna atestación de integridad del dispositivo de la plataforma. |
| `device_rooted_action` | action | Veredicto cuando el dispositivo tiene root o jailbreak. |
| `multiple_devices_action` | action | Veredicto cuando la sesión se realizó desde más de un dispositivo. |
| `device_liveness_attack_history_action` | action | Acción cuando el mismo dispositivo (identificado por su ID persistente de dispositivo) se usó en una sesión anterior de otro usuario cuya captura de prueba de vida se consideró un ataque (advertencia `DEVICE_LINKED_TO_LIVENESS_ATTACK`). El valor predeterminado es `NO_ACTION`. |
| `device_model_inconsistency_action` | action | Acción cuando el mismo dispositivo (identificado por su ID persistente de dispositivo) se registró como un modelo de dispositivo distinto en una sesión anterior (advertencia `DEVICE_MODEL_INCONSISTENT`). El valor predeterminado es `NO_ACTION`. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

Ejemplo:

```json theme={null}
{
  "feature": "IP_ANALYSIS",
  "config": {
    "vpn_detection_action": "REVIEW",
    "duplicated_device_action": "REVIEW",
    "recovered_device_action": "REVIEW",
    "is_ip_geofencing_enabled": true,
    "ip_geofencing_by_country": {
      "USA": { "allowed": true, "states": { "California": { "allowed": false } } },
      "RUS": { "allowed": false, "states": null }
    },
    "ip_geofencing_action": "DECLINE"
  }
}
```

Usa `recovered_device_action` por separado de `duplicated_device_action` cuando quieras supervisar los dispositivos recuperados con alta confianza antes de rechazarlos automáticamente. Esto resulta útil durante el despliegue, porque las coincidencias de dispositivos recuperados están diseñadas para detectar redes de fraude, pero aun así conviene calibrarlas con tu propio tráfico.

## Verificación de ubicación

Valor de la función: `GEOLOCATION`.

Comprueba dónde está la persona mientras se verifica, a partir de la posición del dispositivo o de la ubicación IP de la conexión, y la contrasta con las zonas permitidas y bloqueadas, la ubicación IP y la dirección del documento.
Consulta [Verificación de ubicación](https://docs.didit.me/es/core-technology/location-verification/overview.md) para ver cómo se comporta el paso y [su informe](https://docs.didit.me/es/core-technology/location-verification/report-location-verification.md) para los campos de decisión.
Colócalo después de Verificación de identidad o Prueba de domicilio si quieres obtener la distancia a la dirección de un documento, porque la distancia solo se mide cuando hay una dirección registrada.
Si `geolocation_position_source` no está definido, la distancia a la ubicación IP requiere un paso de Análisis de dispositivo e IP en el mismo flujo.
Todas las claves son opcionales: un paso con un `config` vacío pide al dispositivo una posición con una precisión de 250 m y una antigüedad máxima de 120 segundos, da a la persona 3 intentos y no aplica ninguna regla de zona.

Cada hallazgo tiene su propia clave de acción, y una clave de acción que no definas toma el valor predeterminado del `geolocation_preset` que elegiste, o el valor predeterminado de cada clave que se indica abajo si no elegiste ninguno.
Una ubicación incierta o denegada toma por defecto `REVIEW`, nunca `DECLINE`, porque un permiso denegado o un radio amplio no son prueba de fraude.
Una acción que defines explícitamente siempre prevalece sobre el preajuste.
Un desafío reproducido (`LOCATION_REPLAY_DETECTED`) y una atestación del dispositivo fallida (`LOCATION_INTEGRITY_FAILED`) siempre se rechazan y no tienen clave de acción.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `geolocation_position_source` | string | De dónde procede la posición. `device_and_ip` pide la posición del dispositivo y la compara con la ubicación IP de la conexión desde la que se envía (con una consulta de inteligencia de IP cuando esa IP aún no está en caché). Sin definir (el valor predeterminado), también pide la posición del dispositivo y, como antes de que existiera esta clave, la compara con la ubicación IP que observó el paso de Análisis de dispositivo e IP de la sesión, así que no hay distancia sin ese paso y la conexión nunca se consulta. La excepción es un nodo que actúa ante un hallazgo de VPN, proxy o Tor (por su propia acción o por su preajuste): consulta la conexión para ese hallazgo y compara el dispositivo con ella, exactamente como hace `device_and_ip`. `device_only` nunca compara con la ubicación IP y solo consulta la conexión para esos hallazgos; `ip_only` nunca pregunta a la persona y, en su lugar, evalúa la ubicación IP de la conexión, a nivel de ciudad con un radio de 50 km, sin ninguna regla de precisión, antigüedad ni concesión aproximada; con `geolocation_areas`, una ciudad costera se evalúa dentro de su país salvo que otro país esté dentro de ese radio. En un nodo que pide la posición al dispositivo, un intento sin posición del dispositivo se evalúa como lo que es, una denegación o un fallo: la ubicación IP nunca la sustituye. |
| `geolocation_preset` | string | Los valores predeterminados que toma cada acción sin definir de este nodo. `licensing`: estar fuera de una zona o en una zona bloqueada, una VPN, Tor o un emulador se rechazan, un proxy y los demás hallazgos se envían a revisión, y la falta de atestación del dispositivo se queda en Sin acción. `fraud_screening`: lo mismo, salvo que lo que Licensing rechaza pasa a revisión. Null mantiene los valores predeterminados de siempre. Una acción definida explícitamente siempre prevalece. |
| `geolocation_accuracy_mode` | string | Lo que se pide al dispositivo. `precise` pide al sistema operativo una posición precisa, y a una persona que solo concede una aproximada se le vuelve a pedir mientras queden intentos y después se evalúa según `geolocation_approximate_action`; `approximate_allowed` acepta una concesión aproximada sin ese veredicto. `geolocation_max_accuracy_radius_m` se aplica en ambos casos. `precise` si no se define. |
| `geolocation_max_accuracy_radius_m` | integer | El radio de incertidumbre más amplio, en metros, que puede tener una posición del dispositivo para seguir siendo válida. De 10 a 50000 metros; 250 si no se define. Una posición más amplia, o una que no informa ningún radio, hace lo que indica `geolocation_low_accuracy_behavior` y se evalúa según `geolocation_low_accuracy_action`. Un nodo `ip_only` no tiene radio del dispositivo y nunca lo aplica. |
| `geolocation_max_accuracy_radius_unit` | string | La unidad en la que la consola muestra `geolocation_max_accuracy_radius_m`. Solo afecta a la visualización: el valor almacenado siempre está en metros, ninguna regla depende de ella y los datos del paso solo la reenvían para que un cliente pueda mostrar la misma unidad. |
| `geolocation_low_accuracy_behavior` | string | Qué ocurre con una posición más amplia que `geolocation_max_accuracy_radius_m`, o sin radio: `ask_again` (el valor predeterminado) pide a la persona que lo vuelva a intentar mientras queden intentos; `fail` termina el paso en la primera. |
| `geolocation_max_age_seconds` | integer | Qué antigüedad, en segundos, puede tener una posición del dispositivo cuando la recibe el servidor. De 5 a 3600 segundos; 120 si no se define. Si es más antigua, se vuelve a pedir mientras queden intentos y después se evalúa según `geolocation_stale_fix_action`. |
| `geolocation_timeout_seconds` | integer | Cuánto tiempo, en segundos, deja el cliente que el dispositivo busque una posición en cada intento; el servidor lo reenvía en los datos del paso y no impone nada por sí mismo. De 5 a 120 segundos; 20 si no se define. Un intento que no encuentra una posición a tiempo se envía como `timeout`, se vuelve a pedir mientras queden intentos y después se evalúa según `geolocation_unavailable_action`. |
| `geolocation_max_attempts` | integer | Cuántos intentos tiene la persona en este nodo. De 1 a 5 intentos; 3 si no se define. Un intento que la persona aún puede cambiar (una denegación, una posición amplia, antigua o aproximada, o un hallazgo de zona o de anonimizador ante el que actúa el nodo) se vuelve a pedir mientras queden intentos, y el último decide el paso. Una posición simulada, o un emulador ante el que actúa el nodo, termina el paso en el intento que lo informó. |
| `geolocation_allow_qr_handoff` | boolean | Ofrece continuar en un celular o móvil con un código QR mientras el paso sigue abierto (`allow_qr_handoff` en los datos del paso, `can_handoff` en cada respuesta de envío). Los SDK nativos ya se ejecutan en el celular o móvil y nunca muestran el código. Activado por defecto. |
| `geolocation_allow_skip` | boolean | Permite que la persona continúe sin ubicación en cualquier momento, desde la introducción o una pantalla de reintento (`skipped: true`). La omisión termina el paso y se evalúa según `geolocation_unavailable_action`, salvo una omisión que responde a una denegación con un `geolocation_refusal_path` `continue_without_location`, que se registra como esa denegación. Desactivado por defecto. |
| `geolocation_deep_link_enabled` | boolean | Se reenvía al cliente como `deep_link_enabled` en los datos del paso: ofrece abrir en su lugar la propia aplicación del cliente. El servidor no le aplica ninguna regla. Desactivado por defecto. |
| `geolocation_refusal_path` | string | La alternativa que se ofrece cuando se deniega el acceso a la ubicación. `retry_then_handoff` (el valor por defecto) vuelve a pedirlo mientras queden intentos y ofrece continuar en un teléfono; `continue_without_location` permite que la persona continúe y registra la denegación; `end_session` finaliza el paso y la sesión en la primera denegación, y requiere que `geolocation_permission_denied_action` sea Review o Decline y un flujo con un final de decisión Declined, In Review o Final. La sesión se decide a partir de los pasos que se ejecutaron y nunca como Approved: en un flujo que no puede terminar en esa decisión, toma el otro final no aprobatorio (Declined en lugar de In Review, In Review en lugar de Declined). |
| `is_geolocation_geofencing_enabled` | boolean | Activa las reglas de zonas: `geolocation_areas`, o el antiguo `geolocation_geofencing_by_country`, solo se aplican mientras este valor sea true, y solo entonces los datos del paso incluyen `available_areas`. Desactivado por defecto. Con esta opción activada, una lista `geolocation_areas` necesita al menos una zona permitida. |
| `geolocation_areas` | array | Zonas permitidas y bloqueadas, que se aplican mientras `is_geolocation_geofencing_enabled` sea true. Solo pasa una posición dentro de una zona permitida, y una zona bloqueada siempre prevalece sobre una permitida. Una posición se evalúa por todo su círculo de precisión: un círculo que cruza un borde decisivo para la respuesta queda indeterminado, nunca fuera. Un país o región termina donde empieza otra tierra, nunca en su línea de costa, y una posición que los contornos no sitúan en ninguna tierra (un paseo marítimo o un muelle que la costa simplificada recortó) queda indeterminada para todo país o región dentro de su radio más 12 millas náuticas. `id` es el nombre que usan las reglas de rama y `geolocation.inside_areas` / `geolocation.blocked_areas`; `kind` elige la forma: un `country` completo (ISO 3166-1 alfa-3 con un contorno publicado: un territorio que los contornos dibujan como región de otro país es esa `region`, como Reunión como `FR-RE` de Francia o Bonaire, San Eustaquio y Saba como `NL-BQ1` a `NL-BQ3`), `region` (códigos ISO 3166-2 de un país con límites publicados), `circle` (de 1 a 500 km) o `polygon` (de 3 a 200 puntos, un anillo cuyos lados nunca se cruzan ni se tocan entre sí). Como máximo 50 zonas, con ids únicos, y al menos una zona permitida mientras la geovalla esté activada. No se puede combinar con `geolocation_geofencing_by_country`. |
| `geolocation_geofencing_by_country` | object | Reglas de permiso/denegación por país y región para la propia posición del dispositivo, que solo se aplican mientras `is_geolocation_geofencing_enabled` sea true. Tiene la misma forma que `ip_geofencing_by_country` de Análisis de IP, salvo que las claves de `states` son códigos ISO 3166-2 (`US-NJ`), no nombres de estados, porque la posición se resuelve a una subdivisión y no a la etiqueta de ciudad de un proveedor. Un país que no aparece en la lista está permitido. Al guardar una regla de región para un país sin límites ISO 3166-2 publicados, se rechaza en lugar de ignorarse en silencio. |
| `geolocation_ip_distance_km` | integer | Distancia máxima, en kilómetros, entre la posición del dispositivo y la ubicación de la IP, una vez restados ambos radios de incertidumbre, antes de que se aplique `geolocation_ip_distance_action`. 200 cuando se omite la clave; null desactiva la comparación. Solo compara un nodo cuyo `geolocation_position_source` sea `device_and_ip` o no esté definido; esa clave indica con qué ubicación de IP se compara. |
| `geolocation_ip_distance_unit` | string | La unidad en la que la consola muestra `geolocation_ip_distance_km`. Solo de visualización: el valor almacenado siempre está en kilómetros y ninguna regla depende de ella. |
| `geolocation_document_distance_km` | integer | Distancia máxima, en kilómetros, entre la posición (la ubicación de la IP en un nodo `ip_only`) y la dirección que indica `geolocation_document_distance_basis` antes de que se aplique `geolocation_document_distance_action`. Sin definir o null (el valor por defecto) significa desactivado. |
| `geolocation_document_distance_unit` | string | La unidad en la que la consola muestra `geolocation_document_distance_km`. Solo de visualización: el valor almacenado siempre está en kilómetros y ninguna regla depende de ella. |
| `geolocation_document_distance_basis` | string | Desde qué dirección se mide `geolocation_document_distance_km`: `document` (el valor por defecto: la dirección del documento de identidad y, después, la de la prueba de domicilio), solo `proof_of_address`, o `declared` (la `expected_details.address` indicada al crear la sesión, geocodificada). |
| `geolocation_travel_tolerance_enabled` | boolean | Pasa por alto la distancia respecto a la dirección cuando la misma persona (mismo `vendor_data`) fue vista a menos de `geolocation_travel_usual_area_km` de ella en los últimos `geolocation_travel_max_days` días. Nunca pasa por alto una VPN, una posición suplantada, una zona bloqueada ni estar fuera de las zonas permitidas. Solo cuenta como haber sido visto allí una posición medida por el dispositivo: una ubicación simulada o falseada, un emulador o una atestación fallida nunca cuentan. |
| `geolocation_travel_usual_area_km` | integer | Radio alrededor de la dirección que se considera la zona habitual de la persona. De 10 a 500 km; 100 cuando no está definido. |
| `geolocation_travel_max_days` | integer | Cuánto tiempo después de haber sido vista en la zona habitual una posición lejana sigue considerándose un viaje. De 1 a 90 días; 14 cuando no está definido. |
| `geolocation_consecutive_mismatch_count` | integer | Genera LOCATION\_CONSECUTIVE\_MISMATCHES cuando esta comprobación y las comprobaciones anteriores de la misma persona (mismo `vendor_data`) estuvieron fuera de las zonas permitidas, en una zona bloqueada o demasiado lejos de la dirección este número de veces seguidas. Una comprobación que no comparó nada ni prolonga ni interrumpe la racha, y tampoco lo hace una posición que el dispositivo no midió (una ubicación simulada o falseada, un emulador, una atestación fallida). De 2 a 10; null (el valor por defecto) significa desactivado. |
| `geolocation_approximate_action` | action | Veredicto cuando el usuario concedió una ubicación aproximada mientras `geolocation_accuracy_mode` pide una precisa. El valor por defecto es `REVIEW`. |
| `geolocation_blocked_area_action` | action | Veredicto cuando la posición, con todo su círculo de precisión, cae dentro de una zona bloqueada de `geolocation_areas`. El valor por defecto es Decline. |
| `geolocation_consecutive_mismatch_action` | action | Veredicto cuando se alcanzan `geolocation_consecutive_mismatch_count` discrepancias seguidas. Por defecto es Revisión. |
| `geolocation_document_distance_action` | action | Veredicto cuando la posición del dispositivo está más lejos de la dirección del documento que `geolocation_document_distance_km`. La dirección se geocodifica de forma aproximada, por lo que es una señal débil. Por defecto es `REVIEW`. |
| `geolocation_emulator_action` | action | Veredicto cuando la aplicación que compartió la ubicación indicó que se ejecutaba en un emulador. Los navegadores no pueden indicarlo. Salvo que sea Sin acción, finaliza el paso en ese intento: volver a comprobar no puede cambiar el dispositivo. Sin acción, salvo que se configure o un preajuste indique otra cosa. |
| `geolocation_geofence_undetermined_action` | action | Veredicto cuando no se puede situar la posición dentro o fuera de la geovalla porque su círculo de precisión alcanza el límite. La incertidumbre nunca se indica como fuera. Por defecto es `REVIEW`. |
| `geolocation_geofencing_action` | action | Veredicto cuando la posición del dispositivo, y todo su círculo de incertidumbre, queda fuera de `geolocation_geofencing_by_country`. Por defecto es `DECLINE`. |
| `geolocation_integrity_missing_action` | action | Veredicto cuando un cliente nativo envió una posición sin token de atestación del dispositivo. Por defecto es Sin acción; los clientes web se registran como no compatibles en lugar de como ausentes, porque ningún navegador puede atestar. |
| `geolocation_ip_distance_action` | action | Veredicto cuando la posición del dispositivo y la ubicación IP de la sesión están más alejadas que `geolocation_ip_distance_km`, después de restar ambos radios de incertidumbre. Por defecto es `REVIEW`. |
| `geolocation_low_accuracy_action` | action | Veredicto cuando ningún intento alcanzó la precisión requerida: la mejor posición tiene un radio de incertidumbre mayor que `geolocation_max_accuracy_radius_m`, o no indicó ningún radio. Una posición sin radio nunca se considera dentro del límite. Por defecto es `REVIEW`. |
| `geolocation_mock_location_action` | action | Veredicto cuando el sistema operativo indicó que la posición era simulada en lugar de medida (proveedor de ubicación simulada de Android, simulada por software en iOS). Por defecto es `REVIEW`. |
| `geolocation_permission_denied_action` | action | Veredicto cuando el usuario rechazó o descartó la solicitud de ubicación en todos los intentos permitidos. Por defecto es Revisión: una negativa es una elección, no una señal de fraude. |
| `geolocation_proxy_action` | action | Veredicto cuando la conexión que compartió la ubicación pasa por un proxy abierto, anónimo o de retransmisión privada. Sin acción, salvo que se configure o un preajuste indique otra cosa. |
| `geolocation_stale_fix_action` | action | Veredicto cuando la posición se midió más de `geolocation_max_age_seconds` antes de que el servidor la recibiera. Por defecto es `REVIEW`. |
| `geolocation_tor_action` | action | Veredicto cuando la conexión que compartió la ubicación es un nodo de salida de Tor. Sin acción, salvo que se configure o un preajuste indique otra cosa. |
| `geolocation_unavailable_action` | action | Veredicto cuando no se pudo obtener ninguna posición: servicios de ubicación desactivados o restringidos, el sistema de posicionamiento no devolvió nada, el intento agotó el tiempo de espera, el usuario omitió el paso o el cliente es demasiado antiguo para admitirlo. Por defecto es `REVIEW`. |
| `geolocation_vpn_action` | action | Veredicto cuando la conexión que compartió la ubicación es una VPN comercial. Salvo que sea Sin acción, se pide a la persona que la desactive y vuelva a comprobar mientras queden intentos. Sin acción, salvo que se configure o un preajuste indique otra cosa. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. Puedes usar los campos `geolocation.*` que se indican en [Informe de verificación de ubicación](https://docs.didit.me/es/core-technology/location-verification/report-location-verification.md#campos-para-reglas-de-estado-y-ramas). |

### Formas de las áreas

Cada elemento de `geolocation_areas` tiene un `id` (de 1 a 64 caracteres de `A-Z a-z 0-9 _ -`, único en la lista), una `label` opcional (hasta 80 caracteres), un `type` de `allowed` o `blocked`, y un `kind` que elige la forma.

| `kind` | Campos adicionales | Significado |
| - | - | - |
| `country` | `country` (ISO 3166-1 alpha-3) | Un país completo que tiene un contorno publicado. |
| `region` | `country`, `regions` (códigos ISO 3166-2 de ese país) | Una o más subdivisiones de un país con límites publicados. |
| `circle` | `center` (`latitude`, `longitude`), `radius_km` (de 1 a 500) | Todos los puntos dentro del radio desde el centro. |
| `polygon` | `points` (de 3 a 200 elementos de `latitude`, `longitude`) | Un anillo cerrado cuyos lados nunca se cruzan ni se tocan entre sí. |

Una lista contiene como máximo 50 áreas y necesita al menos un área `allowed` mientras `is_geolocation_geofencing_enabled` sea `true`.
`geolocation_areas` y `geolocation_geofencing_by_country` no se pueden enviar juntos, y `geolocation_refusal_path: "end_session"` requiere que `geolocation_permission_denied_action` sea `REVIEW` o `DECLINE`.
La API rechaza un área que nunca podría coincidir, como una región de un país sin límites publicados, en lugar de guardarla.

Ejemplo:

```json theme={null}
{
  "feature": "GEOLOCATION",
  "config": {
    "geolocation_position_source": "device_and_ip",
    "geolocation_preset": "licensing",
    "geolocation_max_accuracy_radius_m": 250,
    "geolocation_max_attempts": 3,
    "is_geolocation_geofencing_enabled": true,
    "geolocation_areas": [
      { "id": "spain", "label": "Spain", "type": "allowed", "kind": "country", "country": "ESP" },
      { "id": "ceuta-melilla", "type": "blocked", "kind": "region", "country": "ESP", "regions": ["ES-CE", "ES-ML"] }
    ],
    "geolocation_ip_distance_km": 200,
    "geolocation_ip_distance_action": "REVIEW",
    "geolocation_vpn_action": "DECLINE"
  }
}
```

## Prueba de domicilio

Valor de la función: `PROOF_OF_ADDRESS`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `poa_documents_allowed` | object | Asigna a cada código de país ISO3 una configuración de tipos de documento de prueba de domicilio. Debe haber al menos un tipo de documento válido habilitado. |
| `poa_languages_allowed` | object | Asigna a cada código de idioma ISO 639-1 el valor `0` o `1`. Debe haber al menos un idioma habilitado. |
| `poa_name_or_address_mismatch_action` | action | Acción cuando el nombre o la dirección no coinciden con los datos esperados. |
| `poa_document_issues_action` | action | Acción cuando el documento tiene problemas de calidad o de extracción. |
| `poa_max_attempts_exceeded_action` | restricted action | Acción cuando el usuario supera los intentos permitidos. Usa `DECLINE` o `REVIEW`. |
| `poa_document_authenticity_action` | restricted action | Acción cuando fallan las comprobaciones de autenticidad. Usa `DECLINE` o `REVIEW`. |
| `poa_unsupported_document_type_action` | action | Acción cuando el tipo de documento no es compatible. |
| `poa_unsupported_language_action` | action | Acción cuando el idioma del documento no es compatible. |
| `poa_issuer_not_identified_action` | action | Acción cuando no se identifica el emisor del documento. |
| `poa_issue_date_not_detected_action` | action | Acción cuando falta la fecha de emisión. |
| `poa_unparsable_or_invalid_address_action` | action | Acción cuando la dirección no es válida o no se puede analizar. |
| `address_validation_enabled` | boolean | Valida la dirección que lee este paso (la impresa en la prueba de domicilio; solo se valida un documento cargado que haya superado las comprobaciones del documento) frente a datos postales de referencia: confirma que la dirección existe y la normaliza, y nunca la vincula a una persona. El resultado es el objeto `address_validation` del paso en la decisión. **Se cobra \$0.10 por dirección validada**; una validación que no se pudo ejecutar (`unavailable`) es gratuita. Desactivado de forma predeterminada. |
| `address_not_verified_action` | action | Acción cuando la validación de direcciones no pudo confirmar la dirección hasta el nivel del edificio (`ADDRESS_NOT_VERIFIED`: `partially_verified` o `not_verified`). Solo se aplica mientras `address_validation_enabled` está activado. El valor predeterminado es `NO_ACTION`, que solo registra la advertencia. |
| `poa_name_match_score_threshold` | integer | Umbral de coincidencia del nombre. |
| `poa_max_retry_attempts` | integer | Límite de reintentos, de `2` a `5`. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

## Cuestionario

Valor de la función: `QUESTIONNAIRE`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `questionnaire_uuid` | UUID | Obligatorio. Usa el `questionnaire_id` que devuelve `POST /v3/questionnaires/`. |
| `review_questionnaire_manually` | boolean | Envía las respuestas del cuestionario a revisión manual. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. Puedes aplicar reglas a los campos `questionnaire.answers.<question_id>`. |

## Registro KYB

Valor de la función: `KYB_REGISTRY`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `kyb_accepted_countries` | object | Lista heredada de países permitidos (ISO3) para la consulta del registro de empresas. Reemplazada por `kyb_registry_countries_config`; todavía se puede leer y se sigue derivando de ella en los flujos existentes, pero ya no es la forma de configurar flujos nuevos. |
| `kyb_manual_company_action` | action | Acción cuando la empresa requiere tratamiento manual. |
| `kyb_registry_fields_config` | object | Visibilidad y obligatoriedad de cada campo del formulario de registro en el flujo alojado. Consulta más abajo. |
| `kyb_registry_countries_config` | object | Enrutamiento del registro por país, con el formato `{"<ISO2>": {"enabled": bool, "tier": "basic" \| "shareholders" \| "ubo"}}`. Cada país habilitado elige el nivel de datos que se cobra al seleccionar una empresa (`basic` es el nivel Lite), y solo se pueden habilitar los niveles que el [endpoint de precios](https://docs.didit.me/es/getting-started/kyb-registry-pricing.md) marca como disponibles para ese país. Debe haber al menos un país habilitado: se rechaza una comprobación de registro que no busca en ningún lugar. Las empresas introducidas manualmente se facturan por separado y no usan esta configuración. |
| `kyb_registry_monitoring_enabled` | boolean | Mantiene el registro de la empresa bajo monitorización continua tras un resultado de nivel Shareholders o UBO: un cambio de estado, administradores, propiedad o dirección devuelve la sesión a revisión y dispara un webhook. Solo está disponible donde el proveedor del registro ofrece monitorización. USD 2.00 por empresa al año, con cancelación en cualquier momento. Desactivado de forma predeterminada. |
| `kyb_vat_invalid_action` | action | Acción cuando el número de IVA de la empresa no supera la validación de VIES de la UE. El valor predeterminado es `REVIEW`. |
| `kyb_vat_unverified_action` | action | Acción cuando no se pudo validar el número de IVA porque VIES no estaba disponible. El valor predeterminado es `NO_ACTION`. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

`kyb_registry_fields_config` asigna a cada clave de campo configurable un objeto `{"enabled": bool, "required": bool}`. `enabled: false` oculta el campo, `enabled: true, required: false` lo muestra como opcional y `enabled: true, required: true` lo hace obligatorio al enviar. `company_name`, `country_code` y `region` siempre se muestran, son obligatorios y no se pueden configurar. Si el objeto se omite, es `null` o es `{}`, se aplica el valor predeterminado: solo `incorporation_date` es obligatorio y todos los demás campos son opcionales.

```json theme={null}
{
  "kyb_registry_fields_config": {
    "registration_number": { "enabled": true, "required": true },
    "incorporation_date": { "enabled": true, "required": true },
    "vat_number": { "enabled": true, "required": false },
    "control_scheme": { "enabled": false, "required": false }
  }
}
```

Claves de campo configurables: `registration_number`, `incorporation_date`, `legal_address`, `vat_number`, `alternative_names`, `tax_number`, `company_type`, `legal_entity_identifier`, `location_of_registration`, `nature_of_business`, `registered_capital_amount`, `registered_capital_currency`, `website`, `email`, `phone`, `control_scheme`. Consulta [campos configurables del formulario de registro](https://docs.didit.me/es/business-verification/company-data.md#campos-configurables-del-formulario-de-registro) para ver el comportamiento para el usuario final y [validación del IVA y de la identificación fiscal](https://docs.didit.me/es/business-verification/company-data.md#validación-del-iva-y-de-la-identificación-fiscal) para saber cómo se comprueban `vat_number` y `tax_number`.

## Documentos KYB

Valor de la función: `KYB_DOCUMENTS`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `kyb_required_document_groups` | objeto o array | Obligatorio. Grupos de documentos KYB requeridos. |
| `kyb_document_subtype_config` | objeto | Habilitación por subtipo de documento y configuración de antigüedad. |
| `kyb_document_tampering_action` | acción restringida | Acción cuando se detecta manipulación. Usa `DECLINE` o `REVIEW`. |
| `kyb_document_critical_mismatch_action` | acción restringida | Acción ante discrepancias críticas en los documentos. Usa `DECLINE` o `REVIEW`. |
| `kyb_document_non_critical_mismatch_action` | acción | Acción ante discrepancias no críticas en los documentos. |
| `kyb_document_age_action` | acción | Acción cuando no se cumplen las reglas de antigüedad del documento. |
| `kyb_document_max_retry_attempts` | entero | Límite de reintentos para los documentos KYB. |
| `kyb_document_max_attempts_exceeded_action` | acción restringida | Acción cuando se supera el número máximo de intentos. Usa `DECLINE` o `REVIEW`. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

## Personas clave KYB

Valor de la función: `KYB_KEY_PEOPLE`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `kyb_ubo_ownership_threshold` | entero | Umbral de propiedad para UBO, de `0` a `100`. |
| `kyb_shareholder_ownership_threshold` | entero | Umbral de propiedad para accionistas, de `0` a `100`. No puede ser mayor que `kyb_ubo_ownership_threshold`. |
| `kyb_key_people_ownership_required` | booleano | Exige un porcentaje de propiedad en cada persona clave enviada. Se aplica en el envío y se refleja en la interfaz alojada, que marca el campo como obligatorio. Valor predeterminado: `false`. |
| `kyb_require_ubo_kyc` | booleano | Exige que los UBO completen un flujo de verificación de personas. |
| `kyb_ubo_verification_workflow` | UUID | Obligatorio cuando `kyb_require_ubo_kyc` es `true`. Debe hacer referencia a un flujo que no sea KYB en la misma aplicación. |
| `kyb_require_officer_kyc` | booleano | Exige que los directivos completen la verificación de personas. |
| `kyb_shareholder_verification_workflow` | UUID | Flujo de verificación de personas para los accionistas. |
| `kyb_officer_verification_workflow` | UUID | Flujo de verificación de personas para los directivos. |
| `kyb_require_corporate_ubo_kyb` | booleano | Exige que los UBO corporativos completen el KYB. |
| `kyb_corporate_ubo_verification_workflow` | UUID | Obligatorio cuando `kyb_require_corporate_ubo_kyb` es `true`. Debe hacer referencia a un flujo KYB en la misma aplicación. |
| `kyb_reject_if_ubo_rejected` | booleano | Rechaza la empresa cuando se rechaza una verificación de UBO requerida. |
| `kyb_wait_for_all_ubos` | booleano | Espera a todas las verificaciones de UBO requeridas antes de tomar una decisión sobre la sesión de KYB. |
| `kyb_role_config` | objeto o array | Configuración por rol. Cada rol con KYC obligatorio debe incluir un `verification_workflow`. |
| `kyb_reuse_verified_individuals` | booleano | Reutiliza personas ya verificadas cuando es posible. |
| `kyb_notify_parties_by_email` | booleano | Envía notificaciones por correo electrónico a las personas clave invitadas. |
| `kyb_key_people_company_fields` | objeto | Qué datos de la empresa se recopilan para una persona clave CORPORATE. Tiene la misma estructura de lista de descriptores y las mismas reglas que `kyb_key_people_person_fields`. Forma: `[{"key": "<field key>", "label": "<label>", "type": "text"\|"number"\|"date"\|"phone"\|"email", "required": true\|false, "custom": true\|false}]`. |
| `kyb_key_people_document_mismatch_action` | acción | Decisión cuando el documento de una persona clave no coincide con los datos declarados para ella. |
| `kyb_key_people_person_fields` | objeto | Qué datos personales se recopilan para una persona clave física, como una LISTA ORDENADA de descriptores de campo (no un mapa). `key` es obligatorio y no puede estar vacío; `type` debe ser text, number, date, phone o email; `custom` marca un campo que añadió el cliente, en lugar de uno de los predefinidos. Forma: `[{"key": "<field key>", "label": "<label>", "type": "text"\|"number"\|"date"\|"phone"\|"email", "required": true\|false, "custom": true\|false}]`. |
| `kyb_key_people_prefill_from_registry` | booleano | Rellena previamente la lista de personas clave a partir del resultado del registro de empresas, para que el cliente confirme y corrija en lugar de introducir a mano cada directivo y accionista. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. |

## Document AI

Valor de la función: `DOCUMENT_AI`.

Solicita uno o varios documentos al usuario y extrae, con un modelo de visión, los campos que definas. Cada campo configurado se convierte en un valor que se puede usar para ramificar `document_ai.<key>`, y el resultado del paso es `document_ai.status`.

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `document_ai_documents` | array | Obligatorio. Los documentos que se solicitan (como máximo `3`). Cada entrada es un objeto de documento (ver más abajo). |
| `document_ai_unreadable_document_action` | acción | Acción cuando el documento no se puede leer o no se pueden extraer datos. |
| `document_ai_missing_required_fields_action` | acción | Acción cuando no se puede extraer un campo obligatorio. |
| `document_ai_document_tampering_action` | acción restringida | Acción cuando el documento muestra indicios de manipulación. Usa `DECLINE` o `REVIEW`. |
| `document_ai_name_mismatch_action` | acción | Acción cuando el nombre completo extraído no coincide con la identidad verificada. Requiere un campo marcado con `is_full_name`. |
| `document_ai_unsupported_file_action` | acción | Acción cuando el tipo de archivo subido no es compatible. |
| `document_ai_max_attempts_exceeded_action` | acción restringida | Acción cuando el usuario supera los intentos permitidos. Usa `DECLINE` o `REVIEW`. |
| `document_ai_name_match_score_threshold` | integer | Puntuación mínima (`0`–`100`) para que el nombre completo extraído coincida con la identidad verificada. Por debajo de ella, se aplica `document_ai_name_mismatch_action`. |
| `document_ai_max_retry_attempts` | integer | Límite de reintentos, de `2` a `5`. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. Puedes usar como objetivo los campos `document_ai.<key>`. |

Cada entrada de `document_ai_documents` es un documento:

| Campo del documento | Tipo | Descripción |
| - | - | - |
| `document_key` | string | Obligatorio. Identificador estable del documento, único dentro del paso. |
| `title` | string | Obligatorio. Título que se muestra al usuario. |
| `description` | string | Obligatorio. Instrucciones que se muestran al usuario sobre qué debe subir. |
| `title_i18n` | object | Opcional. Código de configuración regional asociado al título traducido (p. ej., `{ "es": "Comprobante de fondos" }`). |
| `description_i18n` | object | Opcional. Código de configuración regional asociado a la descripción traducida. |
| `fields` | array | Obligatorio. Los campos que se extraen (al menos uno). Las claves de los campos deben ser únicas dentro del documento. |

Cada entrada de `fields` de un documento es un campo:

| Campo | Tipo | Descripción |
| - | - | - |
| `key` | string | Obligatorio. Clave JSON estable del valor extraído, única dentro del documento. Puedes ramificar en función de ella como `document_ai.<key>`. |
| `name` | string | Obligatorio. Etiqueta legible del campo. |
| `name_i18n` | object | Opcional. Código de configuración regional asociado al nombre traducido del campo. |
| `instruction` | string | Opcional. Instrucción que indica al modelo exactamente qué extraer para este campo. |
| `type` | string | Tipo de campo: `text`, `number` o `date`. El valor predeterminado es `text`. |
| `required` | boolean | Indica si el campo debe estar presente. El valor predeterminado es `false`. Si es `true` y falta el valor, se aplica `document_ai_missing_required_fields_action`. |
| `is_full_name` | boolean | Opcional, el valor predeterminado es `false`. Marca el campo cuyo valor es el nombre completo del titular del documento, que se compara con la identidad verificada (el nombre obtenido en la verificación de identidad o los datos esperados de la sesión). **Como máximo un campo por documento** puede establecerlo en `true`, y **no es obligatorio**: un documento puede no marcar ninguno, en cuyo caso no se realiza ninguna comparación de nombre para ese documento. Solo los campos `text` pueden ser el nombre completo. |

Ejemplo:

```json theme={null}
{
  "feature": "DOCUMENT_AI",
  "config": {
    "document_ai_documents": [
      {
        "document_key": "proof_of_funds",
        "title": "Proof of Funds",
        "description": "Upload a recent bank statement.",
        "title_i18n": { "es": "Comprobante de fondos" },
        "fields": [
          {
            "key": "account_holder",
            "name": "Account holder",
            "instruction": "The full name of the account holder as printed on the statement.",
            "type": "text",
            "required": true,
            "is_full_name": true
          },
          {
            "key": "closing_balance",
            "name": "Closing balance",
            "instruction": "The closing balance amount.",
            "type": "number",
            "required": false
          }
        ]
      }
    ],
    "document_ai_missing_required_fields_action": "REVIEW",
    "document_ai_name_mismatch_action": "REVIEW",
    "document_ai_name_match_score_threshold": 80
  }
}
```

## Firma electrónica

Valor de la función: `SIGNATURE`.

Permite que la persona verificada, o las personas clave de una empresa, firmen documentos con el nivel Simple (predeterminado) o Avanzado (AES). Colócala después de los pasos que verifican al firmante: Verificación de identidad, y Verificación de correo electrónico o de teléfono para el código. Consulta [Firma electrónica](https://docs.didit.me/es/core-technology/electronic-signature/overview.md).

| Campo de configuración | Tipo | Descripción |
| - | - | - |
| `signature_documents` | array | Los documentos subidos a este flujo en la consola, en el orden en que los ve el firmante, como `[{"uuid", "title", "file_name", "pages", "size_bytes"}]`. Solo se leen los valores `uuid` y su orden; el resto se obtiene de los archivos almacenados. Hasta 20 documentos y 50 MB en total. Valor predeterminado: `[]`. |
| `signature_documents_source` | string | De dónde proceden los documentos: `workflow` (predeterminado), `session` (`sign.documents` al [crear la sesión](https://docs.didit.me/es/sessions-api/create-session.md#documentos-de-firma-electrónica)) o `both` (primero los documentos del flujo). |
| `signature_require_read_to_end` | boolean | El firmante debe llegar al final de cada documento sin campos antes de aceptarlo. Valor predeterminado: `true`. |
| `signature_consent_per_document` | boolean | El firmante acepta por separado cada documento sin campos. En los documentos con campos, lo sustituyen los campos guiados y el consentimiento final. Valor predeterminado: `true`. |
| `signature_signer` | string | Quién firma: `verified_person` (predeterminado, KYC) o, en KYB, `legal_representative` (personas clave con el rol `representative` o `authorized_signatory`) o `key_people` (cada persona clave que sea una persona física con una sesión de KYC). |
| `signature_level` | string | `simple` (predeterminado): sin verificación de identidad, correo electrónico, teléfono ni código; el firmante escribe su nombre y firma en el enlace de la sesión. `aes`: requiere una verificación de identidad aprobada, un correo electrónico o teléfono verificado y un código de un solo uso. `simple` se rechaza para los firmantes `legal_representative` y `key_people` con `signature_simple_requires_verified_person`. Mientras `signature_availability.aes` sea `false` en el flujo, guardar un nuevo paso `aes` devuelve `400` con `aes_not_available`. `qes` estará disponible próximamente: guardarlo devuelve `400` con `qes_not_available`. |
| `signature_format` | string | `pades` (predeterminado). `xades` y `cades` se rechazan para AES con `signature_format_not_supported`. |
| `signature_otp_channel` | string | Adónde se envía el código de un solo uso: `email` (predeterminado) o `sms`. Solo se envía a un contacto verificado previamente en la sesión. |
| `signature_email_signed_copy` | boolean | Envía al firmante por correo electrónico una copia de los documentos firmados. Requiere un correo electrónico verificado. Valor predeterminado: `true`. |
| `signature_evidence_page` | boolean | Añade la página de evidencias a cada PDF firmado. Valor predeterminado: `true`. |
| `signature_link_validity_days` | integer | Cuánto tiempo sigue siendo válido el enlace de firma, de `1` a `30` días desde la creación de la sesión. Valor predeterminado: `7`. |
| `signature_declined_action` | action | Veredicto cuando el firmante rechaza firmar. No se cobra nada. Valor predeterminado: `REVIEW`. |
| `signature_otp_failed_action` | action | Veredicto tras 3 códigos incorrectos o más de 5 códigos solicitados. Valor predeterminado: `DECLINE`. |
| `signature_name_mismatch_action` | action | Veredicto cuando el nombre declarado de una persona clave no coincide con su nombre verificado. Valor predeterminado: `DECLINE`. |
| `signature_identity_not_verified_action` | action | Veredicto cuando el firmante no tiene evidencia de identidad aprobada. Valor predeterminado: `DECLINE`. |
| `signature_document_changed_action` | action | Veredicto cuando un documento ya no coincide con el SHA-256 registrado cuando se mostró. Valor predeterminado: `DECLINE`. |
| `status_rules` | array | Reglas de estado personalizadas opcionales. Puedes definir como objetivo `signature.status`, `signature.level` y `signature.format`. |

Los campos de un documento del flujo se añaden en el editor de plantillas de la consola. Para los documentos de la sesión, envíalos en `sign.documents[].fields` y envía los valores de los campos `api.<key>` en `sign.field_values`. Consulta [Crear sesión](https://docs.didit.me/es/sessions-api/create-session.md#documentos-de-firma-electrónica).

Ejemplo, para documentos enviados con cada sesión:

```json theme={null}
{
  "feature": "SIGNATURE",
  "config": {
    "signature_documents_source": "session",
    "signature_signer": "verified_person",
    "signature_level": "aes",
    "signature_otp_channel": "email",
    "signature_link_validity_days": 14,
    "signature_declined_action": "REVIEW"
  }
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.