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

# Modèles de données Didit : schémas JSON d'API

> Schémas JSON Didit pour chaque rapport : NFC, ID, liveness, Face Match, AML, IP, justificatif de domicile, téléphone, e-mail et KYB.

## Vue d'ensemble

Chaque rapport par fonctionnalité suit la structure du sérialiseur V3 définie dans `service-didit-verification`. Le même objet apparaît à trois endroits, de sorte que le schéma présenté ici constitue la source unique de vérité pour ces trois emplacements :

* `GET /v3/session/{sessionId}/decision/` — chaque fonctionnalité est renvoyée sous la forme d'un tableau au pluriel (`id_verifications[]`, `nfc_verifications[]`, `liveness_checks[]`, `face_matches[]`, `poa_verifications[]`, `phone_verifications[]`, `email_verifications[]`, `aml_screenings[]`, `ip_analyses[]`, `database_validations[]`, `questionnaire_responses[]`, `signatures[]`, `bank_verifications[]` (voir [Méthodes de vérification bancaire](https://docs.didit.me/fr/core-technology/bank-verification/verification-methods.md#lire-la-méthode-dans-le-résultat)), ainsi que les équivalents KYB `registry_checks[]`, `document_verifications[]`, `key_people_checks[]`).
* Payloads de webhook (`status.updated`, `data.updated`) — même structure à l'intérieur de l'enveloppe `decision`.
* API autonomes — les réponses sous forme d'objet unique (Face Search, Age Estimation, Biometric Authentication) réutilisent le même ensemble de champs.

> [!NOTE]
>
> La V3 a introduit les workflows multi-instances : chaque objet de fonctionnalité comporte un champ `node_id` qui rattache le rapport au nœud du graphe de workflow qui l'a généré. Les endpoints V2 (au singulier `kyc`, `face`, `aml`, etc.) restent rétrocompatibles mais ne renvoient que la première instance.

## Champs communs

Chaque objet de rapport expose les éléments suivants :

| Champ | Type | Description |
| - | - | - |
| `status` | string | Statut du cycle de vie au niveau de la fonctionnalité — l'une des valeurs de l'[Énumération des statuts](#référence-des-énumérations-de-statut). Source : `common/config/choices.py:FeatureStatusChoices` (lignes 343-348). Le `status` de premier niveau de la session parente utilise l'enum de session plus étendu (`StatusChoices`, lignes 106-117). |
| `node_id` | string \| null | Identifiant du nœud du graphe de workflow. Renseigné pour les workflows multi-instances V3 ; `null` pour les sessions héritées à fonctionnalité unique. |
| `warnings` | tableau d'[objets d'avertissement](#objet-d’avertissement) | Signaux de risque filtrés pour cette fonctionnalité et ce `node_id`. Renvoyé par `Session.get_logs(...)` (`sessions/models/session.py:1611`). |

Les champs de médias (`portrait_image`, `front_image`, `document_file`, …) sont des URL pré-signées avec une fenêtre de validité limitée — téléchargez-les rapidement plutôt que de conserver l'URL. Les exemples les présentent sous la forme `https://<media-host>/...`.

## Objet d'avertissement

Renvoyé dans chaque tableau `warnings[]`. Schéma issu de `logs/serializers/log.py:8-65` (`LogV3Serializer`).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `feature` | string (enum) | Non | Fonctionnalité ayant émis l'avertissement. Valeurs issues de `LogWarningChoices` (`common/config/choices.py:190-204`) : `ID_VERIFICATION`, `NFC`, `LIVENESS`, `FACEMATCH`, `PROOF_OF_ADDRESS`, `PHONE`, `EMAIL`, `AML`, `LOCATION`, `DATABASE_VALIDATION`, `QUESTIONNAIRE`, `KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`. | `"ID_VERIFICATION"` |
| `risk` | string | Non | Code de risque stable (par ex. `DOCUMENT_EXPIRED`, `LOW_LIVENESS_SCORE`). Valeurs issues de `logs/choices.py:RiskChoices`. Utilisé comme clé d'accès aux tables de descriptions. | `"DOCUMENT_EXPIRED"` |
| `additional_data` | object \| null | Oui | Contexte spécifique au risque (par ex. seuils de score, champs correspondants). La structure varie selon le code de risque. | `{ "score": 42.1, "threshold": 70 }` |
| `log_type` | string (enum) | Non | L'une des valeurs `error`, `warning`, `information`. Issu de `LogTypeChoices` (`common/config/choices.py:207-210`). | `"error"` |
| `short_description` | string | Non | Libellé compréhensible du risque. Issu de `logs/choices.py:RISK_SHORT_DESCRIPTIONS`. | `"Document expired"` |
| `long_description` | string | Non | Explication plus détaillée et compréhensible adaptée aux interfaces destinées aux utilisateurs finaux. Issu de `logs/choices.py:RISK_LONG_DESCRIPTIONS`. | `"The document's expiration date has passed, rendering it no longer valid for use."` |
| `node_id` | string \| null | Oui | Nœud du graphe de workflow pour lequel l'avertissement a été déclenché. `null` pour les journaux V2 hérités sans `node_id`. | `"first_id_verification"` |

```json theme={null}
{
  "feature": "ID_VERIFICATION",
  "risk": "DOCUMENT_EXPIRED",
  "additional_data": null,
  "log_type": "error",
  "short_description": "Document expired",
  "long_description": "The document's expiration date has passed, rendering it no longer valid for use.",
  "node_id": "first_id_verification"
}
```

## Objets de rapport

Les sections suivantes couvrent chaque objet de rapport par fonctionnalité. Le texte des titres H3 est volontairement stable afin que d'autres documentations puissent pointer vers eux par lien direct.

### Vérification d'identité

Renvoyé pour chaque document KYC/d'identité soumis par un utilisateur. Apparaît sous la forme `id_verifications[]` dans `GET /v3/session/{sessionId}/decision/` et dans le champ `kyc` des réponses V2. Source : `kyc/serializers/kyc.py:383-414` (`IDVerificationV3Serializer`, étend `IDVerificationV2Serializer` à `kyc/serializers/kyc.py:320-380`).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `status` | string | Non | Voir [Enum des statuts](#référence-des-énumérations-de-statut). | `"Approved"` |
| `document_type` | string | Oui | Classe de document lisible par l'humain (`Passport`, `Identity Card`, `Driver's License`, `Residence Permit`, `Health Insurance Card`, `Tax Card`, `Social Security Card`, `Work Permit`, `Visa`, `Public Service Card`, `Birth Certificate`, `Firearm License`, `Other`). Source : `DOC_TYPE_MAPPING` (`common/config/choices.py:1275-1289`). | `"Passport"` |
| `document_subtype` | string | Oui | Code de sous-type de document provenant du registre des documents de Didit, filtré selon ce que les paramètres de documents du workflow acceptent. Les documents spécifiques à une région incluent la région. Liste complète des codes : [Sous-types de documents](https://docs.didit.me/fr/core-technology/id-verification/document-subtypes-id-verification.md). | `"QUEENSLAND_DRIVER_LICENSE_GENERIC"` |
| `document_number` | string | Oui | Numéro de document extrait par OCR. | `"AB1234567"` |
| `personal_number` | string | Oui | Identifiant personnel/national extrait par OCR. | `"99999999R"` |
| `portrait_image` | string (URL) | Oui | URL pré-signée vers le recadrage du visage. | `"https://<media-host>/.../portrait.jpg?..."` |
| `front_image` | string (URL) | Oui | URL pré-signée vers le recto nettoyé du document. | `"https://<media-host>/.../front.jpg?..."` |
| `front_video` | string (URL) | Oui | URL pré-signée vers la vidéo de capture du recto (si disponible). | `"https://<media-host>/.../front.mp4?..."` |
| `back_image` | string (URL) | Oui | URL pré-signée vers le verso nettoyé du document. | `"https://<media-host>/.../back.jpg?..."` |
| `back_video` | string (URL) | Oui | URL pré-signée vers la vidéo de capture du verso. | `null` |
| `full_front_image` | string (URL) | Oui | Capture du recto non rognée (plein cadre). | `"https://<media-host>/.../full_front.jpg?..."` |
| `full_back_image` | string (URL) | Oui | Capture du verso non rognée (plein cadre). | `null` |
| `front_image_camera_front` | string (URL) | Oui | Image de la caméra avant prise en même temps que le recto du document. | `null` |
| `back_image_camera_front` | string (URL) | Oui | Image de la caméra avant prise en même temps que le verso du document. | `null` |
| `front_image_camera_front_face_match_score` | float (0-100) | Oui | Similarité entre le portrait du document et la capture de la caméra avant. | `null` |
| `back_image_camera_front_face_match_score` | float (0-100) | Oui | Même chose que ci-dessus, mais pour la capture du verso. | `null` |
| `document_selfie_face_matches` | array | Oui | Sessions précédentes ou entrées de la liste de blocage des visages correspondant au selfie pris lors de la capture du document. Même format d'entrée que `liveness_checks[].matches`. `null` lorsque la recherche n'a pas été exécutée, `[]` lorsque rien ne correspond. | `null` |
| `front_image_quality_score` | object | Oui | Métriques de qualité pour l'image du recto : scores de 0 à 100 (`focus_score`, `brightness_score`, `resolution_score`, `overall_score`), plus `brightness_issue` (`ok`, `too_dark`, `too_bright`) et `is_document_fully_visible` (booléen). | `{ "focus_score": 91.0, "overall_score": 88.5 }` |
| `back_image_quality_score` | object | Oui | Même structure que `front_image_quality_score`. | `null` |
| `date_of_birth` | string (YYYY-MM-DD) | Oui | Date de naissance extraite par OCR. | `"1990-05-12"` |
| `age` | integer | Oui | Âge calculé en années au moment de l'extraction. | `35` |
| `expiration_date` | string (YYYY-MM-DD) | Oui | Expiration du document. | `"2032-05-11"` |
| `date_of_issue` | string (YYYY-MM-DD) | Oui | Date de délivrance du document. | `"2022-05-11"` |
| `issuing_state` | string (ISO 3166-1 alpha-3) | Oui | Code du pays de délivrance. | `"ESP"` |
| `issuing_state_name` | string | Oui | Nom localisé du pays de délivrance. | `"Spain"` |
| `first_name` | string | Oui | Prénom(s) extrait(s) par OCR. | `"María"` |
| `last_name` | string | Oui | Nom(s) de famille extrait(s) par OCR. | `"García López"` |
| `full_name` | string | Oui | Nom complet normalisé (fourni par le fournisseur). | `"María García López"` |
| `gender` | string | Oui | `M`, `F` ou autre valeur fournie par le fournisseur. | `"F"` |
| `address` | string | Oui | Ligne d'adresse brute extraite par OCR. | `"Calle Mayor 1, 28001 Madrid"` |
| `formatted_address` | string | Oui | Adresse géocodée/formatée (lorsqu'elle est analysable). | `"Calle Mayor 1, 28001 Madrid, Spain"` |
| `parsed_address` | object | Oui | Adresse structurée et géocodée : `street_1`, `street_2`, `city`, `region`, `country`, `postal_code`, `address_type`, `formatted_address`, `document_location` (`{latitude, longitude}`), `raw_results`, `is_best_match`. Source : `kyc/utils/address.py:147-197`. | `{ "street_1": "Calle Mayor 1", "city": "Madrid", "postal_code": "28001", "country": "ES" }` |
| `place_of_birth` | string | Oui | Lieu de naissance extrait par OCR. | `"Madrid"` |
| `marital_status` | string | Oui | Lorsqu'il peut être extrait. | `null` |
| `nationality` | string (ISO 3166-1 alpha-3) | Oui | Nationalité extraite par OCR. | `"ESP"` |
| `extra_fields` | object | Oui | Champs spécifiques au type de document non couverts par le schéma canonique (par ex. catégories de permis de conduire). | `{ "DL Class": "B" }` |
| `mrz` | object | Oui | Champs MRZ analysés lorsqu'ils sont présents (`document_number`, `birth_date`, `expiry_date`, `surname`, `given_names`, …). | `{ "document_number": "AB1234567", "surname": "GARCIA", "given_names": "MARIA" }` |
| `extra_files` | array de strings (URL) | Non | URLs pré-signées vers tous les fichiers supplémentaires téléversés. | `[]` |
| `matches` | array d'objets | Non | Correspondances de documents entre sessions. Chaque élément : `{ session_id, session_number, vendor_data, verification_date, user_details: { name, document_type, document_number }, status, is_blocklisted, api_service, front_image_url }`. `front_image_url` est pré-signée. | `[]` |
| `verification_method` | string | Non | La [méthode de vérification d'identité](https://docs.didit.me/fr/core-technology/id-verification/verification-methods.md) ayant produit cette ligne : `document`, `id_lookup` ou `wallet`. Toujours `document` pour un document photographié, y compris pour chaque session créée avant l'apparition des autres méthodes. | `"id_lookup"` |
| `assurance` | string | Non | Niveau d'assurance dérivé de `verification_method` : `documentary`, `data_match` ou `cryptographic`. | `"data_match"` |
| `wallet_provider` | string \| null | Oui | Identifiant du portefeuille du catalogue lorsqu'un portefeuille a produit cette ligne (`mitid`, `bankid_se`, `itsme`, ...). `null` dans le cas contraire. | `"mitid"` |
| `fallback_from` | object \| null | Oui | Raison pour laquelle une méthode autre qu'un document a mis fin à l'étape d'identité : `{ method, reason, action }`. Renseigné lorsqu'une recherche ou une connexion par portefeuille a échoué : sur la ligne refusée lorsque le paramètre du pays était `decline` (`action: "decline"`), et sur la vérification de document avec laquelle l'utilisateur poursuit lorsque c'était `fallback_to_document` (`action: "fallback_to_document"`). `null` si aucun échec antérieur sans document n'est enregistré. | `{ "method": "id_lookup", "reason": "no_match", "action": "decline" }` |
| `id_lookup` | object \| null | Oui | Éléments probants provenant de la source, présents uniquement lorsque `verification_method` est `id_lookup` : `source` (la source exacte interrogée — un registre gouvernemental dans la plupart des pays, un fichier de bureau de crédit ou de registres de résidence dans certains), `checked_at`, `attempts`, `max_attempts`, `outcome` (`match`, `partial_match`, `no_match`, `provider_error`, `format_rejected`), `comparison[]` (`{ field, label, provided, record, result }` ; `field` correspond à `identification_number`, `full_name`, `date_of_birth` ou `address`, et `result` vaut `match`, `partial` ou `no_match` ; les versions antérieures peuvent inclure une ligne `provider` avec `error`), `source_errors[]` (actuellement en environnement de préproduction : diagnostics de source distincts ; déploiement en production à confirmer), `registry_portrait` (URL présignée, uniquement pour les sources qui en renvoient une) et `face_match_score`. | voir ci-dessous |
| `wallet_verification` | object \| null | Oui | Données justificatives, présentes uniquement lorsque `verification_method` est `wallet` : `provider`, `provider_name`, `issuing_authority`, `issuing_country`, `credential_type`, `level_of_assurance` (`low`, `substantial`, `high`), `verified_at`, `signature_valid`, `attributes` (ce que le portefeuille a partagé), `portrait` (URL présignée lorsque le portefeuille en partage un) et `face_match_score`. | voir ci-dessous |
| `document_liveness` | object \| null | Oui | Scores de détection du vivant du document par type de fraude (`portrait_replace`, `printed_copy`, `screen_replay`), signalés qu'un avertissement ait été déclenché ou non. Chaque élément comprend : `score` (0-100, plus il est élevé, plus le document est probablement authentique ; valeur la plus basse, qui est celle utilisée par la décision), `front`, `back`, `decline_threshold`, `review_threshold`, `bucket` (`approve`, `review`, `decline` ou `null`). Les seuils et la catégorie sont enregistrés au moment de l'évaluation ; tous trois sont à `null` lorsque les preuves historiques d'évaluation ne sont pas disponibles, tandis que les scores stockés restent visibles. `null` lorsque la vérification n'a pas été exécutée. Voir [Scores de détection du vivant du document](https://docs.didit.me/fr/core-technology/id-verification/report-id-verification.md#scores-de-détection-du-vivant-du-document). V3 uniquement. | `{ "portrait_replace": { "score": 96.46, "bucket": "approve" } }` |
| `node_id` | string \| null | Oui | Identifiant du nœud de workflow (V3). | `"first_id_verification"` |
| `warnings` | array | Non | Voir [Objet d'avertissement](#objet-d’avertissement). | `[]` |
| `region` | string | Oui | Région ou État du pays de délivrance, lorsque le document en identifie un. | `"CA"` |
| `extracted_data` | object | Oui | Instantané des données extraites du document présentées à la personne pour examen, conservé à côté des valeurs confirmées pour vous permettre de les comparer. `null` lorsque la personne n'a pas été invitée à vérifier. | |
| `barcodes` | tableau d'objets | Non | Données lues à partir des codes-barres du document, une entrée par code-barres avec `type`, `position`, `data`, `data_raw` et `side`. `[]` lorsqu'il n'y en a aucun. | `[]` |

```json theme={null}
{
  "status": "Approved",
  "document_type": "Passport",
  "document_subtype": "PASSPORT_GENERIC",
  "document_number": "AB1234567",
  "personal_number": "99999999R",
  "portrait_image": "https://<media-host>/.../portrait.jpg?signature=...",
  "front_image": "https://<media-host>/.../front.jpg?signature=...",
  "front_video": null,
  "back_image": "https://<media-host>/.../back.jpg?signature=...",
  "back_video": null,
  "full_front_image": "https://<media-host>/.../full_front.jpg?signature=...",
  "full_back_image": null,
  "front_image_camera_front": null,
  "back_image_camera_front": null,
  "front_image_camera_front_face_match_score": null,
  "back_image_camera_front_face_match_score": null,
  "front_image_quality_score": {
    "focus_score": 91.0,
    "brightness_score": 88.0,
    "brightness_issue": "ok",
    "is_document_fully_visible": true,
    "resolution_score": 95.0,
    "overall_score": 88.5
  },
  "back_image_quality_score": null,
  "date_of_birth": "1990-05-12",
  "age": 35,
  "expiration_date": "2032-05-11",
  "date_of_issue": "2022-05-11",
  "issuing_state": "ESP",
  "issuing_state_name": "Spain",
  "first_name": "María",
  "last_name": "García López",
  "full_name": "María García López",
  "gender": "F",
  "address": "Calle Mayor 1, 28001 Madrid",
  "formatted_address": "Calle Mayor 1, 28001 Madrid, Spain",
  "parsed_address": { "street_1": "Calle Mayor 1", "street_2": null, "city": "Madrid", "region": "Madrid", "postal_code": "28001", "country": "ES", "address_type": "Calle" },
  "place_of_birth": "Madrid",
  "marital_status": null,
  "nationality": "ESP",
  "extra_fields": {},
  "mrz": {
    "document_number": "AB1234567",
    "surname": "GARCIA",
    "given_names": "MARIA",
    "birth_date": "900512",
    "expiry_date": "320511"
  },
  "extra_files": [],
  "matches": [],
  "node_id": "first_id_verification",
  "verification_method": "document",
  "assurance": "documentary",
  "wallet_provider": null,
  "fallback_from": null,
  "id_lookup": null,
  "wallet_verification": null,
  "document_liveness": {
    "portrait_replace": {
      "score": 96.46,
      "front": 96.46,
      "back": 98.2,
      "decline_threshold": 35,
      "review_threshold": 70,
      "bucket": "approve"
    },
    "printed_copy": {
      "score": 91.2,
      "front": 91.2,
      "back": 93.7,
      "decline_threshold": 35,
      "review_threshold": 77,
      "bucket": "approve"
    },
    "screen_replay": {
      "score": 99.9,
      "front": 99.9,
      "back": 99.5,
      "decline_threshold": 30,
      "review_threshold": 70,
      "bucket": "approve"
    }
  },
  "warnings": []
}
```

Le même objet avec une méthode sans document. Seules les clés spécifiques à la méthode changent — tout ce qu'une lecture de document renseigne est extrait de l'enregistrement du registre ou des attributs du portefeuille, et les clés qui ne s'appliquent pas sont à `null`.

```json theme={null}
{
  "status": "Approved",
  "issuing_state": "ZAF",
  "first_name": "Thabo",
  "last_name": "Mokoena",
  "full_name": "Thabo Mokoena",
  "date_of_birth": "1991-06-15",
  "personal_number": "9106155043088",
  "node_id": "first_id_verification",
  "verification_method": "id_lookup",
  "assurance": "data_match",
  "wallet_provider": null,
  "fallback_from": null,
  "id_lookup": {
    "source": "Department of Home Affairs",
    "checked_at": "2026-09-04T09:12:44Z",
    "attempts": 1,
    "max_attempts": 2,
    "outcome": "match",
    "comparison": [
      { "field": "identification_number", "label": "ID number", "provided": "9106155043088", "record": "9106155043088", "result": "match" },
      { "field": "full_name", "label": "Full name", "provided": "Thabo Mokoena", "record": "Thabo Mokoena", "result": "match" },
      { "field": "date_of_birth", "label": "Date of birth", "provided": "1991-06-15", "record": "1991-06-15", "result": "match" }
    ],
    "registry_portrait": "https://<media-host>/.../registry_portrait.jpg?signature=...",
    "face_match_score": 96.4
  },
  "wallet_verification": null,
  "warnings": []
}
```

```json theme={null}
{
  "status": "Approved",
  "issuing_state": "DNK",
  "first_name": "Freja",
  "last_name": "Nielsen",
  "full_name": "Freja Nielsen",
  "date_of_birth": "1988-03-02",
  "node_id": "first_id_verification",
  "verification_method": "wallet",
  "assurance": "cryptographic",
  "wallet_provider": "mitid",
  "fallback_from": null,
  "id_lookup": null,
  "wallet_verification": {
    "provider": "mitid",
    "provider_name": "MitID",
    "issuing_authority": "Danish Agency for Digital Government",
    "issuing_country": "DNK",
    "credential_type": "person_identification",
    "level_of_assurance": "substantial",
    "verified_at": "2026-09-04T09:12:44Z",
    "signature_valid": true,
    "attributes": {
      "full_name": "Freja Nielsen",
      "date_of_birth": "1988-03-02",
      "cpr_alias": "b0f1c2d3-e4f5-4678-9abc-def012345678"
    },
    "portrait": null,
    "face_match_score": null
  },
  "warnings": []
}
```

### Vérification NFC

Renvoyé pour chaque lecture de puce effectuée sur un document d'identité : une puce de passeport électronique ou d'eID OACI 9303, ou une carte My Number japonaise lue via JPKI (`chip_protocol: "jpki"`). Apparaît sous forme de `nfc_verifications[]` dans `GET /v3/session/{sessionId}/decision/` (une par enregistrement KYC parent). Source : `kyc/serializers/epassport.py:121-139` (`NFCV3Serializer`, étend `NFCV2Serializer` dans `kyc/serializers/epassport.py:83-118`).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `status` | string | Non | Voir [Énumération des statuts](#référence-des-énumérations-de-statut). | `"Approved"` |
| `portrait_image` | string (URL) | Oui | URL présignée vers l'image du visage extraite de la puce. | `"https://<media-host>/.../nfc_portrait.jpg?..."` |
| `signature_image` | string (URL) | Oui | URL présignée vers l'image de la signature extraite de la puce (lorsqu'elle y est stockée). | `null` |
| `chip_data` | object | Oui | Données personnelles analysées à partir des Data Groups de la puce, aplaties (`kyc/utils/epassport.py:165-212`) : `dgs` (Data Groups lus), `surname`, `name`, `country`, `nationality`, `birth_date` (`YYYY-MM-DD`), `expiry_date` (`YYYY-MM-DD`), `sex` (`M`/`F`), `document_type` (code de document MRZ), `document_number`, `optional_data`, chiffres de contrôle MRZ (`birth_date_hash`, `expiry_date_hash`, `document_number_hash`, `optional_data_hash`, `final_hash`), `mrz_string`, `mrz_type` (`TD1`/`TD2`/`TD3`) ; ainsi que `place_of_birth` et `address` (et `full_name` / `full_name_non_latin` pour les noms non latins) lorsque la puce contient le DG11 — ces clés sont absentes dans le cas contraire. `null` lorsque l'étape NFC a été ignorée. | `{ "document_number": "AB1234567", "name": "MARIA" }` |
| `authenticity` | object | Oui | `{ sod_integrity, dg_integrity }` ; `null` pour une lecture JPKI. `sod_integrity` valide que la signature du Document Security Object (SOD) remonte à une CSCA valide du pays de délivrance (et que le DSC n'est ni révoqué ni expiré) ; `dg_integrity` valide que les hachages de chaque Data Group correspondent au SOD. Le fait que les deux valent `true` indique que la puce est authentique et n'a pas été altérée. | `{ "sod_integrity": true, "dg_integrity": true }` |
| `certificate_summary` | object | Oui | Résumé du certificat du signataire du document (`kyc/utils/epassport.py:338-348`) : `issuer`, `subject`, `serial_number` (entier), `not_valid_before`, `not_valid_after` (`YYYY-MM-DD HH:MM:SS`), ainsi qu'un objet `validation` `{ csca_verified, dsc_revoked, dsc_expired, csca_expired }` (`kyc/views/epassport.py:86`). | `{ "issuer": "Common Name: CSCA SPAIN, Country: ES", "not_valid_after": "2031-02-18 10:21:11" }` |
| `node_id` | string \| null | Oui | Identifiant du nœud du workflow (V3). | `"first_nfc"` |
| `is_nfc_skipped` | boolean | Non | `true` lorsque cette étape NFC a été explicitement ignorée au lieu d'être lue ; `skip_reason` en indique la raison. | `false` |
| `skip_reason` | string | Oui | Raison pour laquelle l'étape a été ignorée — défini uniquement lorsque `is_nfc_skipped` vaut `true`. L'une des valeurs suivantes : `USER_SKIPPED`, `DOCUMENT_WITHOUT_CHIP`, `CHIP_CERTIFICATE_UNAVAILABLE`, `DEVICE_WITHOUT_NFC`, `INTEGRATION_WITHOUT_NFC_ACCESS`, `MRZ_KEY_UNAVAILABLE`, `JPKI_UNAVAILABLE` ; voir [Raisons d'omission](https://docs.didit.me/fr/core-technology/nfc-verification/warnings-nfc-verification.md#motifs-d’omission). Le payload de décision contient également un champ `nfc_skip_reason` au niveau de la session avec la même taxonomie, couvrant les étapes NFC contournées avant la création d'un rapport. | `null` |
| `chip_protocol` | string | Non | Manière dont la puce est lue : `icao` (puce de passeport électronique ou d'eID ICAO 9303) ou `jpki` (carte japonaise My Number). Pour `jpki`, `portrait_image`, `signature_image`, `chip_data`, `authenticity` et `certificate_summary` sont `null`. Également défini pour les étapes ignorées. | `"icao"` |
| `jpki` | object | Oui | Ce que la lecture d'une carte My Number a prouvé : `certificate_types`, `chain_valid`, `signature_valid`, `revocation_status` (`good`, `revoked` ou `unchecked`), `ca_generation`, `certificate_expires_at`, `certificates[]`, `attributes` (nom, date de naissance, sexe et adresse issus du certificat de signature), `attributes_match_ocr` et `mismatched_attributes`. Ne contient jamais les certificats, leurs numéros de série ni les signatures. `null` pour les puces ICAO, pour les étapes ignorées et lorsque l'étape s'est terminée sans aucune lecture de carte. Voir [Champs JPKI](https://docs.didit.me/fr/core-technology/nfc-verification/report-nfc-verification.md#champs-jpki). | `null` |
| `warnings` | array | Non | Voir [Objet d'avertissement](#objet-d’avertissement). | `[]` |

```json theme={null}
{
  "status": "Approved",
  "portrait_image": "https://<media-host>/.../nfc_portrait.jpg?signature=...",
  "signature_image": null,
  "chip_data": {
    "dgs": ["DG1", "DG2", "DG11"],
    "surname": "GARCIA LOPEZ",
    "name": "MARIA",
    "country": "ESP",
    "nationality": "ESP",
    "birth_date": "1990-05-12",
    "expiry_date": "2032-05-11",
    "sex": "F",
    "document_type": "P",
    "document_number": "AB1234567",
    "optional_data": "",
    "birth_date_hash": "4",
    "expiry_date_hash": "7",
    "document_number_hash": "3",
    "optional_data_hash": "",
    "final_hash": "8",
    "mrz_string": "P<ESPGARCIA<LOPEZ<<MARIA<<<<<<<<<<<<<<<<<<<<AB1234567ESP9005124F3205117<<<<<<<<<<<<<<08",
    "mrz_type": "TD3",
    "place_of_birth": "MADRID",
    "address": "CALLE MAYOR 1, MADRID"
  },
  "authenticity": { "sod_integrity": true, "dg_integrity": true },
  "certificate_summary": {
    "issuer": "Common Name: CSCA SPAIN, Organization: DIRECCION GENERAL DE LA POLICIA, Country: ES",
    "subject": "Common Name: DS n-eID SPAIN 2, Organizational Unit: PASSPORT, Organization: DIRECCION GENERAL DE LA POLICIA, Country: ES",
    "serial_number": 118120836164494130086420187336801405660,
    "not_valid_before": "2020-11-18 10:21:11",
    "not_valid_after": "2031-02-18 10:21:11",
    "validation": {
      "csca_verified": true,
      "dsc_revoked": false,
      "dsc_expired": false,
      "csca_expired": false
    }
  },
  "node_id": "first_nfc",
  "is_nfc_skipped": false,
  "skip_reason": null,
  "chip_protocol": "icao",
  "jpki": null,
  "warnings": []
}
```

### Détection du vivant

Renvoyé pour chaque session de détection du vivant. Apparaît sous la forme `liveness_checks[]` dans `GET /v3/session/{sessionId}/decision/`. Source : `face/serializers/face.py:301-320` (`LivenessV3Serializer`, étend `LivenessV2Serializer` dans `face/serializers/face.py:216-298`).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `status` | string | Non | Voir [Enum de statut](#référence-des-énumérations-de-statut). | `"Approved"` |
| `method` | string (enum) | Oui | `ACTIVE_3D`, `FLASHING` ou `PASSIVE` (`LivenessMethodChoices`, `common/config/choices.py:514-517`). Le mode passif s'exécute lorsque les sessions sur ordinateur de bureau sont autorisées et que l'utilisateur est sur un ordinateur de bureau. | `"PASSIVE"` |
| `score` | float (0-100) | Oui | Confiance de la détection du vivant, arrondie à 2 décimales. | `92.41` |
| `reference_image` | string (URL) | Oui | URL pré-signée vers le recadrage du visage de référence de l'utilisateur. | `"https://<media-host>/.../reference.jpg?..."` |
| `video_url` | string (URL) | Oui | URL pré-signée vers la vidéo de détection du vivant (mode actif uniquement). | `"https://<media-host>/.../liveness.webm?..."` |
| `age_estimation` | float | Oui | Âge estimé (en années) du visage le plus grand dans l'image de référence. | `34.2` |
| `matches` | tableau d'objets | Non | Correspondances faciales entre sessions. Chaque élément : `{ session_id, session_number, similarity_percentage, vendor_data, vendor_user_id, biometric_template_id, verification_date, user_details: { full_name, document_type, document_number }, match_image_url, status, is_blocklisted, is_allowlisted, api_service, source }`. `source` vaut `session`, `imported`, `list_entry` ou `retained_template`. Une correspondance sur gabarit biométrique conservé comporte `vendor_user_id`, `vendor_data` et `biometric_template_id` ; ses champs relatifs à la session, à l'image, aux détails d'identité, au statut et au service d'API sont `null`. | `[]` |
| `face_quality` | float (0-100) | Oui | Score de qualité du visage pour la détection passive du vivant (normalisé sous forme de pourcentage). | `87.50` |
| `face_luminance` | float (0-100) | Oui | Score de luminance du visage pour la détection passive du vivant (normalisé de 0-255 en pourcentage). | `54.12` |
| `node_id` | string \| null | Oui | Identifiant du nœud du workflow (V3). | `"first_liveness"` |
| `warnings` | array | Non | Voir [Objet d'avertissement](#objet-d’avertissement). | `[]` |

```json theme={null}
{
  "status": "Approved",
  "method": "PASSIVE",
  "score": 92.41,
  "reference_image": "https://<media-host>/.../reference.jpg?signature=...",
  "video_url": null,
  "age_estimation": 34.2,
  "matches": [],
  "face_quality": 87.50,
  "face_luminance": 54.12,
  "node_id": "first_liveness",
  "warnings": []
}
```

### Correspondance faciale

Renvoyé pour chaque comparaison faciale (généralement le visage de l'utilisateur issu de la détection du vivant par rapport au portrait du document). Apparaît sous la forme `face_matches[]` dans `GET /v3/session/{sessionId}/decision/`. Source : `face/serializers/face.py:367-389` (`FaceMatchV3Serializer`, étend `FaceMatchV2Serializer` dans `face/serializers/face.py:323-364`).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `status` | string | Non | Voir [Enum de statut](#référence-des-énumérations-de-statut). | `"Approved"` |
| `score` | float (0-100) | Oui | Similarité, arrondie à 2 décimales. Lorsque le fournisseur renvoie uniquement un `unmatched_faces[].Confidence`, cette valeur est convertie en `100 - confidence`. | `97.83` |
| `source_image_session_id` | string (UUID) | Oui | La session dont le portrait stocké a fourni l'image source (de référence) — défini dans les flux basés sur un portrait (authentification biométrique, ou portrait fourni lors de la création de la session). `null` lorsque la référence est le portrait du document de la même session. | `null` |
| `source_image` | string (URL) | Oui | URL pré-signée vers l'image source (de référence) — généralement le portrait du document, ou le portrait stocké dans les flux d'authentification biométrique. | `"https://<media-host>/.../source.jpg?..."` |
| `target_image` | string (URL) | Oui | URL pré-signée vers l'image cible (visage capturé en direct) capturée pendant la détection du vivant. | `"https://<media-host>/.../target.jpg?..."` |
| `node_id` | string \| null | Oui | Identifiant du nœud du workflow (V3). | `"first_face_match"` |
| `warnings` | array | Non | Voir [Objet d'avertissement](#objet-d’avertissement). | `[]` |
| `face_coverage` | object | Oui | Indique si les zones `eyes`, `mouth` et `face` sont couvertes dans l'image capturée. Chaque région comporte `covered`, `calibrated` et `visibility_score` ; `calibrated: false` indique la présence d'ombres, qui ne déclenche aucun avertissement. Renvoyé uniquement par `GET /v3/session/{sessionId}/decision/`, jamais dans les payloads des webhooks. | `{ "eyes": { "covered": false, "calibrated": true, "visibility_score": 0.98 } }` |

```json theme={null}
{
  "status": "Approved",
  "score": 97.83,
  "source_image_session_id": null,
  "source_image": "https://<media-host>/.../source.jpg?signature=...",
  "target_image": "https://<media-host>/.../target.jpg?signature=...",
  "node_id": "first_face_match",
  "warnings": []
}
```

### Recherche faciale

Renvoyée par l'API autonome de Recherche faciale (`POST /v3/face-search/`). La Recherche faciale n'apparaît jamais sous forme de tableau contenant plusieurs éléments dans `/v3/session/{sessionId}/decision/` — lorsqu'elle est conservée avec `save_api_request=true`, la session y figure sous la forme d'une entrée `FACE_SEARCH` dans `features[]` plus un élément `liveness_checks[]` contenant les `matches` enregistrés. Sources : `apis/serializers/face_search.py:8-79` (`FaceSearchResponseSerializer` encapsulant `FaceSearchDetailsSerializer`) ; dictionnaires de correspondance construits dans `face/utils/utils.py:869-884`.

Réponse de premier niveau :

| Champ | Type | Autorise la valeur null | Description | Exemple |
| - | - | - | - | - |
| `request_id` | string (UUID) | Non | L'identifiant de session conservé lorsque `save_api_request=true` (utilisable avec `GET /v3/session/{sessionId}/decision/`) ; sinon un UUID de corrélation temporaire. | `"4a1c2c4e-8b1b-4d6a-91b5-ee9a1f3a2c7f"` |
| `face_search` | object | Non | Le payload des détails de recherche — voir les champs ci-dessous. | — |
| `vendor_data` | string | Oui | `vendor_data` renvoyé tel quel depuis la requête. | `null` |
| `metadata` | object | Oui | `metadata` renvoyé tel quel depuis la requête. | `null` |
| `created_at` | string (ISO 8601) | Non | Horodatage de la requête côté serveur. | `"2026-06-12T01:04:42.763237+00:00"` |

Objet `face_search` :

| Champ | Type | Autorise la valeur null | Description | Exemple |
| - | - | - | - | - |
| `status` | string | Non | `Declined` uniquement lorsqu'un avertissement `FACE_IN_BLOCKLIST` ou `POSSIBLE_FACE_IN_BLOCKLIST` s'est déclenché ; `Approved` sinon — les doublons ne suffisent jamais à entraîner un refus (`apis/views/face_search.py:242-248`). | `"Approved"` |
| `total_matches` | integer | Non | Nombre de correspondances renvoyées dans `matches[]` (0–5). | `1` |
| `matches` | tableau de [objets de correspondance de recherche faciale](#objet-de-correspondance-de-recherche-faciale) | Non | Jusqu'à 5 correspondances au-dessus du seuil de similarité, triées par similarité décroissante (entrées sur liste de blocage en premier avec `search_type=blocklisted_or_approved`). | `[…]` |
| `user_image` | object | Non | Résultat de détection pour l'image envoyée : `{ entities: [{ bbox, confidence }], best_angle }` — une entité par visage détecté. | `{ "entities": [{ "bbox": [40, 40, 120, 120], "confidence": 0.73 }], "best_angle": 0 }` |
| `warnings` | tableau d'objets | Non | Format d'avertissement réduit pour cette API autonome — aucun `node_id`. Le contrat du sérialiseur déclare `{ risk, additional_data, log_type, short_description, long_description }` (`apis/serializers/face_search.py:49-54`) ; le payload d'exécution contient également `feature`, toujours `"LIVENESS"` (`apis/views/face_search.py:332-341`). | `[]` |

#### Objet de correspondance de recherche faciale

| Champ | Type | Autorise la valeur null | Description | Exemple |
| - | - | - | - | - |
| `session_id` | string (UUID) | Oui | La session de vérification correspondante. `null` lorsque `source` est `imported`, `list_entry` ou `retained_template`. | `"a3f2a6f1-…"` |
| `session_number` | integer | Oui | Numéro de la session correspondante, facile à lire dans la console ; `null` pour les correspondances hors session. | `1024` |
| `similarity_percentage` | float (0-100) | Non | Similarité entre le visage envoyé et le visage correspondant. | `96.42` |
| `source` | string (enum) | Non | Origine de l'enrôlement du visage correspondant : `session` (session de vérification ou appel autonome sauvegardé), `imported` (téléversement direct du visage sur le profil utilisateur), `list_entry` (visage associé à une liste), `retained_template` ([gabarit biométrique](https://docs.didit.me/fr/management-api/biometric-templates/overview.md) sans image conservé après la suppression de la session source). | `"session"` |
| `vendor_data` | string | Oui | Le `vendor_data` de la session correspondante, ou celui de l'Utilisateur associé pour les correspondances `imported` et `retained_template`. | `"user-12345"` |
| `vendor_user_id` | string (UUID) | Oui | L'Utilisateur associé. `null` pour les correspondances `list_entry` et pour les sessions sans Utilisateur. | `"2f7c1a9e-…"` |
| `biometric_template_id` | string (UUID) | Oui | Le gabarit conservé ayant produit la correspondance. Renseigné uniquement pour les correspondances `retained_template` ; utilisez-le avec `GET`/`DELETE /v3/biometric-templates/{id}/`. | `null` |
| `verification_date` | string (ISO 8601) | Oui | Date à laquelle le visage correspondant a été capturé, ou à laquelle un `retained_template` a été conservé ; `null` pour les correspondances `list_entry`. | `"2024-11-04T09:14:02Z"` |
| `user_details` | object | Oui | `{ full_name, document_type, document_number }` issus de la vérification de document de la session correspondante ; pour les correspondances `imported`, seul `full_name` est renseigné ; `null` lorsqu'aucune donnée d'identité n'existe et toujours `null` pour les correspondances `retained_template`. | `{ "full_name": "María García López", "document_type": "Passport", "document_number": "AB1234567" }` |
| `match_image_url` | string (URL) | Oui | Visage de référence de l'utilisateur correspondant — URL présignée lorsque `save_api_request=true`, chemin de stockage brut sinon. Toujours `null` pour les correspondances `retained_template`, qui ne contiennent aucune image. | `"https://<media-host>/.../matched.jpg?..."` |
| `status` | string | Oui | Le statut de vérification de la session correspondante (voir [Énumération des statuts](#référence-des-énumérations-de-statut)) ; `null` pour les correspondances hors session. | `"Approved"` |
| `is_blocklisted` | boolean | Non | Indique si le visage correspondant figure sur votre liste de blocage de visages. Toujours `false` pour les correspondances `retained_template` ; un visage sur liste de blocage est signalé séparément comme une correspondance `list_entry`. | `false` |
| `is_allowlisted` | boolean | Non | Indique si le visage correspondant figure sur l'une de vos listes d'autorisation. | `false` |
| `api_service` | string (enum) | Oui | Type d'API autonome en majuscules de la session correspondante (par exemple `PASSIVE_LIVENESS`, `FACE_MATCH`) ; `null` pour les sessions de workflow et les correspondances hors session. | `null` |

```json theme={null}
{
  "request_id": "4a1c2c4e-8b1b-4d6a-91b5-ee9a1f3a2c7f",
  "face_search": {
    "status": "Approved",
    "total_matches": 1,
    "matches": [
      {
        "session_id": "a3f2a6f1-1c1c-4eec-8b69-1c1c2f3a2c7f",
        "session_number": 1024,
        "similarity_percentage": 96.42,
        "source": "session",
        "vendor_data": "user-12345",
        "verification_date": "2024-11-04T09:14:02Z",
        "user_details": {
          "full_name": "María García López",
          "document_type": "Passport",
          "document_number": "AB1234567"
        },
        "match_image_url": "https://<media-host>/.../matched.jpg?signature=...",
        "status": "Approved",
        "is_blocklisted": false,
        "is_allowlisted": false,
        "api_service": null
      }
    ],
    "user_image": {
      "entities": [
        {
          "bbox": [40, 40, 120, 120],
          "confidence": 0.732973
        }
      ],
      "best_angle": 0
    },
    "warnings": []
  },
  "vendor_data": null,
  "metadata": null,
  "created_at": "2026-06-12T01:04:42.763237+00:00"
}
```

### Filtrage AML

Renvoyé pour chaque entité soumise au filtrage. Apparaît sous la forme `aml_screenings[]` dans `GET /v3/session/{sessionId}/decision/` pour les sessions KYC et KYB. Source : `aml/serializers/aml.py:63-85` (`AMLV3Serializer`, étend `AMLV2Serializer` à `aml/serializers/aml.py:28-60`).

| Champ | Type | Autorise la valeur null | Description | Exemple |
| - | - | - | - | - |
| `status` | string | Non | Voir [Énumération des statuts](#référence-des-énumérations-de-statut). | `"Approved"` |
| `total_hits` | integer | Non | Nombre de résultats de filtrage (toujours présent, valeur par défaut `0`). | `2` |
| `entity_type` | string (enum) | Oui | `person` ou `company` (`EntityTypeChoices`, `common/config/choices.py:675-677`). | `"person"` |
| `hits` | tableau d'objets | Non | Une entrée par résultat. Champs clés : `id`, `caption`, `match` (bool), `target` (bool \| null — indique si l'entité est la cible directe de l'inscription sur la liste), `match_score` (score de correspondance : flottant de 0 à 100 indiquant la confiance dans l'identité), `risk_score` (score de risque d'entité sous forme de flottant 0-100), `score` (flottant 0-1 obsolète), `datasets[]` (par exemple `PEP`, `PEP Level 1`-`4`, `Sanctions`, `Adverse Media`, `Warnings and Regulatory Enforcement`, `Fitness and Probity`), `properties` (noms, alias, dates de naissance, …), `features`, `url`, `first_seen`, `last_seen`, `rca_name`, `risk_view`, `score_breakdown`, `pep_matches`, `sanction_matches`, `warning_matches`, `adverse_media_matches`, `adverse_media_details`, `linked_entities`, `additional_information` et `review_status` (`Unreviewed`, `Confirmed Match`, `False Positive`, `Inconclusive` — modifiable via l'endpoint de mise à jour du statut des résultats AML, `AMLHitStatusChoices`). | `[…]` |
| `score` | float (0-100) | Oui | Score global de filtrage — le `risk_score` le plus élevé parmi les résultats non marqués comme `False Positive` (`aml/services/aml.py:832-842`) ; `0` lorsque chaque résultat est un faux positif. `null` jusqu'à ce qu'il soit calculé. | `42.7` |
| `screened_data` | object | Oui | Instantané des données envoyées au filtrage : `full_name`, `nationality`, `date_of_birth`, `document_number`. | `{ "full_name": "María García López", "date_of_birth": "1990-05-12" }` |
| `is_ongoing_monitoring_enabled` | boolean | Non | Indique si l'entité est abonnée aux nouveaux filtrages de surveillance continue. | `false` |
| `next_ongoing_monitoring_bill_date` | string (YYYY-MM-DD) | Oui | Calculé comme `last_aml_bill_date + 365 days` lorsque la surveillance continue est activée. Une date de **facturation**, et non une date de filtrage. | `null` |
| `last_ongoing_screening_at` | string (ISO 8601) | Oui | Date et heure auxquelles la surveillance continue a effectué le dernier nouveau filtrage de cet enregistrement, que le résultat ait changé ou non. `null` s'il n'a jamais fait l'objet d'un nouveau filtrage ; jamais renseigné rétroactivement. | `"2026-09-12T04:03:11Z"` |
| `last_ongoing_screening_datasets_updated_at` | string (ISO 8601) | Oui | Mise à jour la plus récente du jeu de données AML signalée par le fournisseur pour ce filtrage. `null` lorsqu'aucune date de jeu de données n'a été signalée ; jamais estimée. | `null` |
| `node_id` | string \| null | Oui | Identifiant du nœud de workflow (V3). | `"first_aml"` |
| `warnings` | array | Non | Voir [Objet d'avertissement](#objet-d’avertissement). | `[]` |

```json theme={null}
{
  "status": "In Review",
  "total_hits": 1,
  "entity_type": "person",
  "hits": [
    {
      "id": "Q7XW3-aml-hit-1",
      "caption": "Maria Garcia Lopez",
      "match": true,
      "target": true,
      "match_score": 86.4,
      "risk_score": 42.7,
      "datasets": ["PEP Level 2"],
      "properties": {
        "name": ["María García López", "M. García"],
        "alias": ["Maria Garcia"],
        "birthDate": ["1990-05-12"]
      },
      "url": "https://example.org/registry/entities/Q7XW3",
      "first_seen": "2023-11-02T00:00:00Z",
      "last_seen": "2026-05-01T00:00:00Z",
      "review_status": "Unreviewed"
    }
  ],
  "score": 42.7,
  "screened_data": {
    "full_name": "María García López",
    "date_of_birth": "1990-05-12",
    "nationality": "ES",
    "document_number": "AB1234567"
  },
  "is_ongoing_monitoring_enabled": false,
  "next_ongoing_monitoring_bill_date": null,
  "last_ongoing_screening_at": null,
  "last_ongoing_screening_datasets_updated_at": null,
  "node_id": "first_aml",
  "warnings": []
}
```

### Analyse de l'IP

Retournée pour chaque emplacement réseau capturé. Apparaît sous la forme `ip_analyses[]` dans `GET /v3/session/{sessionId}/decision/` pour les sessions KYC et KYB. Source : `kyc/serializers/location.py:196-243` (`IPAnalysisSerializerV3`).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `status` | string | Non | Voir [Énumération des statuts](#référence-des-énumérations-de-statut). | `"Approved"` |
| `node_id` | string \| null | Oui | Identifiant du nœud de workflow (V3). | `"first_ip_analysis"` |
| `device_brand` | string | Oui | Marque de l'appareil dérivée de l'agent utilisateur. | `"Apple"` |
| `device_model` | string | Oui | Modèle de l'appareil. | `"iPhone"` |
| `browser_family` | string | Oui | Famille du navigateur. | `"Mobile Safari"` |
| `os_family` | string | Oui | Famille de l'OS. | `"iOS"` |
| `platform` | string | Oui | Plateforme de haut niveau (`mobile`, `desktop`, `tablet`). | `"mobile"` |
| `device_fingerprint` | string | Oui | Empreinte de hachage stable par appareil. | `"f2a3…"` |
| `ip_country` | string | Oui | Nom du pays résolu à partir de l'IP. | `"Spain"` |
| `ip_country_code` | string (ISO 3166-1 alpha-2) | Oui | Code pays résolu à partir de l'IP. | `"ES"` |
| `ip_state` | string | Oui | Région / état résolu à partir de l'IP. | `"Comunidad de Madrid"` |
| `ip_city` | string | Oui | Ville résolue à partir de l'IP. | `"Madrid"` |
| `latitude` | float | Oui | Latitude dérivée de l'IP. | `40.4168` |
| `longitude` | float | Oui | Longitude dérivée de l'IP. | `-3.7038` |
| `ip_address` | string | Oui | L'adresse IP capturée. | `"203.0.113.42"` |
| `isp` | string | Oui | Nom du FAI. | `"Telefonica de Espana"` |
| `organization` | string | Oui | Nom de l'organisation (souvent identique au FAI). | `"Telefonica de Espana"` |
| `is_vpn_or_tor` | boolean | Oui | `true` lorsque l'IP appartient à un VPN, un proxy ou un nœud de sortie Tor. | `false` |
| `is_data_center` | boolean | Oui | `true` lorsque l'IP appartient à un ASN d'hébergement / centre de données connu. | `false` |
| `time_zone` | string | Oui | Nom du fuseau horaire IANA. | `"Europe/Madrid"` |
| `time_zone_offset` | string | Oui | Décalage UTC. | `"+02:00"` |
| `ip` | object | Non | `{ location, distance_from_id_document, distance_from_poa_document }`. `location = { latitude, longitude }`. Distances en km, `null` si l'une des deux localisations est manquante. | `{ "location": { "latitude": 40.4168, "longitude": -3.7038 }, "distance_from_id_document": 3.4, "distance_from_poa_document": 1.1 }` |
| `id_document` | object | Non | `{ location, distance_from_ip, distance_from_poa_document }`. Emplacement du document d'identité résolu à partir de `issuing_state` et de l'adresse analysée. | `{ "location": { "latitude": 40.4165, "longitude": -3.7026 }, "distance_from_ip": 3.4, "distance_from_poa_document": 4.0 }` |
| `poa_document` | object | Non | `{ location, distance_from_ip, distance_from_id_document }`. Adresse du justificatif de domicile géocodée. | `{ "location": { "latitude": 40.4170, "longitude": -3.7040 }, "distance_from_ip": 1.1, "distance_from_id_document": 4.0 }` |
| `matches` | tableau d'objets | Non | Correspondances IP/appareil entre sessions. Chaque élément : `{ session_id, session_number, vendor_data, verification_date, match_type, match_source, matched_value, status, is_blocklisted, api_service, source, device_info, location_info, confidence, match_mode }`. `match_type` est `ip_address` ou `device_fingerprint` ; `match_source` est `ip_address`, `persistent_id`, `legacy_fp` ou `recovered_high` (les correspondances récupérées contiennent également `recovery_similarity`, `tls_ja4_corroborated`, `recovery_gate_reason`). Limité à 5 correspondances d'IP + 5 correspondances d'appareil. | `[]` |
| `warnings` | array | Non | Voir [Objet d'avertissement](#objet-d’avertissement). | `[]` |
| `browser_version`, `os_version` | string | Oui | Versions du navigateur et du système d'exploitation d'après l'agent utilisateur. | `"17.4"` |
| `user_agent`, `accept_language` | string | Oui | La chaîne de l'agent utilisateur et l'en-tête `Accept-Language` envoyés par le navigateur. | `"en-US,en;q=0.9"` |
| `session_identifier`, `session_age_ms` | string, integer | Oui | La session de navigation dans laquelle l'étape s'est exécutée et son ancienneté en millisecondes. | `48210` |
| `coords_accuracy` | float | Oui | Rayon de précision, en mètres, des coordonnées signalées par l'appareil. | `35.0` |
| `raw_device_data` | object | Oui | Signaux bruts de l'appareil collectés pour l'étape. | `{}` |

```json theme={null}
{
  "status": "Approved",
  "node_id": "first_ip_analysis",
  "device_brand": "Apple",
  "device_model": "iPhone",
  "browser_family": "Mobile Safari",
  "os_family": "iOS",
  "platform": "mobile",
  "device_fingerprint": "f2a3c1de8b994a3f9e4cdf3a02b1a7c9",
  "ip_country": "Spain",
  "ip_country_code": "ES",
  "ip_state": "Comunidad de Madrid",
  "ip_city": "Madrid",
  "latitude": 40.4168,
  "longitude": -3.7038,
  "ip_address": "203.0.113.42",
  "isp": "Telefonica de Espana",
  "organization": "Telefonica de Espana",
  "is_vpn_or_tor": false,
  "is_data_center": false,
  "time_zone": "Europe/Madrid",
  "time_zone_offset": "+02:00",
  "ip": {
    "location": { "latitude": 40.4168, "longitude": -3.7038 },
    "distance_from_id_document": 3.4,
    "distance_from_poa_document": 1.1
  },
  "id_document": {
    "location": { "latitude": 40.4165, "longitude": -3.7026 },
    "distance_from_ip": 3.4,
    "distance_from_poa_document": 4.0
  },
  "poa_document": {
    "location": { "latitude": 40.4170, "longitude": -3.7040 },
    "distance_from_ip": 1.1,
    "distance_from_id_document": 4.0
  },
  "matches": [],
  "warnings": []
}
```

### Vérification de la localisation

Renvoyé pour chaque étape de [Vérification de la localisation](https://docs.didit.me/fr/core-technology/location-verification/overview.md). Apparaît sous la forme `geolocation_checks[]` dans `GET /v3/session/{sessionId}/decision/` : un élément par étape, correspondant à sa tentative acceptée. `geolocation_attempts[]` répertorie chaque tentative de chaque étape, la plus ancienne en premier. Les deux valent `null` pour un workflow sans cette étape. Source : `GeolocationDecisionSerializer`.

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `node_id` | string | Oui | Nœud de workflow ayant produit le résultat. | `"geolocation_1"` |
| `status` | string | Non | Voir [Enum de statut](#référence-des-énumérations-de-statut). | `"Declined"` |
| `outcome` | string | Oui | Ce qui s'est produit lors de la tentative : `verified`, `low_accuracy`, `accuracy_undetermined`, `stale`, `approximate`, `denied`, `restricted`, `unavailable`, `timeout`, `mock_detected`, `outside_geofence`, `in_blocked_area`, `anonymizer_detected`, `skipped`, `replay_rejected` ou `unsupported_client`. | `"outside_geofence"` |
| `permission` | string | Oui | Ce que le système a accordé : `granted_precise`, `granted_approximate`, `denied`, `restricted`, `unavailable`, `timeout`, `dismissed` ou `not_requested`. | `"granted_precise"` |
| `latitude`, `longitude` | float | Oui | Position WGS84. `null` lorsqu'il n'y a pas de position. | `48.8566` |
| `accuracy_m` | float | Oui | Rayon d'incertitude en mètres. | `35.0` |
| `accuracy_confidence` | string | Oui | `p95`, `p68` ou `unspecified`. | `"p95"` |
| `measured_at`, `age_seconds` | datetime, integer | Oui | Moment où l'appareil a relevé la position, et secondes écoulées jusqu'à ce que Didit la reçoive. | `2` |
| `source`, `platform`, `sdk_version` | string | Oui | Provenance de la position, client qui l'a produite et sa version du SDK. | `"browser"` |
| `is_mock`, `produced_by_accessory` | boolean | Oui | Éléments de preuve d'usurpation signalés par la plateforme. `null` signifie qu'elle ne les signale pas. | `null` |
| `integrity` | string | Non | `attested`, `not_attested`, `failed`, `unsupported` (web) ou `not_determined`. | `"unsupported"` |
| `country_code`, `region_code`, `city` | string | Oui | Lieu correspondant à la position. | `"FR"` |
| `geofence`, `inside_geofence`, `geofence_basis`, `inside_areas`, `blocked_areas` | object, boolean, string, arrays | Oui | Résultat par pays et par zone. | `{ "enabled": true, "result": "outside" }` |
| `position_source`, `anonymizers` | string, object | Oui | Source de la position pour l'étape, et signaux relatifs aux VPN, proxys, Tor, usurpation et émulateurs. | `"device_and_ip"` |
| `ip_distance_km`, `ip_distance_uncertainty_km`, `ip_consistent`, `document_distance_km`, `travel_excused`, `consecutive_mismatches` | number, boolean, integer | Oui | Comparaisons avec la localisation IP et l'adresse enregistrée au dossier. | `12.4` |
| `attempts` | integer | Non | Numéro de la tentative au sein de l'étape. | `3` |
| `consent` | object | Oui | `accepted_at`, `version` et `locale` de la notification acceptée par la personne. | |
| `warnings` | tableau d'[objets d'avertissement](#objet-d’avertissement) | Non | Avertissements `LOCATION_*` de l'étape. Absents de `geolocation_attempts[]`, qui ajoutent `received_at` et `created_at`. | `[]` |

Chaque champ et exemple figure dans le [Rapport de vérification de localisation](https://docs.didit.me/fr/core-technology/location-verification/report-location-verification.md).

### Justificatif de domicile

Renvoyé pour chaque document d'adresse soumis. Apparaît sous la forme `poa_verifications[]` dans `GET /v3/session/{sessionId}/decision/`. Source : `poa/serializers/poa.py:212-227` (`POAV3Serializer`, étend `POAV2Serializer` à l'emplacement `poa/serializers/poa.py:173-209`).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `status` | string | Non | Voir [Enum de statut](#référence-des-énumérations-de-statut). | `"Approved"` |
| `issuing_state` | string (ISO 3166-1 alpha-3) | Oui | Code pays de l'émetteur du document. | `"ESP"` |
| `document_type` | string | Non | Type général issu de `PoaDocumentTypeChoices` (`common/config/choices.py:868-873`) : `UTILITY_BILL`, `BANK_STATEMENT`, `GOVERNMENT_ISSUED_DOCUMENT`, `OTHER_POA_DOCUMENT`. Se rabat sur `UNKNOWN` — jamais `null`. | `"UTILITY_BILL"` |
| `document_subtype` | string | Non | Code de sous-type issu de `PoaDocumentSubtypeChoices` (par ex. `ELECTRICITY_BILL`, `WATER_BILL`, `ACCOUNT_STATEMENT`). Se rabat sur `UNKNOWN` — jamais `null`. | `"ELECTRICITY_BILL"` |
| `issuer` | string | Oui | Nom de l'entité émettrice. | `"Iberdrola"` |
| `issue_date` | string (YYYY-MM-DD) | Oui | Date d'émission du document. | `"2026-04-15"` |
| `expiration_date` | string (YYYY-MM-DD) | Oui | Date d'expiration imprimée sur le document, lorsqu'elle est présente. | `null` |
| `poa_address` | string | Oui | Adresse brute extraite par OCR. | `"Calle Mayor 1, 28001 Madrid"` |
| `poa_formatted_address` | string | Oui | Adresse géocodée/formatée. | `"Calle Mayor 1, 28001 Madrid, Spain"` |
| `poa_parsed_address` | object | Oui | Adresse structurée (`street_1`, `street_2`, `city`, `region`, `postal_code`, `country` (alpha-2), `address_type`, `document_location`, …). | `{ "street_1": "Calle Mayor 1", "city": "Madrid", "postal_code": "28001" }` |
| `document_file` | string (URL) | Oui | URL pré-signée vers le document téléversé. | `"https://<media-host>/.../poa.pdf?..."` |
| `document_language` | string | Oui | Langue détectée du document (ISO 639-1). | `"es"` |
| `document_metadata` | object | Oui | Métadonnées filtrées : `file_size`, `content_type`, `creation_date`, `modified_date`, `creator`, `producer`, `software`, `encryption`, `is_signed`, `is_tampered`, `signature_info`, `exif_original_date`, `exif_digitized_date`, `processed_by_known_editor`, `has_different_creation_mod_date`, `overlay_manipulation`. | `{ "file_size": 184221, "content_type": "application/pdf", "is_tampered": false }` |
| `extra_fields` | object | Non | Champs de compte bancaire (`bank_account_number`, `bank_iban`, `bank_sort_code`, `bank_routing_number`, `bank_swift_bic`, `bank_branch_name`, `bank_branch_address`), `document_phone_number`, `additional_names`, ainsi que toutes les clés personnalisées conservées sur l'enregistrement. | `{ "bank_iban": null, "additional_names": [] }` |
| `name_on_document` | string | Oui | Nom tel qu'il apparaît sur le justificatif de domicile. | `"María García López"` |
| `expected_details_address` | string | Oui | Adresse saisie par le client lors de l'inscription (verbatim). | `"Calle Mayor 1, Madrid"` |
| `expected_details_formatted_address` | string | Oui | Adresse attendue géocodée. | `"Calle Mayor 1, 28001 Madrid, Spain"` |
| `expected_details_parsed_address` | object | Oui | Adresse attendue structurée. | `{ "city": "Madrid", "postal_code": "28001" }` |
| `name_match_score_expected_details` | float (0-100) | Oui | Correspondance approximative entre `name_on_document` et le nom fourni lors de la création de la session. | `94.0` |
| `name_match_score_id_verification` | float (0-100) | Oui | Correspondance approximative entre `name_on_document` et le champ `full_name` de la vérification d'identité. | `100.0` |
| `extra_files` | tableau de chaînes (URL) | Non | URLs présignées vers des fichiers supplémentaires téléversés. | `[]` |
| `detected_codes` | tableau d'objets | Non | Codes QR et codes-barres détectés sur chaque page traitée du document : `type`, `page_number` (indexé à 1), `position` (polygone), `x`/`y`/`width`/`height` (boîte englobante), `page_width`/`page_height`, `raw_payload` (base64), `parsed_payload` (valeur décodée, `null` lorsqu'un code a été localisé mais n'a pas pu être décodé). Tableau vide lorsque la détection ne trouve rien. | `[{ "type": "QR_CODE", "page_number": 1, "parsed_payload": "https://issuer.example/inv/9981" }]` |
| `node_id` | string \| null | Oui | Identifiant de nœud de workflow (V3). | `"first_poa"` |
| `warnings` | tableau | Non | Voir [Objet d'avertissement](#objet-d’avertissement). | `[]` |

```json theme={null}
{
  "status": "Approved",
  "issuing_state": "ESP",
  "document_type": "UTILITY_BILL",
  "document_subtype": "ELECTRICITY_BILL",
  "issuer": "Iberdrola",
  "issue_date": "2026-04-15",
  "expiration_date": null,
  "poa_address": "Calle Mayor 1, 28001 Madrid",
  "poa_formatted_address": "Calle Mayor 1, 28001 Madrid, Spain",
  "poa_parsed_address": { "street_1": "Calle Mayor 1", "city": "Madrid", "postal_code": "28001", "country": "ES" },
  "document_file": "https://<media-host>/.../poa.pdf?signature=...",
  "document_language": "es",
  "document_metadata": {
    "file_size": 184221,
    "content_type": "application/pdf",
    "creation_date": "2026-04-15T08:11:32Z",
    "modified_date": "2026-04-15T08:11:32Z",
    "creator": "Iberdrola Billing",
    "producer": "Adobe PDF Library 15.0",
    "software": null,
    "encryption": null,
    "is_signed": true,
    "is_tampered": false,
    "signature_info": { "signer_name": "Iberdrola Clientes", "date": "2026-04-15T08:11:32Z" },
    "exif_original_date": null,
    "exif_digitized_date": null,
    "processed_by_known_editor": false,
    "has_different_creation_mod_date": false,
    "overlay_manipulation": null
  },
  "extra_fields": {
    "bank_account_number": null,
    "bank_iban": null,
    "bank_sort_code": null,
    "bank_routing_number": null,
    "bank_swift_bic": null,
    "bank_branch_name": null,
    "bank_branch_address": null,
    "document_phone_number": null,
    "additional_names": []
  },
  "name_on_document": "María García López",
  "expected_details_address": "Calle Mayor 1, Madrid",
  "expected_details_formatted_address": "Calle Mayor 1, 28001 Madrid, Spain",
  "expected_details_parsed_address": { "city": "Madrid", "postal_code": "28001", "country": "ES" },
  "name_match_score_expected_details": 94.0,
  "name_match_score_id_verification": 100.0,
  "extra_files": [],
  "detected_codes": [
    {
      "type": "QR_CODE",
      "page_number": 1,
      "position": [[820, 1120], [1002, 1120], [1002, 1302], [820, 1302]],
      "x": 820,
      "y": 1120,
      "width": 182,
      "height": 182,
      "page_width": 1190,
      "page_height": 1684,
      "raw_payload": "aHR0cHM6Ly9pYmVyZHJvbGEuZXMvZmFjdHVyYS85OTgx",
      "parsed_payload": "https://iberdrola.es/factura/9981"
    },
    {
      "type": "CODE_128",
      "page_number": 1,
      "position": [[112, 1480], [560, 1480], [560, 1540], [112, 1540]],
      "x": 112,
      "y": 1480,
      "width": 448,
      "height": 60,
      "page_width": 1190,
      "page_height": 1684,
      "raw_payload": "MDA5OTgxMDAwNDI=",
      "parsed_payload": "0099810042"
    }
  ],
  "node_id": "first_poa",
  "warnings": []
}
```

### Vérification du téléphone

Renvoyé pour chaque tentative de vérification de téléphone. Apparaît sous la forme `phone_verifications[]` dans `GET /v3/session/{sessionId}/decision/` pour les sessions KYC et KYB. Source : `phone/serializers/phone.py:251-266` (`PhoneV3Serializer`, étend `PhoneV2Serializer` dans `phone/serializers/phone.py:103-248`).

| Champ | Type | Tolère la valeur null | Description | Exemple |
| - | - | - | - | - |
| `status` | string | Non | Voir [Énumération des statuts](#référence-des-énumérations-de-statut). | `"Approved"` |
| `phone_number_prefix` | string | Non | Préfixe international E.164 (avec `+`). | `"+34"` |
| `phone_number` | string | Non | Numéro d'abonné sans le préfixe. | `"612345678"` |
| `full_number` | string | Non | Numéro E.164 complet (`phone_number_prefix + phone_number`). | `"+34612345678"` |
| `country_code` | string (ISO 3166-1 alpha-2) | Oui | Pays du numéro. | `"ES"` |
| `country_name` | string | Oui | Nom localisé du pays. | `"Spain"` |
| `carrier` | objet | Non | `{ name, type }` où `type` est une valeur de `LineTypeChoices` (`common/config/choices.py:648-667`) : `mobile`, `fixed_line`, `voip`, `isp`, `vpn`, `toll_free`, `premium_rate`, `satellite`, `pager`, `payphone`, `voice_mail`, `unknown`, et d'autres catégories de lignes. | `{ "name": "Movistar", "type": "mobile" }` |
| `is_disposable` | boolean | Non | `true` lorsque l'opérateur marque le numéro comme temporaire ou jetable. | `false` |
| `is_virtual` | boolean | Non | `true` lorsque `carrier.type` est l'un des types suivants : `voip`, `isp`, `vpn`. | `false` |
| `verification_method` | string | Non | Canal utilisé pour envoyer l'OTP (`whatsapp`, `sms`, …). Correspond à `actual_channel` de la dernière tentative d'envoi (se rabat sur le `channel` demandé, puis sur `sms`). | `"whatsapp"` |
| `verification_attempts` | integer | Non | Nombre total de tentatives d'envoi d'OTP (envoi initial et renvois). | `1` |
| `verified_at` | string (ISO 8601) | Oui | Horodatage auquel l'OTP a été saisi avec succès. | `"2026-05-17T10:14:02Z"` |
| `lifecycle` | tableau d'objets | Non | Événements chronologiques : tentatives d'envoi, callbacks de livraison, vérifications de code et événement de statut final. Chaque événement est `{ type, timestamp, details, fee }`. Les types d'événements proviennent de `PhoneEventChoices`. | `[…]` |
| `matches` | tableau d'objets | Non | Correspondances du numéro de téléphone entre sessions. Chaque élément : `{ session_id, session_number, vendor_data, verification_date, phone_number, status, is_blocklisted, api_service, source }`. `source` est `session` ou `list_entry`. | `[]` |
| `node_id` | string \| null | Oui | Identifiant de nœud de workflow (V3). | `"first_phone"` |
| `warnings` | tableau | Non | Voir [Objet d'avertissement](#objet-d’avertissement). | `[]` |
| `phone_intelligence` | objet | Oui | Signaux d'intelligence téléphonique. Présent uniquement lorsque le module complémentaire d'intelligence a été exécuté pour le numéro. | |
| `phone_social` | objet | Oui | Empreinte sociale du numéro. Présent uniquement lorsque le module complémentaire d'empreinte sociale a été exécuté. | |

```json theme={null}
{
  "status": "Approved",
  "phone_number_prefix": "+34",
  "phone_number": "612345678",
  "full_number": "+34612345678",
  "country_code": "ES",
  "country_name": "Spain",
  "carrier": { "name": "Movistar", "type": "mobile" },
  "is_disposable": false,
  "is_virtual": false,
  "verification_method": "whatsapp",
  "verification_attempts": 1,
  "verified_at": "2026-05-17T10:14:02Z",
  "lifecycle": [
    {
      "type": "PHONE_VERIFICATION_MESSAGE_SENT",
      "timestamp": "2026-05-17T10:13:51Z",
      "details": { "status": "Success", "reason": null, "channel": "whatsapp", "actual_channel": "whatsapp" },
      "fee": 0.02
    },
    {
      "type": "PHONE_DELIVERY_DELIVERED",
      "timestamp": "2026-05-17T10:13:52Z",
      "details": { "channel": "whatsapp", "status": "delivered" },
      "fee": 0
    },
    {
      "type": "VALID_CODE_ENTERED",
      "timestamp": "2026-05-17T10:14:02Z",
      "details": { "code_tried": "482917", "status": "Approved" },
      "fee": 0
    },
    {
      "type": "PHONE_VERIFICATION_APPROVED",
      "timestamp": "2026-05-17T10:14:02Z",
      "details": null,
      "fee": 0
    }
  ],
  "matches": [],
  "node_id": "first_phone",
  "warnings": []
}
```

### Vérification de l'e-mail

Renvoyé pour chaque tentative de vérification d'e-mail. Apparaît sous la forme `email_verifications[]` dans `GET /v3/session/{sessionId}/decision/` pour les sessions KYC et KYB. Source : `email_verification/serializers/email.py:149-164` (`EmailV3Serializer`, étend `EmailV2Serializer` dans `email_verification/serializers/email.py:38-146`).

| Champ | Type | Tolère la valeur null | Description | Exemple |
| - | - | - | - | - |
| `status` | string | Non | Voir [Énumération des statuts](#référence-des-énumérations-de-statut). | `"Approved"` |
| `email` | string | Non | Adresse e-mail soumise. | `"maria.garcia@example.com"` |
| `is_breached` | boolean | Non | `true` lorsque l'e-mail figure dans une fuite de données connue. | `false` |
| `breaches` | tableau d'objets | Non | Détails de chaque fuite de données lorsque `is_breached` est `true` : `{ name, domain, logo_path, breach_date, description, is_verified, data_classes, breach_emails_count }`. | `[]` |
| `is_disposable` | boolean | Non | `true` lorsque l'e-mail appartient à un fournisseur d'adresses jetables. | `false` |
| `is_undeliverable` | boolean | Non | `true` lorsque le test de délivrabilité SMTP indique que la boîte de réception n'accepte pas de messages. | `false` |
| `verification_attempts` | integer | Non | Nombre total de tentatives de vérification d'OTP. | `1` |
| `verified_at` | string (ISO 8601) | Oui | Horodatage auquel l'OTP a été saisi avec succès. | `"2026-05-17T10:15:22Z"` |
| `lifecycle` | tableau d'objets | Non | Événements chronologiques : tentatives d'envoi, vérifications de code et événement de statut final. Chaque événement est `{ type, timestamp, details, fee }`. Les types d'événements proviennent de `EmailEventChoices`. | `[…]` |
| `matches` | tableau d'objets | Non | Correspondances d'e-mail entre sessions. Chaque élément : `{ session_id, session_number, vendor_data, verification_date, email, status, is_blocklisted, api_service, source }`. `source` est `session` ou `list_entry`. | `[]` |
| `node_id` | string \| null | Oui | Identifiant de nœud de workflow (V3). | `"first_email"` |
| `warnings` | tableau | Non | Voir [Objet d'avertissement](#objet-d’avertissement). | `[]` |
| `email_intelligence` | objet | Oui | Signaux d'intelligence d'e-mail. Présent uniquement lorsque le module complémentaire d'intelligence a été exécuté pour l'adresse. | |
| `email_social` | objet | Oui | Empreinte sociale de l'adresse. Présent uniquement lorsque le module complémentaire d'empreinte sociale a été exécuté. | |

```json theme={null}
{
  "status": "Approved",
  "email": "maria.garcia@example.com",
  "is_breached": false,
  "breaches": [],
  "is_disposable": false,
  "is_undeliverable": false,
  "verification_attempts": 1,
  "verified_at": "2026-05-17T10:15:22Z",
  "lifecycle": [
    {
      "type": "EMAIL_VERIFICATION_MESSAGE_SENT",
      "timestamp": "2026-05-17T10:15:11Z",
      "details": { "status": "Success", "reason": null },
      "fee": 0.02
    },
    {
      "type": "VALID_CODE_ENTERED",
      "timestamp": "2026-05-17T10:15:22Z",
      "details": { "code_tried": "739204", "status": "Approved" },
      "fee": 0
    },
    {
      "type": "EMAIL_VERIFICATION_APPROVED",
      "timestamp": "2026-05-17T10:15:22Z",
      "details": null,
      "fee": 0
    }
  ],
  "matches": [],
  "node_id": "first_email",
  "warnings": []
}
```

### Validation en base de données

Renvoyé pour chaque recherche dans la base de données exécutée sur les données soumises par l'utilisateur. Apparaît sous la forme `database_validations[]` dans `GET /v3/session/{sessionId}/decision/`. Source : `database_validation/serializers/database_validation.py:21-142` (`DatabaseValidationV3Serializer`, étend `DatabaseValidationV2Serializer`).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `issuing_state` | string (ISO 3166-1 alpha-3) | Oui | Pays dont le registre a été interrogé. | `"ESP"` |
| `validation_type` | string (enum) | Non | Manière dont le résultat a été corroboré : `one_by_one` (résultat d'un service unique), `two_by_two` (deux services distincts ou plus ont trouvé indépendamment une correspondance complète pour le numéro d'identification) ou `not_enabled` (le validateur a été ignoré ou aucun fournisseur n'a répondu — un `no_match` définitif produit tout de même `one_by_one`). Jamais `null`. Source : `DatabaseValidationChoices` (`common/config/choices.py:1097-1100`). | `"one_by_one"` |
| `screened_data` | object | Non | Données soumises au registre. Les champs de fichier (`selfie`, `cnh_qr_code_image`, `document_image`) sont pré-signés au moment de la lecture. | `{ "document_number": "99999999R", "date_of_birth": "1990-05-12" }` |
| `validations` | tableau d'objets | Non | Une entrée par service du catalogue ayant produit une correspondance. Chaque entrée peut inclure `service_id`, `service_name`, `validation` (objet du verdict du fournisseur), `outcome_code`, `outcome_detail` et `source_data` (profil citoyen nettoyé : `full_name`, `gender`, `date_of_birth`, `photo` (URL pré-signée), `signature` (URL pré-signée), …). | `[…]` |
| `errors` | tableau d'objets | Oui | Erreurs par service en cas d'échec de la recherche ; la clé est entièrement omise lorsqu'elle est vide. Chaque entrée est l'objet d'erreur du service en amont associé au `service_id` qui l'a généré. | `[]` |
| `match_type` | string (enum) | Oui | Verdict global de correspondance parmi les services interrogés : `full_match`, `partial_match` ou `no_match` (`DatabaseValidationMatchTypeChoices`, `common/config/choices.py:1103-1106`). `null` tant qu'il n'a pas été évalué. | `"full_match"` |
| `status` | string | Non | Consultez [Énumération des statuts](#référence-des-énumérations-de-statut). | `"Approved"` |
| `node_id` | string \| null | Oui | Identifiant du nœud du workflow (V3). | `"first_db_validation"` |
| `warnings` | array | Non | Consultez [Objet d'avertissement](#objet-d’avertissement). | `[]` |

```json theme={null}
{
  "issuing_state": "ESP",
  "validation_type": "one_by_one",
  "screened_data": {
    "document_number": "99999999R",
    "date_of_birth": "1990-05-12",
    "first_name": "María",
    "last_name": "García López"
  },
  "validations": [
    {
      "service_id": "esp_dni",
      "service_name": "Spain - DNI/NIE verification",
      "validation": { "is_valid": true, "match_score": 100 },
      "outcome_code": "MATCH",
      "outcome_detail": "All identifiers match the registry record.",
      "source_data": {
        "full_name": "María García López",
        "gender": "F",
        "date_of_birth": "1990-05-12",
        "photo": "https://<media-host>/.../registry_photo.jpg?signature=...",
        "signature": null
      }
    }
  ],
  "match_type": "full_match",
  "status": "Approved",
  "node_id": "first_db_validation",
  "warnings": []
}
```

### Réponse au questionnaire

Renvoyée pour chaque soumission de questionnaire. Apparaît sous la forme `questionnaire_responses[]` dans `GET /v3/session/{sessionId}/decision/` pour les sessions KYC et KYB. Source : `questionnaires/serializers/questionnaire.py:591-597` (`QuestionnaireResponseV3Serializer`, étend `QuestionnaireResponseSerializer` dans `questionnaires/serializers/questionnaire.py:520-588`).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `questionnaire_id` | string (UUID) | Non | Identifiant de la version du questionnaire à laquelle il a été répondu. | `"6a0f1c2c-…"` |
| `title` | string | Non | Nom du questionnaire, tel que défini dans la console. | `"Customer risk profile"` |
| `description` | string | Oui | Description du questionnaire. | `"Short risk-profile questions."` |
| `languages` | tableau de chaînes | Non | Codes de langue dans lesquels le questionnaire est publié. | `["en", "es"]` |
| `default_language` | string | Non | Code de langue par défaut. | `"en"` |
| `is_active` | boolean | Non | Indique si cette version du questionnaire est la version active. | `true` |
| `is_simple_questionnaire` | boolean | Non | `true` lorsque le questionnaire ne comporte pas de branchement (liste plate). | `true` |
| `questionnaire_group_id` | string (UUID) | Non | Identifiant partagé entre les versions d'un même questionnaire. | `"a7c2c2c2-…"` |
| `version` | integer | Non | Numéro de version du modèle actif. | `3` |
| `status` | string | Non | L'une des valeurs `Approved`, `In Review`, `Not Finished` (un refus au niveau du questionnaire équivaut à `In Review`). | `"Approved"` |
| `published_at` | string (ISO 8601) | Oui | Date et heure de publication du modèle. | `"2026-01-12T11:00:00Z"` |
| `sections` | tableau d'objets | Non | Sections ordonnées après application du parcours dans le graphe et du filtrage de visibilité. Chaque section est `{ title, description, items[] }` (title/description proviennent du `SECTION_HEADER` d'ouverture, pré-traduit). Chaque élément est un champ de formulaire (`uuid`, `value` (identifiant de nœud), `element_type`, `is_required`, `title`, `description`, `placeholder`, `choices`, `max_files`, `required_if`, `repeatable_config`, plus un champ `answer` — `null` en l'absence de réponse, omis sur les éléments de mise en page `HEADING`/`PARAGRAPH`/`SEPARATOR`). Les réponses de type fichier contiennent `{ files: [<presigned URL>, …] }`. | `[…]` |
| `node_id` | string \| null | Oui | Identifiant du nœud du workflow (V3). | `"first_questionnaire"` |

```json theme={null}
{
  "questionnaire_id": "6a0f1c2c-3b7d-4d2c-9eb6-fdc6c7c92ef9",
  "title": "Customer risk profile",
  "description": "Short risk-profile questions.",
  "languages": ["en", "es"],
  "default_language": "en",
  "is_active": true,
  "is_simple_questionnaire": true,
  "questionnaire_group_id": "a7c2c2c2-1111-4d2c-9eb6-fdc6c7c92ef9",
  "version": 3,
  "status": "Approved",
  "published_at": "2026-01-12T11:00:00Z",
  "sections": [
    {
      "title": "Source of funds",
      "description": null,
      "items": [
        {
          "uuid": "4f1d5e2c-aaaa-4d2c-9eb6-fdc6c7c92ef9",
          "value": "q_source_of_funds",
          "element_type": "SINGLE_CHOICE",
          "is_required": true,
          "title": "What is your main source of funds?",
          "description": null,
          "placeholder": null,
          "choices": [
            { "label": "Salary", "value": "salary" },
            { "label": "Business income", "value": "business" },
            { "label": "Investments", "value": "investments" }
          ],
          "max_files": 1,
          "required_if": null,
          "repeatable_config": null,
          "answer": { "value": "salary" }
        }
      ]
    }
  ],
  "node_id": "first_questionnaire"
}
```

### Signature électronique

Renvoyé pour chaque signataire d'une étape de [Signature électronique](https://docs.didit.me/fr/core-technology/electronic-signature/overview.md). Apparaît sous la forme `signatures[]` dans `GET /v3/session/{sessionId}/decision/` pour les sessions KYC et KYB, uniquement lorsque le workflow comprend cette étape. Contrairement aux autres objets de rapport, son champ `status` indique l'étape de signature et son résultat figure dans `verdict`, et les éléments de `warnings[]` sont de la forme `{ code, node_id }` plutôt que des [objets d'avertissement](#objet-d’avertissement).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `id` | string (UUID) | Non | Signature du signataire. Utilisez-le comme `signature_id` pour les routes de preuve et de validation. | `"0e6c2a8e-…"` |
| `node_id` | string | Non | Identifiant du nœud du workflow. | `"feature_signature"` |
| `status` | string | Non | Étape de signature : `intro`, `review`, `code`, `signing`, `signed` ou `declined`. Seul `signed` signifie que les documents sont signés. | `"signed"` |
| `verdict` | string | Non | `Not Finished`, `Approved`, `In Review` ou `Declined`. | `"Approved"` |
| `level` | string | Non | `simple` (par défaut) ou `aes`. `qes` est un module complémentaire qui n'est pas encore disponible. | `"aes"` |
| `format` | string | Non | `pdf` pour une signature simple, `pades` pour une signature avancée (AES). | `"pades"` |
| `profile` | string | Oui | `PAdES-B-LT` une fois qu'une signature avancée (AES) est signée, sinon null. | `"PAdES-B-LT"` |
| `signer` | object | Non | `{ name, capacity, company, role, roles, identity_session_id }`. `capacity` est `self` (KYC) ou `company` (KYB). | `{ "name": "Jane Doe", "capacity": "self", … }` |
| `identity_used` | object | Non | `{ session_id, kyc_id, verified, expected_name }` : l'identité vérifiée sur laquelle repose la signature. Vide pour une signature simple sans identité vérifiée. | `{ "verified": true, … }` |
| `certificate` | object | Oui | `{ issuer, issued_to, serial, valid_from, valid_until }`. `null` jusqu'à la signature, et toujours `null` pour une signature simple. | `{ "serial": "5A3F9C21", … }` |
| `confirmation` | objet | Non | `{ channel, destination, confirmed_at, attempts }`. `destination` est masqué ; `attempts` compte les codes saisis, y compris le bon. Une signature Simple ne comporte aucun code, donc `channel` et `destination` sont `null`. | `{ "channel": "email", … }` |
| `timestamp` | objet | Oui | `{ time, qualified, valid }`. `qualified` est toujours `false` pour l'AES. `null` jusqu'à la signature, et toujours `null` pour une signature Simple. | `{ "qualified": false, … }` |
| `documents` | tableau d'objets | Non | `{ id, uuid, title, file_name, pages, size_bytes, sha256_original, sha256_signed, status, opened_at, read_at, read_to_end, consented_at, consent, signed_file, mode, source_format, conversion, fields }`. `status` est `signed`, `declined`, `not_signed` ou `not_reached`. `mode` est `fields` ou `read_and_agree`. `source_format` est `pdf` ou `docx` ; `conversion` décrit le fichier Word d'origine, ou est `null` pour un PDF. | `[…]` |
| `documents[].fields` | tableau d'objets | Non | `{ key, type, role, label, page, x, y, width, height, required, value, display_value, value_source, filled_at, image_url, value_unavailable_reason }` pour chaque champ du document. `value` est une chaîne, un booléen pour une case à cocher, ou `true` pour une signature ou des initiales apposées. Vide pour un document sans champs. | `[…]` |
| `adopted_signature` | objet | Oui | `{ method, font, adopted_at }` : la signature et les initiales adoptées par le signataire. `method` est `typed` ou `drawn` ; `font` est le style manuscrit d'une signature saisie. `null` jusqu'à l'adoption. | `{ "method": "drawn", … }` |
| `electronic_signature_consent_at` | chaîne (ISO 8601) | Oui | Date et heure auxquelles le signataire a consenti à signer les documents par voie électronique. Défini lorsqu'un document comporte des champs. | `"2026-11-03T10:41:40Z"` |
| `evidence_file` | chaîne | Oui | Chemin du PDF de preuve, une fois signé. | `"/v3/session/…/evidence/?signature_id=…"` |
| `warnings` | tableau d'objets | Non | `{ code, node_id }`, avec `code` valant `SIGNATURE_DECLINED`, `SIGNATURE_OTP_FAILED`, `SIGNATURE_NAME_MISMATCH`, `SIGNATURE_IDENTITY_NOT_VERIFIED` ou `SIGNATURE_DOCUMENT_CHANGED`. | `[]` |
| `validation` | objet | Oui | `{ valid, checked_at, documents[] }` : la dernière vérification cryptographique des documents signés. `null` jusqu'à la signature. `{ valid: null, reason: "signature_provider_outcome_unknown", checked_at }` lorsque l'issue de la signature n'a pas pu être confirmée. | `{ "valid": true, … }` |
| `declined_at` | chaîne (ISO 8601) | Oui | Date et heure auxquelles le signataire a refusé. | `null` |
| `declined_action` | chaîne | Non | Le paramètre `signature_declined_action` de l'étape. | `"REVIEW"` |
| `signed_at` | chaîne (ISO 8601) | Oui | Date et heure auxquelles les documents ont été signés. | `"2026-11-03T10:42:24Z"` |
| `expires_at` | chaîne (ISO 8601) | Non | Date et heure d'expiration du lien de signature. | `"2026-11-10T10:30:00Z"` |
| `email_sent_at` | chaîne (ISO 8601) | Oui | Date et heure auxquelles une copie signée a été envoyée par e-mail au signataire. | `"2026-11-03T10:42:30Z"` |
| `email_unavailable_reason` | chaîne | Oui | Raison pour laquelle aucune copie n'a été envoyée par e-mail, lorsqu'une copie était demandée. | `null` |
| `ip_address` | chaîne | Oui | L'adresse IP du signataire lorsqu'il a demandé son code. | `"203.0.113.10"` |
| `place` | chaîne | Oui | Non collecté : toujours `null`. | `null` |
| `place_unavailable_reason` | chaîne | Oui | `not_collected`. | `"not_collected"` |

Le [rapport de Signature électronique](https://docs.didit.me/fr/core-technology/electronic-signature/report-electronic-signature.md) fournit un exemple complet et l'ensemble des champs imbriqués.

### Estimation de l'âge

Renvoyé par l'API autonome d'Estimation de l'âge (`POST /v3/age-estimation/`). La réponse contient un sous-ensemble de la structure de [`Liveness check`](#détection-du-vivant) sous une enveloppe `age_estimation` — `status`, `method`, `score`, `age_estimation`, `warnings` — plus un bloc de détection faciale `user_image` réservé au mode autonome ; elle n'inclut **pas** `reference_image`, `video_url`, `matches`, `face_quality` ni `face_luminance`. Dans les sessions de workflow, il n'y a pas de tableau distinct — l'âge estimé apparaît sous la forme `liveness_checks[].age_estimation` dans `GET /v3/session/{sessionId}/decision/`. Source : `apis/serializers/age_estimation.py:50-55` (`AgeEstimationResponseSerializer`), enveloppe assemblée dans `apis/views/age_estimation.py:138-174`.

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `request_id` | chaîne (UUID) | Non | Identifiant de session conservé lorsque `save_api_request=true` (valeur par défaut) ; sinon un UUID de corrélation temporaire. | `"3b1f1e2c-…"` |
| `age_estimation` | objet | Non | Enveloppe de résultat : `status` (`Approved` / `Declined`), `method` (toujours `PASSIVE`), `score` (score de détection du vivant de 0 à 100, nullable), `age_estimation` (âge prédit en années du visage le plus grand, nullable), `user_image` (`entities[]` avec pour chaque visage `age`, `bbox` `[x_min, y_min, x_max, y_max]`, `confidence`, `gender` ; ainsi que `best_angle`), `warnings[]`. | `{ … }` |
| `vendor_data` | chaîne | Oui | `vendor_data` renvoyé tel quel depuis la requête. | `null` |
| `metadata` | objet | Oui | `metadata` renvoyé tel quel depuis la requête. | `null` |
| `created_at` | chaîne (ISO 8601) | Non | Horodatage de la requête côté serveur. | `"2026-05-17T10:22:13.512941+00:00"` |

```json theme={null}
{
  "request_id": "3b1f1e2c-7777-4d2c-9eb6-fdc6c7c92ef9",
  "age_estimation": {
    "status": "Approved",
    "method": "PASSIVE",
    "score": 94.10,
    "age_estimation": 28.7,
    "user_image": {
      "entities": [
        { "age": 28.7, "bbox": [40, 40, 100, 100], "confidence": 0.72, "gender": "male" }
      ],
      "best_angle": 0
    },
    "warnings": []
  },
  "vendor_data": null,
  "metadata": null,
  "created_at": "2026-05-17T10:22:13.512941+00:00"
}
```

### Authentification biométrique

L'authentification biométrique exécute le même pipeline de détection du vivant et de correspondance faciale que celui utilisé dans le KYC standard, mais configuré pour comparer le visage capturé à l'image de référence d'un utilisateur existant au lieu d'un portrait de document extrait par OCR. Il n'y a pas de sérialiseur dédié — `GET /v3/session/{sessionId}/decision/` renvoie les objets standards [Détection du vivant](#détection-du-vivant) et [Correspondance faciale](#correspondance-faciale) sous `liveness_checks[]` et `face_matches[]`. Le workflow de la session est configuré avec `workflow_type = "biometric_authentication"` (`WorkflowTypeChoices`, `common/config/choices.py:636`).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `liveness_checks` | tableau de [Détection du vivant](#détection-du-vivant) | Non | Résultat de la détection du vivant pour la tentative d'authentification. | `[ { "status": "Approved", … } ]` |
| `face_matches` | tableau de [Correspondance faciale](#correspondance-faciale) | Non | Résultat de correspondance par rapport à la référence enregistrée. `source_image_session_id` est défini sur le `session_id` de la session elle-même — le visage de référence (le `portrait_image` fourni, ou le visage stocké réutilisé via `vendor_data` lorsque `portrait_image` est omis) est enregistré sous la session d'authentification elle-même (`face/views/face.py:656-659`). | `[ { "status": "Approved", "source_image_session_id": "…", … } ]` |
| `status` | string | Non | Statut global de la session (voir l'[énumération des statuts](#référence-des-énumérations-de-statut)). | `"Approved"` |

```json theme={null}
{
  "session_id": "9b1f1e2c-8888-4d2c-9eb6-fdc6c7c92ef9",
  "status": "Approved",
  "liveness_checks": [
    {
      "status": "Approved",
      "method": "PASSIVE",
      "score": 95.10,
      "reference_image": "https://<media-host>/.../reference.jpg?signature=...",
      "video_url": null,
      "age_estimation": null,
      "matches": [],
      "face_quality": 91.20,
      "face_luminance": 53.10,
      "node_id": "biometric_auth_liveness",
      "warnings": []
    }
  ],
  "face_matches": [
    {
      "status": "Approved",
      "score": 98.42,
      "source_image_session_id": "9b1f1e2c-8888-4d2c-9eb6-fdc6c7c92ef9",
      "source_image": "https://<media-host>/.../source.jpg?signature=...",
      "target_image": "https://<media-host>/.../target.jpg?signature=...",
      "node_id": "biometric_auth_face_match",
      "warnings": []
    }
  ]
}
```

### Registre KYB

Renvoyé pour chaque entreprise confirmée par un registre dans un workflow KYB. Apparaît sous la forme `registry_checks[]` dans `GET /v3/session/{sessionId}/decision/` pour les sessions d'entreprise. Source : `kyb/serializers/kyb.py:939-964` (`RegistryCheckV3Serializer`).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `status` | string | Non | Voir l'[énumération des statuts](#référence-des-énumérations-de-statut). | `"Approved"` |
| `node_id` | string \| null | Oui | Identifiant du nœud de workflow (V3). | `"first_registry"` |
| `data_resolved` | boolean | Non | `true` lorsque la récupération auprès du registre est terminée (ou que `is_from_registry` vaut `false`, ce qui signifie que les données ont été saisies manuellement). | `true` |
| `company` | object | Non | Payload complet de l'entreprise — voir l'[objet Entreprise](#objet-entreprise) ci-dessous. | `{ … }` |
| `ownership_structure` | object | Oui | La table de capitalisation attestée par le registre : `shareholders[]` et `beneficial_owners[]`, chaque propriétaire figurant avec son identité au registre, sa participation et son `shareholding` canonique. | `{ "shareholders": [...], "beneficial_owners": [] }` |
| `warnings` | array | Non | Voir l'[objet Avertissement](#objet-d’avertissement). | `[]` |

#### Objet Entreprise

Issu de `kyb/serializers/kyb.py:220-321` (`KYBCompanyResponseSerializer`).

| Champ | Type | Nullable | Description |
| - | - | - | - |
| `uuid` | string (UUID) | Non | Identifiant interne de l'entreprise. |
| `node_id` | string \| null | Oui | Identifiant du nœud de workflow. |
| `status` | string | Non | Statut de la fonctionnalité (`FeatureStatusChoices`). |
| `registry_status` | string | Oui | Statut de l'entreprise issu du registre (`active`, `dissolved`, …). |
| `data_resolved` | boolean | Non | Même définition que sur l'objet parent. |
| `company_name` | string | Oui | Dénomination sociale enregistrée. |
| `registration_number` | string | Oui | Numéro d'immatriculation au registre. |
| `country_code` | string (ISO 3166-1 alpha-2) | Oui | Pays de constitution. |
| `region` | string | Oui | Subdivision ISO 3166-2 le cas échéant (par ex. `US-CA`). |
| `company_type` | string | Oui | Forme juridique (`LLC`, `SL`, …). |
| `incorporation_date` | string (YYYY-MM-DD) | Oui | Date de constitution. |
| `registered_address` | string | Oui | Adresse du siège social. |
| `tax_number` | string | Oui | Identifiant fiscal / de TVA. |
| `risk_level` | string | Oui | Niveau de risque fourni par le prestataire. |
| `verification_status` | string | Oui | Énumération interne du statut de vérification. |
| `is_from_registry` | boolean | Non | `true` lorsque les données proviennent du registre (par opposition à une saisie manuelle). |
| `fetch_status` | string | Oui | `pending`, `resolved`, `failed`. |
| `alternative_names` | string | Oui | Noms commerciaux alternatifs séparés par des virgules. |
| `nature_of_business` | string | Oui | Description en texte libre de l'activité de l'entreprise. |
| `registered_capital` | string | Oui | Capital social sous forme de chaîne lisible. |
| `registered_capital_amount` | string (decimal) | Oui | Montant extrait du capital social. |
| `registered_capital_currency` | string (ISO 4217) | Oui | Code devise. |
| `website` | string (URL) | Oui | Site web de l'entreprise. |
| `email` | string | Oui | E-mail de contact public. |
| `phone` | string | Oui | Téléphone de contact public. |
| `legal_entity_identifier` | string | Oui | LEI lorsqu'il est disponible. |
| `location_of_registration` | string | Oui | Greffe / région d'enregistrement. |
| `vat_number` | string | Oui | Numéro de TVA soumis pour l'entreprise. |
| `vat_validation_status` | string | Non | Résultat de la validation du numéro de TVA, ou du `tax_number` s'il n'y en a pas : `valid`, `invalid`, `format_valid`, `invalid_format`, `could_not_validate` ou `not_applicable`. Voir [Validation de TVA et d'identifiant fiscal](https://docs.didit.me/fr/business-verification/company-data.md#validation-du-numéro-de-tva-et-de-l’identifiant-fiscal). |
| `vat_validated_number` | string | Oui | Numéro vérifié, tel qu'il est connu de la source. |
| `vat_validation_source` | string | Oui | Source ayant déterminé le statut : `eu_vies`, `pl_vat_white_list`, `no_brreg`, `ch_uid_register`, `br_receita_federal`, `co_rues`, `cr_hacienda`, `ec_sri`, `py_dnit` ou `format_rules`. |
| `vat_validated_name` | string | Oui | Nom enregistré auprès de la source (vide si celle-ci n'en communique pas). |
| `vat_validated_address` | string | Oui | Adresse enregistrée auprès de la source (vide si non communiquée). |
| `vat_checked_at` | string (ISO 8601) | Oui | Horodatage de la vérification ; `null` si aucune vérification n'a été effectuée. |
| `financial_summary` | object | Oui | Instantané des principaux indicateurs financiers les plus récents lorsqu'ils sont fournis par le registre. |
| `officers` | array of objects | Non | Liste des dirigeants adaptée au B2C : `{ uuid, name, designation, role, nationality, is_active, kyc_status, kyc_session_url }`. |
| `beneficial_owners` | array of objects | Non | Liste des bénéficiaires effectifs adaptée au B2C : `{ uuid, name, first_name, last_name, entity_type, roles, ownership_min_shares, ownership_max_shares, is_active, kyc_status, kyc_session_url, effective_ownership_percent }`. |
| `addresses` | array of objects | Oui | Détail de chaque adresse provenant du registre. |
| `industries` | array of objects | Oui | Classifications de type SIC/NAICS. |
| `accounts` | array of objects | Oui | Métadonnées des comptes déposés. |
| `registry_data` | object | Oui | Données détaillées et normalisées du registre par Didit (résultat de l'actionnariat, corrections dans la console, informations du registre n'ayant pas de champ dédié). Ce contrat n'est pas stable. |
| `user_provided_data` | object | Oui | Aperçu des champs modifiés par l'utilisateur. |
| `confirmed_by_user_at` | string (ISO 8601) | Oui | Horodatage auquel l'utilisateur a confirmé les données extraites. |
| `last_console_edit_at` | string (ISO 8601) | Oui | Horodatage de la dernière modification dans la console. |
| `is_editable` | boolean | Non | `true` tant que les données provenant du registre peuvent encore être modifiées par l'utilisateur final. |

```json theme={null}
{
  "status": "Approved",
  "node_id": "first_registry",
  "data_resolved": true,
  "company": {
    "uuid": "b1f1e2c2-9999-4d2c-9eb6-fdc6c7c92ef9",
    "node_id": "first_registry",
    "status": "Approved",
    "registry_status": "active",
    "data_resolved": true,
    "company_name": "Sante Clinics SL",
    "registration_number": "B12345678",
    "country_code": "ES",
    "region": null,
    "company_type": "SL",
    "incorporation_date": "2018-03-22",
    "registered_address": "Calle Mayor 1, 28001 Madrid, Spain",
    "tax_number": "B12345678",
    "risk_level": "low",
    "verification_status": "verified",
    "is_from_registry": true,
    "fetch_status": "resolved",
    "alternative_names": "Sante Clinics",
    "nature_of_business": "Medical clinic operations",
    "registered_capital": "EUR 50,000",
    "registered_capital_amount": "50000.00",
    "registered_capital_currency": "EUR",
    "website": "https://santeclinics.com",
    "email": "info@santeclinics.com",
    "phone": "+34911223344",
    "legal_entity_identifier": null,
    "location_of_registration": "Registro Mercantil de Madrid",
    "vat_number": "ESB12345678",
    "vat_validation_status": "valid",
    "vat_validated_name": "SANTE CLINICS SL",
    "vat_validated_address": "CALLE MAYOR 1, 28001 MADRID",
    "vat_checked_at": "2026-05-17T10:11:05Z",
    "financial_summary": null,
    "officers": [
      {
        "uuid": "c1f1e2c2-aaaa-4d2c-9eb6-fdc6c7c92ef9",
        "name": "María García López",
        "designation": "Administrador único",
        "role": "Director",
        "nationality": "ESP",
        "is_active": true,
        "kyc_status": "Approved",
        "kyc_session_url": "https://verify.didit.me/s/…"
      }
    ],
    "beneficial_owners": [
      {
        "uuid": "d1f1e2c2-bbbb-4d2c-9eb6-fdc6c7c92ef9",
        "name": "María García López",
        "first_name": "María",
        "last_name": "García López",
        "entity_type": "person",
        "roles": ["UBO"],
        "ownership_min_shares": "75.00",
        "ownership_max_shares": "75.00",
        "is_active": true,
        "kyc_status": "Approved",
        "kyc_session_url": "https://verify.didit.me/s/…",
        "effective_ownership_percent": 75.0
      }
    ],
    "addresses": [],
    "industries": [],
    "accounts": [],
    "registry_data": {},
    "user_provided_data": {},
    "confirmed_by_user_at": "2026-05-17T10:11:02Z",
    "last_console_edit_at": null,
    "is_editable": false
  },
  "ownership_structure": null,
  "warnings": []
}
```

### Document KYB

Renvoyé pour chaque nœud qui collecte des pièces justificatives KYB. Apparaît sous la forme `document_verifications[]` dans `GET /v3/session/{sessionId}/decision/` pour les sessions d'entreprise — une entrée par `node_id`, avec `items[]` listant chaque document téléversé. Source : `kyb/serializers/kyb.py:1053-1068` (`DocumentVerificationV3Serializer`) ; chaque élément suit `kyb/serializers/kyb.py:811-851` (`KYBDocumentResponseSerializer`).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `status` | string | Non | Statut agrégé sur l'ensemble des documents de ce nœud : `Approved` uniquement lorsque chaque document du pipeline est approuvé ; `Declined` si l'un d'eux est refusé ; `In Review` dans les autres cas ; `Not Finished` tant qu'il est en attente. Voir [Énumération des statuts](#référence-des-énumérations-de-statut). | `"Approved"` |
| `node_id` | string \| null | Oui | Identifiant du nœud du workflow (V3). | `"first_kyb_documents"` |
| `items` | tableau d'[objets représentant des éléments de document KYB](#objet-représentant-un-élément-de-document-kyb) | Non | Une entrée par document téléversé ou demandé. | `[…]` |
| `groups` | object | Non | Nombres par groupe de documents : `{ <group_name>: { total, approved, pending, declined, in_review, other, missing } }`. | `{ "incorporation_certificate": { "total": 1, "approved": 1, "pending": 0, "declined": 0, "in_review": 0, "other": 0, "missing": 0 } }` |
| `required_groups` | tableau de chaînes | Non | Groupes de documents requis par la configuration du workflow. | `["incorporation_certificate", "shareholder_register"]` |
| `warnings` | array | Non | Voir [Objet d'avertissement](#objet-d’avertissement). | `[]` |

#### Objet représentant un élément de document KYB

| Champ | Type | Nullable | Description |
| - | - | - | - |
| `uuid` | string (UUID) | Non | Identifiant interne du document. |
| `document_type` | string | Oui | Groupe de haut niveau (`incorporation_certificate`, `shareholder_register`, …). |
| `document_subtype` | string | Oui | Sous-type spécifique au fournisseur. |
| `document_group` | string | Oui | Miroir de `document_type` (alias conservé par souci de clarté). |
| `file_url` | string (URL) | Oui | URL pré-signée vers le fichier nettoyé. |
| `original_filename` | string | Oui | Nom du fichier tel qu'il a été téléversé. |
| `file_size` | integer | Oui | Taille du fichier en octets. |
| `status` | string | Non | Statut par document (`FeatureStatusChoices`). |
| `created_at` | string (ISO 8601) | Non | Horodatage du téléversement. |
| `cross_check_result` | object | Oui | Verdict du contrôle croisé par rapport au registre / aux autres documents. |
| `document_metadata` | object | Oui | Même structure de métadonnées filtrées que le `document_metadata` de POA. |
| `description` | string | Oui | Description fournie par le réviseur ou le système. |
| `is_requested` | boolean | Non | `true` lorsque le workflow attendait ce document. |
| `ocr_data` | object | Oui | Champs extraits par OCR lorsqu'ils sont disponibles. |
| `is_console_upload` | boolean | Non | `true` lorsque le document a été téléversé par un réviseur dans la console (exclu du verdict agrégé). |
| `is_confirmed` | boolean | Non | `true` lorsque le réviseur a explicitement confirmé le document. |

```json theme={null}
{
  "status": "Approved",
  "node_id": "first_kyb_documents",
  "items": [
    {
      "uuid": "e1f1e2c2-cccc-4d2c-9eb6-fdc6c7c92ef9",
      "document_type": "incorporation_certificate",
      "document_subtype": "registro_mercantil_extract",
      "document_group": "incorporation_certificate",
      "file_url": "https://<media-host>/.../incorporation.pdf?signature=...",
      "original_filename": "incorporation_certificate.pdf",
      "file_size": 256412,
      "status": "Approved",
      "created_at": "2026-05-17T10:08:00Z",
      "cross_check_result": { "matches_registry_name": true, "matches_registration_number": true },
      "document_metadata": {
        "file_size": 256412,
        "content_type": "application/pdf",
        "is_signed": true,
        "is_tampered": false
      },
      "description": null,
      "is_requested": true,
      "ocr_data": { "company_name": "Sante Clinics SL", "registration_number": "B12345678" },
      "is_console_upload": false,
      "is_confirmed": true
    }
  ],
  "groups": {
    "incorporation_certificate": { "total": 1, "approved": 1, "pending": 0, "declined": 0, "in_review": 0, "other": 0, "missing": 0 }
  },
  "required_groups": ["incorporation_certificate", "shareholder_register"],
  "warnings": []
}
```

### Personne clé KYB

Renvoyé pour chaque nœud Personnes clés dans un workflow KYB. Apparaît sous la forme `key_people_checks[]` dans `GET /v3/session/{sessionId}/decision/` pour les sessions d'entreprise. Source : `kyb/serializers/kyb.py:967-1050` (`KeyPeopleCheckV3Serializer`).

| Champ | Type | Nullable | Description | Exemple |
| - | - | - | - | - |
| `status` | string | Non | Voir [Énumération des statuts](#référence-des-énumérations-de-statut). | `"Approved"` |
| `node_id` | string \| null | Oui | Identifiant du nœud du workflow (V3). | `"first_key_people"` |
| `registry` | object | Non | `{ officers[], beneficial_owners[] }` extraits du registre. Les dirigeants suivent `KYBPersonResponseSerializer` (`kyb/serializers/kyb.py:533-645`) ; les bénéficiaires effectifs suivent `KYBBeneficialOwnerResponseSerializer` (`kyb/serializers/kyb.py:648-788`, qui ajoute `date_of_birth`, `country_of_birth`, `email`, `company_name`, `registration_number`, `entity_type`, `roles`, `ownership_min_shares`, `ownership_max_shares`, `child_beneficial_owners`, `effective_ownership_percent`). Les deux incluent un enrichissement AML + KYC par partie (`aml_status`, `kyc_status`, `kyc_session_url`, `kyc_session_id`, `verification_workflow_type`, `verification_workflow_id`, `verification_workflow_label`, `verification_workflow_features`, `didit_internal_id`, `kyc_document_type`, `kyc_nationality`, `kyc_liveness_passed`, `kyc_verified_at`, `kyc_aml_categories`, `kyc_notification_sent_at`). | `{ "officers": [...], "beneficial_owners": [...] }` |
| `submitted` | object | Non | `{ parties[] }` - entrées que l'entreprise a confirmées / soumises via le flux de personnes clés (lignes `BusinessParty` avec `source=USER`). Chaque partie suit `BusinessPartySubmissionResponseSerializer` (`kyb/serializers/party.py:146-194`) : `uuid`, `entity_type`, `source`, `name`, `first_name`, `last_name`, `company_name`, `registration_number`, `email`, `nationality`, `phone_number`, `date_of_birth`, `position`, `custom_fields`, `is_active`, `is_skipped`, `requires_verification`, `roles[]` (`{ role, ownership_percent, voting_percent }`), `kyc_session_id`, `kyc_session_status`, `kyc_session_url`, `kyc_session_deleted`, `kyb_sub_session_id`, `kyb_sub_session_status`, `kyb_sub_session_url`, `kyb_sub_session_deleted`, `verification_workflow_type`, `verification_workflow_id`, `verification_workflow_label`, `verification_workflow_features`, `didit_internal_id`. `kyc_session_deleted` / `kyb_sub_session_deleted` indiquent une session enfant qui a été supprimée : son statut reste figé tel quel, le champ `*_session_url` correspondant renvoie `null` car le lien n'est plus accessible, et la partie cesse de bloquer le parent (le contrôle passe plutôt à `In Review`). Effacez-le avec [`PATCH /v3/session/{id}/kyb/parties/{party_uuid}/`](https://docs.didit.me/fr/sessions-api/update-data#ignorer-une-partie-des-personnes-clés). | `{ "parties": [...] }` |
| `ubo_kyc_summary` | object | Oui | Nombres sur l'ensemble des UBO actifs avec KYC lié : `{ total, approved, flagged, pending }`. `null` lorsqu'aucun UBO actif n'a de KYC lié. | `{ "total": 2, "approved": 2, "flagged": 0, "pending": 0 }` |
| `warnings` | array | Non | Voir [Objet d'avertissement](#objet-d’avertissement). | `[]` |

```json theme={null}
{
  "status": "Approved",
  "node_id": "first_key_people",
  "registry": {
    "officers": [
      {
        "uuid": "c1f1e2c2-aaaa-4d2c-9eb6-fdc6c7c92ef9",
        "name": "María García López",
        "designation": "Administrador único",
        "role": "Director",
        "nationality": "ESP",
        "appointment_date": "2018-03-22",
        "termination_date": null,
        "is_active": true,
        "address": "Calle Mayor 1, 28001 Madrid",
        "aml_status": "Approved",
        "kyc_status": "Approved",
        "kyc_session_url": "https://verify.didit.me/s/…",
        "kyc_session_id": "9b1f1e2c-8888-4d2c-9eb6-fdc6c7c92ef9",
        "verification_workflow_type": "kyc",
        "verification_workflow_id": "11111111-1111-1111-1111-111111111111",
        "verification_workflow_label": "KYB officer KYC",
        "verification_workflow_features": [
          { "feature": "ID_VERIFICATION", "status": "Approved" },
          { "feature": "LIVENESS", "status": "Approved" },
          { "feature": "FACE_MATCH", "status": "Approved" }
        ],
        "didit_internal_id": "user-12345",
        "kyc_document_type": "Passport",
        "kyc_nationality": "ESP",
        "kyc_liveness_passed": true,
        "kyc_verified_at": "2026-05-17T10:10:11Z",
        "kyc_aml_categories": [],
        "kyc_notification_sent_at": "2026-05-15T08:00:00Z"
      }
    ],
    "beneficial_owners": []
  },
  "submitted": {
    "parties": [
      {
        "uuid": "d1f1e2c2-bbbb-4d2c-9eb6-fdc6c7c92ef9",
        "entity_type": "person",
        "source": "USER",
        "name": "María García López",
        "first_name": "María",
        "last_name": "García López",
        "company_name": null,
        "registration_number": null,
        "email": "maria.garcia@example.com",
        "nationality": "ESP",
        "phone_number": null,
        "date_of_birth": "1990-05-12",
        "position": "Administrador único",
        "custom_fields": {},
        "is_active": true,
        "is_skipped": false,
        "requires_verification": true,
        "roles": [
          { "role": "UBO", "ownership_percent": 75.0, "voting_percent": null }
        ],
        "kyc_session_id": "9b1f1e2c-8888-4d2c-9eb6-fdc6c7c92ef9",
        "kyc_session_status": "Approved",
        "kyc_session_url": "https://verify.didit.me/s/…",
        "kyb_sub_session_id": null,
        "kyb_sub_session_status": null,
        "kyb_sub_session_url": null,
        "verification_workflow_type": "kyc",
        "verification_workflow_id": "11111111-1111-1111-1111-111111111111",
        "verification_workflow_label": "KYB officer KYC",
        "verification_workflow_features": [
          { "feature": "ID_VERIFICATION", "status": "Approved" },
          { "feature": "LIVENESS", "status": "Approved" }
        ],
        "didit_internal_id": "user-12345"
      }
    ]
  },
  "ubo_kyc_summary": { "total": 1, "approved": 1, "flagged": 0, "pending": 0 },
  "warnings": []
}
```

## Champs au niveau de la décision

Ces clés figurent aux côtés des tableaux de fonctionnalités sur `GET /v3/session/{sessionId}/decision/` et à l'intérieur de la propriété `decision` d'un webhook.

| Champ | Type | Nullable | Description |
| - | - | - | - |
| `status_override` | object | Oui | `{ overridden_at, automatic_status }` après qu'un réviseur a défini `status` manuellement ; `null` lorsque le statut est le statut automatique. |
| `decision_trace` | object | Non | La manière dont le statut a été obtenu : `status`, `decided_by` (`manual`, `automatic` ou `investigator`), `decided_at`, `automatic_status`, `terminal_node_id`, `actor`, `warning_counts` et `status_warnings`. |
| `linked_records` | object | Oui | Synthèses de `same_face`, `earlier_verifications` et `networks` ; `null` lorsqu'il n'y a rien à afficher. |
| `biometric_retention` | object | Non | `{ jurisdictions, deletes_at }`. `deletes_at` est la date à laquelle les données biométriques en direct de la session sont supprimées, et `null` lorsqu'aucune date ne s'applique pour le moment. |
| `database_validation_not_performed_reason` | object | Oui | `{ code, message }` expliquant pourquoi une validation en base de données configurée n'a produit aucun résultat. |
| `assignee`, `waiting_since`, `sla_due_at` | object, datetime | Oui | Le réviseur de la Console auquel la session est attribuée et l'horloge de son examen ; l'horloge est `null` sauf si la session est `In Review`. |
| `shared_from_session`, `shared_from_session_number` | UUID, integer | Oui | La session source d'une session importée. |
| `sandbox_scenario` | string | Oui | Le scénario avec lequel une session de sandbox a été créée. |
| `fraud_check` | object | Oui | Le résultat de l'API Fraud Check ; `null` pour toutes les autres sessions. |
| `full_session_video`, `full_session_video_recorded_at` | URL, datetime | Oui | L'enregistrement et le moment où il a été réalisé. Renvoyés uniquement lorsque votre organisation enregistre la vidéo de session intégrale. |

Consultez [Récupérer une session](https://docs.didit.me/fr/sessions-api/retrieve-session.md#statut-trace-de-décision-et-champs-d’examen) pour savoir comment les lire.

## Consentement biométrique

Chaque décision de vérification des utilisateurs et chaque webhook de session comporte un objet `biometric_consent` unique (pas un tableau) : indique si la session nécessitait un consentement biométrique explicite, pourquoi, ainsi que les éléments de preuve de la réponse. Il vaut `null` lorsque la session n'a jamais été évaluée, par exemple un workflow sans capture de visage. Source : `BiometricConsentDecisionSerializer` (`sessions/serializers/biometric_consent.py`). Le moment où l'étape apparaît et la signification de chaque cas sont expliqués dans [Consentement biométrique](https://docs.didit.me/fr/getting-started/biometric-consent.md).

Les champs sans valeur enregistrée sont `null`, jamais une chaîne vide.

| Champ | Type | Description |
| - | - | - |
| `required` | boolean | Indique si la session doit recueillir un consentement biométrique explicite. Ne repasse jamais à `false`. |
| `trigger` | string (enum) \| null | Pourquoi le consentement est requis, ou comment il a été satisfait : `declared_state`, `ip_state`, `ip_unknown`, `document_issuer`, `forced` (le mode de l'application est Always), `customer_collected` (vous avez envoyé `biometric_consent` lors de la création de la session). `null` tant qu'il n'est pas requis. |
| `status` | string (enum) | `not_required`, `pending` (requis, non donné), `given`, `declined` (un refus a été enregistré ; aucun écran Didit ne propose de refus aujourd'hui). |
| `given_at` | string (ISO 8601) \| null | Date et heure auxquelles le consentement a été donné. Pour `customer_collected`, le `given_at` que vous avez envoyé. |
| `declined_at` | string (ISO 8601) \| null | Date et heure auxquelles un refus a été enregistré. |
| `text_version` | string \| null | Identifiant de version du texte de consentement auquel la personne a répondu, ou celui que vous avez envoyé. |
| `text_hash` | string \| null | SHA-256 (hexadécimal) du texte exact affiché, dans la langue dans laquelle il a été affiché. |
| `locale` | string \| null | Langue dans laquelle le texte a été affiché. |
| `policy_url` | string \| null | La politique de données biométriques vers laquelle l'étape renvoyait. |
| `step` | string \| null | Étape du workflow sur laquelle se trouvait la session lorsque la personne a répondu (par exemple `LIVENESS`). |
| `node_id` | string \| null | Nœud du graphe de workflow sur lequel se trouvait la session lorsque la personne a répondu. |
| `ip_address` | string \| null | Adresse IP d'où provient la réponse. |
| `ip_country_code` | string \| null | Pays ISO 3166-1 alpha-2 de l'adresse IP de la réponse. |
| `ip_state` | string \| null | Subdivision ISO 3166-2 de l'adresse IP de la réponse (par exemple `US-IL`). |
| `ip_city` | string \| null | Ville de l'adresse IP de la réponse. |
| `user_agent` | string \| null | Agent utilisateur de la requête à l'origine de la réponse. |
| `detected_ip_address` | string \| null | Adresse IP de la personne à partir de laquelle l'obligation a été évaluée pour la dernière fois. Peut différer d'`ip_address` lorsque la personne a répondu sur un autre appareil. |
| `detected_country_code` | string \| null | Pays ISO 3166-1 alpha-2 de l'adresse IP détectée. |
| `detected_state` | string \| null | Subdivision ISO 3166-2 de l'adresse IP détectée. |
| `detected_city` | string \| null | Ville de l'adresse IP détectée. |
| `declared_state` | string \| null | Subdivision ISO 3166-2 que vous avez déclarée : `user_state`, ou l'État d'une adresse américaine dans `expected_details`. |
| `document_state` | string \| null | Subdivision ISO 3166-2 ayant délivré le document d'identité, lue lors de la capture de la pièce d'identité. |
| `jurisdictions` | array of string | États américains (codes USPS, par exemple `IL`) dont la législation biométrique couvre la personne. `US` lorsque les éléments placent la personne aux États-Unis mais qu'aucun État n'est connu. Vide si aucun ne s'applique. |
| `retention_months` | integer \| null | La durée de conservation biométrique la plus courte, en mois, parmi `jurisdictions`. `null` si aucune ne s'applique. |
| `reason` | string (enum) \| null | `BIOMETRIC_CONSENT_UNSUPPORTED_SDK` : le consentement était requis et un SDK natif antérieur à la version 4.10.0, ou ne signalant pas sa version, a capturé un visage sans cette étape ; `status` reste `pending`, ou passe à `given` si la personne a accepté ultérieurement dans le flux hébergé. `BIOMETRIC_CONSENT_DECLINED` : un refus a été enregistré (il remplace la raison liée au SDK). `null` dans le cas contraire, et toujours `null` lorsque la session ne nécessitait pas de consentement. |
| `decline_reason` | string \| null | `BIOMETRIC_CONSENT_DECLINED` lorsqu'un refus enregistré a mis fin à la session, sinon `null`. |
| `face_data_deleted_at` | string (ISO 8601) \| null | Date et heure auxquelles le refus a entraîné la suppression des images de visage, vidéos et gabarits biométriques de la session. `null` à moins qu'un refus n'ait été enregistré. |

Une session dans l'Illinois traitée par un SDK natif antérieur à la version 4.10.0, qui a capturé le selfie sans l'étape :

```json theme={null}
{
  "required": true,
  "trigger": "ip_state",
  "status": "pending",
  "given_at": null,
  "declined_at": null,
  "text_version": null,
  "text_hash": null,
  "locale": null,
  "policy_url": null,
  "step": null,
  "node_id": null,
  "ip_address": null,
  "ip_country_code": null,
  "ip_state": null,
  "ip_city": null,
  "user_agent": null,
  "detected_ip_address": "203.0.113.42",
  "detected_country_code": "US",
  "detected_state": "US-IL",
  "detected_city": "Chicago",
  "declared_state": null,
  "document_state": null,
  "jurisdictions": ["IL"],
  "retention_months": 36,
  "reason": "BIOMETRIC_CONSENT_UNSUPPORTED_SDK",
  "decline_reason": null,
  "face_data_deleted_at": null
}
```

Une personne utilisant un VPN dont le point de sortie est situé en dehors des États-Unis, qui a donné son accord dans le flux hébergé :

```json theme={null}
{
  "required": true,
  "trigger": "declared_state",
  "status": "given",
  "given_at": "2026-10-13T18:31:07.412000Z",
  "declined_at": null,
  "text_version": "bio-consent-2026-10-12",
  "text_hash": "9b2f0c5e4d8a7f61c3e2b4a5d6f7081923a4b5c6d7e8f90a1b2c3d4e5f6a7b8c",
  "locale": "en",
  "policy_url": "https://didit.me/legal/biometric-data-policy",
  "step": "LIVENESS",
  "node_id": "feature_liveness_1",
  "ip_address": "198.51.100.23",
  "ip_country_code": "ES",
  "ip_state": "ES-M",
  "ip_city": "Madrid",
  "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1",
  "detected_ip_address": "198.51.100.23",
  "detected_country_code": "ES",
  "detected_state": "ES-M",
  "detected_city": "Madrid",
  "declared_state": null,
  "document_state": null,
  "jurisdictions": ["IL"],
  "retention_months": 36,
  "reason": null,
  "decline_reason": null,
  "face_data_deleted_at": null
}
```

## Référence des énumérations de statut

Deux espaces de valeurs liés partagent le nom de champ `status`. Chaque objet de rapport par fonctionnalité sur cette page utilise l'énumération au niveau de la fonctionnalité ; le champ `status` de premier niveau de la session parente utilise l'énumération plus large de la session.

### Statuts au niveau de la fonctionnalité

Utilisé par le champ `status` de chaque objet de rapport. Source : `common/config/choices.py:343-348` (`FeatureStatusChoices`).

| Valeur | Signification |
| - | - |
| `Not Finished` | La fonctionnalité a été provisionnée mais l'utilisateur ne l'a pas encore terminée. |
| `Approved` | La fonctionnalité a réussi tous les contrôles. |
| `Declined` | La fonctionnalité a échoué à au moins un contrôle bloquant (voir `warnings[]` avec `log_type: "error"`). |
| `In Review` | La fonctionnalité a déclenché des signaux d'échec non bloquants et est en attente d'un examen manuel (voir `warnings[]` avec `log_type: "warning"`). |
| `Resub Requested` | Un réviseur a demandé à l'utilisateur de soumettre à nouveau cette fonctionnalité. |

Les vérifications du téléphone, de l'e-mail et de l'identité peuvent également renvoyer `Expired` lorsque l'étape correspondante expire (`PhoneStatusChoices` à `common/config/choices.py:377-382`, `EmailStatusChoices` à `common/config/choices.py:434-439`).

### Statuts au niveau de la session

Utilisé par le champ `status` de premier niveau de la session parente. Source : `common/config/choices.py:106-117` (`StatusChoices`).

| Valeur | Signification |
| - | - |
| `Not Started` | La session a été créée mais l'utilisateur ne l'a pas encore commencée. |
| `In Progress` | L'utilisateur a commencé le flux ; le résultat n'est pas encore finalisé. |
| `Approved` | La session a réussi tous les contrôles. |
| `Declined` | La session a échoué à au moins un contrôle bloquant. |
| `In Review` | La session est en attente d'un examen manuel. |
| `Expired` | La session a expiré avant d'être terminée. |
| `Abandoned` | L'utilisateur a quitté le flux sans le terminer. |
| `Kyc Expired` | La fenêtre de validité du KYC a expiré (utilisé dans les flux de revérification). |
| `Resubmitted` | L'utilisateur a soumis à nouveau après un refus antérieur ; cette session est remplacée par une plus récente. |
| `Awaiting User` | Le système attend une action de l'utilisateur (par exemple la saisie d'un OTP). |

> [!TIP]
>
> Les valeurs terminales d'une session sont `Approved`, `Declined`, `In Review`, `Expired`, `Kyc Expired` et `Abandoned`. Une session peut atteindre sa décision globale alors qu'une fonctionnalité individuelle reste `In Review`.


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