> ## 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.

# Configurations des workflows : référence de l'API

> Référence Didit des champs de configuration de POST et PATCH /v3/workflows/ pour les workflows linéaires avec le tableau features.

Utilisez ces champs `config` dans chaque élément du tableau `features` pour [`POST /v3/workflows/`](https://docs.didit.me/fr/management-api/workflows/create) et [`PATCH /v3/workflows/{settings_uuid}/`](https://docs.didit.me/fr/management-api/workflows/update).

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

L'API de workflows v3 construit un workflow linéaire basé sur des nœuds à partir du tableau ordonné `features`. Envoyez les fonctionnalités dans l'ordre exact d'exécution.

> [!NOTE]
>
> Le moteur qui exécute une fonctionnalité, celui de Didit ou celui d'un fournisseur tiers, ne fait pas partie des champs de configuration ci-dessous. Il est géré via la [Marketplace](https://docs.didit.me/fr/console/marketplace.md) de la console, qui définit automatiquement `provider_key` et `fallback_to_native` sur l'objet `config` de la fonctionnalité pour vous.

## Règles de validation

* `OCR` prend par défaut tous les pays et types de documents pris en charge lorsque `config.documents_allowed` est omis, égal à `null` ou à `{}`. Si vous envoyez un objet `documents_allowed` personnalisé, il doit contenir au moins un pays valide et un type de document activé. Chaque configuration de document peut définir `sides` à `1` pour une capture du recto uniquement, ou à `2` pour une capture recto et verso.
* `QUESTIONNAIRE` exige `config.questionnaire_uuid`.
* `KYB_DOCUMENTS` exige `config.kyb_required_document_groups`.
* `SIGNATURE` refuse `signature_level: "qes"` avec `qes_not_available` tant que les signatures qualifiées ne sont pas disponibles, et une nouvelle étape à `signature_level: "aes"` avec `aes_not_available` tant que `signature_availability.aes` vaut `false` sur le workflow. Ses documents doivent exister au moment de la création d'une session : avec `signature_documents_source` défini sur `workflow`, l'étape nécessite des documents téléversés dans la console, et une étape sans document peut rester en brouillon mais ne peut pas être mise en production ; avec `session`, chaque appel de création doit envoyer `sign.documents`.
* `FACE_MATCH` doit venir après `OCR` dans les requêtes de workflow simples.
* `NFC` et `DATABASE_VALIDATION` nécessitent `OCR` lorsqu'ils figurent dans le même workflow. `AML` nécessite l'un de `OCR`, `KYB_REGISTRY` ou `DOCUMENT_AI` en amont. Si seul `DOCUMENT_AI` le précède, le `full_name` à filtrer doit pouvoir être renseigné, soit à partir d'un champ Document AI en amont déjà défini sur `full_name`, qui est mappé automatiquement, soit à partir d'une entrée explicite `config.aml_field_sources` (voir [AML](#aml)).
* Les sous-fonctionnalités KYB, comme `KYB_DOCUMENTS` et `KYB_KEY_PEOPLE`, nécessitent `KYB_REGISTRY` plus haut dans le workflow.
* Un workflow est soit un workflow de personne (KYC), soit un workflow d'entreprise (KYB), jamais les deux. Un workflow qui utilise une fonctionnalité KYB (`KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`) ne peut combiner ces fonctionnalités qu'avec `AML`, `DOCUMENT_AI`, `QUESTIONNAIRE`, `PHONE_VERIFICATION`, `EMAIL_VERIFICATION`, `IP_ANALYSIS` et `SIGNATURE`. Il ne peut pas inclure de fonctionnalités réservées aux personnes, comme `OCR`, `LIVENESS`, `FACE_MATCH`, `NFC`, `PROOF_OF_ADDRESS`, `DATABASE_VALIDATION` ou `AGE_ESTIMATION`, et un workflow de personne ne peut pas inclure de fonctionnalités KYB. Sur un workflow d'entreprise, `DOCUMENT_AI` compare tout champ marqué `is_full_name` avec l'entreprise vérifiée, et non avec une personne. Pour vérifier les personnes derrière une entreprise, créez un workflow KYC distinct et référencez-le depuis le nœud `KYB_KEY_PEOPLE` à l'aide de `kyb_ubo_verification_workflow`, `kyb_officer_verification_workflow` ou `kyb_shareholder_verification_workflow`.
* Les champs d'action utilisent `DECLINE`, `REVIEW` ou `NO_ACTION`, sauf si le champ ci-dessous indique qu'il est restreint.
* Les champs de score et de seuil sont des nombres compris entre `0` et `100`, sauf si une plage plus étroite est indiquée.

## Règles de statut communes

Chaque fonctionnalité accepte un tableau `status_rules` facultatif. Utilisez-le pour remplacer le statut de la fonctionnalité lorsqu'une condition sur un champ est remplie.

```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"
    }
  ]
}
```

| Champ | Type | Description |
| - | - | - |
| `field` | string | Chemin du champ à vérifier, par exemple `kyc.issuing_state` ou `kyc.document_type`. |
| `operator` | string | L'un 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` ou `fuzzy_match`. |
| `value` | any | Valeur de comparaison. Omettez-la ou envoyez `null` pour les opérateurs qui n'en nécessitent pas. |
| `status` | string | L'un de `Approved`, `Declined`, `In Review` ou `No Action`. |
| `value_type` | string | Facultatif. `literal` par défaut. Utilisez `field` pour comparer à un autre champ, `list` pour résoudre un UUID de liste Didit à l'exécution, ou `relative_date` pour comparer un champ de date à aujourd'hui, plus ou moins une durée. |
| `score` | number | Obligatoire pour `fuzzy_match`. Score de similarité minimal, de `0` à `100`. La règle correspond lorsque la similarité calculée est supérieure ou égale à cette valeur (`similarity >= score`). Par exemple, `Software Engineer` peut correspondre à `Soft. Engineer` lorsque la similarité est d'au moins `80`. |

Lisez l'exemple ci-dessus ainsi : `kyc.extra_fields.profession` correspond de façon floue à `Soft. Engineer` avec un score minimal de `80` → définissez le statut de la fonctionnalité sur `Declined`.

Pour la Vérification d'identité, ciblez les valeurs extraites de `extra_fields`, comme `kyc.extra_fields.profession`, les dates de validité des catégories du permis de conduire, comme `kyc.extra_fields.dl_class_code_b_from` et `kyc.extra_fields.dl_class_code_b_to`, ou les codes de restriction ou d'information par catégorie comme `kyc.extra_fields.dl_class_code_b_notes` (colonne 12 des permis britanniques). Ces valeurs proviennent de l'objet `extra_fields` du résultat OCR ; elles ne font pas partie de `expected_details`.

> [!NOTE]
>
> `dl_class_code_*_from` et `dl_class_code_*_to` contiennent toujours soit une date ISO valide, soit aucune valeur dans `extra_fields`. Didit ne renvoie jamais de texte OCR illisible dans un champ de date. Si la cellule du tableau des catégories est illisible, le champ est omis au lieu d'être envoyé sous forme de chaîne brute. Utilisez donc l'opérateur `is_empty` pour orienter les dates de catégorie illisibles, plutôt que de supposer que le champ est toujours présent.

Pour les champs de date, utilisez `value_type: "relative_date"` avec un objet de valeur de la forme `{ "direction": "past" | "future", "amount": number, "unit": "days" | "months" | "years" }`. Par exemple, `operator: "less_than"` avec `{ "direction": "past", "amount": 3, "unit": "years" }` correspond aux dates antérieures à trois ans à compter d'aujourd'hui.

### Comparer avec une étape précise

Un workflow en graphe peut exécuter plusieurs fois la même fonctionnalité, par exemple trois étapes de Vérification d'identité.
Avec `value_type: "field"`, ajoutez `@<node_id>` à la valeur pour la lire depuis une étape précise.
Le nœud référencé doit être une étape de fonctionnalité qui s'exécute toujours avant l'étape propre à la règle, sur tous les chemins qui y mènent, ou l'étape propre à la règle elle-même.
Une valeur sans ce suffixe est lue depuis l'étape propre à la règle.

```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"
    }
  ]
}
```

Lisez cette règle, définie sur la troisième étape de Vérification d'identité, ainsi : le `kyc.full_name` de cette étape correspond de façon floue au nom complet lu par l'étape `ocr_1`, avec un score minimal de `80` → définissez le statut de la fonctionnalité sur `Declined`.
Dans la console, le sélecteur de variables liste chaque étape éligible par son numéro sur le canevas et enregistre le suffixe à votre place.

## Vérification d'identité (OCR)

Valeur de la fonctionnalité : `OCR`.

| Champ de configuration | Type | Description |
| - | - | - |
| `documents_allowed` | object | Facultatif. Omettez-le, envoyez `null` ou envoyez `{}` pour autoriser tous les pays et tous les types de documents pris en charge. Envoyez un code pays ISO3 dans la configuration du type de document uniquement si vous souhaitez restreindre les documents autorisés. Au moins un document personnalisé doit avoir `enabled: 1`. Les configurations de document peuvent inclure `sides: 1` pour une capture recto seul, ou `sides: 2` pour une capture recto et verso. Les types de documents comprennent `P`, `ID`, `DL`, `RP`, `HIC`, `TC`, `SSC` et d'autres valeurs prises en charge par pays. |
| `methods` | object | Les [méthodes de vérification d'identité](https://docs.didit.me/fr/core-technology/id-verification/verification-methods.md) que chaque pays peut utiliser parmi les trois : capture de document, recherche hors document auprès d'une source gouvernementale ou d'une autre source faisant autorité, et portefeuilles d'identité numérique. Si vous omettez la clé, un pays ou une méthode dans un pays, ce pays n'autorise que la capture de document. Chaque méthode et chaque portefeuille doit être marqué comme disponible pour le pays dans le catalogue des capacités, sinon l'enregistrement est refusé. Voir [Méthodes par pays](#méthodes-par-pays) ci-dessous. |
| `document_blur_fields_by_country` | object | Code pays ISO3 vers les noms de champs à flouter pour masquer des informations sur les images de documents. |
| `image_capture_methods_allowed` | string\[] | Méthodes de capture autorisées. Les valeurs incluent `CAMERA_SCAN` et `UPLOAD`. |
| `duplicated_user_action` | action | Action pour un utilisateur en double. |
| `is_age_restrictions_enabled` | boolean | Active les contrôles d'âge minimum et maximum. |
| `age_restrictions_by_country` | object | Code pays ISO3 vers une configuration d'âge comprenant `minimum_age`, `maximum_age` (facultatif) et `states` (facultatif). |
| `minimum_age` | integer | Âge minimum global, de `1` à `120`. |
| `minimum_age_action` | action | Action lorsque l'utilisateur est en dessous de `minimum_age`. |
| `maximum_age` | integer | Âge maximum global, de `1` à `120`. |
| `maximum_age_action` | action | Action lorsque l'utilisateur est au-dessus de `maximum_age`. |
| `expiration_date_not_detected_action` | action | Action lorsque la date d'expiration du document est absente. |
| `invalid_code_action` | action | Action lorsqu'un code-barres ou un code lisible par machine est invalide. |
| `invalid_mrz_action` | action | Action lorsque la MRZ est invalide. |
| `inconsistent_data_action` | action | Action lorsque les champs extraits du document sont en conflit. |
| `invalid_validation_action` | action | Action lorsque la validation du document échoue. |
| `expected_details_mismatch_action` | action | Action lorsque les informations attendues sur l'utilisateur ne correspondent pas au document. |
| `image_too_blurry_action` | action | Action pour les images de document floues. |
| `image_too_dark_action` | action | Action pour les images de document trop sombres. |
| `image_too_bright_action` | action | Action pour les images de document surexposées. |
| `unparsed_address_action` | action | Action lorsque l'adresse du document ne peut pas être analysée. |
| `address_validation_enabled` | boolean | Valide l'adresse lue à cette étape (imprimée sur le document d'identité) par rapport aux données de référence postales : elle confirme que l'adresse existe et la normalise, sans jamais la relier à une personne. Le résultat figure dans l'objet `address_validation` de l'étape, dans la décision. **Facturé \$0.10 par adresse validée** ; une validation qui n'a pas pu être exécutée (`unavailable`) est gratuite. Désactivé par défaut. |
| `address_not_verified_action` | action | Action lorsque la validation d'adresse n'a pas pu confirmer l'adresse au niveau du bâtiment (`ADDRESS_NOT_VERIFIED` : `partially_verified` ou `not_verified`). S'applique uniquement lorsque `address_validation_enabled` est activé. Par défaut : `NO_ACTION`, qui se contente d'enregistrer l'avertissement. |
| `document_or_personal_number_format_mismatch_action` | action | Action lorsque le format du numéro de document ou du numéro personnel ne correspond pas au modèle attendu. |
| `critical_field_occlusion_action` | action | Action lorsque le contrôle d'occultation signale qu'un champ imprimé critique (un numéro d'identité, un nom, la date de naissance ou la date d'expiration) a été physiquement couvert sur le document capturé. Couvrir un numéro d'identité est un signal de manipulation et non un signe de qualité de capture ; cette action vaut donc `REVIEW` par défaut. La valeur lue pour un champ couvert est de toute façon supprimée de l'extraction. Passez-la à `DECLINE` lorsqu'un document caviardé ne doit jamais parvenir à un réviseur. |
| `document_without_portrait_action` | action | Action lorsque le type de document reconnu ne comporte jamais de photo d'identité sur aucune face (certains titres de séjour, cartes de santé, certificats d'immatriculation et autres familles de documents sans portrait connues du catalogue). Par défaut : `REVIEW`. Envisagez `DECLINE` lorsque la Correspondance faciale sert de point d'ancrage à la vérification d'identité du workflow. |
| `is_document_selfie_portrait_match_enabled` | boolean | Active la comparaison entre le portrait du document et le selfie. |
| `document_selfie_portrait_match_decline_threshold` | integer | Seuil de refus pour la comparaison entre le portrait du document et le selfie. |
| `document_selfie_portrait_match_review_threshold` | integer | Seuil d'examen pour la comparaison entre le portrait du document et le selfie. |
| `document_selfie_face_search_enabled` | boolean | Lance la [Recherche faciale 1:N](https://docs.didit.me/fr/core-technology/face-search/overview.md#le-selfie-pris-pendant-la-capture-du-document) sur le selfie pris pendant la capture du document (nécessite `is_document_selfie_portrait_match_enabled`) : il est comparé à la liste de blocage des visages et aux utilisateurs déjà vérifiés. Le selfie est uniquement comparé, son gabarit n'est jamais stocké. Activé par défaut. `false` ignore la recherche et ne laisse aucune action de doublon de visage du selfie du document à appliquer. `face_search_enabled: false` sur l'étape de détection du vivant l'ignore également, car cette désactivation couvre chaque selfie de la session. |
| `document_selfie_duplicated_face_action` | action | Verdict lorsque le selfie de la capture du document correspond, ou correspond peut-être, au visage d'un utilisateur déjà vérifié dans cette application. Par défaut : `NO_ACTION`. |
| `document_selfie_duplicated_face_name_mismatch_action` | action | Verdict lorsque le selfie de la capture du document correspond à un utilisateur déjà vérifié sous un nom différent. Peut uniquement aggraver `document_selfie_duplicated_face_action`. Par défaut : `REVIEW`. |
| `document_selfie_duplicated_face_document_mismatch_action` | action | Verdict lorsque le selfie de la capture du document correspond à un utilisateur déjà vérifié dont la date de naissance sur le document d'identité est différente. La même personne avec un document différent ou renouvelé n'est pas signalée. Peut uniquement aggraver `document_selfie_duplicated_face_action`. Par défaut : `REVIEW`. |
| `id_verification_name_match_score_threshold` | integer | Seuil de correspondance des noms entre plusieurs vérifications d'identité. |
| `id_verification_max_retry_attempts` | integer | Limite de nouvelles tentatives pour la vérification d'identité, de `2` à `5`. |
| `id_document_quality_threshold` | integer | Score minimal de qualité de capture (de `0` à `100`) qu'une image de document doit atteindre pour être acceptée. Le contrôle de qualité s'exécute toujours ; seul ce seuil est configurable. Par défaut, il est fixé à `20`, réglé de sorte que les captures dégradées ou limites (flou, mouvement, texte illisible) soient rejetées tandis que les documents lisibles passent ; augmentez-le pour des exigences de capture plus strictes. La console présente cette valeur sur un curseur perceptuel où la valeur par défaut de `20` s'affiche comme une position équilibrée à 50 %. |
| `cross_org_fraud_document_action` | action | Verdict lorsque ce document a été signalé comme frauduleux par une autre organisation du réseau. |
| `document_audio_recording_enabled` | boolean | Enregistrer le microphone pendant la capture du document, afin qu'un réviseur puisse écouter la session. Désactivé par défaut. |
| `document_liveness_portrait_replace_decline_threshold` | integer | Score de remplacement du portrait (de `0` à `100`, plus il est élevé, plus l'authenticité est probable) en dessous duquel la session est refusée. Par défaut, `35`. Voir [seuils de détection du vivant du document](https://docs.didit.me/fr/core-technology/id-verification/warnings-id-verification.md#configuration-des-seuils-de-détection-du-vivant-du-document). |
| `document_liveness_portrait_replace_review_threshold` | integer | Score de remplacement du portrait en dessous duquel la session passe en cours d'examen, lorsqu'elle n'est pas déjà refusée. À `100`, presque toutes les sessions sont retenues. Par défaut, `70`. Voir [seuils de détection du vivant du document](https://docs.didit.me/fr/core-technology/id-verification/warnings-id-verification.md#configuration-des-seuils-de-détection-du-vivant-du-document). |
| `document_liveness_printed_copy_decline_threshold` | integer | Score de copie imprimée (de `0` à `100`, plus il est élevé, plus l'authenticité est probable) en dessous duquel la session est refusée. Par défaut, `35`. Voir [seuils de détection du vivant du document](https://docs.didit.me/fr/core-technology/id-verification/warnings-id-verification.md#configuration-des-seuils-de-détection-du-vivant-du-document). |
| `document_liveness_printed_copy_review_threshold` | integer | Score de copie imprimée en dessous duquel la session passe en cours d'examen, lorsqu'elle n'est pas déjà refusée. À `100`, presque toutes les sessions sont retenues. Par défaut, `77`. Voir [seuils de détection du vivant du document](https://docs.didit.me/fr/core-technology/id-verification/warnings-id-verification.md#configuration-des-seuils-de-détection-du-vivant-du-document). |
| `document_liveness_screen_replay_decline_threshold` | integer | Score de capture d'écran (de `0` à `100`, plus il est élevé, plus l'authenticité est probable) en dessous duquel la session est refusée. Par défaut, `30`. Voir [seuils de détection du vivant du document](https://docs.didit.me/fr/core-technology/id-verification/warnings-id-verification.md#configuration-des-seuils-de-détection-du-vivant-du-document). |
| `document_liveness_screen_replay_review_threshold` | integer | Score de capture d'écran en dessous duquel la session passe en cours d'examen, lorsqu'elle n'est pas déjà refusée. À `100`, presque toutes les sessions sont retenues. Par défaut, `70`. Voir [seuils de détection du vivant du document](https://docs.didit.me/fr/core-technology/id-verification/warnings-id-verification.md#configuration-des-seuils-de-détection-du-vivant-du-document). |
| `id_verification_injection_attack_action` | action | Verdict lorsque le document, ou le selfie pris pour une recherche d'identité, a été injecté plutôt que capturé par la caméra intégrée de l'appareil (`INJECTION_ATTACK_DETECTED`) : une caméra virtuelle logicielle, un flux de caméra généré par la page ou par l'automatisation du navigateur, une caméra interceptée, ou un outil d'instrumentation attaché à l'application. Valeurs : `DECLINE`, `REVIEW`, `NO_ACTION`. Par défaut, `DECLINE`. Les signaux qu'une personne authentique peut produire ne déclenchent jamais ce verdict. Pour la détection du vivant et la correspondance faciale, c'est plutôt `frame_injection_action` qui détermine le risque. |
| `image_quality_too_low_action` | action | Verdict lorsque la qualité globale de l'image du document est inférieure au seuil requis. |
| `is_image_capture_review_screen_enabled` | boolean | Afficher à l'utilisateur un écran de révision après chaque capture de document, lui permettant de reprendre la photo avant son envoi. Désactivé par défaut. |
| `is_ocr_id_verification_data_review_enabled` | boolean | Permettre à l'utilisateur de vérifier et de corriger les données d'identité extraites avant la fin de l'étape. Désactivé par défaut. Une correction est comparée à `ocr_id_verification_data_review_critical_fields`, et une divergence déclenche l'action critique ou l'action mineure selon le cas. La révision s'exécute aussi lorsque le workflow inclut la NFC : une lecture ultérieure de la puce remplace simplement cette révision. |
| `ocr_id_verification_data_review_critical_fields` | string\[] | Champs d'identité extraits considérés comme critiques lorsque l'utilisateur modifie le résultat OCR, afin qu'une divergence déclenche l'action critique plutôt que l'action mineure. Forme : `["first_name" \| "last_name" \| "date_of_birth" \| ...]`. |
| `ocr_id_verification_data_review_critical_mismatch_action` | restricted action | Verdict lorsque la modification de l'utilisateur diverge de l'OCR sur un champ critique. |
| `ocr_id_verification_data_review_minor_mismatch_action` | action | Verdict lorsque la modification de l'utilisateur diverge de l'OCR sur un champ non critique. |
| `status_rules` | array | Règles de statut personnalisées facultatives. |

> [!NOTE]
>
> La détection du vivant du document se configure avec les six seuils `document_liveness_*` ci-dessus, et non avec des champs d'action par signal. `portrait_replacement_action`, `printed_copy_action` et `screen_capture_action` sont des paramètres au niveau du compte et ne sont **pas** acceptés dans la configuration d'un workflow : l'API supprime les clés de configuration inconnues à l'enregistrement, donc les y envoyer n'a aucun effet. Chaque signal dispose d'un seuil de refus et d'un seuil de révision sur une échelle de `0`-`100`, où un score plus élevé indique une plus grande probabilité d'authenticité.

Exemple :

```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éthodes par pays

`methods` est indexé par le code pays [ISO 3166-1 alpha-3](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3). Chaque pays accepte jusqu'à trois objets de méthode ; tout ce que vous omettez prend sa valeur par défaut.

```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" }
      }
    }
  }
}
```

`wallet.on_failure` vaut `fallback_to_document`, `decline` ou `retry`. `retry` (portefeuille uniquement, capture de document désactivée pour le pays) permet à un utilisateur dont la connexion n'a pas abouti à l'étape du portefeuille de réessayer ; la session n'est jamais refusée à ce titre et reste ouverte jusqu'à ce qu'il termine ou qu'elle expire. Les commutateurs id\_lookup n'acceptent que `fallback_to_document` ou `decline`.

Pour écarter les documents du premier écran et ne les proposer que lorsqu'un portefeuille ou une recherche n'aboutit pas, définissez `document.fallback_only`. L'exemple utilise la Finlande, où le Finnish Trust Network passe en premier et où la capture de document sert de solution de repli. La Finlande exige aussi que ses types de documents soient activés dans `documents_allowed` (par exemple passeport et carte d'identité) afin que la solution de repli ait des documents à proposer.

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

Les deux recherches ci-dessus sont `available` dans le catalogue actuel, donc cette configuration s'enregistre telle quelle. Le bloc portefeuille est volontairement omis de cet exemple : un portefeuille ne s'enregistre que dans un pays où le catalogue le marque `available`, et `wallet.enabled: true` ailleurs est rejeté, ce qui fait échouer l'enregistrement complet, configuration des recherches comprise. Lorsque le catalogue marque un portefeuille comme `available`, ajoutez-le à ce pays :

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

| Clé | Type | Valeur par défaut | Description |
| - | - | - | - |
| `<ISO3>.document.enabled` | booléen | `true` | Indique si un document photographié est accepté dans ce pays. La liste des documents acceptés reste définie dans `documents_allowed`. |
| `<ISO3>.document.fallback_only` | booléen | `false` | Garder la capture de document activée sans la proposer sur le premier écran. Les utilisateurs commencent par le portefeuille ou la consultation d'identité du pays, et seuls ceux dont la connexion au portefeuille échoue, est annulée ou expire, ou dont la consultation ne correspond pas (selon les commutateurs `on_failure`, `on_partial_match`, `on_no_match` et `on_provider_error` réglés sur `fallback_to_document`) sont redirigés vers la capture de document. Avec un seul portefeuille, l'utilisateur arrive directement sur celui-ci. Sans portefeuille unique, un portefeuille ou une consultation est affiché côte à côte avec la capture de document. Rejeté avec le code HTTP 400, sauf si `document.enabled` vaut `true` et qu'au moins un portefeuille ou une consultation d'identité du pays bascule vers la capture de document. |
| `<ISO3>.id_lookup.enabled` | booléen | `false` | Proposer la consultation sans document auprès de la source officielle du pays ou de toute autre source faisant autorité. Rejeté lorsque le catalogue n'indique pas la source du pays comme `available`. |
| `<ISO3>.id_lookup.max_attempts` | entier | `1` | `1` à `5`. Nombre de consultations **répondues** dont dispose l'utilisateur avant que le commutateur de repli ne se déclenche. Une valeur qui échoue à la vérification de format côté client n'atteint jamais le registre : elle n'est ni comptée ni facturée. |
| `<ISO3>.id_lookup.skip_liveness_and_face_match` | booléen | `true` | Après une correspondance avec un registre qui renvoie un portrait, ignorer les étapes Détection du vivant et Correspondance faciale du workflow : la consultation a déjà exécuté la détection passive du vivant sur le selfie et l'a comparé à ce portrait. Normalisé à `false` à l'enregistrement pour une source qui ne renvoie aucun portrait, car le commutateur n'aurait alors aucun effet. |
| `<ISO3>.id_lookup.on_partial_match` | `fallback_to_document` \| `decline` | `fallback_to_document` | Ce qui se passe lorsque le registre a répondu mais que certains champs ne correspondent pas. |
| `<ISO3>.id_lookup.on_no_match` | `fallback_to_document` \| `decline` | `fallback_to_document` | Ce qui se passe lorsque le registre a répondu et ne contient aucun enregistrement correspondant. |
| `<ISO3>.id_lookup.on_provider_error` | `fallback_to_document` \| `decline` | `fallback_to_document` | Ce qui se passe lorsque le registre n'a pas pu être joint. Jamais facturé. |
| `<ISO3>.id_lookup.response_fields` | string\[] \| null | `null` | Sous-ensemble facultatif des clés des champs de réponse de la source. Les clés inconnues sont rejetées et les champs obligatoires de la source sont toujours réintégrés, de sorte que la valeur enregistrée reste toujours une sélection valide. La mise en œuvre actuelle en préproduction applique cette sélection aux résultats de comparaison, au genre facultatif et aux portraits de registre conservés. Les champs d'identité obligatoires restent présents. Voir la note sur le déploiement et la conservation ci-dessous. |
| `<ISO3>.wallet.enabled` | booléen | `false` | Proposer la connexion par portefeuille d'identité numérique dans ce pays. |
| `<ISO3>.wallet.providers` | string\[] | `[]` | Identifiants de portefeuille du catalogue acceptés dans ce pays : une liste d'acceptation, jamais un classement. L'ordre envoyé est normalisé selon l'ordre du catalogue. Au moins un portefeuille est requis lorsque `enabled` vaut `true`. Un portefeuille non proposé dans le pays, ou encore annoncé comme « bientôt disponible », est rejeté. |
| `<ISO3>.wallet.on_failure` | `fallback_to_document` \| `decline` \| `retry` | `fallback_to_document` | Ce qui se passe lorsque la connexion est annulée, expire ou échoue. `retry` maintient l'utilisateur à l'étape du portefeuille pour qu'il réessaie (portefeuille uniquement) ; cette valeur est refusée en même temps que `document.fallback_only`. |

Règles de validation appliquées par l'API à l'enregistrement :

* Un code pays inconnu, une clé inconnue dans un pays ou une clé inconnue dans une méthode est rejeté : aucune donnée n'est ignorée silencieusement.
* Un pays où aucune méthode n'est activée est rejeté : personne dans ce pays ne pourrait vérifier son identité.
* Un portefeuille ou une consultation ne peut basculer vers la capture de document que si celle-ci est activée pour ce pays. `fallback_to_document` dans un pays où `document.enabled` vaut `false` entraîne un refus à l'exécution, car il n'existe aucune capture de document vers laquelle basculer.
* `document.fallback_only: true` est rejeté avec le code HTTP 400, sauf si `document.enabled` vaut `true` et qu'au moins un portefeuille ou une consultation d'identité de ce pays bascule vers la capture de document.

> [!WARNING]
>
> Le déploiement actuel en préproduction applique `id_lookup.response_fields` aux résultats de comparaison, au genre facultatif et aux portraits de registre conservés. Les champs d'identité obligatoires restent intégrés à l'enregistrement de vérification. Il ne s'agit pas d'une garantie que chaque charge utile intermédiaire du fournisseur est exclue du traitement. Le déploiement en production de cette modification n'a pas été vérifié : confirmez le comportement dans votre environnement cible avant de vous appuyer sur la sélection des champs pour répondre à des exigences de conservation.

Consultez le catalogue des capacités avant de rédiger `methods`, dans l'onglet **Pays** de la console ou avec l'outil MCP [`didit_workflow_get_id_verification_methods_catalog`](https://docs.didit.me/fr/integration/mcp/tools). Le comportement, la couverture et la facturation sont décrits dans [Méthodes de vérification d'identité](https://docs.didit.me/fr/core-technology/id-verification/verification-methods.md).

## NFC / ePassport

Valeur de la fonctionnalité : `NFC`.

| Champ de configuration | Type | Description |
| - | - | - |
| `allow_nfc_skip` | booléen | Autorise les utilisateurs à ignorer la lecture NFC lorsque leur document prend en charge la lecture de la puce. |
| `skip_nfc_action` | action | Action lorsque l'utilisateur ignore la lecture NFC. |
| `unverified_chip_action` | action | Action lorsque la vérification de la puce échoue. |
| `trust_anchor_missing_action` | action | Verdict lorsque les empreintes des groupes de données de la puce sont intactes, mais que la chaîne de certificats ne peut pas être vérifiée, parce que l'ancre de confiance CSCA du pays de délivrance n'est pas chargée. |
| `jpki_request_attributes` | booléen | Carte My Number du Japon ([JPKI](https://docs.didit.me/fr/core-technology/nfc-verification/overview.md#carte-my-number-japonaise-jpki), uniquement avec les SDK natifs) : lit également le certificat de signature, qui nécessite le code PIN de signature de la carte et contient le nom, la date de naissance, le sexe et l'adresse du titulaire, comparés aux données de la vérification d'identité. Par défaut `true`. `false` ne lit que le certificat d'authentification de l'utilisateur (code PIN à 4 chiffres), qui prouve la carte et le code PIN, mais ne contient aucune donnée sur le titulaire. |
| `jpki_certificate_invalid_action` | action | Verdict lorsqu'un certificat de la carte My Number n'est pas rattaché par une chaîne de certificats à l'autorité de certification JPKI, est hors de sa période de validité, ou n'est pas un certificat de carte du type demandé (`JPKI_CERTIFICATE_INVALID`). Par défaut `DECLINE`. |
| `jpki_signature_invalid_action` | action | Verdict lorsque la signature de la carte My Number sur le challenge à usage unique ne peut pas être vérifiée, de sorte que la possession de la carte et la connaissance de son code PIN ne sont pas prouvées (`JPKI_SIGNATURE_INVALID`). Par défaut `DECLINE`. |
| `jpki_certificate_revoked_action` | action | Verdict lorsque la vérification de révocation indique qu'un certificat de la carte My Number est révoqué (`JPKI_CERTIFICATE_REVOKED`). Par défaut `DECLINE`. |
| `jpki_revocation_unchecked_action` | action | Verdict lorsque la carte My Number a été vérifiée, mais qu'aucune réponse sur la révocation n'était disponible, de sorte qu'une carte révoquée ne peut pas être écartée (`JPKI_REVOCATION_UNCHECKED`). Par défaut `REVIEW`. |
| `jpki_inconsistent_data_action` | action | Verdict lorsque le nom, la date de naissance, le sexe ou l'adresse dans le certificat de signature de la carte My Number diffèrent des données de vérification d'identité de cette même carte (`JPKI_AND_OCR_DATA_NOT_SAME`). Par défaut `REVIEW`. |
| `status_rules` | tableau | Règles de statut personnalisées facultatives. |

## Détection du vivant

Valeur de fonctionnalité : `LIVENESS`.

| Champ de configuration | Type | Description |
| - | - | - |
| `face_liveness_method` | string | L'une des valeurs suivantes : `ACTIVE_3D`, `FLASHING` ou `PASSIVE`. |
| `face_liveness_mode` | string | Remplacement du mode de détection du vivant. |
| `face_liveness_flash_mode` | string | Mode flash pour les méthodes `ACTIVE_3D` et `FLASHING`. `"0"` (non strict, par défaut) vérifie que les couleurs projetées à l'écran se reflètent sur le visage de l'utilisateur ; `"1"` (strict) exige en plus que les reflets correspondent exactement à la séquence de couleurs projetée. Ce mode est plus robuste contre les attaques par rejeu et par injection de vidéo, mais il entraîne davantage de faux rejets. |
| `face_liveness_score_decline_threshold` | integer | Seuil de refus. |
| `face_liveness_score_review_threshold` | integer | Seuil d'examen. |
| `face_liveness_possible_duplicated_face_action` | action | Action lorsque le visage peut être dupliqué. |
| `face_liveness_multiple_faces_action` | action | Action lorsque plusieurs visages sont détectés. |
| `face_liveness_video_anomaly_action` | action | Action lorsque l'enregistrement stocké contient une séquence de mouvements répétée. Valeur par défaut : `NO_ACTION` ; `REVIEW` et `DECLINE` peuvent faire évoluer de façon asynchrone une vérification déjà décidée. Des images fixes éparses ou répétées ne suffisent pas à la déclencher. |
| `face_liveness_attack_face_match_action` | action | Action lorsque le visage capturé lors de la détection du vivant correspond à un visage issu d'une session antérieure de cette application, appartenant à un autre utilisateur dont la capture a été jugée comme une attaque par présentation avec un haut niveau de confiance (avertissement `FACE_MATCHES_LIVENESS_ATTACK`). Accepte `NO_ACTION` ou `REVIEW` ; `DECLINE` est accepté mais appliqué comme `REVIEW`, car un utilisateur légitime peut être refusé une fois par erreur, puis réussir. Valeur par défaut : `NO_ACTION`. |
| `race_map_similarity_thresholds` | object | Seuils de similarité par groupe démographique. |
| `face_privacy_mode_enabled` | boolean | Active le mode confidentialité pour les données faciales. |
| `face_quality_review_threshold` | integer | Seuil d'examen pour la qualité de l'image du visage. |
| `face_quality_decline_threshold` | integer | Seuil de refus pour la qualité de l'image du visage. Doit être inférieur ou égal au seuil d'examen. |
| `face_luminance_min_threshold` | integer | Seuil minimal de luminance. Doit être inférieur à `face_luminance_max_threshold`. |
| `face_luminance_min_action` | action | Action lorsque la luminance est trop faible. |
| `face_luminance_max_threshold` | integer | Seuil maximal de luminance. |
| `face_luminance_max_action` | action | Action lorsque la luminance est trop élevée. |
| `face_liveness_max_attempts` | integer | Nombre total de soumissions de détection du vivant par session, de `1` à `3`. La valeur par défaut `3` correspond à une tentative initiale et deux nouvelles tentatives. Définir `1` ne désactive pas les nouvelles tentatives en cas d'échec lié à la qualité de capture : lorsque tous les avertissements de la tentative sont liés à l'environnement (`LOW_FACE_LUMINANCE`, `HIGH_FACE_LUMINANCE`, `LOW_FACE_QUALITY`, `HIGH_FACE_OCCLUSION`, `NO_FACE_DETECTED`), l'utilisateur obtient toujours une seconde tentative, accompagnée d'indications concrètes. |
| `cross_org_fraud_face_action` | action | **Déprécié et n'est plus appliqué.** Cette option traitait un visage comme s'il portait un verdict de fraude, ce qu'une identité biométrique stable ne peut pas porter. Toujours acceptée afin que les workflows existants continuent de valider. Utilisez `cross_org_identity_claim_pattern_action`. |
| `cross_org_identity_claim_pattern_action` | action | Décision lorsque d'autres organisations du réseau ont enregistré des événements de déclaration d'identité concernant cette même personne, pour lesquels l'identité déclarée ne correspondait pas. Examen ou Aucune action uniquement ; un Refus défini ici est rétrogradé en Examen. Voir [Déclarations d'identité inter-organisations](https://docs.didit.me/fr/core-technology/liveness/cross-organization-identity-claims.md). |
| `external_capture_device_action` | action | Décision lorsqu'un périphérique de capture externe est détecté. |
| `face_audio_recording_enabled` | boolean | Enregistre le microphone pendant la capture du selfie, afin qu'un réviseur puisse écouter la session. Désactivé par défaut. |
| `face_search_enabled` | boolean | Lance la [Recherche faciale 1:N](https://docs.didit.me/fr/core-technology/face-search/overview.md#désactiver-la-recherche-faciale-automatique) automatique sur le selfie : celui-ci est comparé aux utilisateurs déjà vérifiés, à la liste de blocage et à la liste d'autorisation des visages, et son gabarit biométrique est stocké pour les comparaisons ultérieures. Activé par défaut. `false` ignore la recherche, ne conserve aucun gabarit facial pour cette étape et laisse les actions liées aux visages dupliqués sans rien à traiter. |
| `face_liveness_uncertain_retry_enabled` | boolean | Détection du vivant active du SDK natif uniquement. Lorsqu'elle est activée, une capture dont le score de détection du vivant se situe strictement entre `face_liveness_score_decline_threshold` et `face_liveness_score_review_threshold` ne fait jamais l'objet d'une décision, quelle que soit la décision attribuée par le moteur : la personne est informée que le résultat n'était pas concluant et invitée à capturer à nouveau, à chaque fois, en dehors du quota `face_liveness_max_attempts` (qui s'applique toujours aux captures que le moteur n'a pas pu évaluer). Désactivé par défaut ; le parcours web l'ignore. |
| `face_liveness_duplicated_face_name_mismatch_action` | action | Décision lorsqu'un visage en double est trouvé sous un nom différent. |
| `face_liveness_duplicated_face_document_mismatch_action` | action | Décision lorsqu'un visage en double est trouvé et que le document d'identité de l'utilisateur correspondant indique une date de naissance différente. La même personne présentant un document différent ou renouvelé n'est pas signalée. Valeur par défaut : `REVIEW`. |
| `frame_injection_action` | action | Décision lorsque des images vidéo injectées sont détectées. |
| `screen_capture_action` | action | Décision lorsque le selfie est une photo d'un écran. |
| `virtual_camera_action` | action | Décision lorsqu'un flux de caméra virtuelle est détecté. |
| `status_rules` | array | Règles de statut personnalisées, facultatives. |

## Correspondance faciale

Valeur de fonctionnalité : `FACE_MATCH`.

| Champ de configuration | Type | Description |
| - | - | - |
| `face_match_score_decline_threshold` | entier | Seuil de refus. |
| `face_match_score_review_threshold` | entier | Seuil d'examen. |
| `face_match_max_attempts` | entier | Nombre total de soumissions de correspondance faciale par session, de `1` à `3`. La valeur par défaut `3` correspond à une tentative initiale suivie de deux nouvelles tentatives. |
| `face_match_not_computed_action` | action restreinte | Décision lorsqu'aucun score de correspondance n'a pu être calculé (portrait ou selfie manquant). |
| `face_match_eyes_covered_action` | action | Décision lorsque la zone des yeux est couverte sur le selfie. La valeur par défaut est `NO_ACTION`, qui enregistre la preuve sans modifier le résultat de la correspondance faciale. Ce signal est encore en cours de calibrage : il reste en mode observation tant que la zone n'est pas signalée comme calibrée. Si vous définissez dès maintenant `REVIEW` ou `DECLINE`, il prend effet à partir de ce moment-là. |
| `face_match_mouth_covered_action` | action | Décision lorsque la zone de la bouche est couverte sur le selfie. Même valeur par défaut `NO_ACTION` et même mise en garde sur le calibrage que pour `face_match_eyes_covered_action`. |
| `face_match_face_covered_action` | action | Décision lorsque le visage dans son ensemble est couvert sur le selfie. Même valeur par défaut `NO_ACTION` et même mise en garde sur le calibrage que pour `face_match_eyes_covered_action`. |
| `status_rules` | tableau | Règles de statut personnalisées facultatives. |

## Estimation de l'âge

Valeur de la fonctionnalité : `AGE_ESTIMATION`.

| Champ de configuration | Type | Description |
| - | - | - |
| `enable_id_verification_fallback` | booléen | Lance la Vérification d'identité lorsque l'estimation de l'âge tombe dans la plage limite. |
| `minimum_age_threshold` | entier | Âge minimum accepté, de `1` à `100`. |
| `borderline_minimum_age_threshold` | entier | Borne inférieure de la plage limite, de `1` à `100`. |
| `borderline_maximum_age_threshold` | entier | Borne supérieure de la plage limite, de `1` à `100`. |
| `face_liveness_method` | chaîne | Une des valeurs suivantes : `ACTIVE_3D`, `FLASHING` ou `PASSIVE`. |
| `face_liveness_flash_mode` | chaîne | Mode de flash pour les méthodes `ACTIVE_3D` et `FLASHING`. `"0"` (non strict, valeur par défaut) vérifie que les couleurs projetées à l'écran se reflètent sur le visage de l'utilisateur ; `"1"` (strict) exige en plus que les reflets correspondent exactement à la séquence de couleurs projetée. |
| `face_liveness_score_decline_threshold` | nombre | Seuil de refus de la détection du vivant utilisée pour l'estimation de l'âge. |
| `face_liveness_score_review_threshold` | nombre | Seuil d'examen de la détection du vivant utilisée pour l'estimation de l'âge. |
| `face_liveness_possible_duplicated_face_action` | action | Action lorsque le visage peut être dupliqué. |
| `face_liveness_multiple_faces_action` | action | Action lorsque plusieurs visages sont détectés. |
| `face_liveness_video_anomaly_action` | action | Action lorsque l'enregistrement conservé contient une séquence de mouvements répétée. Valeur par défaut `NO_ACTION` ; `REVIEW` et `DECLINE` peuvent faire évoluer une vérification déjà décidée de manière asynchrone. Des images fixes clairsemées ou répétées ne déclenchent pas cette action à elles seules. |
| `face_liveness_attack_face_match_action` | action | Action lorsque le visage de la détection du vivant correspond à un visage issu d'une session antérieure de cette application, appartenant à un autre utilisateur dont la capture a été jugée comme une attaque par présentation avec un niveau de confiance élevé (avertissement `FACE_MATCHES_LIVENESS_ATTACK`). Accepte `NO_ACTION` ou `REVIEW` ; `DECLINE` est accepté mais appliqué comme `REVIEW`, car un utilisateur légitime peut être refusé une fois par erreur, puis réussir. Valeur par défaut `NO_ACTION`. |
| `face_privacy_mode_enabled` | booléen | Active le mode de confidentialité pour les éléments faciaux. |
| `face_quality_review_threshold` | entier | Seuil d'examen de la qualité du visage. |
| `face_quality_decline_threshold` | entier | Seuil de refus de la qualité du visage. |
| `face_luminance_min_threshold` | entier | Seuil minimal de luminosité. |
| `face_luminance_min_action` | action | Action lorsque la luminosité est trop faible. |
| `face_luminance_max_threshold` | entier | Seuil maximal de luminosité. |
| `face_luminance_max_action` | action | Action lorsque la luminosité est trop forte. |
| `face_liveness_max_attempts` | entier | Nombre total de soumissions de la détection du vivant par session, de `1` à `3`. La valeur `3` par défaut correspond à une tentative initiale et deux nouvelles tentatives. Définir `1` ne désactive pas les nouvelles tentatives en cas d'échec lié à la qualité de capture : lorsque tous les avertissements de la tentative sont liés à l'environnement (`LOW_FACE_LUMINANCE`, `HIGH_FACE_LUMINANCE`, `LOW_FACE_QUALITY`, `HIGH_FACE_OCCLUSION`, `NO_FACE_DETECTED`), l'utilisateur obtient toujours une seconde tentative accompagnée de conseils exploitables. |
| `external_capture_device_action` | action | Décision lorsqu'un périphérique de capture externe est détecté. |
| `face_audio_recording_enabled` | booléen | Enregistre le microphone pendant la capture du selfie, afin qu'un réviseur puisse écouter la session. Désactivé par défaut. |
| `face_search_enabled` | booléen | Lance la [Recherche faciale 1:N](https://docs.didit.me/fr/core-technology/face-search/overview.md#désactiver-la-recherche-faciale-automatique) automatique sur le selfie : compare celui-ci aux utilisateurs précédemment vérifiés, à la liste de blocage et à la liste d'autorisation de visages, et conserve son gabarit biométrique pour les comparaisons ultérieures. Activé par défaut. `false` ignore la recherche, ne conserve aucun gabarit facial pour cette étape et laisse les actions liées aux visages dupliqués sans rien à traiter. |
| `face_liveness_uncertain_retry_enabled` | booléen | Uniquement pour la détection du vivant active du SDK natif. Lorsqu'il est activé, une capture dont le score de détection du vivant se situe strictement entre `face_liveness_score_decline_threshold` et `face_liveness_score_review_threshold` n'est jamais décidée, quelle que soit la décision attribuée par le moteur : la personne est informée que le résultat n'était pas clair et invitée à capturer à nouveau, à chaque fois, en dehors du budget `face_liveness_max_attempts` (qui s'applique toujours aux captures que le moteur n'a pas pu évaluer). Désactivé par défaut ; le parcours web l'ignore. |
| `face_liveness_duplicated_face_name_mismatch_action` | action | Décision lorsqu'un visage dupliqué est trouvé sous un nom différent. |
| `face_liveness_duplicated_face_document_mismatch_action` | action | Décision lorsqu'un visage dupliqué est trouvé et que le document d'identité de l'utilisateur correspondant indique une date de naissance différente. Une même personne présentant un document différent ou renouvelé n'est pas signalée. Valeur par défaut `REVIEW`. |
| `frame_injection_action` | action | Décision lorsque des images vidéo injectées sont détectées. |
| `screen_capture_action` | action | Décision lorsque le selfie est une photo d'un écran. |
| `virtual_camera_action` | action | Décision lorsqu'un flux de caméra virtuelle est détecté. |
| `status_rules` | tableau | Règles de statut personnalisées facultatives. |

## Vérification du téléphone

Valeur de fonctionnalité : `PHONE_VERIFICATION`.

| Champ de configuration | Type | Description |
| - | - | - |
| `code_size` | entier | Taille du code à usage unique, de `4` à `8`. |
| `phone_max_retries` | entier | Nombre maximal de nouvelles tentatives d'envoi, de `1` à `5`. |
| `phone_max_check_attempts` | entier | Nombre maximal de tentatives de vérification du code à usage unique, de `1` à `5`. |
| `phone_verification_countries` | objet | Associe un code pays ISO2 à une configuration de canal. Exemple : `{ "US": { "sms": { "enabled": true } } }`. |
| `disposable_number_action` | action | Action pour les numéros jetables. |
| `voip_number_action` | action | Action pour les numéros VoIP. |
| `duplicated_phone_number_action` | action | Action pour les numéros de téléphone en double. |
| `high_risk_phone_action` | action | Action lorsque le fournisseur de livraison bloque l'envoi du code à usage unique. Seules les valeurs `DECLINE` ou `REVIEW` sont acceptées ; valeur par défaut `DECLINE`. Appliquée uniquement lorsque chaque blocage de l'étape porte des `risk_factors` valant exactement `["device_attribute"]`. Tout autre facteur de risque, tout mélange incluant celui-ci, ou l'absence de facteur de risque entraîne un refus, quel que soit ce paramètre. |
| `phone_shared_device_mode` | booléen | Autorise le mode de vérification du téléphone sur un appareil partagé. |
| `phone_enrichment_enabled` | booléen | Active l'enrichissement des informations sur le téléphone (risque lié au type de ligne, indice de confiance, opérateur, historique de portabilité et de changement de SIM, score de risque de fraude). **Facturé \$0.05 par vérification** en plus du prix de la vérification du téléphone. |
| `phone_intelligence_score_action` | action | Action lorsque le score de risque de fraude du téléphone est supérieur ou égal à `phone_intelligence_score_threshold`. |
| `phone_intelligence_score_threshold` | entier | Score de risque de fraude (`0`–`100`, plus il est élevé, plus le risque est grand) qui déclenche `phone_intelligence_score_action`. Valeur par défaut `80`. |
| `phone_type_risk_action` | action | Action lorsque le numéro est signalé comme un type de téléphone à haut risque. |
| `recent_port_action` | action | Action lorsque le numéro a été porté récemment (signal de portabilité ou de changement de SIM). |
| `low_phone_trust_action` | action | Action lorsque l'indice de confiance du téléphone est inférieur ou égal à `phone_trust_index_threshold`. |
| `phone_trust_index_threshold` | entier | Indice de confiance (`0`–`100`, plus il est bas, plus le risque est grand) auquel `low_phone_trust_action` s'applique lorsqu'il est inférieur ou égal à ce seuil. Valeur par défaut `30`. |
| `phone_social_enabled` | booléen | Active la vérification de l'empreinte sociale : sur quelles plateformes de messagerie, réseaux sociaux, sites de commerce en ligne et plateformes professionnelles le numéro vérifié est enregistré. **Facturé \$0.05 par vérification** en plus du prix de la vérification du téléphone, indépendamment de `phone_enrichment_enabled`. |
| `phone_no_social_presence_action` | action | Action lorsque la vérification de l'empreinte sociale constate que le numéro n'est enregistré sur aucune des plateformes couvertes - un signal courant d'identité synthétique. Valeur par défaut `NO_ACTION`. |
| `cross_org_fraud_phone_action` | action | Verdict lorsque ce numéro a été signalé comme frauduleux par une autre organisation du réseau. |
| `status_rules` | tableau | Règles de statut personnalisées, facultatives. |

La vérification du téléphone est désactivée tant que l'organisation n'a pas effectué sa première recharge.

> [!NOTE]
>
> L'enrichissement des informations sur le téléphone est une option facultative. Lorsque `phone_enrichment_enabled` vaut `true`, chaque vérification du téléphone terminée est enrichie d'informations sur le téléphone et **facturée \$0.05 par requête** en plus du coût standard de la vérification du téléphone. Les actions basées sur le score ne prennent effet qu'une fois le score d'enrichissement disponible ; les actions liées à l'indice de confiance, au type de téléphone et à la portabilité s'appliquent dès que l'enrichissement est exécuté.
>
> La vérification de l'empreinte sociale est une deuxième option, distincte de la première. Lorsque `phone_social_enabled` vaut `true`, chaque vérification du téléphone terminée indique également sur quelles plateformes en ligne le numéro est enregistré - messagerie, réseaux sociaux, plateformes de commerce en ligne et plateformes professionnelles - et est **facturée \$0.05 par requête**. Elle peut être activée avec ou sans `phone_enrichment_enabled` : les deux options sont tarifées et facturées indépendamment. Une recherche qui ne trouve le numéro sur aucune des plateformes couvertes constitue une réponse valide et facturable, et déclenche `phone_no_social_presence_action`. Utilisez `phone.social_profiles_registered` (le nombre de plateformes sur lesquelles le numéro est enregistré) pour orienter le parcours dans un graphe de workflow selon ce résultat.

## Vérification de l'e-mail

Valeur de fonctionnalité : `EMAIL_VERIFICATION`.

| Champ de configuration | Type | Description |
| - | - | - |
| `email_code_size` | entier | Taille du code OTP, de `4` à `8`. |
| `email_max_retries` | entier | Nombre maximal de nouvelles tentatives d'envoi, de `1` à `5`. |
| `email_max_check_attempts` | entier | Nombre maximal de tentatives de vérification du code OTP, de `1` à `5`. |
| `email_alphanumeric_code` | booléen | Utilise des codes e-mail alphanumériques. |
| `breached_email_action` | action | Action pour les e-mails compromis. |
| `disposable_email_action` | action | Action pour les e-mails jetables. |
| `duplicated_email_action` | action | Action pour les e-mails en double. |
| `only_corporate_emails_allowed` | booléen | Rejette les adresses e-mail non professionnelles. |
| `email_enrichment_enabled` | booléen | Active l'enrichissement par des données de renseignement sur les e-mails (délivrabilité, réputation du domaine, exposition aux fuites de données, score de risque de fraude). **Facturé \$0.05 par vérification** en plus du prix de la vérification e-mail. |
| `email_intelligence_score_action` | action | Action lorsque le score de risque de fraude de l'e-mail est supérieur ou égal à `email_intelligence_score_threshold`. |
| `email_intelligence_score_threshold` | entier | Score de risque de fraude (`0`–`100`, plus le score est élevé, plus le risque est élevé) qui déclenche `email_intelligence_score_action`. Valeur par défaut : `80`. |
| `recent_email_breach_action` | action | Action lorsque l'e-mail apparaît dans une fuite de données connue et récente. |
| `frequent_email_breach_action` | action | Action lorsque l'e-mail apparaît dans de nombreuses fuites de données connues. |
| `email_social_enabled` | booléen | Active la vérification de l'empreinte sociale : les plateformes d'e-mail, réseaux sociaux, plateformes professionnelles, de commerce en ligne et de divertissement sur lesquelles l'adresse vérifiée est enregistrée. **Facturé \$0.05 par vérification** en plus du prix de la vérification e-mail, indépendamment de `email_enrichment_enabled`. |
| `email_no_social_presence_action` | action | Action lorsque la vérification de l'empreinte sociale constate que l'adresse n'est enregistrée sur aucune des plateformes couvertes, un signal courant d'identité synthétique. Valeur par défaut : `NO_ACTION`. |
| `cross_org_fraud_email_action` | action | Verdict lorsque cette adresse a été signalée comme frauduleuse par une autre organisation du réseau. |
| `status_rules` | tableau | Règles de statut personnalisées facultatives. |

> [!NOTE]
>
> L'enrichissement par des données de renseignement sur les e-mails est un module complémentaire facultatif. Lorsque `email_enrichment_enabled` a pour valeur `true`, chaque vérification e-mail terminée est enrichie par des données de renseignement sur les e-mails et **facturée \$0.05 par requête** en plus du coût standard de la vérification e-mail. L'action basée sur le score prend effet dès que le score d'enrichissement est disponible ; les actions liées aux fuites de données s'appliquent dès que l'enrichissement est exécuté.
>
> La vérification de l'empreinte sociale est un second module complémentaire, distinct du premier. Lorsque `email_social_enabled` a pour valeur `true`, chaque vérification e-mail terminée indique aussi sur quelles plateformes en ligne l'adresse est enregistrée (fournisseurs d'e-mail, réseaux sociaux, services professionnels, de commerce en ligne et de divertissement) et est **facturée \$0.05 par requête**. Elle peut être activée avec ou sans `email_enrichment_enabled` : les deux modules complémentaires sont tarifés et facturés indépendamment. Une recherche qui trouve l'adresse sur aucune des plateformes couvertes constitue une réponse valide et facturable, et déclenche `email_no_social_presence_action`. Utilisez `email.social_profiles_registered` (le nombre de plateformes sur lesquelles l'adresse est enregistrée) pour créer une branche selon ce résultat dans un graphe de workflow.

## Validation en base de données

Valeur de la fonctionnalité : `DATABASE_VALIDATION`.

| Champ de configuration | Type | Description |
| - | - | - |
| `database_validation_countries` | objet | Code de pays ISO3 associé à `{ "services": ["service_id"] }`. Utilisez les identifiants de service du catalogue de validation en base de données. |
| `database_validation_partial_match_action` | action | Action à effectuer lorsque la validation en base de données renvoie une correspondance partielle. |
| `database_validation_no_match_action` | action | Action à effectuer lorsque la validation en base de données ne renvoie aucune correspondance. |
| `database_validation_not_applicable_action` | action | Action à effectuer lorsque la validation en base de données ne peut pas être exécutée, parce que le document ne contient pas l'identifiant requis par les services configurés (par exemple, un passeport sans numéro d'identification national). Par défaut, `NO_ACTION`. |
| `database_validation_field_sources` | objet | Source d'une entrée de base de données qu'aucune étape précédente du graphe ne peut renseigner. `source` désigne le producteur et `key` désigne la valeur à l'intérieur de celui-ci : une clé de champ Document AI pour `document_ai`, un identifiant de nœud de questionnaire pour `questionnaire`, et `expected_details.<field>` ou `metadata.<key>` pour `expected_data`. Les correspondances exactes de clé avec une étape en amont sont résolues automatiquement et ne sont volontairement pas enregistrées. Ainsi, renommer un champ Document AI n'enregistre jamais un mappage obsolète dans la configuration. Une entrée mal formée est rejetée avec un `400` qui nomme son champ d'entrée. Forme : `{"<db_validation_input_field>": {"source": "document_ai"\|"questionnaire"\|"expected_data", "key": "<docai field key>\|<questionnaire node id>\|expected_details.<field>\|metadata.<key>"}}`. |
| `status_rules` | tableau | Règles de statut personnalisées, facultatives. |

Exemple :

```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` est ce qui permet à cette étape de fonctionner réellement. Une fonctionnalité `DATABASE_VALIDATION`
> enregistrée sans ce champ est acceptée, puis n'exécute aucune vérification. Envoyez donc toujours au moins un pays
> avec au moins un identifiant de service.

Un identifiant de service que l'étape ne peut pas exécuter est rejeté avec un `400` qui le nomme et indique la raison, et rien n'est enregistré.
Cela couvre un identifiant absent du catalogue, un identifiant qui appartient à un autre pays, un service pas encore disponible, et un service proposé uniquement via le [`POST /v3/database-validation/`](https://docs.didit.me/fr/core-technology/database-validation/overview) autonome.
Un service dont les entrées ne sont fournies par aucune étape précédente est rejeté de la même manière, avec la liste des entrées manquantes.
Un service que le workflow enregistré contient déjà, mais ne peut plus exécuter, est supprimé lorsque vous enregistrez à nouveau le workflow.

Par exemple, ce workflow argentin lit le numéro de DNI et le genre depuis la Vérification d'identité, puis les compare à RENAPER sans selfie :

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

Utilisez plutôt `arg_renaper`, après une étape `LIVENESS`, pour comparer aussi le selfie à la photo détenue par RENAPER.
Voir [RENAPER](https://docs.didit.me/fr/api-reference/database-validation/argentina/renaper.md) pour son score de correspondance faciale et son seuil.

## Vérification bancaire

Valeur de la fonctionnalité : `BANK_VERIFICATION`.

L'utilisateur vérifie un compte bancaire, et le titulaire communiqué par la banque est comparé à l'identité établie par une étape précédente du workflow. Il le fait selon l'une de deux méthodes : la connexion à sa banque (`open_banking`), où il se connecte auprès de sa banque, ou la vérification du compte (`account_lookup`), où il saisit les coordonnées du compte et la banque confirme le nom qui y est associé. `bank_method_order` et le `methods` de chaque pays déterminent les méthodes proposées dans un pays et celle qui apparaît en premier ; voir [Méthodes de vérification bancaire](https://docs.didit.me/fr/core-technology/bank-verification/verification-methods.md). L'étape produit des éléments de preuve (un score de correspondance du nom du titulaire, la comparaison qui l'a produit, les codes de motif), et les clés `bank_*_action` transforment ces éléments en statut.

Deux éléments déterminent si le nœud fait quoi que ce soit. `bank_countries` est une liste blanche : un objet vide ne propose aucune banque et n'exécute aucune vérification. Par ailleurs, le titulaire doit pouvoir être comparé à quelque chose : placez devant ce nœud une étape `OCR`, `DATABASE_VALIDATION` ou `QUESTIONNAIRE`, envoyez `expected_details` à la création de la session, ou associez vous-même les champs avec `bank_field_sources`. Sans aucun de ces éléments, la titularité ne peut être que `unknown`, ce que décide `bank_reference_identity_missing_action`.

> [!NOTE]
>
> La vérification bancaire est encore en cours de déploiement : un nœud `BANK_VERIFICATION` n'est accepté que sur un compte où elle a été activée. Partout ailleurs, l'enregistrement est rejeté et le message l'indique. La route qui exécute l'étape n'est pas non plus configurée ici : elle est définie par la paire `provider_key` et `fallback_to_native` que la [Marketplace](https://docs.didit.me/fr/console/marketplace.md) de la console renseigne pour vous.

### Connecter un compte

| Champ de configuration | Type | Description |
| - | - | - |
| `bank_countries` | object | Les pays dans lesquels un utilisateur peut connecter une banque. Liste blanche : un objet vide signifie que le nœud ne propose rien et n'exécute rien. `institutions` restreint le sélecteur à des identifiants d'établissements précis, `"all"` propose chaque banque du pays capable de vérifier l'identité. Un pays qu'aucune route du nœud ne dessert est conservé : il ne propose que ses solutions de repli et « Continuer sans votre banque », voir [Quand la personne ne peut pas vérifier sa banque](https://docs.didit.me/fr/core-technology/bank-verification/fallbacks.md). Un code qui ne désigne aucun pays est refusé à l'enregistrement. `methods` définit, dans l'ordre, les méthodes que le pays propose parmi la connexion bancaire (`open_banking`) et la vérification du compte (`account_lookup`), en remplacement de `bank_method_order` : l'utilisateur commence par la première et se voit proposer la seconde comme solution de secours. Un pays activé dont `methods` nomme une méthode qu'aucune route du nœud ne dessert là-bas est refusé à l'enregistrement, de même qu'un pays desservi par une route mais pour lequel `methods` ne laisse aucune méthode. Forme : `{"<ISO3>": {"enabled": true\|false, "institutions": ["<institution_id>", ...]\|"all", "methods"?: ["open_banking"\|"account_lookup", ...]}}`. |
| `bank_method_order` | string\[] | Laquelle des deux méthodes l'étape propose, et dans quel ordre, dans chaque pays qui ne définit pas ses propres `methods` : `open_banking` (connexion bancaire : l'utilisateur se connecte auprès de sa banque, et seule cette méthode lit les soldes, les transactions et les revenus) et `account_lookup` (vérification du compte : pas de connexion, titularité uniquement). Dans chaque pays, l'utilisateur commence par la première méthode qu'une route dessert dans ce pays et se voit proposer l'autre comme solution de secours ; une méthode qu'aucune route ne prend en charge dans un pays en est exclue. Au moins une méthode. Un enregistrement qui n'en envoie aucune reçoit `["open_banking", "account_lookup"]`, sauf s'il envoie `bank_open_banking_enabled` ou `bank_account_lookup_enabled`, qui la définissent alors. |
| `bank_scopes` | object | Ce à quoi l'utilisateur est invité à consentir en matière de partage. `ownership` est ce que le produit vérifie et ne peut pas être désactivé. `identifiers` démasque l'IBAN ou le numéro de compte ; `balances`, `transactions` et `income` lisent de véritables données financières, sont chacun facturés séparément, et sont refusés à l'enregistrement sauf si votre application dispose de l'autorisation relative aux données financières. Seule la connexion bancaire lit des données : un pays qui propose la vérification du compte n'est pas refusé, et un utilisateur qui vérifie par ce moyen passe sans ces données, que le résultat liste dans `financial_data.not_collected`. Un périmètre désactivé n'est jamais demandé, si bien que la banque ne l'affiche jamais sur son écran de consentement. Par défaut, `ownership` seul. Forme : `{"ownership": true, "identifiers": true\|false, "balances": true\|false, "transactions": true\|false, "income": true\|false}`. |
| `bank_eligible_account_types` | string\[] | Les types de comptes que l'utilisateur peut choisir : `checking`, `current`, `savings`, `business` ou `other`. Les cartes de crédit, les prêts et les comptes d'investissement ne sont jamais éligibles : ils n'établissent pas la titularité d'un compte de paiement. Par défaut, les comptes courants et les comptes chèques. |
| `bank_account_selection` | string | `user` permet à l'utilisateur de choisir lequel des comptes connectés est vérifié ; `auto` prend le premier compte éligible. |
| `bank_require_oauth_only` | boolean | Ne proposer que les établissements accessibles par OAuth ou d'application à application, jamais un écran obsolète de saisie d'identifiants. Dans les marchés où les services bancaires ouverts font déjà d'OAuth le seul mode d'accès, cela ne change rien. |
| `bank_max_attempts` | integer | Le nombre de tentatives de connexion bancaire accordées à l'utilisateur, de `1` à `5` ; un micro-dépôt ou un envoi de relevé en consomme aussi une. La vérification du compte a son propre `bank_account_check_max_attempts`. Une fois que toutes les méthodes encore proposées pour vérifier l'utilisateur, y compris l'envoi d'un relevé, ont épuisé leurs tentatives sans connexion réussie, `bank_attempts_exhausted_action` décide. |
| `bank_connection_timeout_minutes` | integer | Durée pendant laquelle une connexion commencée reste ouverte avant que la tentative soit abandonnée, de `5` à `60` minutes. |
| `bank_allow_skip` | boolean | Remplacé par `bank_continue_without_bank` : l'utilisateur peut désormais toujours continuer sans banque. Lu pendant une seule version lorsqu'un enregistrement n'envoie pas `bank_continue_without_bank` : `true` définit `from_start`, toute autre valeur `when_needed`. Chaque enregistrement le réécrit : `true` pour `from_start`, `false` pour `when_needed`. |

### Quand l'utilisateur ne peut pas vérifier

L'utilisateur peut toujours continuer sans banque, et l'étape ne le bloque jamais. Voir [Quand la personne ne peut pas vérifier sa banque](https://docs.didit.me/fr/core-technology/bank-verification/fallbacks.md).

| Champ de configuration | Type | Description |
| - | - | - |
| `bank_continue_without_bank` | string | Lorsque l'étape affiche **Continue without your bank**. `when_needed`, la valeur par défaut, l'affiche une fois qu'aucune méthode ne fonctionne pour le pays ou la banque de l'utilisateur, lorsque sa banque est injoignable et qu'aucune autre méthode n'a pu le vérifier, par exemple parce que la vérification du compte n'a pas pu non plus joindre la banque, ou lorsqu'il déclare ne pas avoir de banque en ligne. `from_start` l'affiche aussi sur le premier écran. Elle ne peut pas être désactivée. Un enregistrement qui n'envoie ni cette clé ni `bank_allow_skip` reçoit `when_needed`. |
| `bank_statement_standalone_enabled` | boolean | Avec `bank_statement_enabled`, proposer aussi le téléversement de relevé lorsqu'aucune tentative bancaire n'a eu lieu, dans tous les pays, y compris ceux qu'aucune connexion bancaire ni aucune vérification de compte ne couvre. Il est alors facturé séparément, sous le nom `bank_statement_upload`, à USD 0.20 par relevé évalué, avant votre tarif contractuel ou votre prix spécial : voir [Tarifs](https://docs.didit.me/fr/core-technology/bank-verification/fallbacks.md#tarifs). Les sessions sandbox peuvent le tester sans facturation. Activé par défaut. |

Ce que la poursuite implique pour la session est défini par `bank_unsupported_action`, `bank_attempts_exhausted_action` ou `bank_skipped_action`, selon la raison pour laquelle l'utilisateur a continué, sauf si une tentative évaluée auparavant a déjà décidé de l'étape : voir [Actions de décision](#actions-de-verdict).

### Comparaison du titulaire

| Champ de configuration | Type | Description |
| - | - | - |
| `bank_reference_identity` | string | Étape précédente qui fournit l'identité à laquelle le titulaire est comparé : `kyc` (Vérification d'identité), `database_validation`, `expected_details` (ce que vous avez envoyé à la création de la session), `questionnaire`, ou `auto` pour utiliser celle que le workflow a produite. L'étape qui l'a effectivement fournie est renvoyée dans le résultat sous `reference_identity_source`. |
| `bank_field_sources` | object | Emplacement où lire un champ d'identité de référence lorsqu'aucune étape précédente du graphe ne peut le renseigner. La clé de l'objet est l'une de `full_name`, `first_name`, `last_name`, `address` ; `source` désigne le producteur et `key` désigne la valeur qu'il contient : une clé de champ Document AI pour `document_ai`, un identifiant de nœud de questionnaire pour `questionnaire`, et `expected_details.<field>` ou `metadata.<key>` pour `expected_data`. Une valeur sous `expected_details.` ne peut désigner qu'un champ que la charge utile de création de session transmet réellement : `address`, `country`, `date_of_birth`, `first_name`, `gender`, `id_country`, `identification_number`, `ip_address`, `last_name`, `nationality` ou `poa_country`. Une entrée mal formée est refusée à l'enregistrement, et non ignorée. Format : `{"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 | À ce score ou au-dessus, le nom du titulaire constitue une correspondance. `50` à `100`, par défaut `85`. |
| `bank_partial_match_floor` | integer | En dessous de ce score, le nom ne correspond pas. `0` à `99`, par défaut `70`. La zone située entre le plancher et le seuil correspond à la correspondance partielle. Le plancher doit donc être strictement inférieur au seuil, faute de quoi l'enregistrement est refusé. Une valeur `null` explicite signifie ici « utiliser la valeur par défaut ». C'est pourquoi un seuil de `50` sans plancher est refusé : il est contrôlé comme `50` par rapport au plancher par défaut de `70`. |
| `bank_require_address_match` | boolean | Exige aussi que l'adresse du titulaire corresponde. Un nom ayant atteint le seuil mais dont l'adresse obtient un score inférieur à celui-ci devient une correspondance partielle. Une institution qui ne renvoie aucune adresse est dispensée de cette exigence. Une session qui n'a pas sa propre adresse à comparer n'en dispense pas et aboutit à une correspondance partielle. Désactivé par défaut. |
| `bank_use_provider_score` | boolean | Lit aussi le score de correspondance du nom établi par l'institution elle-même, et le laisse décider lorsqu'il est supérieur à celui de Didit ou lorsque Didit n'avait aucun nom de titulaire à comparer. Un résultat décidé de cette façon indique `provider_only` comme méthode de correspondance, et une connexion qui n'a renvoyé aucun score de ce type enregistre un avertissement `provider_score_unavailable`. Activé par défaut. |
| `bank_show_match_result_to_user` | boolean | Affiche à l'utilisateur le résultat de titularité dans le parcours de vérification. Lorsque cette option est désactivée, le résultat est enregistré sur la session mais ne lui est jamais montré. |

### Vérification du compte

Ces clés ne s'appliquent qu'à la vérification du compte. La connexion bancaire conserve ses propres correspondances proches et son propre `bank_max_attempts`.

| Champ de configuration | Type | Description |
| - | - | - |
| `bank_account_check_accept_close_match` | boolean | Lorsqu'il est activé (par défaut), un nom que la banque évalue entre `bank_partial_match_floor` et `bank_name_match_threshold` est une correspondance proche : l'utilisateur confirme le nom que détient la banque lorsque `bank_suggest_holder_name` est activé, et `bank_partial_match_action` décide. Désactivé, cette correspondance proche devient une absence de correspondance (`OWNER_NAME_MISMATCH`, décidée par `bank_no_match_action`) et consomme la tentative. |
| `bank_account_check_max_attempts` | integer | Nombre de vérifications de compte dont dispose l'utilisateur, de `1` à `5`, `3` si non défini : nombre de fois où il peut saisir les coordonnées du compte pour une vérification à laquelle la banque répond. Compteur distinct de `bank_max_attempts`. Une vérification refusée telle que saisie (un IBAN invalide) ou à laquelle la banque n'a pu répondre ne consomme aucune tentative. |

### Données financières

`bank_expected_currencies` fonctionne avec le seul consentement `ownership` par défaut. Les trois autres clés lisent de véritables données financières : chacune nécessite le périmètre de consentement correspondant dans `bank_scopes`, faute de quoi l'enregistrement est refusé.

| Champ de configuration | Type | Description |
| - | - | - |
| `bank_expected_currencies` | string\[] | Devises ISO 4217 dans lesquelles le compte est censé être libellé. Vide signifie n'importe laquelle ; un écart est signalé via `bank_currency_mismatch_action`. |
| `bank_min_balance` | number | Solde disponible minimal, dans la devise propre du compte. En dessous, `bank_low_balance_action` se déclenche. Nécessite le périmètre `balances`. `0` est un seuil réel, et non équivalent à omettre la clé : un compte à découvert déclenche l'action. Cette action vaut `NO_ACTION` par défaut, ce qui laisse la décision inchangée. Pour rejeter un compte à découvert, il faut donc aussi définir `bank_low_balance_action: "DECLINE"`. |
| `bank_transactions_history_days` | entier | Nombre de jours d'historique des transactions à lire, de `30` à `365` jours. Valeur par défaut : `90`. Nécessite le scope `transactions`. |
| `bank_refresh_enabled` | booléen | Récupérer à nouveau les données financières du compte une fois l'étape déjà décidée, tant que le consentement bancaire est valide. Nécessite au moins un des scopes `balances`, `transactions` ou `income`. Un consentement qui expire ensuite relève de `bank_consent_expired_action`. |

### Ce qui est stocké

| Champ de configuration | Type | Description |
| - | - | - |
| `bank_store_full_identifiers` | booléen | Stocker les identifiants du compte sans masquage plutôt que masqués. Nécessite le scope `identifiers`. Même dans ce cas, la forme non masquée n'est renvoyée qu'à un appelant disposant de l'autorisation de lecture de la vérification bancaire. |
| `bank_store_raw_owner_data` | booléen | Conserver les informations du titulaire renvoyées par l'établissement à côté des preuves d'actionnariat. Lorsqu'elle est désactivée, seule la comparaison elle-même est conservée : scores, méthode de correspondance et codes de motif. |

### Actions de verdict

Chaque clé ici prend `DECLINE`, `REVIEW` ou `NO_ACTION`, sauf si elle est marquée comme restreinte, et revient à la valeur par défaut ci-dessous lorsque vous l'omettez ou envoyez `null`. Rien qui ne constitue pas une preuve positive de propriété n'est approuvé par défaut, et seule une preuve démontrable contre l'utilisateur entraîne un refus.

| Champ de configuration | Type | Description |
| - | - | - |
| `bank_no_match_action` | action restreinte | Verdict lorsque le titulaire du compte n'est manifestement pas la personne vérifiée : le meilleur score de nom est inférieur à `bank_partial_match_floor`. Utilisez `DECLINE` ou `REVIEW`. Valeur par défaut : `DECLINE`. |
| `bank_partial_match_action` | action | Verdict lorsque le nom du titulaire se situe entre `bank_partial_match_floor` et `bank_name_match_threshold`. Valeur par défaut : `REVIEW`, et n'approuve jamais par défaut. |
| `bank_not_verifiable_action` | action | Verdict lorsque l'établissement a été connecté mais n'a renvoyé aucune identité de titulaire à comparer. Valeur par défaut : `REVIEW`. |
| `bank_unknown_action` | action | Verdict lorsque les preuves n'ont pas pu être récupérées après les nouvelles tentatives, en cas d'échec temporaire. Valeur par défaut : `REVIEW`. |
| `bank_reference_identity_missing_action` | action | Verdict lorsqu'aucune étape précédente n'a produit d'identité à laquelle comparer le titulaire, de sorte que l'actionnariat ne peut être que `unknown`. Valeur par défaut : `REVIEW`. |
| `bank_joint_account_action` | action | Verdict lorsque le compte a plusieurs titulaires. Valeur par défaut : `NO_ACTION`. |
| `bank_business_account_action` | action | Verdict lorsque l'établissement qualifie le titulaire d'entreprise et non de personne. Valeur par défaut : `REVIEW` sur un workflow de vérification de personne, et `NO_ACTION` sur un workflow de vérification d'entreprise (KYB), où la session doit trouver une entreprise comme titulaire. |
| `bank_unsupported_action` | action | Verdict lorsque l'utilisateur poursuit sans banque parce qu'aucune méthode ne peut vérifier son pays ou sa banque : aucune route de connexion bancaire ni de contrôle de compte ne dessert le pays, ou la banque choisie ne peut pas être utilisée à cette étape. Le résultat a alors `continued_without_bank` à vrai et `NOT_COVERED` dans ses codes de motif. Valeur par défaut : `REVIEW`. |
| `bank_skipped_action` | action restreinte | Verdict lorsque l'utilisateur a choisi « Continuer sans votre banque » alors qu'un moyen de vérification était disponible. Le résultat a alors `continued_without_bank` à vrai et `SKIPPED` dans ses codes de motif. Utilisez `DECLINE` ou `REVIEW`. Valeur par défaut : `REVIEW`. |
| `bank_attempts_exhausted_action` | action restreinte | Verdict lorsque l'utilisateur a épuisé les tentatives de chaque moyen de vérification encore proposé, y compris le téléversement d'un relevé (`bank_max_attempts`, et `bank_account_check_max_attempts` lorsque le pays propose le contrôle de compte), sans connexion réussie, y compris lorsqu'il poursuit ensuite sans banque. Utilisez `DECLINE` ou `REVIEW`. Valeur par défaut : `DECLINE`. |
| `bank_consent_expired_action` | action | Verdict lorsque le consentement bancaire expire après que l'étape a déjà été décidée. N'a de sens qu'avec `bank_refresh_enabled`. Valeur par défaut : `NO_ACTION`. |
| `bank_currency_mismatch_action` | action | Verdict lorsque la devise du compte ne figure pas dans `bank_expected_currencies`. Valeur par défaut : `NO_ACTION`. |
| `bank_country_mismatch_action` | action | Verdict lorsque le pays de l'établissement diffère du pays attendu ou de celui du document. Valeur par défaut : `NO_ACTION`. |
| `bank_low_balance_action` | action | Verdict lorsque le solde disponible est inférieur à `bank_min_balance`. Nécessite le scope `balances`. Valeur par défaut : `NO_ACTION`. |
| `status_rules` | tableau | Règles de statut personnalisées, facultatives. |

### Autres contrôles

Ces clés sont facultatives. Chaque clé d'action prend `DECLINE`, `REVIEW` ou `NO_ACTION`.

| Champ de configuration | Type | Description |
| - | - | - |
| `bank_abandoned_action` | action | Verdict lorsque l'étape se termine sans correspondance, la personne ayant quitté le parcours de sa banque sans jamais revenir (une tentative a expiré). |
| `bank_account_age_action` | action | Verdict lorsque le compte est plus récent que `bank_account_age_days`, un schéma courant de comptes mules. |
| `bank_account_age_days` | entier | Un compte dont l'historique commence il y a moins de ce nombre de jours est considéré comme récent, de 1 à 365, valeur par défaut : 30. Lu depuis l'historique des transactions, donc uniquement avec le scope `transactions`. |
| `bank_account_lookup_enabled` | booléen | Obsolète : utilisez `bank_method_order` et `bank_countries.<ISO3>.methods`. Lu pendant une version seulement à partir d'un enregistrement qui n'envoie pas de `bank_method_order` : avec `bank_open_banking_enabled`, il définit l'ordre, le contrôle de compte après la connexion bancaire lorsqu'il est activé, omis lorsqu'il est désactivé ou non défini. Chaque sauvegarde le réécrit en indiquant si un pays propose le contrôle de compte. |
| `bank_account_type_action` | action | Verdict lorsque le compte vérifié est un compte d'épargne. |
| `bank_address_match_threshold` | entier | À partir de ce score, l'adresse du titulaire correspond, de 50 à 100, valeur par défaut : 70. Lu uniquement avec `bank_require_address_match`. |
| `bank_address_mismatch_action` | action | Verdict lorsque l'adresse du titulaire diffère, ce qui transforme une correspondance en correspondance approchante. Uniquement avec `bank_require_address_match`. |
| `bank_auto_add_countries` | booléen | Proposer chaque pays desservi par une route de ce nœud, y compris les pays ajoutés après l'enregistrement du nœud, à l'exception des pays que `bank_countries` désactive. Désactivé lorsque la clé est absente, afin qu'un nœud existant ne s'élargisse jamais de lui-même. |
| `bank_cash_flow_action` | action | Verdict lorsque de l'argent entre puis ressort aussitôt, ou lorsque de nombreux petits virements entrent (flux de fonds de transit). Nécessite la portée `transactions`. |
| `bank_dob_match_enabled` | booléen | Comparer la date de naissance du titulaire, lorsque la banque en communique une, avec celle vérifiée. Une non-correspondance ne modifie jamais le résultat de vérification de titularité : elle déclenche `bank_dob_mismatch_action`. Activé par défaut. |
| `bank_dob_match_threshold` | entier | À partir de ce score, la date de naissance correspond, de 50 à 100, 70 par défaut. Une date correspond au même jour ou non ; le score est donc de 100 ou de 0. |
| `bank_dob_mismatch_action` | action | Verdict lorsque la date de naissance du titulaire diffère. Uniquement avec `bank_dob_match_enabled`. |
| `bank_email_match_enabled` | booléen | Comparer l'e-mail enregistré auprès de la banque avec l'e-mail vérifié de la session. Une non-correspondance déclenche `bank_email_mismatch_action`. Désactivé par défaut. |
| `bank_email_match_threshold` | entier | À partir de ce score, l'e-mail correspond, de 50 à 100, 70 par défaut. |
| `bank_email_mismatch_action` | action | Verdict lorsque l'e-mail du titulaire diffère. Uniquement avec `bank_email_match_enabled`. |
| `bank_evidence_retention_days` | entier | Supprimer les preuves bancaires ce nombre de jours après le verdict : 30, 90, 365 ou 1825. Null les conserve avec la session. Supprimées : les informations du titulaire, l'identité à laquelle elles ont été comparées, les identifiants de compte, les données financières et un relevé téléversé ; une connexion encore active est révoquée. Le verdict, les scores et les codes de motif sont conservés. La suppression de la session supprime tout, selon l'événement qui survient en premier. |
| `bank_fallback_used_action` | action | Verdict lorsque le compte a été vérifié par micro-dépôts ou par téléversement d'un relevé. |
| `bank_match_any_holder` | booléen | Un compte joint ou détenu en commun correspond lorsque N'IMPORTE QUEL titulaire listé correspond à la personne. Désactivé : seul le premier titulaire listé par la banque peut correspondre. Activé par défaut. |
| `bank_microdeposits_enabled` | booléen | Proposer les micro-dépôts en solution de repli : deux petits dépôts parviennent sur le compte et la personne saisit les montants. Proposés uniquement dans un pays dont la route peut les envoyer, après une tentative de vérification bancaire facturée dans la même session. Inclus sans frais supplémentaire ; le client paie le prix de la route une seule fois. Les sessions sandbox peuvent le tester sans facturation. Le titulaire est le nom vérifié dans la session, que la personne déclare être celui du compte ; un compte vérifié enregistre donc un avertissement `holder_declared`. Activé par défaut. |
| `bank_mule_score_action` | action | Verdict lorsque le score mule est égal ou supérieur à `bank_mule_score_threshold`. |
| `bank_mule_score_threshold` | entier | À partir de ce score mule, de 0 à 100, `bank_mule_score_action` se déclenche ; 70 par défaut. Le score combine un nouveau compte, un flux de fonds de transit, un solde vidé et de nombreux petits virements entrants, lus dans l'historique des transactions (la portée `transactions`). |
| `bank_open_banking_enabled` | booléen | Obsolète : utilisez `bank_method_order` et `bank_countries.<ISO3>.methods`. Lu pendant une seule version à partir d'un enregistrement qui n'envoie pas de `bank_method_order` : avec `bank_account_lookup_enabled`, il définit l'ordre, la connexion bancaire lorsqu'elle est activée ou non définie. Chaque enregistrement le réécrit selon qu'au moins un pays propose la connexion bancaire. |
| `bank_phone_match_enabled` | booléen | Comparer le téléphone enregistré auprès de la banque avec le téléphone vérifié de la session. Une non-correspondance déclenche `bank_phone_mismatch_action`. Désactivé par défaut. |
| `bank_phone_match_threshold` | entier | À partir de ce score, le téléphone correspond, de 50 à 100, 70 par défaut. |
| `bank_phone_mismatch_action` | action | Verdict lorsque le téléphone du titulaire diffère. Uniquement avec `bank_phone_match_enabled`. |
| `bank_popular_mode` | chaîne | `auto` (par défaut) classe les banques populaires selon celles auxquelles les habitants du pays se connectent le plus ; `manual` affiche à la place les `popular_institutions` de chaque pays issus de `bank_countries`, dans leur ordre. |
| `bank_statement_document_checks_action` | action | Verdict lorsqu'un relevé téléversé présente des indices de modification ou de falsification. Par défaut `REVIEW`. |
| `bank_statement_enabled` | booléen | Proposer le téléversement d'un relevé bancaire en solution de repli : un relevé datant des 3 derniers mois, vérifié pour détecter toute falsification, dont le nom du titulaire est comparé de la même manière que celui fourni par une banque. Inclus sans frais supplémentaire après une tentative de vérification bancaire facturée dans la même session. Avec `bank_statement_standalone_enabled`, il est aussi proposé sans tentative bancaire préalable, dans n'importe quel pays, et facturé séparément. Les sessions sandbox peuvent le tester sans facturation. Désactivé par défaut. |
| `bank_suggest_holder_name` | booléen | En cas de correspondance proche, afficher à la personne le nom sous lequel la banque détient le compte et lui demander de confirmer que ce nom est le sien ou de connecter un autre compte. Sa réponse est enregistrée comme `holder_confirmation` ; la confirmation met fin à l'étape sur `bank_partial_match_action`. Activé par défaut. |
| `fallback_to_native` | booléen | Indique si une connexion à une place de marché qui ne peut être établie bascule sur la route native de Didit. Désactivé par défaut : un basculement silencieux consommerait votre solde Didit pour une session que vous attendiez sur votre propre contrat fournisseur. Une connexion de repli est enregistrée comme `credential_source = native` et facturée au prix natif. |
| `provider_key` | chaîne | Route qui exécute l'étape. Vide (par défaut) correspond à la Vérification bancaire native de Didit, un produit indépendant du fournisseur que Didit achemine vers le prestataire open banking régional qui dessert le pays et l'établissement de l'utilisateur, selon les contrats et la facturation de Didit. Une valeur désigne un fournisseur MARKETPLACE dont les identifiants propres ont été connectés à cette application : la session s'exécute alors, est facturée et révoquée sur votre compte fournisseur, et Didit ne facture que les frais de plateforme marketplace. Un fournisseur non connecté est refusé à l'enregistrement. |

Exemple d'objet `config`, pour un compte où la Vérification bancaire est activée et où la route que vous avez choisie couvre le pays que vous indiquez :

```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` est ce qui permet à cette étape d'avoir un effet, et il est vérifié par rapport à la route sur laquelle s'exécute le nœud, et non par rapport à une liste globale. Un pays pour lequel cette route ne peut pas établir la titularité du compte est refusé à l'enregistrement et nommé dans l'erreur ; lisez donc l'erreur plutôt que de supposer que le pays a été accepté et qu'il sera ignoré à l'exécution.

## AML

Valeur de fonctionnalité : `AML`.

Pour le filtrage des personnes dans le cadre du KYC, utilisez les champs suivants :

| Champ de configuration | Type | Description |
| - | - | - |
| `is_aml_ongoing_monitoring_enabled` | booléen | Active la surveillance AML continue. |
| `aml_score_approve_threshold` | entier | Seuil d'approbation. |
| `aml_score_review_threshold` | entier | Seuil d'examen. |
| `aml_match_score_threshold` | entier | Seuil du score de correspondance pour les correspondances possibles. |
| `aml_name_weight` | entier | Poids du nom. Si un poids AML est renseigné, les poids du nom, de la date de naissance et du pays doivent totaliser `100`. |
| `aml_dob_weight` | entier | Poids de la date de naissance. |
| `aml_country_weight` | entier | Poids du pays. |
| `create_cases_on_hit` | booléen | Ouvre automatiquement un dossier lorsque le filtrage renvoie une correspondance, au lieu de laisser la correspondance être triée depuis la session. Désactivé par défaut. |
| `case_blueprint` | uuid | Modèle de dossier à partir duquel le dossier créé automatiquement est construit. N'a de sens qu'avec `create_cases_on_hit` ; le modèle par défaut du compte est utilisé lorsqu'il n'est pas renseigné. |
| `status_rules` | tableau | Règles de statut personnalisées facultatives. |

Pour le filtrage des entreprises dans le cadre du KYB, utilisez les champs suivants :

| Champ de configuration | Type | Description |
| - | - | - |
| `kyb_score_approve_threshold` | entier | Seuil d'approbation AML de l'entreprise. |
| `kyb_score_review_threshold` | entier | Seuil d'examen AML de l'entreprise. |
| `kyb_enable_ongoing_monitoring` | booléen | Active la surveillance AML continue dans le cadre du KYB. |
| `kyb_company_aml_match_score_threshold` | entier | Seuil du score de correspondance AML de l'entreprise. |
| `kyb_company_aml_name_weight` | entier | Poids de la raison sociale. Les poids AML de l'entreprise doivent totaliser `100` lorsqu'ils sont renseignés. |
| `kyb_company_aml_dob_weight` | entier | Poids de la date de constitution ou de la date de naissance. |
| `kyb_company_aml_country_weight` | entier | Poids du pays. |

### Filtrage d'une entité extraite par une étape Document AI

Une étape AML lit normalement l'entité à filtrer depuis l'étape `OCR` (une personne) ou l'étape `KYB_REGISTRY` (une entreprise). Un workflow dont la seule étape d'extraction est `DOCUMENT_AI`, c'est-à-dire des documents non standardisés comme un certificat fiscal ou un acte constitutif, n'a ni l'une ni l'autre. Il doit donc préciser d'où provient chaque entrée de filtrage.

| Champ de configuration | Type | Description |
| - | - | - |
| `aml_field_sources` | objet | Où lire l'entité que cette étape filtre. `source` désigne le producteur et `key` désigne la valeur qu'il contient : une clé de champ Document AI pour `document_ai`, un identifiant de nœud de questionnaire pour `questionnaire`, et `expected_details.<field>` ou `metadata.<key>` pour `expected_data`. La CLÉ du mappage est l'une des quatre entrées de filtrage, `full_name`, `date_of_birth`, `nationality` ou `document_number`, lues pour une entreprise comme raison sociale, date de constitution, pays et numéro d'immatriculation. Un champ Document AI déjà nommé comme l'une de ces quatre entrées est mappé automatiquement et n'est volontairement pas enregistré, afin que le renommer ne fige jamais un mappage obsolète. Un mappage explicite prime sur le mappage automatique et sur le document d'identité, et un mappage qui ne renvoie rien à l'exécution laisse l'entrée vide au lieu de revenir à une autre valeur. Sur un workflow d'entreprise (KYB), l'entreprise renvoyée par une étape `KYB_REGISTRY` fait foi : seul un mappage explicite remplace l'une de ses entrées, le mappage automatique n'est pas appliqué par-dessus une fiche du registre, et sans étape de registre, le mappage constitue à lui seul l'identité complète. Forme : `{"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` | chaîne | `person` ou `company`. Par défaut `person` sur un workflow de personne (KYC) et `company` sur un workflow d'entreprise (KYB). Définissez `company` pour filtrer l'entreprise nommée dans un document téléversé sans étape `KYB_REGISTRY` : le prestataire recherche dans les registres d'entreprises et le score de correspondance est calculé comme pour une entreprise. |
| `aml_incomplete_data_action` | action | Verdict lorsque le filtrage a été effectué sur une identité incomplète (nom, date de naissance et pays). `REVIEW` est la valeur par défaut. `NO_ACTION` poursuit avec des données réduites pour un workflow qui ne contient sciemment qu'un nom. Le filtrage est exécuté dans tous les cas, et le journal des données partielles est enregistré dans tous les cas : cette valeur détermine seulement l'effet sur le statut. |

Exemple : filtrage de l'entreprise mentionnée dans une *acta constitutiva* mexicaine, sans aucun document d'identité dans le workflow :

```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]
>
> Sans étape `OCR` ni étape `KYB_REGISTRY` en amont, une étape `AML` doit pouvoir renseigner
> `full_name`, car il n'y a pas de recherche auprès du prestataire sans nom. Un workflow qui ne
> mappe rien, ou qui mappe une clé Document AI qu'aucune étape amont n'extrait, est rejeté lors de
> l'enregistrement au lieu d'être enregistré et de ne rien filtrer. La précision du filtrage AML
> dépend directement du nombre d'identifiants fournis : un filtrage sur le seul nom produit un
> volume élevé de faux positifs.

## Analyse de l'appareil et de l'IP

Valeur de fonctionnalité : `IP_ANALYSIS`.

| Champ de configuration | Type | Description |
| - | - | - |
| `ip_mismatch_action` | action | Action lorsque la géolocalisation de l'IP ne correspond pas aux données attendues. |
| `ip_location_not_determined_action` | action | Décision lorsqu'aucune adresse IP identifiant l'utilisateur final n'a été enregistrée, de sorte que la session ne dispose d'aucune localisation IP : le pays, la ville, le fournisseur d'accès à Internet (FAI), les coordonnées et le fuseau horaire sont indisponibles, et `ip_geofencing_by_country`, la comparaison avec le pays du document et les contrôles du VPN et du centre de données ne peuvent pas être exécutés. La valeur par défaut est `NO_ACTION`, qui conserve l'avertissement `IP_LOCATION_NOT_DETERMINED` visible sur la session sans modifier sa décision ; définissez `REVIEW` ou `DECLINE` si une session non localisée ne doit pas être validée. |
| `vpn_detection_action` | action | Action lorsqu'une utilisation de VPN ou de proxy est détectée. |
| `expected_ip_mismatch_action` | action | Action lorsque l'IP ne correspond pas à l'IP attendue. |
| `duplicated_ip_action` | action | Action lorsque l'IP est réutilisée de manière suspecte. |
| `duplicated_device_action` | action | Action lorsque la même empreinte persistante de l'appareil est réutilisée dans des sessions provenant de valeurs `vendor_data` différentes. |
| `recovered_device_action` | action | Action lorsque la récupération de l'empreinte v2 relie la session à un appareil déjà vu précédemment avec un niveau de confiance élevé, après que l'identifiant persistant de l'appareil a changé. |
| `is_ip_geofencing_enabled` | booléen | Active les restrictions de géofencing par IP. Lorsque la valeur est `false`, `ip_geofencing_by_country` est conservé mais n'est pas appliqué. |
| `ip_geofencing_by_country` | objet | Règles de localisation IP par pays, indexées par code pays ISO-3 : `{"USA": {"allowed": true, "states": {"California": {"allowed": false}}}}`. Les entrées par état ou région remplacent l'indicateur du pays ; les pays non listés sont autorisés. |
| `ip_geofencing_action` | action | Action lorsque l'IP de la session est localisée dans un pays, un État ou une région non autorisé(e). La valeur par défaut est `DECLINE`. |
| `automation_detected_action` | action | Décision lorsque la session semble pilotée par un système automatisé plutôt que par une personne. |
| `cross_org_fraud_device_action` | action | Décision lorsque cet appareil a été signalé comme frauduleux par une autre organisation du réseau. |
| `cross_org_fraud_ip_action` | action | Décision lorsque cette IP a été signalée comme frauduleuse par une autre organisation du réseau. |
| `device_app_tampered_action` | action | Décision lorsque le binaire de l'application hôte semble avoir été altéré. |
| `device_blocklist_action` | action | Décision lorsque l'appareil figure sur la liste de blocage de l'organisation. |
| `device_debugger_action` | action | Décision lorsqu'un débogueur est rattaché à l'application hôte. |
| `device_emulator_action` | action | Décision lorsque l'appareil est un émulateur plutôt que du matériel réel. |
| `device_hooking_action` | action | Décision lorsqu'une interception dynamique ou une instrumentation à l'exécution est détectée. |
| `device_integrity_missing_action` | action | Décision lorsqu'aucune attestation d'intégrité de l'appareil fournie par la plateforme n'a été renvoyée. |
| `device_rooted_action` | action | Décision lorsque l'appareil est rooté ou jailbreaké. |
| `multiple_devices_action` | action | Décision lorsque la session a été pilotée depuis plusieurs appareils. |
| `device_liveness_attack_history_action` | action | Action lorsque le même appareil (identifié par son identifiant persistant) a été utilisé lors d'une session antérieure d'un autre utilisateur dont la capture de détection du vivant a été considérée comme une attaque (avertissement `DEVICE_LINKED_TO_LIVENESS_ATTACK`). La valeur par défaut est `NO_ACTION`. |
| `device_model_inconsistency_action` | action | Action lorsque le même appareil (identifié par son identifiant persistant) a été signalé comme un modèle d'appareil différent lors d'une session antérieure (avertissement `DEVICE_MODEL_INCONSISTENT`). La valeur par défaut est `NO_ACTION`. |
| `status_rules` | tableau | Règles de statut personnalisées facultatives. |

Exemple :

```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"
  }
}
```

Utilisez `recovered_device_action` séparément de `duplicated_device_action` lorsque vous souhaitez surveiller les appareils récupérés avec un niveau de confiance élevé avant de les refuser automatiquement. Cela est utile pendant le déploiement, car les correspondances d'appareils récupérés sont conçues pour détecter les réseaux de fraude, mais doivent tout de même être calibrées sur votre propre trafic.

## Vérification de la localisation

Valeur de la fonctionnalité : `GEOLOCATION`.

Vérifie où se trouve la personne pendant sa vérification, à partir de la position de l'appareil ou de la localisation IP de la connexion, par rapport aux zones autorisées et bloquées, à la localisation IP et à l'adresse du document.
Consultez [Vérification de la localisation](https://docs.didit.me/fr/core-technology/location-verification/overview.md) pour savoir comment se comporte l'étape, et [son rapport](https://docs.didit.me/fr/core-technology/location-verification/report-location-verification.md) pour les champs de décision.
Placez-la après la Vérification d'identité ou le Justificatif de domicile si vous voulez mesurer la distance jusqu'à l'adresse du document, car cette distance n'est calculée que lorsqu'une adresse est enregistrée.
Si `geolocation_position_source` n'est pas défini, la distance par rapport à la localisation IP nécessite une étape Analyse de l'appareil et de l'IP dans le même workflow.
Toutes les clés sont facultatives : une étape dont `config` est vide demande à l'appareil une position précise à 250 m, pas plus ancienne que 120 secondes, accorde 3 tentatives à la personne et n'applique aucune règle de zone.

Chaque constat possède sa propre clé d'action. Une clé d'action que vous ne définissez pas prend la valeur par défaut du `geolocation_preset` choisi, ou la valeur par défaut de chaque clé indiquée ci-dessous si aucun préréglage n'est choisi.
Une localisation incertaine ou refusée prend par défaut `REVIEW`, jamais `DECLINE`, car une autorisation refusée ou un rayon large ne sont pas une preuve de fraude.
Une action que vous définissez explicitement l'emporte toujours sur le préréglage.
Un défi rejoué (`LOCATION_REPLAY_DETECTED`) et une attestation d'appareil ayant échoué (`LOCATION_INTEGRITY_FAILED`) entraînent toujours un refus et n'ont pas de clé d'action.

| Champ de configuration | Type | Description |
| - | - | - |
| `geolocation_position_source` | chaîne | D'où provient la position. `device_and_ip` demande la position de l'appareil et la compare à la localisation IP de la connexion depuis laquelle elle est soumise (une recherche de renseignements IP si cette IP n'est pas encore en cache). Lorsqu'il n'est pas défini (valeur par défaut), ce paramètre demande aussi la position de l'appareil et, comme avant l'existence de cette clé, la compare à la localisation IP observée par l'étape Analyse de l'appareil et de l'IP de la session. Sans cette étape, il n'y a donc aucune distance, et la connexion n'est jamais recherchée. L'exception est un nœud qui agit sur un constat VPN, proxy ou Tor (son action propre ou son préréglage) : il effectue une recherche sur la connexion pour ce constat et compare l'appareil avec elle, exactement comme `device_and_ip`. `device_only` ne compare jamais avec la localisation IP et ne recherche la connexion que pour ces constats. `ip_only` ne demande jamais rien à la personne et juge à la place la localisation IP de la connexion, au niveau de la ville, avec un rayon de 50 km, sans règle de précision, de fraîcheur ni d'autorisation d'une position approximative. Avec `geolocation_areas`, une ville côtière est jugée à l'intérieur de son pays, sauf si un autre pays se trouve dans ce rayon. Sur un nœud qui demande la position à l'appareil, une tentative sans position de l'appareil est traitée comme le refus ou l'échec qu'elle constitue : la localisation IP ne la remplace jamais. |
| `geolocation_preset` | chaîne | Les valeurs par défaut que prend chaque action non définie de ce nœud. `licensing` : hors d'une zone, dans une zone bloquée, en cas de VPN, de Tor ou d'émulateur, la demande est refusée ; un proxy et les autres constats sont soumis à examen, et une attestation d'appareil manquante reste Aucune action. `fraud_screening` : identique, sauf que ce que Licensing refuse est soumis à examen. Null conserve les valeurs par défaut historiques. Une action définie explicitement l'emporte toujours. |
| `geolocation_accuracy_mode` | chaîne | Ce que l'on demande à l'appareil. `precise` demande au système d'exploitation une position précise ; une personne qui n'accorde qu'une position approximative est sollicitée à nouveau tant qu'il reste des tentatives, puis jugée selon `geolocation_approximate_action`. `approximate_allowed` accepte une autorisation approximative sans ce verdict. `geolocation_max_accuracy_radius_m` s'applique dans les deux cas. `precise` si non défini. |
| `geolocation_max_accuracy_radius_m` | entier | Le rayon d'incertitude le plus large, en mètres, qu'une position de l'appareil peut avoir tout en restant valide. De 10 à 50000 mètres ; 250 si non défini. Une position dont le rayon est supérieur à cette valeur, ou qui ne signale aucun rayon, suit ce que prévoit `geolocation_low_accuracy_behavior` et est jugée selon `geolocation_low_accuracy_action`. Un nœud `ip_only` n'a pas de rayon d'appareil et ne l'applique jamais. |
| `geolocation_max_accuracy_radius_unit` | chaîne | L'unité dans laquelle la console affiche `geolocation_max_accuracy_radius_m`. Affichage uniquement : la valeur enregistrée est toujours en mètres, aucune règle ne dépend de cette unité, et les données de l'étape la transmettent seulement pour qu'un client puisse afficher la même unité. |
| `geolocation_low_accuracy_behavior` | chaîne | Ce que fait une position plus large que `geolocation_max_accuracy_radius_m`, ou sans rayon : `ask_again` (valeur par défaut) demande à la personne de réessayer tant qu'il reste des tentatives ; `fail` met fin à l'étape dès la première. |
| `geolocation_max_age_seconds` | entier | L'ancienneté, en secondes, qu'une position de l'appareil peut avoir au moment où le serveur la reçoit. De 5 à 3600 secondes ; 120 si non défini. Une position plus ancienne est demandée à nouveau tant qu'il reste des tentatives, puis jugée selon `geolocation_stale_fix_action`. |
| `geolocation_timeout_seconds` | entier | Le temps, en secondes, pendant lequel le client laisse l'appareil chercher une position à chaque tentative ; le serveur le transmet dans les données de l'étape et ne l'applique pas lui-même. De 5 à 120 secondes ; 20 si non défini. Une tentative qui ne trouve aucune position à temps est soumise comme `timeout`, demandée à nouveau tant qu'il reste des tentatives, puis jugée selon `geolocation_unavailable_action`. |
| `geolocation_max_attempts` | entier | Le nombre de tentatives accordées à la personne sur ce nœud. De 1 à 5 tentatives ; 3 si non défini. Une tentative que la personne peut encore modifier (un refus, une position large, ancienne ou approximative, ou un constat de zone ou de détection d'un anonymiseur sur lequel le nœud agit) est reproposée tant qu'il reste des tentatives, et la dernière tentative décide de l'étape. Une position simulée, ou un émulateur sur lequel le nœud agit, met fin à l'étape lors de la tentative qui l'a signalé. |
| `geolocation_allow_qr_handoff` | booléen | Proposer de continuer sur un téléphone à l'aide d'un code QR tant que l'étape est encore ouverte (`allow_qr_handoff` dans les données de l'étape, `can_handoff` dans chaque réponse de soumission). Les SDK natifs s'exécutent déjà sur le téléphone et n'affichent jamais ce code. Activé par défaut. |
| `geolocation_allow_skip` | booléen | Permettre à la personne de continuer sans localisation à tout moment, depuis l'introduction ou un écran de nouvelle tentative (`skipped: true`). Le fait d'ignorer l'étape met fin à celle-ci et est jugé selon `geolocation_unavailable_action`, sauf si le passage répond à un refus sur un `geolocation_refusal_path` `continue_without_location`, lequel est enregistré comme ce refus. Désactivé par défaut. |
| `geolocation_deep_link_enabled` | booléen | Transmis au client sous la forme `deep_link_enabled` dans les données de l'étape : propose d'ouvrir l'application propre au client à la place. Le serveur n'applique aucune règle à ce paramètre. Désactivé par défaut. |
| `geolocation_refusal_path` | chaîne | La suite proposée lorsque l'accès à la localisation est refusé. `retry_then_handoff` (par défaut) redemande tant qu'il reste des tentatives et propose un transfert vers le téléphone ; `continue_without_location` permet à la personne de poursuivre, en consignant le refus ; `end_session` met fin à l'étape et à la session dès le premier refus, et nécessite que `geolocation_permission_denied_action` soit Review ou Decline, ainsi qu'un workflow dont la fin est une décision Declined, In Review ou Final. La décision de la session est prise à partir des étapes exécutées et n'est jamais Approved : sur un workflow qui ne peut pas se terminer sur cette décision, elle prend l'autre fin non approuvée (Declined pour In Review, In Review pour Declined). |
| `is_geolocation_geofencing_enabled` | booléen | Active les règles de zones : `geolocation_areas`, ou l'ancien `geolocation_geofencing_by_country`, ne s'appliquent que lorsque cette valeur est vraie, et ce n'est qu'alors que les données de l'étape listent `available_areas`. Désactivé par défaut. Lorsqu'elle est activée, une liste `geolocation_areas` nécessite au moins une zone autorisée. |
| `geolocation_areas` | tableau | Zones autorisées et bloquées, appliquées lorsque `is_geolocation_geofencing_enabled` est vrai. Seule une position située dans une zone autorisée est acceptée, et une zone bloquée l'emporte toujours sur une zone autorisée. Une position est évaluée selon l'ensemble de son cercle de précision : un cercle qui croise une frontière déterminante est indéterminé, jamais en dehors. Un pays ou une région s'arrête là où commence une autre terre, jamais à son littoral, et une position que les contours placent sur aucune terre (un bord de mer ou une jetée que le littoral simplifié a coupé) est indéterminée pour chaque pays ou région situé dans un rayon égal à son rayon augmenté de 12 milles nautiques. `id` est le nom utilisé par les règles de branche et par `geolocation.inside_areas` / `geolocation.blocked_areas` ; `kind` définit la forme : un `country` entier (code ISO 3166-1 alpha-3 avec un contour publié : un territoire que les contours représentent comme une région d'un autre pays est une `region`, comme La Réunion en tant que `FR-RE` de la France, ou Bonaire, Saint-Eustache et Saba en tant que `NL-BQ1` à `NL-BQ3`), `region` (codes ISO 3166-2 d'un même pays dont les frontières sont publiées), `circle` (de 1 à 500 km) ou `polygon` (de 3 à 200 points, un anneau dont les arêtes ne se croisent ni ne se touchent). 50 zones au maximum, avec des identifiants uniques, et au moins une zone autorisée lorsque le géorepérage est activé. Ne peut pas être combiné avec `geolocation_geofencing_by_country`. |
| `geolocation_geofencing_by_country` | objet | Règles d'autorisation et de refus par pays et par région pour la propre position de l'appareil, appliquées uniquement lorsque `is_geolocation_geofencing_enabled` est vrai. Même structure que `ip_geofencing_by_country` de l'analyse IP, sauf que les clés de `states` sont des codes ISO 3166-2 (`US-NJ`), et non des noms d'États, car la position est résolue en subdivision et non en libellé de ville fourni par un prestataire. Un pays absent de la liste est autorisé. L'enregistrement d'une règle de région pour un pays sans frontières ISO 3166-2 publiées est rejeté plutôt qu'ignoré silencieusement. |
| `geolocation_ip_distance_km` | entier | Écart maximal, en kilomètres, entre la position de l'appareil et la localisation IP, après soustraction des deux rayons d'incertitude, avant que `geolocation_ip_distance_action` ne s'applique. 200 lorsque la clé est omise ; null désactive la comparaison. Seul un nœud dont `geolocation_position_source` vaut `device_and_ip` ou n'est pas défini effectue la comparaison ; cette clé indique avec quelle localisation IP elle est comparée. |
| `geolocation_ip_distance_unit` | chaîne | Unité dans laquelle la console affiche `geolocation_ip_distance_km`. Affichage uniquement : la valeur stockée est toujours en kilomètres et aucune règle n'en dépend. |
| `geolocation_document_distance_km` | entier | Distance maximale, en kilomètres, entre la position (la localisation IP sur un nœud `ip_only`) et l'adresse désignée par `geolocation_document_distance_basis`, avant que `geolocation_document_distance_action` ne s'applique. Non défini ou null (par défaut) : désactivé. |
| `geolocation_document_distance_unit` | chaîne | Unité dans laquelle la console affiche `geolocation_document_distance_km`. Affichage uniquement : la valeur stockée est toujours en kilomètres et aucune règle n'en dépend. |
| `geolocation_document_distance_basis` | chaîne | Adresse à partir de laquelle `geolocation_document_distance_km` est mesurée : `document` (par défaut : l'adresse du document d'identité, puis l'adresse du justificatif de domicile), `proof_of_address` uniquement, ou `declared` (le `expected_details.address` fourni à la création de la session, géocodée). |
| `geolocation_travel_tolerance_enabled` | booléen | Excuse la distance par rapport à l'adresse lorsque la même personne (même `vendor_data`) a été vue à moins de `geolocation_travel_usual_area_km` de celle-ci au cours des `geolocation_travel_max_days` derniers jours. N'excuse jamais un VPN, une position usurpée, une zone bloquée ni le fait de se trouver hors des zones autorisées. Seule une position mesurée par l'appareil compte comme un lieu où la personne a été vue : une localisation simulée, un émulateur ou une attestation échouée ne compte jamais. |
| `geolocation_travel_usual_area_km` | entier | Rayon autour de l'adresse qui définit la zone habituelle de la personne. De 10 à 500 km ; 100 lorsqu'il n'est pas défini. |
| `geolocation_travel_max_days` | entier | Durée pendant laquelle une position éloignée reste un déplacement après que la personne a été vue dans la zone habituelle. De 1 à 90 jours ; 14 lorsqu'elle n'est pas définie. |
| `geolocation_consecutive_mismatch_count` | entier | Déclenche LOCATION\_CONSECUTIVE\_MISMATCHES lorsque cette vérification et les vérifications précédentes de la même personne (même `vendor_data`) se sont trouvées hors des zones autorisées, dans une zone bloquée ou trop loin de l'adresse, ce nombre de fois de suite. Une vérification qui n'a rien comparé ne prolonge ni ne rompt la série, pas plus qu'une position non mesurée par l'appareil (localisation simulée, émulateur, attestation échouée). De 2 à 10 ; null (par défaut) : désactivé. |
| `geolocation_approximate_action` | action | Verdict lorsque l'utilisateur a accordé une localisation approximative alors que `geolocation_accuracy_mode` demande une localisation précise. Vaut `REVIEW` par défaut. |
| `geolocation_blocked_area_action` | action | Verdict lorsque la position, ainsi que l'ensemble de son cercle de précision, se trouve dans une zone bloquée de `geolocation_areas`. Par défaut : Decline. |
| `geolocation_consecutive_mismatch_action` | action | Verdict lorsque le nombre de non-correspondances consécutives atteint `geolocation_consecutive_mismatch_count`. Par défaut : Examen. |
| `geolocation_document_distance_action` | action | Verdict lorsque la position de l'appareil est plus éloignée de l'adresse du document que `geolocation_document_distance_km`. L'adresse est géocodée de manière approximative, donc ce signal est faible. Par défaut : `REVIEW`. |
| `geolocation_emulator_action` | action | Verdict lorsque l'application ayant partagé la position signale qu'elle s'exécute sur un émulateur. Les navigateurs ne peuvent pas le signaler. Sauf si la valeur est Aucune action, cela met fin à l'étape lors de cette tentative : une nouvelle vérification ne peut pas changer l'appareil. Aucune action, sauf si une valeur ou un préréglage en décide autrement. |
| `geolocation_geofence_undetermined_action` | action | Verdict lorsque la position ne peut être située ni à l'intérieur ni à l'extérieur de la zone, car son cercle de précision atteint la limite. L'incertitude n'est jamais signalée comme étant à l'extérieur. Par défaut : `REVIEW`. |
| `geolocation_geofencing_action` | action | Verdict lorsque la position de l'appareil et tout son cercle d'incertitude se trouvent hors de `geolocation_geofencing_by_country`. Par défaut : `DECLINE`. |
| `geolocation_integrity_missing_action` | action | Verdict lorsqu'un client natif a soumis une position sans token d'attestation de l'appareil. Par défaut : Aucune action ; les clients web sont enregistrés comme non pris en charge plutôt que comme manquants, car aucun navigateur ne peut attester. |
| `geolocation_ip_distance_action` | action | Verdict lorsque la position de l'appareil et la localisation IP de la session sont plus éloignées que `geolocation_ip_distance_km`, après soustraction des deux rayons d'incertitude. Par défaut : `REVIEW`. |
| `geolocation_low_accuracy_action` | action | Verdict lorsqu'aucune tentative n'a atteint la précision requise : la meilleure position a un rayon d'incertitude supérieur à `geolocation_max_accuracy_radius_m`, ou elle n'indiquait aucun rayon. Une position sans rayon n'est jamais considérée comme respectant la limite. Par défaut : `REVIEW`. |
| `geolocation_mock_location_action` | action | Verdict lorsque le système d'exploitation a signalé la position comme simulée plutôt que mesurée (fournisseur de localisation fictive Android, simulée par logiciel sur iOS). Par défaut : `REVIEW`. |
| `geolocation_permission_denied_action` | action | Verdict lorsque l'utilisateur a refusé ou ignoré la demande de localisation à chaque tentative autorisée. Par défaut : Examen, car un refus est un choix, et non un signal de fraude. |
| `geolocation_proxy_action` | action | Verdict lorsque la connexion ayant partagé la position passe par un proxy ouvert, anonyme ou de relais privé. Aucune action, sauf si une valeur ou un préréglage en décide autrement. |
| `geolocation_stale_fix_action` | action | Verdict lorsque la position a été mesurée plus de `geolocation_max_age_seconds` avant que le serveur ne la reçoive. Par défaut : `REVIEW`. |
| `geolocation_tor_action` | action | Verdict lorsque la connexion ayant partagé la position est un nœud de sortie Tor. Aucune action, sauf si une valeur ou un préréglage en décide autrement. |
| `geolocation_unavailable_action` | action | Verdict lorsqu'aucune position n'a pu être obtenue : services de localisation désactivés ou restreints, système de positionnement sans résultat, délai de la tentative dépassé, étape ignorée par l'utilisateur, ou client trop ancien pour la prendre en charge. Par défaut : `REVIEW`. |
| `geolocation_vpn_action` | action | Verdict lorsque la connexion ayant partagé la position est un VPN commercial. Sauf si la valeur est Aucune action, la personne est invitée à le désactiver et à vérifier à nouveau tant qu'il reste des tentatives. Aucune action, sauf si une valeur ou un préréglage en décide autrement. |
| `status_rules` | array | Règles de statut personnalisées facultatives. Vous pouvez cibler les champs `geolocation.*` listés dans [Rapport de vérification de localisation](https://docs.didit.me/fr/core-technology/location-verification/report-location-verification.md#champs-pour-les-règles-de-statut-et-les-branches). |

### Formes de zones

Chaque élément de `geolocation_areas` possède un `id` (de 1 à 64 caractères parmi `A-Z a-z 0-9 _ -`, unique dans la liste), un `label` facultatif (80 caractères maximum), un `type` égal à `allowed` ou `blocked`, et un `kind` qui détermine la forme.

| `kind` | Champs supplémentaires | Signification |
| - | - | - |
| `country` | `country` (ISO 3166-1 alpha-3) | Un pays entier dont le contour est publié. |
| `region` | `country`, `regions` (codes ISO 3166-2 de ce pays) | Une ou plusieurs subdivisions d'un même pays dont les frontières sont publiées. |
| `circle` | `center` (`latitude`, `longitude`), `radius_km` (de 1 à 500) | Tout point situé à l'intérieur du rayon autour du centre. |
| `polygon` | `points` (de 3 à 200 éléments `latitude`, `longitude`) | Un anneau fermé dont les arêtes ne se croisent ni ne se touchent jamais. |

Une liste contient au maximum 50 zones et doit comporter au moins une zone `allowed` tant que `is_geolocation_geofencing_enabled` vaut `true`.
`geolocation_areas` et `geolocation_geofencing_by_country` ne peuvent pas être envoyés ensemble, et `geolocation_refusal_path: "end_session"` exige que `geolocation_permission_denied_action` soit `REVIEW` ou `DECLINE`.
L'API refuse une zone qui ne pourrait jamais correspondre, comme une région d'un pays sans frontières publiées, au lieu de l'enregistrer.

Exemple :

```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"
  }
}
```

## Justificatif de domicile

Valeur de fonctionnalité : `PROOF_OF_ADDRESS`.

| Champ de configuration | Type | Description |
| - | - | - |
| `poa_documents_allowed` | object | Configuration des types de documents de justificatif de domicile, par code pays ISO3. Au moins un type de document valide doit être activé. |
| `poa_languages_allowed` | object | Code de langue ISO 639-1 vers `0` ou `1`. Au moins une langue doit être activée. |
| `poa_name_or_address_mismatch_action` | action | Action lorsque le nom ou l'adresse ne correspond pas aux données attendues. |
| `poa_document_issues_action` | action | Action lorsque le document présente des problèmes de qualité ou d'extraction. |
| `poa_max_attempts_exceeded_action` | action restreinte | Action lorsque l'utilisateur dépasse le nombre de tentatives de réessai. Utilisez `DECLINE` ou `REVIEW`. |
| `poa_document_authenticity_action` | action restreinte | Action lorsque les contrôles d'authenticité échouent. Utilisez `DECLINE` ou `REVIEW`. |
| `poa_document_unproven_text_replacement_action` | action | Action lorsqu'un champ de texte a été effacé puis ressaisi dans une autre police, et que le fichier ne permet pas de prouver si son contenu a changé (`POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT`). |
| `poa_unsupported_document_type_action` | action | Action lorsque le type de document n'est pas pris en charge. |
| `poa_unsupported_language_action` | action | Action lorsque la langue du document n'est pas prise en charge. |
| `poa_issuer_not_identified_action` | action | Action lorsque l'émetteur du document n'est pas identifié. |
| `poa_issue_date_not_detected_action` | action | Action lorsque la date d'émission est absente. |
| `poa_unparsable_or_invalid_address_action` | action | Action lorsque l'adresse est invalide ou ne peut pas être analysée. |
| `address_validation_enabled` | boolean | Valide l'adresse lue par cette étape (imprimée sur le justificatif de domicile ; seul un fichier ayant réussi les contrôles de document est validé) par rapport aux données de référence postales : elle confirme que l'adresse existe et la normalise, sans jamais la relier à une personne. Le résultat figure dans l'objet `address_validation` de l'étape, dans la décision. **Facturé \$0.10 par adresse validée** ; une validation qui n'a pas pu être exécutée (`unavailable`) est gratuite. Désactivé par défaut. |
| `address_not_verified_action` | action | Action lorsque Address Validation ne peut pas confirmer l'adresse au niveau du bâtiment (`ADDRESS_NOT_VERIFIED` : `partially_verified` ou `not_verified`). S'applique uniquement lorsque `address_validation_enabled` est activé. Vaut `NO_ACTION` par défaut, ce qui enregistre seulement l'avertissement. |
| `poa_name_match_score_threshold` | integer | Seuil de correspondance du nom. |
| `poa_max_retry_attempts` | integer | Limite de tentatives de réessai, de `2` à `5`. |
| `status_rules` | array | Règles de statut personnalisées facultatives. |

## Questionnaire

Valeur de fonctionnalité : `QUESTIONNAIRE`.

| Champ de configuration | Type | Description |
| - | - | - |
| `questionnaire_uuid` | UUID | Obligatoire. Utilisez le `questionnaire_id` renvoyé par `POST /v3/questionnaires/`. |
| `review_questionnaire_manually` | boolean | Soumet les réponses au questionnaire à un examen manuel. |
| `status_rules` | array | Règles de statut personnalisées facultatives. Vous pouvez cibler les champs `questionnaire.answers.<question_id>`. |

## Registre KYB

Valeur de fonctionnalité : `KYB_REGISTRY`.

| Champ de configuration | Type | Description |
| - | - | - |
| `kyb_accepted_countries` | object | Liste d'autorisation historique de pays ISO3 pour la recherche dans le registre des sociétés. Remplacée par `kyb_registry_countries_config` : elle reste lisible et reste dérivée de celui-ci pour les workflows existants, mais ne sert plus à configurer les nouveaux. |
| `kyb_manual_company_action` | action | Action lorsque l'entreprise nécessite un traitement manuel. |
| `kyb_registry_fields_config` | object | Visibilité et caractère obligatoire de chaque champ du formulaire de registre dans le parcours hébergé. Voir ci-dessous. |
| `kyb_registry_countries_config` | object | Routage du registre par pays, sous la forme `{"<ISO2>": {"enabled": bool, "tier": "basic" \| "shareholders" \| "ubo"}}`. Chaque pays activé détermine le niveau de données facturé lorsqu'une entreprise est sélectionnée (`basic` correspond au niveau Lite), et seuls les niveaux que l'[endpoint des tarifs](https://docs.didit.me/fr/getting-started/kyb-registry-pricing.md) indique comme disponibles pour ce pays peuvent être activés. Au moins un pays doit être activé : une vérification de registre qui n'effectue aucune recherche est rejetée. Les entreprises saisies manuellement sont facturées séparément et n'utilisent pas cette configuration. |
| `kyb_registry_monitoring_enabled` | boolean | Maintient le dossier de registre de l'entreprise sous surveillance continue après un résultat Shareholders ou UBO : un changement de statut, de dirigeants, d'actionnariat ou d'adresse renvoie la session en cours d'examen et déclenche un webhook. Disponible uniquement lorsque le fournisseur de registre propose la surveillance. USD 2.00 par entreprise et par an, résiliable à tout moment. Désactivé par défaut. |
| `kyb_vat_invalid_action` | action | Action lorsque le numéro de TVA de l'entreprise échoue à la validation EU VIES. Vaut `REVIEW` par défaut. |
| `kyb_vat_unverified_action` | action | Action lorsque le numéro de TVA n'a pas pu être validé parce que VIES était indisponible. Vaut `NO_ACTION` par défaut. |
| `status_rules` | array | Règles de statut personnalisées facultatives. |

`kyb_registry_fields_config` associe chaque clé de champ configurable à `{"enabled": bool, "required": bool}`. `enabled: false` masque le champ, `enabled: true, required: false` l'affiche comme facultatif, et `enabled: true, required: true` le rend obligatoire à la soumission. `company_name`, `country_code` et `region` sont toujours affichés et obligatoires, et ne peuvent pas être configurés. Lorsque l'objet est omis, égal à `null` ou à `{}`, la valeur par défaut s'applique : seul `incorporation_date` est obligatoire et tous les autres champs sont facultatifs.

```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 }
  }
}
```

Clés de champs 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`. Consultez [champs configurables du formulaire de registre](https://docs.didit.me/fr/business-verification/company-data.md#champs-configurables-du-formulaire-du-registre) pour le comportement côté utilisateur final, et [validation du numéro de TVA et de l'identifiant fiscal](https://docs.didit.me/fr/business-verification/company-data.md#validation-du-numéro-de-tva-et-de-l’identifiant-fiscal) pour savoir comment `vat_number` et `tax_number` sont vérifiés.

## Documents KYB

Valeur de fonctionnalité : `KYB_DOCUMENTS`.

| Champ de configuration | Type | Description |
| - | - | - |
| `kyb_required_document_groups` | objet ou tableau | Obligatoire. Groupes de documents KYB requis. |
| `kyb_document_subtype_config` | objet | Activation par sous-type de document et configuration de l'ancienneté. |
| `kyb_document_tampering_action` | action restreinte | Action lorsqu'une altération est détectée. Utilisez `DECLINE` ou `REVIEW`. |
| `kyb_document_unproven_text_replacement_action` | action | Action lorsqu'un champ de texte d'un document d'entreprise a été effacé puis retapé dans une autre police, et que le fichier ne permet pas de savoir si son contenu a changé (`KYB_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT`). |
| `kyb_document_critical_mismatch_action` | action restreinte | Action en cas d'écarts critiques entre documents. Utilisez `DECLINE` ou `REVIEW`. |
| `kyb_document_non_critical_mismatch_action` | action | Action en cas d'écarts non critiques entre documents. |
| `kyb_document_age_action` | action | Action lorsque les règles d'ancienneté du document ne sont pas respectées. |
| `kyb_document_max_retry_attempts` | entier | Limite de nouvelles tentatives pour les documents KYB. |
| `kyb_document_max_attempts_exceeded_action` | action restreinte | Action lorsque le nombre maximal de tentatives est dépassé. Utilisez `DECLINE` ou `REVIEW`. |
| `status_rules` | tableau | Règles de statut personnalisées facultatives. |

## Personnes clés KYB

Valeur de fonctionnalité : `KYB_KEY_PEOPLE`.

| Champ de configuration | Type | Description |
| - | - | - |
| `kyb_ubo_ownership_threshold` | entier | Seuil de détention UBO, de `0` à `100`. |
| `kyb_shareholder_ownership_threshold` | entier | Seuil de détention des actionnaires, de `0` à `100`. Il ne peut pas être supérieur à `kyb_ubo_ownership_threshold`. |
| `kyb_key_people_ownership_required` | booléen | Exige un pourcentage de détention pour chaque personne clé soumise. Appliqué à la soumission et transmis à l'interface hébergée, qui marque le champ comme obligatoire. Valeur par défaut : `false`. |
| `kyb_require_ubo_kyc` | booléen | Exige que les UBO suivent un workflow de vérification de personne. |
| `kyb_ubo_verification_workflow` | UUID | Obligatoire lorsque `kyb_require_ubo_kyc` vaut `true`. Doit référencer un workflow non KYB de la même application. |
| `kyb_require_officer_kyc` | booléen | Exige que les dirigeants effectuent une vérification de personne. |
| `kyb_shareholder_verification_workflow` | UUID | Workflow de vérification de personne pour les actionnaires. |
| `kyb_officer_verification_workflow` | UUID | Workflow de vérification de personne pour les dirigeants. |
| `kyb_require_corporate_ubo_kyb` | booléen | Exige que les UBO de type entreprise effectuent un KYB. |
| `kyb_corporate_ubo_verification_workflow` | UUID | Obligatoire lorsque `kyb_require_corporate_ubo_kyb` vaut `true`. Doit référencer un workflow KYB de la même application. |
| `kyb_reject_if_ubo_rejected` | booléen | Rejette l'entreprise lorsqu'une vérification UBO obligatoire est refusée. |
| `kyb_wait_for_all_ubos` | booléen | Attend toutes les vérifications UBO obligatoires avant de statuer sur la session KYB. |
| `kyb_role_config` | objet ou tableau | Configuration par rôle. Chaque rôle KYC obligatoire doit inclure un `verification_workflow`. |
| `kyb_reuse_verified_individuals` | booléen | Réutilise les personnes déjà vérifiées lorsque c'est possible. |
| `kyb_notify_parties_by_email` | booléen | Envoie des notifications par e-mail aux personnes clés invitées. |
| `kyb_key_people_company_fields` | objet | Détails d'entreprise collectés pour une personne clé de type CORPORATE. Même forme de liste de descripteurs et mêmes règles que `kyb_key_people_person_fields`. Forme : `[{"key": "<field key>", "label": "<label>", "type": "text"\|"number"\|"date"\|"phone"\|"email", "required": true\|false, "custom": true\|false}]`. |
| `kyb_key_people_document_mismatch_action` | action | Verdict lorsque le document d'une personne clé ne concorde pas avec les informations déclarées pour elle. |
| `kyb_key_people_person_fields` | objet | Détails personnels collectés pour une personne clé qui est une personne physique, sous forme de LISTE ORDONNÉE de descripteurs de champs (et non un objet à clés). `key` est obligatoire et non vide ; `type` doit être l'une des valeurs text, number, date, phone ou email ; `custom` marque un champ ajouté par le client plutôt qu'un champ intégré. Forme : `[{"key": "<field key>", "label": "<label>", "type": "text"\|"number"\|"date"\|"phone"\|"email", "required": true\|false, "custom": true\|false}]`. |
| `kyb_key_people_prefill_from_registry` | booléen | Pré-remplit la liste des personnes clés à partir du résultat du registre des sociétés, afin que le client confirme et corrige les informations au lieu de saisir chaque dirigeant et actionnaire. |
| `status_rules` | tableau | Règles de statut personnalisées facultatives. |

## Document AI

Valeur de fonctionnalité : `DOCUMENT_AI`.

Demande un ou plusieurs documents à l'utilisateur et extrait les champs nommés que vous définissez à l'aide d'un modèle de vision. Chaque champ configuré devient une valeur exploitable dans les branchements, `document_ai.<key>`, et le résultat de l'étape est `document_ai.status`.

| Champ de configuration | Type | Description |
| - | - | - |
| `document_ai_documents` | array | Obligatoire. Les documents à demander (`3` au maximum). Chaque entrée est un objet document (voir ci-dessous). |
| `document_ai_unreadable_document_action` | action | Action à appliquer lorsque le document est illisible ou qu'aucune donnée ne peut être extraite. |
| `document_ai_missing_required_fields_action` | action | Action à appliquer lorsqu'un champ obligatoire ne peut pas être extrait. |
| `document_ai_document_tampering_action` | action restreinte | Action à appliquer lorsque le document présente des signes de manipulation. Utilisez `DECLINE` ou `REVIEW`. |
| `document_ai_name_mismatch_action` | action | Action à appliquer lorsque le nom complet extrait ne correspond pas à l'identité vérifiée. Nécessite un champ marqué par `is_full_name`. |
| `document_ai_unsupported_file_action` | action | Action à appliquer lorsque le type de fichier téléversé n'est pas pris en charge. |
| `document_ai_max_attempts_exceeded_action` | action restreinte | Action à appliquer lorsque l'utilisateur dépasse le nombre de tentatives de réessai. Utilisez `DECLINE` ou `REVIEW`. |
| `document_ai_name_match_score_threshold` | integer | Score minimal (`0` à `100`) pour que le nom complet extrait corresponde à l'identité vérifiée. En dessous, `document_ai_name_mismatch_action` s'applique. |
| `document_ai_max_retry_attempts` | integer | Limite de réessais, de `2` à `5`. |
| `status_rules` | array | Règles de statut personnalisées, facultatives. Vous pouvez cibler les champs `document_ai.<key>`. |

Chaque entrée de `document_ai_documents` est un document :

| Champ du document | Type | Description |
| - | - | - |
| `document_key` | string | Obligatoire. Identifiant stable du document, unique au sein de l'étape. |
| `title` | string | Obligatoire. Titre affiché à l'utilisateur. |
| `description` | string | Obligatoire. Instructions affichées à l'utilisateur sur ce qu'il doit téléverser. |
| `title_i18n` | object | Facultatif. Code de langue associé au titre traduit (par exemple `{ "es": "Comprobante de fondos" }`). |
| `description_i18n` | object | Facultatif. Code de langue associé à la description traduite. |
| `fields` | array | Obligatoire. Les champs à extraire (au moins un). Les clés des champs doivent être uniques au sein du document. |

Chaque entrée du tableau `fields` d'un document est un champ :

| Champ | Type | Description |
| - | - | - |
| `key` | string | Obligatoire. Clé JSON stable de la valeur extraite, unique au sein du document. Utilisez-la dans les branchements sous la forme `document_ai.<key>`. |
| `name` | string | Obligatoire. Libellé lisible du champ. |
| `name_i18n` | object | Facultatif. Code de langue associé au nom de champ traduit. |
| `instruction` | string | Facultatif. Instruction indiquant au modèle exactement quoi extraire pour ce champ. |
| `type` | string | Type du champ : `text`, `number` ou `date`. Valeur par défaut : `text`. |
| `required` | boolean | Indique si le champ doit être présent. Valeur par défaut : `false`. Si la valeur est `true` et qu'elle est absente, `document_ai_missing_required_fields_action` s'applique. |
| `is_full_name` | boolean | Facultatif, valeur par défaut `false`. Marque le champ dont la valeur est le nom complet du titulaire du document, comparé à l'identité vérifiée (le nom issu de la vérification d'identité, ou les informations attendues de la session). **Un seul champ par document** peut être défini à `true`, et ce n'est **pas obligatoire** : un document peut n'en marquer aucun, auquel cas aucune comparaison de nom n'est effectuée pour ce document. Seuls les champs `text` peuvent être le nom complet. |

Exemple :

```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
  }
}
```

## Signature électronique

Valeur de la fonctionnalité : `SIGNATURE`.

Permet à la personne vérifiée, ou aux personnes clés d'une entreprise, de signer des documents, au niveau Simple (par défaut) ou Avancé (AES). Placez-la après les étapes qui vérifient le signataire : Vérification d'identité, et Vérification de l'e-mail ou du téléphone pour le code. Voir [Signature électronique](https://docs.didit.me/fr/core-technology/electronic-signature/overview.md).

| Champ de configuration | Type | Description |
| - | - | - |
| `signature_documents` | tableau | Les documents importés dans ce workflow depuis la console, dans l'ordre dans lequel le signataire les voit, au format `[{"uuid", "title", "file_name", "pages", "size_bytes"}]`. Seules les valeurs `uuid` et leur ordre sont lus ; le reste provient des fichiers enregistrés. Jusqu'à 20 documents et 50 MB au total. Par défaut `[]`. |
| `signature_documents_source` | chaîne | Origine des documents : `workflow` (par défaut), `session` (`sign.documents` sur [Créer une session](https://docs.didit.me/fr/sessions-api/create-session.md#documents-de-signature-électronique)) ou `both` (documents du workflow en premier). |
| `signature_require_read_to_end` | booléen | Le signataire doit atteindre la fin de chaque document ne comportant aucun champ avant de l'accepter. Par défaut `true`. |
| `signature_consent_per_document` | booléen | Le signataire accepte séparément chaque document ne comportant aucun champ. Pour les documents avec champs, les champs guidés et le consentement final le remplacent. Par défaut `true`. |
| `signature_signer` | chaîne | Qui signe : `verified_person` (par défaut, KYC), ou pour KYB `legal_representative` (personnes clés avec le rôle `representative` ou `authorized_signatory`) ou `key_people` (chaque personne physique clé disposant d'une session KYC). |
| `signature_level` | chaîne | `simple` (par défaut) : aucune vérification d'identité, d'e-mail, de téléphone ni de code ; le signataire saisit son nom et signe via le lien de session. `aes` : nécessite une vérification d'identité approuvée, un e-mail ou un téléphone vérifié, et un code à usage unique. `simple` est refusé pour les signataires `legal_representative` et `key_people` avec `signature_simple_requires_verified_person`. Tant que `signature_availability.aes` vaut `false` sur le workflow, l'enregistrement d'une nouvelle étape `aes` renvoie `400` avec `aes_not_available`. `qes` est bientôt disponible : son enregistrement renvoie `400` avec `qes_not_available`. |
| `signature_format` | chaîne | `pades` (par défaut). `xades` et `cades` sont refusés pour AES avec `signature_format_not_supported`. |
| `signature_otp_channel` | chaîne | Destination du code à usage unique : `email` (par défaut) ou `sms`. Il n'est envoyé qu'à un contact vérifié plus tôt dans la session. |
| `signature_email_signed_copy` | booléen | Envoyez au signataire une copie des documents signés par e-mail. Nécessite un e-mail vérifié. Par défaut `true`. |
| `signature_evidence_page` | booléen | Ajoutez la page de preuves à chaque PDF signé. Par défaut `true`. |
| `signature_link_validity_days` | entier | Durée de validité du lien de signature, de `1` à `30` jours à compter de la création de la session. Par défaut `7`. |
| `signature_declined_action` | action | Verdict lorsque le signataire refuse. Rien n'est facturé. Par défaut `REVIEW`. |
| `signature_otp_failed_action` | action | Verdict après 3 codes erronés ou plus de 5 codes demandés. Par défaut `DECLINE`. |
| `signature_name_mismatch_action` | action | Verdict lorsque le nom déclaré d'une personne clé ne correspond pas à son nom vérifié. Par défaut `DECLINE`. |
| `signature_identity_not_verified_action` | action | Verdict lorsque le signataire ne dispose d'aucune preuve d'identité approuvée. Par défaut `DECLINE`. |
| `signature_document_changed_action` | action | Verdict lorsqu'un document ne correspond plus au SHA-256 enregistré au moment de son affichage. Par défaut `DECLINE`. |
| `status_rules` | tableau | Règles de statut personnalisées facultatives. Vous pouvez cibler `signature.status`, `signature.level` et `signature.format`. |

Les champs d'un document de workflow se placent dans l'éditeur de modèles de la console. Pour les documents de session, envoyez-les dans `sign.documents[].fields`, et envoyez les valeurs des champs `api.<key>` dans `sign.field_values`. Voir [Créer une session](https://docs.didit.me/fr/sessions-api/create-session.md#documents-de-signature-électronique).

Exemple, pour des documents envoyés avec chaque session :

```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.