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

# Модели данных Didit: JSON-схемы отчётов

> Канонические JSON-схемы для всех объектов отчётов Didit: NFC, ID, Liveness, Face Match, AML, IP, POA, Phone, Email, KYB Registry, Documents, Key People.

## Обзор

Каждый отчёт по функции следует форме сериализатора V3, определённой в `service-didit-verification`. Один и тот же объект встречается в трёх местах, поэтому схема, которую вы видите здесь, является единственным источником истины для всех них:

* `GET /v3/session/{sessionId}/decision/`: каждая функция возвращается как массив во множественном числе (`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[]` (см. [Методы верификации банка](https://docs.didit.me/ru/core-technology/bank-verification/verification-methods.md#определение-метода-в-результате)), а также KYB-аналоги `registry_checks[]`, `document_verifications[]`, `key_people_checks[]`).
* Payload webhook-событий (`status.updated`, `data.updated`): та же форма внутри обёртки `decision`.
* Отдельные API: ответы с одним объектом (Поиск по лицу, Оценка возраста, Биометрическая аутентификация) используют тот же набор полей.

> [!NOTE]
>
> V3 вводит многоэкземплярные сценарии: каждый объект функции содержит `node_id`, который привязывает отчёт к узлу графа сценария, создавшему его. Эндпоинты V2 (с формами единственного числа `kyc`, `face`, `aml` и т. д.) сохраняют обратную совместимость, но возвращают только первый экземпляр.

## Общие поля

Каждый объект отчёта содержит следующие поля:

| Поле | Тип | Описание |
| - | - | - |
| `status` | строка | Статус жизненного цикла на уровне функции, один из вариантов в [Перечисление статусов](#справочник-значений-перечисления-status). Источник: `common/config/choices.py:FeatureStatusChoices` (строки 343-348). Верхнеуровневый `status` родительской сессии использует более широкий набор статусов сессии (`StatusChoices`, строки 106-117). |
| `node_id` | строка \| null | Идентификатор узла графа сценария. Заполняется для многоэкземплярных сценариев V3; `null` для устаревших сессий с одной функцией. |
| `warnings` | массив [объектов предупреждений](#объект-предупреждения) | Сигналы риска, отфильтрованные по этой функции и `node_id`. Возвращаются методом `Session.get_logs(...)` (`sessions/models/session.py:1611`). |

Медиаполя (`portrait_image`, `front_image`, `document_file`, …) являются предподписанными URL с ограниченным сроком действия. Скачивайте их сразу, а не сохраняйте URL. В примерах они показаны как `https://<media-host>/...`.

## Объект предупреждения

Возвращается в каждом массиве `warnings[]`. Схема из `logs/serializers/log.py:8-65` (`LogV3Serializer`).

| Поле | Тип | Допускает null | Описание | Пример |
| - | - | - | - | - |
| `feature` | строка (перечисление) | Нет | Функция, которая сгенерировала предупреждение. Значения из `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` | строка | Нет | Стабильный код риска (например, `DOCUMENT_EXPIRED`, `LOW_LIVENESS_SCORE`). Значения из `logs/choices.py:RiskChoices`. Используется как ключ в таблицах описаний. | `"DOCUMENT_EXPIRED"` |
| `additional_data` | объект \| null | Да | Контекст, специфичный для риска (например, пороговые значения оценок, совпавшие поля). Структура зависит от кода риска. | `{ "score": 42.1, "threshold": 70 }` |
| `log_type` | строка (перечисление) | Нет | Одно из значений `error`, `warning`, `information`. Из `LogTypeChoices` (`common/config/choices.py:207-210`). | `"error"` |
| `short_description` | строка | Нет | Понятное название риска. Из `logs/choices.py:RISK_SHORT_DESCRIPTIONS`. | `"Document expired"` |
| `long_description` | строка | Нет | Более подробное пояснение, понятное человеку и пригодное для показа конечным пользователям. Из `logs/choices.py:RISK_LONG_DESCRIPTIONS`. | `"The document's expiration date has passed, rendering it no longer valid for use."` |
| `node_id` | строка \| null | Да | Узел графа сценария, в отношении которого было создано предупреждение. `null` для устаревших логов V2 без `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"
}
```

## Объекты отчётов

Остальные разделы описывают объекты отчётов по каждой функции. Текст заголовков H3 намеренно не меняется, чтобы на него могли ссылаться другие документы.

### Верификация личности

Возвращается для каждого документа, удостоверяющего личность, который загрузил пользователь. Появляется как `id_verifications[]` в `GET /v3/session/{sessionId}/decision/` и внутри поля `kyc` в ответах V2. Источник: `kyc/serializers/kyc.py:383-414` (`IDVerificationV3Serializer`, расширяет `IDVerificationV2Serializer` из `kyc/serializers/kyc.py:320-380`).

| Поле | Тип | Может быть null | Описание | Пример |
| - | - | - | - | - |
| `status` | string | Нет | См. [Перечисление статусов](#справочник-значений-перечисления-status). | `"Approved"` |
| `document_type` | string | Да | Понятный человеку класс документа (`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`). Источник: `DOC_TYPE_MAPPING` (`common/config/choices.py:1275-1289`). | `"Passport"` |
| `document_subtype` | string | Да | Код подтипа документа из реестра документов Didit, отфильтрованный по тем документам, которые принимают настройки документов сценария. Документы, специфичные для региона, содержат регион. Полный список кодов: [Подтипы документов](https://docs.didit.me/ru/core-technology/id-verification/document-subtypes-id-verification.md). | `"QUEENSLAND_DRIVER_LICENSE_GENERIC"` |
| `document_number` | string | Да | Номер документа, извлечённый с помощью OCR. | `"AB1234567"` |
| `personal_number` | string | Да | Личный или национальный идентификатор, извлечённый с помощью OCR. | `"99999999R"` |
| `portrait_image` | string (URL) | Да | URL с предварительной подписью обрезанного изображения лица. | `"https://<media-host>/.../portrait.jpg?..."` |
| `front_image` | string (URL) | Да | URL с предварительной подписью очищенной лицевой стороны документа. | `"https://<media-host>/.../front.jpg?..."` |
| `front_video` | string (URL) | Да | URL с предварительной подписью видео съёмки лицевой стороны (если доступно). | `"https://<media-host>/.../front.mp4?..."` |
| `back_image` | string (URL) | Да | URL с предварительной подписью очищенной оборотной стороны документа. | `"https://<media-host>/.../back.jpg?..."` |
| `back_video` | string (URL) | Да | URL с предварительной подписью видео съёмки оборотной стороны. | `null` |
| `full_front_image` | string (URL) | Да | Снимок лицевой стороны без обрезки (полный кадр). | `"https://<media-host>/.../full_front.jpg?..."` |
| `full_back_image` | string (URL) | Да | Снимок оборотной стороны без обрезки (полный кадр). | `null` |
| `front_image_camera_front` | string (URL) | Да | Изображение с фронтальной камеры, снятое одновременно со снимком лицевой стороны документа. | `null` |
| `back_image_camera_front` | string (URL) | Да | Изображение с фронтальной камеры, снятое одновременно со снимком оборотной стороны документа. | `null` |
| `front_image_camera_front_face_match_score` | float (0-100) | Да | Степень сходства между портретом из документа и снимком с фронтальной камеры. | `null` |
| `back_image_camera_front_face_match_score` | float (0-100) | Да | То же, что выше, но для снимка оборотной стороны. | `null` |
| `document_selfie_face_matches` | array | Да | Предыдущие сессии или записи списка блокировки лиц, совпадающие с селфи, сделанным при съёмке документа. Формат записей такой же, как у `liveness_checks[].matches`. `null`, если поиск не выполнялся, `[]`, если совпадений не найдено. | `null` |
| `front_image_quality_score` | object | Да | Показатели качества лицевой стороны: оценки от 0 до 100 (`focus_score`, `brightness_score`, `resolution_score`, `overall_score`), а также `brightness_issue` (`ok`, `too_dark`, `too_bright`) и `is_document_fully_visible` (логическое значение). | `{ "focus_score": 91.0, "overall_score": 88.5 }` |
| `back_image_quality_score` | object | Да | Структура такая же, как у `front_image_quality_score`. | `null` |
| `date_of_birth` | string (YYYY-MM-DD) | Да | Дата рождения, извлечённая с помощью OCR. | `"1990-05-12"` |
| `age` | integer | Да | Возраст в годах на момент извлечения данных, вычисленный автоматически. | `35` |
| `expiration_date` | string (YYYY-MM-DD) | Да | Срок действия документа. | `"2032-05-11"` |
| `date_of_issue` | string (YYYY-MM-DD) | Да | Дата выдачи документа. | `"2022-05-11"` |
| `issuing_state` | string (ISO 3166-1 alpha-3) | Да | Код страны выдачи. | `"ESP"` |
| `issuing_state_name` | string | Да | Локализованное название страны выдачи. | `"Spain"` |
| `first_name` | string | Да | Имя или имена, извлечённые с помощью OCR. | `"María"` |
| `last_name` | string | Да | Фамилия или фамилии, извлечённые с помощью OCR. | `"García López"` |
| `full_name` | string | Да | Полное нормализованное имя (предоставлено поставщиком). | `"María García López"` |
| `gender` | string | Да | `M`, `F` или другое значение, предоставленное поставщиком. | `"F"` |
| `address` | string | Да | Необработанная строка адреса, извлечённая с помощью OCR. | `"Calle Mayor 1, 28001 Madrid"` |
| `formatted_address` | string | Да | Геокодированный или отформатированный адрес (если его удалось разобрать). | `"Calle Mayor 1, 28001 Madrid, Spain"` |
| `parsed_address` | object | Да | Структурированный геокодированный адрес: `street_1`, `street_2`, `city`, `region`, `country`, `postal_code`, `address_type`, `formatted_address`, `document_location` (`{latitude, longitude}`), `raw_results`, `is_best_match`. Источник: `kyc/utils/address.py:147-197`. | `{ "street_1": "Calle Mayor 1", "city": "Madrid", "postal_code": "28001", "country": "ES" }` |
| `place_of_birth` | string | Да | Место рождения, извлечённое с помощью OCR. | `"Madrid"` |
| `marital_status` | string | Да | Если его можно извлечь. | `null` |
| `nationality` | string (ISO 3166-1 alpha-3) | Да | Гражданство, извлечённое с помощью OCR. | `"ESP"` |
| `extra_fields` | object | Да | Поля, специфичные для типа документа, которых нет в канонической схеме (например, категории водительского удостоверения). | `{ "DL Class": "B" }` |
| `mrz` | object | Да | Разобранные поля MRZ, если они есть (`document_number`, `birth_date`, `expiry_date`, `surname`, `given_names`, …). | `{ "document_number": "AB1234567", "surname": "GARCIA", "given_names": "MARIA" }` |
| `extra_files` | array of strings (URL) | Нет | URL с предварительной подписью любых дополнительно загруженных файлов. | `[]` |
| `matches` | array of objects | Нет | Совпадения документов между сессиями. Каждый элемент: `{ 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` содержит URL с предварительной подписью. | `[]` |
| `verification_method` | string | Нет | Какой [метод верификации личности](https://docs.didit.me/ru/core-technology/id-verification/verification-methods.md) создал эту строку: `document`, `id_lookup` или `wallet`. Всегда `document` для сфотографированного документа, включая все сессии, созданные до появления других методов. | `"id_lookup"` |
| `assurance` | string | Нет | Уровень гарантий, выводимый из `verification_method`: `documentary`, `data_match` или `cryptographic`. | `"data_match"` |
| `wallet_provider` | string \| null | Да | Идентификатор кошелька из каталога, если строку создал кошелёк (`mitid`, `bankid_se`, `itsme`, ...). Иначе `null`. | `"mitid"` |
| `fallback_from` | object \| null | Да | Причина, по которой метод, отличный от документа, завершил шаг ID: `{ method, reason, action }`. Заполняется, когда поиск или вход через кошелёк не удался: в строке с отклонённым результатом, если переключатель для страны стоял в `decline` (`action: "decline"`), и в верификации документа, которую продолжает пользователь, если стоял `fallback_to_document` (`action: "fallback_to_document"`). `null`, если более ранних сбоев метода, отличного от документа, не зафиксировано. | `{ "method": "id_lookup", "reason": "no_match", "action": "decline" }` |
| `id_lookup` | object \| null | Да | Исходные доказательства, присутствуют только когда `verification_method` равен `id_lookup`: `source` (точный источник запроса: государственный реестр в большинстве стран, а в некоторых странах файл бюро кредитных историй или данных о регистрации по месту жительства), `checked_at`, `attempts`, `max_attempts`, `outcome` (`match`, `partial_match`, `no_match`, `provider_error`, `format_rejected`), `comparison[]` (`{ field, label, provided, record, result }`; `field` принимает одно из значений `identification_number`, `full_name`, `date_of_birth`, `address`, а `result` равен `match`, `partial` или `no_match`; более ранние версии могут включать строку `provider` с `error`), `source_errors[]` (текущая staging-среда: отдельная диагностика источников; подтвердите выкатку в продакшн), `registry_portrait` (предподписанный URL, только для источников, которые его возвращают) и `face_match_score`. | см. ниже |
| `wallet_verification` | object \| null | Да | Доказательства учётных данных, присутствуют только когда `verification_method` равен `wallet`: `provider`, `provider_name`, `issuing_authority`, `issuing_country`, `credential_type`, `level_of_assurance` (`low`, `substantial`, `high`), `verified_at`, `signature_valid`, `attributes` (что передал кошелёк), `portrait` (предподписанный URL, когда кошелёк передаёт портрет) и `face_match_score`. | см. ниже |
| `document_liveness` | object \| null | Да | Оценки живости документа по типам подделки (`portrait_replace`, `printed_copy`, `screen_replay`), возвращаются независимо от того, сработало ли предупреждение. Каждая содержит: `score` (0–100, чем выше, тем выше вероятность подлинности; берётся наименьшее значение, то есть то, которое использовало решение), `front`, `back`, `decline_threshold`, `review_threshold`, `bucket` (`approve`, `review`, `decline` или `null`). Пороги и категория сохраняются на момент оценки; все три равны `null`, когда исторические данные оценки недоступны, при этом сохранённые оценки остаются видимыми. `null`, если проверка не запускалась. См. [Оценки живости документа](https://docs.didit.me/ru/core-technology/id-verification/report-id-verification.md#оценки-проверки-живости-документа). Только V3. | `{ "portrait_replace": { "score": 96.46, "bucket": "approve" } }` |
| `node_id` | string \| null | Да | Идентификатор узла сценария (V3). | `"first_id_verification"` |
| `warnings` | array | Нет | См. [Объект предупреждения](#объект-предупреждения). | `[]` |
| `region` | string | Да | Регион или штат страны выдачи, если документ его указывает. | `"CA"` |
| `extracted_data` | object | Да | Снимок данных, извлечённых из документа, который показали пользователю для проверки. Хранится рядом с подтверждёнными значениями, чтобы вы могли их сравнить. `null`, если пользователя не попросили проверить данные. | |
| `barcodes` | array of objects | Нет | Данные, считанные со штрихкодов документа: по одной записи на штрихкод с полями `type`, `position`, `data`, `data_raw` и `side`. `[]`, если штрихкодов нет. | `[]` |

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

Такой же объект для метода, отличного от документа. Меняются только ключи, специфичные для метода: всё, что при чтении документа заполняется данными документа, заполняется из записи реестра или атрибутов кошелька, а ключи, которые не применяются, равны `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": []
}
```

### NFC-верификация

Возвращается для каждого чтения чипа документа, удостоверяющего личность: электронный паспорт ICAO 9303 или чип eID, либо чтение карты My Number (Япония) через JPKI (`chip_protocol: "jpki"`). Появляется как `nfc_verifications[]` в `GET /v3/session/{sessionId}/decision/` (по одной записи на родительскую запись KYC). Источник: `kyc/serializers/epassport.py:121-139` (`NFCV3Serializer`, наследует `NFCV2Serializer` из `kyc/serializers/epassport.py:83-118`).

| Поле | Тип | Допустимо null | Описание | Пример |
| - | - | - | - | - |
| `status` | string | Нет | См. [Перечисление статусов](#справочник-значений-перечисления-status). | `"Approved"` |
| `portrait_image` | string (URL) | Да | Предподписанный URL изображения лица, извлечённого из чипа. | `"https://<media-host>/.../nfc_portrait.jpg?..."` |
| `signature_image` | string (URL) | Да | Предподписанный URL изображения подписи, извлечённого из чипа (если оно хранится на чипе). | `null` |
| `chip_data` | object | Да | Персональные данные, разобранные из групп данных (Data Groups) чипа, в плоском виде (`kyc/utils/epassport.py:165-212`): `dgs` (прочитанные группы данных), `surname`, `name`, `country`, `nationality`, `birth_date` (`YYYY-MM-DD`), `expiry_date` (`YYYY-MM-DD`), `sex` (`M`/`F`), `document_type` (код документа из MRZ), `document_number`, `optional_data`, контрольные цифры MRZ (`birth_date_hash`, `expiry_date_hash`, `document_number_hash`, `optional_data_hash`, `final_hash`), `mrz_string`, `mrz_type` (`TD1`/`TD2`/`TD3`); а также `place_of_birth` и `address` (и `full_name` / `full_name_non_latin` для имён на нелатинице), когда чип содержит DG11. Без DG11 этих ключей нет. `null`, если шаг NFC был пропущен. | `{ "document_number": "AB1234567", "name": "MARIA" }` |
| `authenticity` | object | Да | `{ sod_integrity, dg_integrity }`; `null` для чтения JPKI. `sod_integrity` проверяет, что подпись Document Security Object (SOD) выстраивается в цепочку до действующего CSCA страны выдачи (и что DSC не отозван и не истёк); `dg_integrity` проверяет, что хэши каждой группы данных соответствуют SOD. Если оба значения `true`, чип подлинный и не изменён. | `{ "sod_integrity": true, "dg_integrity": true }` |
| `certificate_summary` | object | Да | Сводка по сертификату подписанта документа (`kyc/utils/epassport.py:338-348`): `issuer`, `subject`, `serial_number` (integer), `not_valid_before`, `not_valid_after` (`YYYY-MM-DD HH:MM:SS`), а также объект `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 | Да | Идентификатор узла сценария (V3). | `"first_nfc"` |
| `is_nfc_skipped` | boolean | Нет | `true`, если этот шаг NFC был явно пропущен, а не считан. Причина указана в `skip_reason`. | `false` |
| `skip_reason` | string | Да | Причина пропуска шага. Заполняется только если `is_nfc_skipped` равно `true`. Одно из значений: `USER_SKIPPED`, `DOCUMENT_WITHOUT_CHIP`, `CHIP_CERTIFICATE_UNAVAILABLE`, `DEVICE_WITHOUT_NFC`, `INTEGRATION_WITHOUT_NFC_ACCESS`, `MRZ_KEY_UNAVAILABLE`, `JPKI_UNAVAILABLE`; см. [Причины пропуска](https://docs.didit.me/ru/core-technology/nfc-verification/warnings-nfc-verification.md#причины-пропуска). Payload решения также содержит `nfc_skip_reason` уровня сессии с той же таксономией, которая охватывает NFC-шаги, пропущенные до создания какого-либо отчёта. | `null` |
| `chip_protocol` | string | Нет | Способ чтения чипа: `icao` (чип ePassport или eID по стандарту ICAO 9303) или `jpki` (карта Japan My Number Card). Для `jpki` поля `portrait_image`, `signature_image`, `chip_data`, `authenticity` и `certificate_summary` равны `null`. Также задаётся для пропущенных шагов. | `"icao"` |
| `jpki` | object | Да | Что подтverждено при чтении карты My Number: `certificate_types`, `chain_valid`, `signature_valid`, `revocation_status` (`good`, `revoked` или `unchecked`), `ca_generation`, `certificate_expires_at`, `certificates[]`, `attributes` (имя, дата рождения, пол и адрес из сертификата подписи), `attributes_match_ocr` и `mismatched_attributes`. Сами сертификаты, их серийные номера и подписи никогда не возвращаются. `null` для чипов ICAO, для пропущенных шагов и когда шаг завершился без чтения карты. См. [Поля JPKI](https://docs.didit.me/ru/core-technology/nfc-verification/report-nfc-verification.md#поля-jpki). | `null` |
| `warnings` | array | Нет | См. [Объект предупреждения](#объект-предупреждения). | `[]` |

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

### Проверка живости

Возвращается для каждой сессии проверки живости. Появляется как `liveness_checks[]` в `GET /v3/session/{sessionId}/decision/`. Источник: `face/serializers/face.py:301-320` (`LivenessV3Serializer`, расширяет `LivenessV2Serializer` в `face/serializers/face.py:216-298`).

| Поле | Тип | Nullable | Описание | Пример |
| - | - | - | - | - |
| `status` | string | Нет | См. [Перечисление статусов](#справочник-значений-перечисления-status). | `"Approved"` |
| `method` | string (enum) | Да | `ACTIVE_3D`, `FLASHING` или `PASSIVE` (`LivenessMethodChoices`, `common/config/choices.py:514-517`). Пассивный режим применяется, когда разрешены сессии на компьютере и пользователь находится на компьютере. | `"PASSIVE"` |
| `score` | float (0-100) | Да | Уверенность в живости, округлённая до 2 знаков после запятой. | `92.41` |
| `reference_image` | string (URL) | Да | URL с предварительной подписью на эталонное обрезанное изображение лица пользователя. | `"https://<media-host>/.../reference.jpg?..."` |
| `video_url` | string (URL) | Да | URL с предварительной подписью на видео проверки живости (только в активном режиме). | `"https://<media-host>/.../liveness.webm?..."` |
| `age_estimation` | float | Да | Оценочный возраст (в годах) самого крупного лица на эталонном изображении. | `34.2` |
| `matches` | массив объектов | Нет | Совпадения лиц между сессиями. Каждый элемент: `{ 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` принимает значения `session`, `imported`, `list_entry` или `retained_template`. У совпадения с сохранённым шаблоном заполнены `vendor_user_id`, `vendor_data` и `biometric_template_id`, а поля сессии, изображения, данных личности, статуса и API-сервиса равны `null`. | `[]` |
| `face_quality` | float (0-100) | Да | Оценка качества лица для пассивной проверки живости (нормализована в процентах). | `87.50` |
| `face_luminance` | float (0-100) | Да | Оценка освещённости лица для пассивной проверки живости (нормализована из диапазона 0-255 в проценты). | `54.12` |
| `node_id` | string \| null | Да | Идентификатор узла сценария (V3). | `"first_liveness"` |
| `warnings` | array | Нет | См. [Объект предупреждения](#объект-предупреждения). | `[]` |

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

### Сравнение лиц

Возвращается для каждого сравнения лиц (обычно живого лица пользователя с портретом на документе). Появляется как `face_matches[]` в `GET /v3/session/{sessionId}/decision/`. Источник: `face/serializers/face.py:367-389` (`FaceMatchV3Serializer`, расширяет `FaceMatchV2Serializer` в `face/serializers/face.py:323-364`).

| Поле | Тип | Nullable | Описание | Пример |
| - | - | - | - | - |
| `status` | string | Нет | См. [Перечисление статусов](#справочник-значений-перечисления-status). | `"Approved"` |
| `score` | float (0-100) | Да | Сходство, округлённое до 2 знаков. Если провайдер возвращает только `unmatched_faces[].Confidence`, оно пересчитывается как `100 - confidence`. | `97.83` |
| `source_image_session_id` | string (UUID) | Да | Сессия, из которой было взято сохранённое портретное изображение для использования в качестве исходного (эталонного). Задаётся в сценариях на основе портрета (биометрическая аутентификация или портрет, переданный при создании сессии). `null`, когда эталоном является портрет с документа из этой же сессии. | `null` |
| `source_image` | string (URL) | Да | URL с предварительной подписью на исходное (эталонное) изображение: обычно портрет с документа или сохранённый портрет в сценариях биометрической аутентификации. | `"https://<media-host>/.../source.jpg?..."` |
| `target_image` | string (URL) | Да | URL с предварительной подписью на целевое изображение (лицо в реальном времени), снятое во время проверки живости. | `"https://<media-host>/.../target.jpg?..."` |
| `node_id` | string \| null | Да | Идентификатор узла сценария (V3). | `"first_face_match"` |
| `warnings` | array | Нет | См. [Объект предупреждения](#объект-предупреждения). | `[]` |
| `face_coverage` | object | Да | Закрыты ли `eyes`, `mouth` и `face` на снятом изображении. Для каждой области есть `covered`, `calibrated` и `visibility_score`; `calibrated: false` означает, что это признак, обусловленный тенью, на который не распространяется ни одно предупреждение. Возвращается только в `GET /v3/session/{sessionId}/decision/` и никогда не входит в payload webhook. | `{ "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": []
}
```

### Поиск по лицу

Возвращается отдельным API поиска по лицу (`POST /v3/face-search/`). Поиск по лицу никогда не появляется в виде массива с несколькими элементами в `/v3/session/{sessionId}/decision/`. Если сохранение выполнено с `save_api_request=true`, сессия отображается там как запись `FACE_SEARCH` в `features[]` и как элемент `liveness_checks[]` с сохранённым `matches`. Источники: `apis/serializers/face_search.py:8-79` (`FaceSearchResponseSerializer`, который оборачивает `FaceSearchDetailsSerializer`); словари совпадений формируются в `face/utils/utils.py:869-884`.

Ответ верхнего уровня:

| Поле | Тип | Допускает null | Описание | Пример |
| - | - | - | - | - |
| `request_id` | строка (UUID) | Нет | Идентификатор сохранённой сессии, если `save_api_request=true` (его можно использовать с `GET /v3/session/{sessionId}/decision/`); в противном случае временный UUID корреляции. | `"4a1c2c4e-8b1b-4d6a-91b5-ee9a1f3a2c7f"` |
| `face_search` | объект | Нет | Объект с данными поиска, см. поля ниже. | — |
| `vendor_data` | строка | Да | `vendor_data` из запроса, возвращённый без изменений. | `null` |
| `metadata` | объект | Да | `metadata` из запроса, возвращённые без изменений. | `null` |
| `created_at` | строка (ISO 8601) | Нет | Временна́я метка запроса на стороне сервера. | `"2026-06-12T01:04:42.763237+00:00"` |

Объект `face_search`:

| Поле | Тип | Допускает null | Описание | Пример |
| - | - | - | - | - |
| `status` | строка | Нет | `Declined` возвращается только тогда, когда сработало предупреждение `FACE_IN_BLOCKLIST` или `POSSIBLE_FACE_IN_BLOCKLIST`. Во всех остальных случаях возвращается `Approved`. Одни только повторные совпадения никогда не приводят к отклонению (`apis/views/face_search.py:242-248`). | `"Approved"` |
| `total_matches` | целое число | Нет | Количество возвращённых совпадений в `matches[]` (0–5). | `1` |
| `matches` | массив [объектов совпадения поиска по лицу](#объект-совпадения-поиска-по-лицу) | Нет | До 5 совпадений выше порога схожести, отсортированных по убыванию схожести. Совпадения из списка блокировки идут первыми, с `search_type=blocklisted_or_approved`. | `[…]` |
| `user_image` | объект | Нет | Результат обнаружения для отправленного изображения: `{ entities: [{ bbox, confidence }], best_angle }`, по одной сущности на каждое обнаруженное лицо. | `{ "entities": [{ "bbox": [40, 40, 120, 120], "confidence": 0.73 }], "best_angle": 0 }` |
| `warnings` | массив объектов | Нет | Сокращённая структура предупреждений для этого отдельного API, без `node_id`. Контракт сериализатора объявляет `{ risk, additional_data, log_type, short_description, long_description }` (`apis/serializers/face_search.py:49-54`). Фактический ответ также содержит поле `feature`, которое всегда равно `"LIVENESS"` (`apis/views/face_search.py:332-341`). | `[]` |

#### Объект совпадения поиска по лицу

| Поле | Тип | Допускает null | Описание | Пример |
| - | - | - | - | - |
| `session_id` | строка (UUID) | Да | Сессия верификации, с которой найдено совпадение. Равно `null`, когда `source` имеет значение `imported`, `list_entry` или `retained_template`. | `"a3f2a6f1-…"` |
| `session_number` | целое число | Да | Номер найденной сессии, удобный для консоли. Для совпадений, не связанных с сессией, равно `null`. | `1024` |
| `similarity_percentage` | число с плавающей точкой (0-100) | Нет | Схожесть между отправленным лицом и найденным лицом. | `96.42` |
| `source` | строка (перечисление) | Нет | Откуда было зарегистрировано найденное лицо: `session` (сессия верификации или сохранённый отдельный вызов), `imported` (лицо, загруженное непосредственно в профиль пользователя), `list_entry` (лицо, прикреплённое к списку), `retained_template` ([биометрический шаблон](https://docs.didit.me/ru/management-api/biometric-templates/overview.md) без изображения, сохранённый после удаления исходной сессии). | `"session"` |
| `vendor_data` | строка | Да | `vendor_data` найденной сессии или данные связанного пользователя для совпадений `imported` и `retained_template`. | `"user-12345"` |
| `vendor_user_id` | строка (UUID) | Да | Связанный пользователь. Равно `null` для совпадений `list_entry` и для сессий без пользователя. | `"2f7c1a9e-…"` |
| `biometric_template_id` | строка (UUID) | Да | Сохранённый шаблон, с которым найдено совпадение. Заполняется только для совпадений `retained_template`; используйте его с `GET`/`DELETE /v3/biometric-templates/{id}/`. | `null` |
| `verification_date` | строка (ISO 8601) | Да | Когда было снято найденное лицо или, для `retained_template`, когда шаблон был сохранён. Равно `null` для совпадений `list_entry`. | `"2024-11-04T09:14:02Z"` |
| `user_details` | объект | Да | `{ full_name, document_type, document_number }` из верификации документа найденной сессии. Для совпадений `imported` заполнено только `full_name`. Равно `null`, когда данных о личности нет, и всегда `null` для совпадений `retained_template`. | `{ "full_name": "María García López", "document_type": "Passport", "document_number": "AB1234567" }` |
| `match_image_url` | строка (URL) | Да | Эталонное лицо найденного пользователя: URL с предварительной подписью, если `save_api_request=true`, иначе необработанный путь в хранилище. Всегда `null` для совпадений `retained_template`, так как они не содержат изображения. | `"https://<media-host>/.../matched.jpg?..."` |
| `status` | строка | Да | Статус верификации найденной сессии (см. [перечисление статусов](#справочник-значений-перечисления-status)). Равно `null` для совпадений, не связанных с сессией. | `"Approved"` |
| `is_blocklisted` | логическое значение | Нет | Находится ли найденное лицо в вашем списке блокировки лиц. Всегда `false` для совпадений `retained_template`; лицо из списка блокировки указывается отдельно как совпадение `list_entry`. | `false` |
| `is_allowlisted` | логическое значение | Нет | Находится ли найденное лицо в одном из ваших списков разрешённых. | `false` |
| `api_service` | строка (перечисление) | Да | Тип отдельного API в верхнем регистре для найденной сессии (например, `PASSIVE_LIVENESS`, `FACE_MATCH`). Равно `null` для сессий сценария и для совпадений, не связанных с сессией. | `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"
}
```

### AML-скрининг

Возвращается для каждой проверяемой сущности. Появляется как `aml_screenings[]` в `GET /v3/session/{sessionId}/decision/` как для сессий KYC, так и для сессий KYB. Источник: `aml/serializers/aml.py:63-85` (`AMLV3Serializer`, наследует `AMLV2Serializer` из `aml/serializers/aml.py:28-60`).

| Поле | Тип | Допускает null | Описание | Пример |
| - | - | - | - | - |
| `status` | строка | Нет | См. [перечисление статусов](#справочник-значений-перечисления-status). | `"Approved"` |
| `total_hits` | целое число | Нет | Количество совпадений при скрининге (поле всегда присутствует, по умолчанию `0`). | `2` |
| `entity_type` | строка (перечисление) | Да | `person` или `company` (`EntityTypeChoices`, `common/config/choices.py:675-677`). | `"person"` |
| `hits` | массив объектов | Нет | Одна запись на каждое совпадение. Ключевые поля: `id`, `caption`, `match` (bool), `target` (bool \| null: является ли сущность прямой целью записи в списке), `match_score` (float 0-100, уверенность в совпадении личности), `risk_score` (float 0-100, риск сущности), `score` (устаревший float 0-1), `datasets[]` (например, `PEP`, `PEP Level 1`-`4`, `Sanctions`, `Adverse Media`, `Warnings and Regulatory Enforcement`, `Fitness and Probity`), `properties` (имена, псевдонимы, даты рождения и т. д.), `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` и `review_status` (`Unreviewed`, `Confirmed Match`, `False Positive`, `Inconclusive`; редактируется через endpoint обновления статуса совпадения AML, `AMLHitStatusChoices`). | `[…]` |
| `score` | float (0-100) | Да | Общая оценка скрининга: наибольший `risk_score` среди совпадений, не помеченных как `False Positive` (`aml/services/aml.py:832-842`). Равна `0`, если все совпадения являются ложными срабатываниями. `null`, пока не вычислена. | `42.7` |
| `screened_data` | object | Да | Снимок данных, отправленных на скрининг: `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 | Нет | Подключена ли сущность к повторным проверкам в рамках постоянного мониторинга. | `false` |
| `next_ongoing_monitoring_bill_date` | string (YYYY-MM-DD) | Да | Вычисляется как `last_aml_bill_date + 365 days`, когда постоянный мониторинг включён. Это дата **биллинга**, а не дата скрининга. | `null` |
| `last_ongoing_screening_at` | string (ISO 8601) | Да | Когда постоянный мониторинг в последний раз завершил повторную проверку этой записи, независимо от того, изменился ли результат. `null`, если повторной проверки не было; никогда не заполняется задним числом. | `"2026-09-12T04:03:11Z"` |
| `last_ongoing_screening_datasets_updated_at` | string (ISO 8601) | Да | Самое последнее обновление набора данных AML, о котором провайдер сообщил для этой проверки. `null`, если дата набора данных не была сообщена; никогда не оценивается. | `null` |
| `node_id` | string \| null | Да | Идентификатор узла сценария (V3). | `"first_aml"` |
| `warnings` | array | Нет | См. [Объект предупреждения](#объект-предупреждения). | `[]` |

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

### Анализ IP

Возвращается для каждого зафиксированного сетевого местоположения. Появляется как `ip_analyses[]` в `GET /v3/session/{sessionId}/decision/` для сессий KYC и KYB. Источник: `kyc/serializers/location.py:196-243` (`IPAnalysisSerializerV3`).

| Поле | Тип | Может быть null | Описание | Пример |
| - | - | - | - | - |
| `status` | string | Нет | См. [Перечисление статусов](#справочник-значений-перечисления-status). | `"Approved"` |
| `node_id` | string \| null | Да | Идентификатор узла сценария (V3). | `"first_ip_analysis"` |
| `device_brand` | string | Да | Бренд устройства, определённый по строке User-Agent. | `"Apple"` |
| `device_model` | string | Да | Модель устройства. | `"iPhone"` |
| `browser_family` | string | Да | Семейство браузера. | `"Mobile Safari"` |
| `os_family` | string | Да | Семейство ОС. | `"iOS"` |
| `platform` | string | Да | Платформа верхнего уровня (`mobile`, `desktop`, `tablet`). | `"mobile"` |
| `device_fingerprint` | string | Да | Стабильный хеш отпечатка устройства. | `"f2a3…"` |
| `ip_country` | string | Да | Название страны, определённое по IP. | `"Spain"` |
| `ip_country_code` | string (ISO 3166-1 alpha-2) | Да | Код страны, определённый по IP. | `"ES"` |
| `ip_state` | string | Да | Регион или штат, определённый по IP. | `"Comunidad de Madrid"` |
| `ip_city` | string | Да | Город, определённый по IP. | `"Madrid"` |
| `latitude` | float | Да | Широта, определённая по IP. | `40.4168` |
| `longitude` | float | Да | Долгота, определённая по IP. | `-3.7038` |
| `ip_address` | string | Да | Зафиксированный адрес. | `"203.0.113.42"` |
| `isp` | string | Да | Название интернет-провайдера. | `"Telefonica de Espana"` |
| `organization` | string | Да | Название организации (часто совпадает с провайдером). | `"Telefonica de Espana"` |
| `is_vpn_or_tor` | boolean | Да | `true`, если адрес принадлежит VPN, прокси или выходному узлу Tor. | `false` |
| `is_data_center` | boolean | Да | `true`, если IP принадлежит известному ASN хостинга или дата-центра. | `false` |
| `time_zone` | string | Да | Название часового пояса IANA. | `"Europe/Madrid"` |
| `time_zone_offset` | string | Да | Смещение от UTC. | `"+02:00"` |
| `ip` | object | Нет | `{ location, distance_from_id_document, distance_from_poa_document }`. `location = { latitude, longitude }`. Расстояния в км, `null`, если какая-либо из сторон отсутствует. | `{ "location": { "latitude": 40.4168, "longitude": -3.7038 }, "distance_from_id_document": 3.4, "distance_from_poa_document": 1.1 }` |
| `id_document` | object | Нет | `{ location, distance_from_ip, distance_from_poa_document }`. Местоположение документа, удостоверяющего личность, определённое по `issuing_state` и разобранному адресу. | `{ "location": { "latitude": 40.4165, "longitude": -3.7026 }, "distance_from_ip": 3.4, "distance_from_poa_document": 4.0 }` |
| `poa_document` | object | Нет | `{ location, distance_from_ip, distance_from_id_document }`. Адрес из подтверждения адреса, геокодированный. | `{ "location": { "latitude": 40.4170, "longitude": -3.7040 }, "distance_from_ip": 1.1, "distance_from_id_document": 4.0 }` |
| `matches` | array of objects | Нет | Совпадения по IP и устройству между сессиями. Каждый элемент: `{ 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`: `ip_address` или `device_fingerprint`; `match_source`: `ip_address`, `persistent_id`, `legacy_fp` или `recovered_high` (восстановленные совпадения также содержат `recovery_similarity`, `tls_ja4_corroborated`, `recovery_gate_reason`). Не более 5 совпадений по IP и 5 по устройству. | `[]` |
| `warnings` | array | Нет | См. [Объект предупреждения](#объект-предупреждения). | `[]` |
| `browser_version`, `os_version` | string | Да | Версии браузера и ОС, определённые по user agent. | `"17.4"` |
| `user_agent`, `accept_language` | string | Да | Строка User-Agent и заголовок `Accept-Language`, которые отправил браузер. | `"en-US,en;q=0.9"` |
| `session_identifier`, `session_age_ms` | string, integer | Да | Браузерная сессия, в которой выполнялся шаг, и её возраст в миллисекундах. | `48210` |
| `coords_accuracy` | float | Да | Радиус точности координат, переданных устройством, в метрах. | `35.0` |
| `raw_device_data` | object | Да | Необработанные сигналы устройства, собранные для шага. | `{}` |

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

### Проверка местоположения

Возвращается для каждого шага [Проверка местоположения](https://docs.didit.me/ru/core-technology/location-verification/overview.md). Появляется как `geolocation_checks[]` в `GET /v3/session/{sessionId}/decision/`: один элемент на шаг, соответствующий его принятой попытке. `geolocation_attempts[]` содержит все попытки всех шагов, от самой старой к самой новой. Оба поля равны `null` для сценария без этого шага. Источник: `GeolocationDecisionSerializer`.

| Поле | Тип | Может быть null | Описание | Пример |
| - | - | - | - | - |
| `node_id` | string | Да | Узел сценария, который выдал результат. | `"geolocation_1"` |
| `status` | строка | Нет | См. [Перечисление статусов](#справочник-значений-перечисления-status). | `"Declined"` |
| `outcome` | строка | Да | Что произошло при попытке: `verified`, `low_accuracy`, `accuracy_undetermined`, `stale`, `approximate`, `denied`, `restricted`, `unavailable`, `timeout`, `mock_detected`, `outside_geofence`, `in_blocked_area`, `anonymizer_detected`, `skipped`, `replay_rejected` или `unsupported_client`. | `"outside_geofence"` |
| `permission` | строка | Да | Какое разрешение предоставила система: `granted_precise`, `granted_approximate`, `denied`, `restricted`, `unavailable`, `timeout`, `dismissed` или `not_requested`. | `"granted_precise"` |
| `latitude`, `longitude` | float | Да | Координаты в WGS84. `null`, если координаты отсутствуют. | `48.8566` |
| `accuracy_m` | float | Да | Радиус неопределённости в метрах. | `35.0` |
| `accuracy_confidence` | строка | Да | `p95`, `p68` или `unspecified`. | `"p95"` |
| `measured_at`, `age_seconds` | дата и время, целое число | Да | Когда устройство определило местоположение и сколько секунд прошло до того, как Didit его получил. | `2` |
| `source`, `platform`, `sdk_version` | строка | Да | Откуда получено определение, клиент, который его сформировал, и версия его SDK. | `"browser"` |
| `is_mock`, `produced_by_accessory` | логическое значение | Да | Признаки подмены (спуфинга), которые сообщает платформа. `null` означает, что платформа этого не сообщает. | `null` |
| `integrity` | строка | Нет | `attested`, `not_attested`, `failed`, `unsupported` (веб) или `not_determined`. | `"unsupported"` |
| `country_code`, `region_code`, `city` | строка | Да | Место, которому соответствует определение. | `"FR"` |
| `geofence`, `inside_geofence`, `geofence_basis`, `inside_areas`, `blocked_areas` | объект, логическое значение, строка, массивы | Да | Результат проверки страны и области. | `{ "enabled": true, "result": "outside" }` |
| `position_source`, `anonymizers` | строка, объект | Да | Откуда шаг получает позицию и сигналы VPN, прокси, Tor, спуфинга и эмулятора. | `"device_and_ip"` |
| `ip_distance_km`, `ip_distance_uncertainty_km`, `ip_consistent`, `document_distance_km`, `travel_excused`, `consecutive_mismatches` | число, логическое значение, целое число | Да | Сравнения с местоположением по IP и с адресом, указанным в записи. | `12.4` |
| `attempts` | целое число | Нет | Номер попытки в рамках шага. | `3` |
| `consent` | объект | Да | `accepted_at`, `version` и `locale` уведомления, которое принял пользователь. | |
| `warnings` | массив [объектов предупреждений](#объект-предупреждения) | Нет | Предупреждения `LOCATION_*` шага. Отсутствуют в `geolocation_attempts[]`, который дополнительно содержит `received_at` и `created_at`. | `[]` |

Все поля и примеры есть в [отчёте о верификации местоположения](https://docs.didit.me/ru/core-technology/location-verification/report-location-verification.md).

### Подтверждение адреса

Возвращается для каждого предоставленного документа с адресом. Появляется как `poa_verifications[]` в `GET /v3/session/{sessionId}/decision/`. Источник: `poa/serializers/poa.py:212-227` (`POAV3Serializer`, расширяет `POAV2Serializer` в `poa/serializers/poa.py:173-209`).

| Поле | Тип | Может быть null | Описание | Пример |
| - | - | - | - | - |
| `status` | строка | Нет | См. [Перечисление статусов](#справочник-значений-перечисления-status). | `"Approved"` |
| `issuing_state` | строка (ISO 3166-1 alpha-3) | Да | Код страны эмитента документа. | `"ESP"` |
| `document_type` | строка | Нет | Тип верхнего уровня из `PoaDocumentTypeChoices` (`common/config/choices.py:868-873`): `UTILITY_BILL`, `BANK_STATEMENT`, `GOVERNMENT_ISSUED_DOCUMENT`, `OTHER_POA_DOCUMENT`. При отсутствии данных подставляется `UNKNOWN`, никогда не `null`. | `"UTILITY_BILL"` |
| `document_subtype` | строка | Нет | Код подтипа из `PoaDocumentSubtypeChoices` (например, `ELECTRICITY_BILL`, `WATER_BILL`, `ACCOUNT_STATEMENT`). При отсутствии данных подставляется `UNKNOWN`, никогда не `null`. | `"ELECTRICITY_BILL"` |
| `issuer` | строка | Да | Название выдавшей организации. | `"Iberdrola"` |
| `issue_date` | строка (YYYY-MM-DD) | Да | Дата выдачи документа. | `"2026-04-15"` |
| `expiration_date` | строка (YYYY-MM-DD) | Да | Дата окончания срока действия, указанная на документе, если она есть. | `null` |
| `poa_address` | строка | Да | Адрес в необработанном виде, извлечённый с помощью OCR. | `"Calle Mayor 1, 28001 Madrid"` |
| `poa_formatted_address` | строка | Да | Адрес после геокодирования и форматирования. | `"Calle Mayor 1, 28001 Madrid, Spain"` |
| `poa_parsed_address` | объект | Да | Структурированный адрес (`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` | строка (URL) | Да | Предподписанный URL загруженного документа. | `"https://<media-host>/.../poa.pdf?..."` |
| `document_language` | строка | Да | Определённый язык документа (ISO 639-1). | `"es"` |
| `document_metadata` | объект | Да | Отфильтрованные метаданные: `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` | объект | Нет | Поля банковского счёта (`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`, а также любые пользовательские ключи, сохранённые в записи. | `{ "bank_iban": 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" }` |
| `name_match_score_expected_details` | float (0–100) | Да | Нечёткое сравнение `name_on_document` с именем, переданным при создании сессии. | `94.0` |
| `name_match_score_id_verification` | float (0–100) | Да | Нечёткое сравнение `name_on_document` с `full_name` проверенного удостоверения личности. | `100.0` |
| `extra_files` | массив строк (URL) | Нет | Предподписанные URL дополнительно загруженных файлов. | `[]` |
| `detected_codes` | массив объектов | Нет | QR-коды и штрихкоды, обнаруженные на всех обработанных страницах документа: `type`, `page_number` (нумерация с 1), `position` (полигон), `x`/`y`/`width`/`height` (ограничивающий прямоугольник), `page_width`/`page_height`, `raw_payload` (base64), `parsed_payload` (декодированное значение; `null`, если код найден, но его не удалось декодировать). Пустой массив, если ничего не обнаружено. | `[{ "type": "QR_CODE", "page_number": 1, "parsed_payload": "https://issuer.example/inv/9981" }]` |
| `node_id` | строка \| null | Да | Идентификатор узла сценария (V3). | `"first_poa"` |
| `warnings` | массив | Нет | См. [Объект предупреждения](#объект-предупреждения). | `[]` |

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

### Проверка телефона

Возвращается для каждой попытки проверки телефона. Появляется как `phone_verifications[]` в `GET /v3/session/{sessionId}/decision/` для сессий KYC и KYB. Источник: `phone/serializers/phone.py:251-266` (`PhoneV3Serializer`, расширяет `PhoneV2Serializer` в `phone/serializers/phone.py:103-248`).

| Поле | Тип | Может быть null | Описание | Пример |
| - | - | - | - | - |
| `status` | строка | Нет | См. [Перечисление статусов](#справочник-значений-перечисления-status). | `"Approved"` |
| `phone_number_prefix` | строка | Нет | Код страны в формате E.164 (с `+`). | `"+34"` |
| `phone_number` | строка | Нет | Абонентский номер без кода страны. | `"612345678"` |
| `full_number` | строка | Нет | Полный номер в формате E.164 (`phone_number_prefix + phone_number`). | `"+34612345678"` |
| `country_code` | строка (ISO 3166-1 alpha-2) | Да | Страна номера. | `"ES"` |
| `country_name` | строка | Да | Локализованное название страны. | `"Spain"` |
| `carrier` | объект | Нет | `{ name, type }`, где `type` принимает значение из `LineTypeChoices` (`common/config/choices.py:648-667`): `mobile`, `fixed_line`, `voip`, `isp`, `vpn`, `toll_free`, `premium_rate`, `satellite`, `pager`, `payphone`, `voice_mail`, `unknown` и другие типы линий. | `{ "name": "Movistar", "type": "mobile" }` |
| `is_disposable` | логическое значение | Нет | `true`, если оператор связи помечает номер как временный или одноразовый. | `false` |
| `is_virtual` | логическое значение | Нет | `true`, если `carrier.type` является одним из значений `voip`, `isp`, `vpn`. | `false` |
| `verification_method` | строка | Нет | Канал доставки OTP (`whatsapp`, `sms`, …). Берётся из `actual_channel` последней попытки отправки (если его нет, то из запрошенного `channel`, затем `sms`). | `"whatsapp"` |
| `verification_attempts` | целое число | Нет | Общее количество попыток отправки OTP (первая отправка плюс повторные). | `1` |
| `verified_at` | строка (ISO 8601) | Да | Время, когда OTP был успешно введён. | `"2026-05-17T10:14:02Z"` |
| `lifecycle` | массив объектов | Нет | Хронологические события: попытки отправки, обратные вызовы о доставке, проверки кода и итоговое событие статуса. Каждое событие имеет вид `{ type, timestamp, details, fee }`. Типы событий берутся из `PhoneEventChoices`. | `[…]` |
| `matches` | массив объектов | Нет | Совпадения номера телефона между сессиями. Каждый элемент: `{ session_id, session_number, vendor_data, verification_date, phone_number, status, is_blocklisted, api_service, source }`. Значения `source`: `session` или `list_entry`. | `[]` |
| `node_id` | строка \| null | Да | Идентификатор узла сценария (V3). | `"first_phone"` |
| `warnings` | массив | Нет | См. [Объект предупреждения](#объект-предупреждения). | `[]` |
| `phone_intelligence` | объект | Да | Сигналы интеллектуального анализа телефона. Присутствует, только если для номера выполнялся дополнительный модуль интеллектуального анализа. | |
| `phone_social` | объект | Да | Социальный след номера. Присутствует, только если выполнялся дополнительный модуль анализа социального следа. | |

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

### Проверка электронной почты

Возвращается для каждой попытки проверки электронной почты. Появляется как `email_verifications[]` в `GET /v3/session/{sessionId}/decision/` для сессий KYC и KYB. Источник: `email_verification/serializers/email.py:149-164` (`EmailV3Serializer`, расширяет `EmailV2Serializer` в `email_verification/serializers/email.py:38-146`).

| Поле | Тип | Может быть null | Описание | Пример |
| - | - | - | - | - |
| `status` | строка | Нет | См. [Перечисление статусов](#справочник-значений-перечисления-status). | `"Approved"` |
| `email` | строка | Нет | Указанный адрес электронной почты. | `"maria.garcia@example.com"` |
| `is_breached` | логическое значение | Нет | `true`, если адрес найден в известной утечке данных. | `false` |
| `breaches` | массив объектов | Нет | Подробности по каждой утечке, когда `is_breached` равно `true`: `{ name, domain, logo_path, breach_date, description, is_verified, data_classes, breach_emails_count }`. | `[]` |
| `is_disposable` | логическое значение | Нет | `true`, если адрес принадлежит провайдеру одноразовой почты. | `false` |
| `is_undeliverable` | логическое значение | Нет | `true`, если SMTP-проверка доставки показывает, что почтовый ящик не принимает письма. | `false` |
| `verification_attempts` | целое число | Нет | Общее количество попыток проверки OTP. | `1` |
| `verified_at` | строка (ISO 8601) | Да | Время, когда OTP был успешно введён. | `"2026-05-17T10:15:22Z"` |
| `lifecycle` | массив объектов | Нет | Хронологические события: попытки отправки, проверки кода и итоговое событие статуса. Каждое событие имеет вид `{ type, timestamp, details, fee }`. Типы событий берутся из `EmailEventChoices`. | `[…]` |
| `matches` | массив объектов | Нет | Совпадения адреса электронной почты между сессиями. Каждый элемент: `{ session_id, session_number, vendor_data, verification_date, email, status, is_blocklisted, api_service, source }`. Значения `source`: `session` или `list_entry`. | `[]` |
| `node_id` | строка \| null | Да | Идентификатор узла сценария (V3). | `"first_email"` |
| `warnings` | массив | Нет | См. [Объект предупреждения](#объект-предупреждения). | `[]` |
| `email_intelligence` | объект | Да | Сигналы интеллектуального анализа адреса электронной почты. Присутствует, только если для адреса выполнялся дополнительный модуль интеллектуального анализа. | |
| `email_social` | объект | Да | Социальный след адреса. Присутствует, только если выполнялся дополнительный модуль анализа социального следа. | |

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

### Проверка по базам данных

Возвращается для каждого поиска по базе данных, выполненного по данным, которые отправил пользователь. Появляется как `database_validations[]` в `GET /v3/session/{sessionId}/decision/`. Источник: `database_validation/serializers/database_validation.py:21-142` (`DatabaseValidationV3Serializer`, расширяет `DatabaseValidationV2Serializer`).

| Поле | Тип | Допускает null | Описание | Пример |
| - | - | - | - | - |
| `issuing_state` | строка (ISO 3166-1 alpha-3) | Да | Страна, в реестре которой выполнялся запрос. | `"ESP"` |
| `validation_type` | строка (enum) | Нет | Способ подтверждения результата: `one_by_one` (результат одного сервиса), `two_by_two` (два или более разных сервиса независимо подтвердили полное совпадение идентификационного номера) или `not_enabled` (валидатор не запускался или ни один провайдер не ответил; окончательный `no_match` по-прежнему дает `one_by_one`). Никогда не `null`. Источник: `DatabaseValidationChoices` (`common/config/choices.py:1097-1100`). | `"one_by_one"` |
| `screened_data` | объект | Нет | Данные, отправленные в реестр. Для файловых полей (`selfie`, `cnh_qr_code_image`, `document_image`) в момент чтения создаются URL с предварительной подписью. | `{ "document_number": "99999999R", "date_of_birth": "1990-05-12" }` |
| `validations` | массив объектов | Нет | Одна запись на каждый сервис из каталога, который дал совпадение. Каждая запись может содержать `service_id`, `service_name`, `validation` (объект вердикта провайдера), `outcome_code`, `outcome_detail` и `source_data` (очищенный профиль гражданина: `full_name`, `gender`, `date_of_birth`, `photo` (предподписанный URL), `signature` (предподписанный URL), …). | `[…]` |
| `errors` | массив объектов | Да | Ошибки по сервисам, если запрос к сервису не удался; ключ полностью отсутствует, когда список пуст. Каждая запись представляет собой объект ошибки вышестоящего сервиса плюс `service_id`, который её породил. | `[]` |
| `match_type` | строка (enum) | Да | Общий вердикт совпадения по всем запрошенным сервисам: `full_match`, `partial_match` или `no_match` (`DatabaseValidationMatchTypeChoices`, `common/config/choices.py:1103-1106`). `null`, пока не оценено. | `"full_match"` |
| `status` | строка | Нет | См. [Перечисление статусов](#справочник-значений-перечисления-status). | `"Approved"` |
| `node_id` | строка \| null | Да | Идентификатор узла сценария (V3). | `"first_db_validation"` |
| `warnings` | массив | Нет | См. [Объект предупреждения](#объект-предупреждения). | `[]` |

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

### Ответ на анкету

Возвращается для каждой отправки анкеты. Появляется как `questionnaire_responses[]` в `GET /v3/session/{sessionId}/decision/` для сессий KYC и KYB. Источник: `questionnaires/serializers/questionnaire.py:591-597` (`QuestionnaireResponseV3Serializer`, расширяет `QuestionnaireResponseSerializer` из `questionnaires/serializers/questionnaire.py:520-588`).

| Поле | Тип | Допускает null | Описание | Пример |
| - | - | - | - | - |
| `questionnaire_id` | строка (UUID) | Нет | Идентификатор версии анкеты, на которую был дан ответ. | `"6a0f1c2c-…"` |
| `title` | строка | Нет | Название анкеты, как задано в Console. | `"Customer risk profile"` |
| `description` | строка | Да | Описание анкеты. | `"Short risk-profile questions."` |
| `languages` | массив строк | Нет | Коды языков, на которых опубликована анкета. | `["en", "es"]` |
| `default_language` | строка | Нет | Код языка по умолчанию. | `"en"` |
| `is_active` | логическое значение | Нет | Является ли эта версия анкеты активной. | `true` |
| `is_simple_questionnaire` | логическое значение | Нет | `true`, если в анкете нет ветвлений (плоский список). | `true` |
| `questionnaire_group_id` | строка (UUID) | Нет | Идентификатор, общий для всех версий одной и той же анкеты. | `"a7c2c2c2-…"` |
| `version` | целое число | Нет | Номер версии активного шаблона. | `3` |
| `status` | строка | Нет | Одно из: `Approved`, `In Review`, `Not Finished` (отклонение на уровне анкеты соответствует `In Review`). | `"Approved"` |
| `published_at` | строка (ISO 8601) | Да | Когда шаблон был опубликован. | `"2026-01-12T11:00:00Z"` |
| `sections` | массив объектов | Нет | Упорядоченные разделы после применения обхода графа и фильтрации по видимости. Каждый раздел имеет вид `{ title, description, items[] }` (title и description берутся из открывающего `SECTION_HEADER` и уже переведены). Каждый элемент является элементом формы (`uuid`, `value` (идентификатор узла), `element_type`, `is_required`, `title`, `description`, `placeholder`, `choices`, `max_files`, `required_if`, `repeatable_config`, а также поле `answer`: `null`, если ответа нет, и отсутствует у элементов макета `HEADING`/`PARAGRAPH`/`SEPARATOR`). Файловые ответы содержат `{ files: [<presigned URL>, …] }`. | `[…]` |
| `node_id` | строка \| null | Да | Идентификатор узла сценария (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"
}
```

### Электронная подпись

Возвращается для каждого подписанта на шаге [Электронная подпись](https://docs.didit.me/ru/core-technology/electronic-signature/overview.md). Появляется как `signatures[]` в `GET /v3/session/{sessionId}/decision/` для сессий KYC и KYB, только если в сценарии есть этот шаг. В отличие от других объектов отчетов, его `status` указывает этап подписания, а результат находится в `verdict`, и элементы `warnings[]` имеют вид `{ code, node_id }`, а не [объектов предупреждений](#объект-предупреждения).

| Поле | Тип | Допускает null | Описание | Пример |
| - | - | - | - | - |
| `id` | строка (UUID) | Нет | Идентификатор подписи подписанта. Используйте его как `signature_id` для маршрутов evidence и validate. | `"0e6c2a8e-…"` |
| `node_id` | строка | Нет | Идентификатор узла сценария. | `"feature_signature"` |
| `status` | строка | Нет | Этап подписания: `intro`, `review`, `code`, `signing`, `signed` или `declined`. Только `signed` означает, что документы подписаны. | `"signed"` |
| `verdict` | строка | Нет | `Not Finished`, `Approved`, `In Review` или `Declined`. | `"Approved"` |
| `level` | строка | Нет | `simple` (по умолчанию) или `aes`. `qes` является дополнением, которое пока недоступно. | `"aes"` |
| `format` | строка | Нет | `pdf` для простой подписи, `pades` для расширенной (AES). | `"pades"` |
| `profile` | строка | Да | `PAdES-B-LT` после подписания документа расширенной (AES) подписью, в остальных случаях null. | `"PAdES-B-LT"` |
| `signer` | объект | Нет | `{ name, capacity, company, role, roles, identity_session_id }`. `capacity` имеет значение `self` (KYC) или `company` (KYB). | `{ "name": "Jane Doe", "capacity": "self", … }` |
| `identity_used` | объект | Нет | `{ session_id, kyc_id, verified, expected_name }`: проверенная личность, на которую опирается подпись. Пустой объект для простой подписи без проверенной личности. | `{ "verified": true, … }` |
| `certificate` | объект | Да | `{ issuer, issued_to, serial, valid_from, valid_until }`. `null` до подписания, и всегда `null` для простой подписи. | `{ "serial": "5A3F9C21", … }` |
| `confirmation` | объект | Нет | `{ channel, destination, confirmed_at, attempts }`. `destination` маскируется. `attempts` считает введённые коды, включая правильный. У простой подписи кода нет, поэтому `channel` и `destination` равны `null`. | `{ "channel": "email", … }` |
| `timestamp` | объект | Да | `{ time, qualified, valid }`. Для AES `qualified` всегда `false`. До подписания значение `null`, а для простой подписи всегда `null`. | `{ "qualified": false, … }` |
| `documents` | массив объектов | Нет | `{ 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` принимает значения `signed`, `declined`, `not_signed` или `not_reached`. `mode` принимает значения `fields` или `read_and_agree`. `source_format` принимает значения `pdf` или `docx`. `conversion` описывает исходный файл Word или равно `null` для PDF. | `[…]` |
| `documents[].fields` | массив объектов | Нет | `{ key, type, role, label, page, x, y, width, height, required, value, display_value, value_source, filled_at, image_url, value_unavailable_reason }` для каждого поля в документе. `value` — строка, логическое значение для флажка или `true` для проставленной подписи или инициалов. Для документа без полей массив пустой. | `[…]` |
| `adopted_signature` | объект | Да | `{ method, font, adopted_at }`: подпись и инициалы, которые принял подписант. `method` принимает значения `typed` или `drawn`. `font` задаёт стиль почерка для напечатанной подписи. Значение `null`, пока подпись и инициалы не приняты. | `{ "method": "drawn", … }` |
| `electronic_signature_consent_at` | строка (ISO 8601) | Да | Когда подписант согласился подписывать документы электронно. Заполняется, если в каком-либо документе есть поля. | `"2026-11-03T10:41:40Z"` |
| `evidence_file` | строка | Да | Путь к PDF с доказательствами после подписания. | `"/v3/session/…/evidence/?signature_id=…"` |
| `warnings` | массив объектов | Нет | `{ code, node_id }`, где `code` принимает одно из значений: `SIGNATURE_DECLINED`, `SIGNATURE_OTP_FAILED`, `SIGNATURE_NAME_MISMATCH`, `SIGNATURE_IDENTITY_NOT_VERIFIED`, `SIGNATURE_DOCUMENT_CHANGED`. | `[]` |
| `validation` | объект | Да | `{ valid, checked_at, documents[] }`: последняя криптографическая проверка подписанных документов. Значение `null`, пока документы не подписаны. `{ valid: null, reason: "signature_provider_outcome_unknown", checked_at }`, если результат подписания не удалось подтвердить. | `{ "valid": true, … }` |
| `declined_at` | строка (ISO 8601) | Да | Когда подписант отказался. | `null` |
| `declined_action` | строка | Нет | Значение `signature_declined_action` для шага. | `"REVIEW"` |
| `signed_at` | строка (ISO 8601) | Да | Когда документы были подписаны. | `"2026-11-03T10:42:24Z"` |
| `expires_at` | строка (ISO 8601) | Нет | Когда ссылка для подписания перестаёт работать. | `"2026-11-10T10:30:00Z"` |
| `email_sent_at` | строка (ISO 8601) | Да | Когда подписанту отправлена по электронной почте подписанная копия. | `"2026-11-03T10:42:30Z"` |
| `email_unavailable_reason` | строка | Да | Почему копия не отправлена по электронной почте, если её запросили. | `null` |
| `ip_address` | строка | Да | IP-адрес подписанта в момент запроса кода. | `"203.0.113.10"` |
| `place` | строка | Да | Не собирается: всегда `null`. | `null` |
| `place_unavailable_reason` | строка | Да | `not_collected`. | `"not_collected"` |

[Отчёт об электронной подписи](https://docs.didit.me/ru/core-technology/electronic-signature/report-electronic-signature.md) содержит полный пример и все вложенные поля.

### Оценка возраста

Возвращается отдельным API оценки возраста (`POST /v3/age-estimation/`). Ответ содержит часть структуры [`Liveness check`](#проверка-живости) внутри конверта `age_estimation`: `status`, `method`, `score`, `age_estimation`, `warnings`. Кроме того, есть блок обнаружения лица `user_image`, который доступен только в отдельном API. Ответ **не** включает `reference_image`, `video_url`, `matches`, `face_quality` и `face_luminance`. В сессиях сценария отдельного массива нет: оценочный возраст возвращается в `liveness_checks[].age_estimation` в ответе `GET /v3/session/{sessionId}/decision/`. Источник: `apis/serializers/age_estimation.py:50-55` (`AgeEstimationResponseSerializer`), конверт формируется в `apis/views/age_estimation.py:138-174`.

| Поле | Тип | Допускает null | Описание | Пример |
| - | - | - | - | - |
| `request_id` | строка (UUID) | Нет | ID сохранённой сессии, если `save_api_request=true` (по умолчанию). Иначе временный корреляционный UUID. | `"3b1f1e2c-…"` |
| `age_estimation` | объект | Нет | Конверт результата: `status` (`Approved` / `Declined`), `method` (всегда `PASSIVE`), `score` (оценка живости, 0–100, может быть null), `age_estimation` (предсказанный возраст в годах для самого крупного лица, может быть null), `user_image` (`entities[]` с полями для каждого лица: `age`, `bbox` `[x_min, y_min, x_max, y_max]`, `confidence`, `gender`; а также `best_angle`), `warnings[]`. | `{ … }` |
| `vendor_data` | строка | Да | Повторяет `vendor_data` из запроса. | `null` |
| `metadata` | объект | Да | Повторяет `metadata` из запроса. | `null` |
| `created_at` | строка (ISO 8601) | Нет | Серверное время запроса. | `"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"
}
```

### Биометрическая аутентификация

Биометрическая аутентификация использует тот же конвейер проверки живости и сравнения лиц, что и стандартный KYC. Но он настроен на сравнение снятого лица с эталонным изображением существующего пользователя, а не с портретом из документа, полученным через OCR. Отдельного сериализатора нет: `GET /v3/session/{sessionId}/decision/` возвращает стандартные объекты [Проверка живости](#проверка-живости) и [Сравнение лиц](#сравнение-лиц) в `liveness_checks[]` и `face_matches[]`. Сценарий сессии настраивается с `workflow_type = "biometric_authentication"` (`WorkflowTypeChoices`, `common/config/choices.py:636`).

| Поле | Тип | Допускает null | Описание | Пример |
| - | - | - | - | - |
| `liveness_checks` | массив [Проверка живости](#проверка-живости) | Нет | Результат проверки живости для попытки аутентификации. | `[ { "status": "Approved", … } ]` |
| `face_matches` | массив [Сравнение лиц](#сравнение-лиц) | Нет | Результат сравнения с зарегистрированным эталоном. `source_image_session_id` равен собственному `session_id` сессии: эталонное лицо (переданный `portrait_image` или сохранённое лицо, которое переиспользуется через `vendor_data`, если `portrait_image` не передан) записывается в саму сессию аутентификации (`face/views/face.py:656-659`). | `[ { "status": "Approved", "source_image_session_id": "…", … } ]` |
| `status` | string | Нет | Статус сессии верхнего уровня (см. [Перечисление статусов](#справочник-значений-перечисления-status)). | `"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": []
    }
  ]
}
```

### Реестр KYB

Возвращается для каждой компании, подтверждённой реестром, в сценарии KYB. Появляется как `registry_checks[]` в `GET /v3/session/{sessionId}/decision/` для бизнес-сессий. Источник: `kyb/serializers/kyb.py:939-964` (`RegistryCheckV3Serializer`).

| Поле | Тип | Может быть null | Описание | Пример |
| - | - | - | - | - |
| `status` | string | Нет | См. [Перечисление статусов](#справочник-значений-перечисления-status). | `"Approved"` |
| `node_id` | string \| null | Да | Идентификатор узла сценария (V3). | `"first_registry"` |
| `data_resolved` | boolean | Нет | `true`, когда получение данных из реестра завершено (или `is_from_registry` равно `false`, то есть данные введены вручную). | `true` |
| `company` | object | Нет | Полный payload компании, см. [Объект компании](#объект-компании) ниже. | `{ … }` |
| `ownership_structure` | object | Да | Таблица капитализации, подтверждённая реестром: `shareholders[]` и `beneficial_owners[]`, у каждого владельца его идентификатор в реестре, доля и каноническое значение `shareholding`. | `{ "shareholders": [...], "beneficial_owners": [] }` |
| `warnings` | array | Нет | См. [Объект предупреждения](#объект-предупреждения). | `[]` |

#### Объект компании

Из `kyb/serializers/kyb.py:220-321` (`KYBCompanyResponseSerializer`).

| Поле | Тип | Может быть null | Описание |
| - | - | - | - |
| `uuid` | string (UUID) | Нет | Внутренний идентификатор компании. |
| `node_id` | string \| null | Да | Идентификатор узла сценария. |
| `status` | string | Нет | Статус функции (`FeatureStatusChoices`). |
| `registry_status` | string | Да | Статус компании в реестре (`active`, `dissolved`, …). |
| `data_resolved` | boolean | Нет | То же определение, что и у родительского объекта. |
| `company_name` | string | Да | Зарегистрированное название компании. |
| `registration_number` | string | Да | Регистрационный номер в реестре. |
| `country_code` | string (ISO 3166-1 alpha-2) | Да | Страна регистрации. |
| `region` | string | Да | Подразделение по ISO 3166-2, когда применимо (например, `US-CA`). |
| `company_type` | string | Да | Организационно-правовая форма (`LLC`, `SL`, …). |
| `incorporation_date` | string (YYYY-MM-DD) | Да | Дата регистрации компании. |
| `registered_address` | string | Да | Зарегистрированный юридический адрес. |
| `tax_number` | string | Да | Налоговый или НДС-идентификатор. |
| `risk_level` | string | Да | Рейтинг риска от провайдера данных. |
| `verification_status` | string | Да | Внутреннее перечисление статусов верификации. |
| `is_from_registry` | boolean | Нет | `true`, если данные получены из реестра (а не введены вручную). |
| `fetch_status` | string | Да | `pending`, `resolved`, `failed`. |
| `alternative_names` | string | Да | Альтернативные торговые названия через запятую. |
| `nature_of_business` | string | Да | Свободное текстовое описание деятельности компании. |
| `registered_capital` | string | Да | Зарегистрированный капитал в читаемом виде. |
| `registered_capital_amount` | string (decimal) | Да | Разобранная сумма зарегистрированного капитала. |
| `registered_capital_currency` | string (ISO 4217) | Да | Код валюты. |
| `website` | string (URL) | Да | Веб-сайт компании. |
| `email` | string | Да | Публичный контактный адрес электронной почты. |
| `phone` | string | Да | Публичный контактный телефон. |
| `legal_entity_identifier` | string | Да | LEI, когда доступен. |
| `location_of_registration` | string | Да | Офис или регион регистрации в реестре. |
| `vat_number` | string | Да | Номер НДС, указанный для компании. |
| `vat_validation_status` | string | Нет | Результат проверки номера НДС или `tax_number`, если номера НДС нет: `valid`, `invalid`, `format_valid`, `invalid_format`, `could_not_validate` или `not_applicable`. См. [Проверка НДС и налогового идентификатора](https://docs.didit.me/ru/business-verification/company-data.md#vat-и-проверка-налогового-номера). |
| `vat_validated_number` | string | Да | Проверенный номер в том виде, в котором его знает источник. |
| `vat_validation_source` | string | Да | Источник, определивший статус: `eu_vies`, `pl_vat_white_list`, `no_brreg`, `ch_uid_register`, `br_receita_federal`, `co_rues`, `cr_hacienda`, `ec_sri`, `py_dnit` или `format_rules`. |
| `vat_validated_name` | string | Да | Название, зарегистрированное в источнике (пусто, если источник его не раскрывает). |
| `vat_validated_address` | string | Да | Адрес, зарегистрированный в источнике (пусто, если не раскрывается). |
| `vat_checked_at` | string (ISO 8601) | Да | Время проверки; `null`, если проверка не выполнялась. |
| `financial_summary` | object | Да | Снимок последних финансовых показателей, когда их предоставляет реестр. |
| `officers` | array of objects | Нет | Список должностных лиц, безопасный для B2C: `{ uuid, name, designation, role, nationality, is_active, kyc_status, kyc_session_url }`. |
| `beneficial_owners` | array of objects | Нет | Список UBO (бенефициарных владельцев), безопасный для 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 | Да | Подробные данные по каждому адресу из реестра. |
| `industries` | array of objects | Да | Классификации в стиле SIC/NAICS. |
| `accounts` | array of objects | Да | Метаданные поданной отчётности. |
| `registry_data` | object | Да | Нормализованные данные реестра Didit (итог по владению, исправления из консоли, факты реестра без отдельного поля). Не является стабильным контрактом. |
| `user_provided_data` | object | Да | Снимок полей, отредактированных пользователем. |
| `confirmed_by_user_at` | string (ISO 8601) | Да | Время, когда пользователь подтвердил извлечённые данные. |
| `last_console_edit_at` | string (ISO 8601) | Да | Время последнего редактирования в консоли. |
| `is_editable` | boolean | Нет | `true`, пока данные из реестра ещё может редактировать конечный пользователь. |

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

### Документ KYB

Возвращается для каждого узла, который собирает подтверждающие документы KYB. Появляется как `document_verifications[]` в `GET /v3/session/{sessionId}/decision/` для бизнес-сессий: по одной записи на каждый `node_id`, а `items[]` содержит список каждого загруженного документа. Источник: `kyb/serializers/kyb.py:1053-1068` (`DocumentVerificationV3Serializer`); каждый элемент соответствует `kyb/serializers/kyb.py:811-851` (`KYBDocumentResponseSerializer`).

| Поле | Тип | Может быть null | Описание | Пример |
| - | - | - | - | - |
| `status` | string | Нет | Совокупный статус по всем документам этого узла: `Approved` только тогда, когда одобрены все документы сценария; `Declined`, если отклонён хотя бы один; `In Review` во всех остальных случаях; `Not Finished`, пока документы находятся в ожидании. См. [Перечисление статусов](#справочник-значений-перечисления-status). | `"Approved"` |
| `node_id` | string \| null | Да | Идентификатор узла сценария (V3). | `"first_kyb_documents"` |
| `items` | массив [объектов элементов документов KYB](#объект-элемента-документа-kyb) | Нет | По одной записи на каждый загруженный или запрошенный документ. | `[…]` |
| `groups` | object | Нет | Счётчики по группам документов: `{ <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` | массив строк | Нет | Группы документов, обязательные согласно конфигурации сценария. | `["incorporation_certificate", "shareholder_register"]` |
| `warnings` | array | Нет | См. [Объект предупреждения](#объект-предупреждения). | `[]` |

#### Объект элемента документа KYB

| Поле | Тип | Может быть null | Описание |
| - | - | - | - |
| `uuid` | string (UUID) | Нет | Внутренний идентификатор документа. |
| `document_type` | string | Да | Группа верхнего уровня (`incorporation_certificate`, `shareholder_register`, …). |
| `document_subtype` | string | Да | Подтип, специфичный для провайдера. |
| `document_group` | string | Да | Дублирует `document_type` (псевдоним, оставлен для наглядности). |
| `file_url` | string (URL) | Да | Предподписанный URL очищенного файла. |
| `original_filename` | string | Да | Имя файла в том виде, в котором он был загружен. |
| `file_size` | integer | Да | Размер файла в байтах. |
| `status` | string | Нет | Статус отдельного документа (`FeatureStatusChoices`). |
| `created_at` | string (ISO 8601) | Нет | Время загрузки. |
| `cross_check_result` | object | Да | Результат перекрёстной проверки с реестром и другими документами. |
| `document_metadata` | object | Да | Метаданные той же отфильтрованной структуры, что и `document_metadata` для POA. |
| `description` | string | Да | Описание, добавленное проверяющим или системой. |
| `is_requested` | boolean | Нет | `true`, если сценарий ожидал этот документ. |
| `ocr_data` | object | Да | Поля, извлечённые с помощью OCR, если они доступны. |
| `is_console_upload` | boolean | Нет | `true`, если документ загружен проверяющим в консоли (не учитывается в совокупном вердикте). |
| `is_confirmed` | boolean | Нет | `true`, если проверяющий явно подтвердил документ. |

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

### Ключевое лицо KYB

Возвращается для каждого узла «Ключевые лица» в сценарии KYB. Появляется как `key_people_checks[]` в `GET /v3/session/{sessionId}/decision/` для сессий компаний. Источник: `kyb/serializers/kyb.py:967-1050` (`KeyPeopleCheckV3Serializer`).

| Поле | Тип | Может быть null | Описание | Пример |
| - | - | - | - | - |
| `status` | string | Нет | См. [Перечисление статусов](#справочник-значений-перечисления-status). | `"Approved"` |
| `node_id` | string \| null | Да | Идентификатор узла сценария (V3). | `"first_key_people"` |
| `registry` | object | Нет | `{ officers[], beneficial_owners[] }`, извлечённые из реестра. Должностные лица соответствуют `KYBPersonResponseSerializer` (`kyb/serializers/kyb.py:533-645`); бенефициарные владельцы соответствуют `KYBBeneficialOwnerResponseSerializer` (`kyb/serializers/kyb.py:648-788`), который добавляет `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`. Оба включают обогащение AML и KYC по каждой стороне (`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 | Нет | `{ parties[] }`: записи, которые компания подтвердила или отправила через процесс ключевых лиц (строки `BusinessParty` с `source=USER`). Каждая запись соответствует `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` отмечают удалённую дочернюю сессию: её статус остаётся замороженным на последнем значении, соответствующий `*_session_url` возвращается как `null`, потому что ссылка больше не работает, а запись перестаёт блокировать родительскую проверку (вместо этого проверка переходит в статус `In Review`). Сбросить это состояние можно с помощью [`PATCH /v3/session/{id}/kyb/parties/{party_uuid}/`](https://docs.didit.me/ru/sessions-api/update-data#пропуск-стороны-key-people). | `{ "parties": [...] }` |
| `ubo_kyc_summary` | object | Да | Счётчики по активным UBO со связанным KYC: `{ total, approved, flagged, pending }`. `null`, если к активным UBO не привязан KYC. | `{ "total": 2, "approved": 2, "flagged": 0, "pending": 0 }` |
| `warnings` | array | Нет | См. [Объект предупреждения](#объект-предупреждения). | `[]` |

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

## Поля уровня решения

Эти ключи находятся рядом с массивами функций в `GET /v3/session/{sessionId}/decision/` и внутри `decision` в webhook.

| Поле | Тип | Может быть null | Описание |
| - | - | - | - |
| `status_override` | object | Да | `{ overridden_at, automatic_status }` после того, как проверяющий вручную установил `status`; `null`, если статус автоматический. |
| `decision_trace` | object | Нет | Как был получен статус: `status`, `decided_by` (`manual`, `automatic` или `investigator`), `decided_at`, `automatic_status`, `terminal_node_id`, `actor`, `warning_counts` и `status_warnings`. |
| `linked_records` | object | Да | Сводки `same_face`, `earlier_verifications` и `networks`; `null`, если показывать нечего. |
| `biometric_retention` | object | Нет | `{ jurisdictions, deletes_at }`. `deletes_at`: дата, когда удаляются полученные в реальном времени биометрические данные сессии; `null`, если дата пока не применима. |
| `database_validation_not_performed_reason` | object | Да | `{ code, message }`, объясняющий, почему настроенная проверка по базам данных не дала результата. |
| `assignee`, `waiting_since`, `sla_due_at` | object, datetime | Да | Проверяющий Console, которому назначена сессия, и её временной отсчёт проверки; отсчёт равен `null`, если сессия не находится в статусе `In Review`. |
| `shared_from_session`, `shared_from_session_number` | UUID, integer | Да | Исходная сессия, из которой была импортирована текущая сессия. |
| `sandbox_scenario` | string | Да | Сценарий, с которым была создана сессия песочницы. |
| `fraud_check` | object | Да | Результат Fraud Check API; `null` для всех остальных сессий. |
| `full_session_video`, `full_session_video_recorded_at` | URL, datetime | Да | Запись и время её создания. Возвращаются только в том случае, если ваша организация записывает видео всей сессии. |

Подробнее о том, как читать эти поля, см. в разделе [Получение сессии](https://docs.didit.me/ru/sessions-api/retrieve-session.md#статус-трассировка-решения-и-поля-проверки).

## Согласие на биометрические данные

Каждое решение по проверке пользователей и webhook сессии содержат один объект `biometric_consent` (не массив). В нём указано, требовалось ли для сессии явно получить согласие на обработку биометрических данных, по какой причине и какие данные подтверждают этот ответ. Значение `null`, если сессия никогда не оценивалась, например для сценария без захвата лица. Источник: `BiometricConsentDecisionSerializer` (`sessions/serializers/biometric_consent.py`). Когда появляется этот шаг и что означает каждый случай, описано в разделе [Согласие на биометрические данные](https://docs.didit.me/ru/getting-started/biometric-consent.md).

Поля без записанного значения равны `null`, но никогда не являются пустой строкой.

| Поле | Тип | Описание |
| - | - | - |
| `required` | логическое значение | Должна ли сессия получить явное согласие на обработку биометрических данных. Никогда не возвращается к `false`. |
| `trigger` | строка (перечисление) \| null | Почему требуется согласие или каким образом оно было получено: `declared_state`, `ip_state`, `ip_unknown`, `document_issuer`, `forced` (режим приложения: Always), `customer_collected` (вы передали `biometric_consent` при создании сессии). `null`, пока согласие не требуется. |
| `status` | строка (перечисление) | `not_required`, `pending` (требуется, но не дано), `given`, `declined` (отказ зафиксирован; ни один экран Didit сейчас не предлагает отказ). |
| `given_at` | строка (ISO 8601) \| null | Когда было дано согласие. Для `customer_collected` это `given_at`, который вы передали. |
| `declined_at` | строка (ISO 8601) \| null | Когда был зафиксирован отказ. |
| `text_version` | строка \| null | Идентификатор версии текста согласия, на который ответил человек, или версии, которую вы передали. |
| `text_hash` | строка \| null | SHA-256 (в шестнадцатеричном виде) точного показанного текста на языке, на котором он был показан. |
| `locale` | строка \| null | Язык, на котором был показан текст. |
| `policy_url` | строка \| null | Политика обработки биометрических данных, на которую ссылался этот шаг. |
| `step` | строка \| null | Шаг сценария, на котором находилась сессия, когда человек ответил (например, `LIVENESS`). |
| `node_id` | строка \| null | Узел графа сценария, на котором находилась сессия, когда человек ответил. |
| `ip_address` | строка \| null | IP-адрес, с которого пришёл ответ. |
| `ip_country_code` | строка \| null | Страна IP-адреса ответа в формате ISO 3166-1 alpha-2. |
| `ip_state` | строка \| null | Административная единица IP-адреса ответа по ISO 3166-2 (например, `US-IL`). |
| `ip_city` | строка \| null | Город IP-адреса ответа. |
| `user_agent` | строка \| null | Агент пользователя запроса, содержащего ответ. |
| `detected_ip_address` | строка \| null | IP-адрес человека, с которого в последний раз оценивалось требование. Может отличаться от `ip_address`, если человек ответил с другого устройства. |
| `detected_country_code` | строка \| null | Страна обнаруженного IP-адреса в формате ISO 3166-1 alpha-2. |
| `detected_state` | строка \| null | Административная единица обнаруженного IP-адреса по ISO 3166-2. |
| `detected_city` | строка \| null | Город обнаруженного IP-адреса. |
| `declared_state` | строка \| null | Административная единица по ISO 3166-2, которую вы указали: `user_state` или штат адреса в США из `expected_details`. |
| `document_state` | строка \| null | Административная единица по ISO 3166-2, которая выдала удостоверение личности. Считывается при съёмке документа. |
| `jurisdictions` | массив строк | Штаты США (коды USPS, например `IL`), на которые распространяется биометрическое законодательство, действующее для этого человека. `US`, если данные указывают, что человек находится в США, но штат неизвестен. Пустой массив, если ничего не применимо. |
| `retention_months` | целое число \| null | Наименьший срок хранения биометрических данных в месяцах среди `jurisdictions`. `null`, если ничего не применимо. |
| `reason` | строка (перечисление) \| null | `BIOMETRIC_CONSENT_UNSUPPORTED_SDK`: согласие требовалось, а нативный SDK версии ниже 4.10.0 (или SDK, не сообщивший свою версию) выполнил захват лица без этого шага. `status` остаётся `pending`, либо становится `given`, если человек позже согласился на размещённой странице верификации. `BIOMETRIC_CONSENT_DECLINED`: зафиксирован отказ (он заменяет причину, связанную с SDK). В остальных случаях `null`. Всегда `null`, если сессия не требовала согласия. |
| `decline_reason` | строка \| null | `BIOMETRIC_CONSENT_DECLINED`, когда зафиксированный отказ завершил сессию, иначе `null`. |
| `face_data_deleted_at` | строка (ISO 8601) \| null | Когда вследствие отказа были удалены изображения лица, видео и биометрические шаблоны лица сессии. `null`, если отказ не был зафиксирован. |

Сессия в штате Иллинойс, проведённая на нативном SDK версии ниже 4.10.0, который снял селфи без этого шага:

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

Человек с VPN, выход которого находится за пределами США и который дал согласие на размещённой странице верификации:

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

## Справочник значений перечисления status

Два связанных набора значений используют одно и то же имя поля `status`. Каждый объект отчёта по отдельной функции на этой странице использует перечисление уровня функции. Верхнеуровневое поле `status` родительской сессии использует более широкое перечисление уровня сессии.

### Статусы на уровне функций

Используется в поле `status` каждого объекта отчёта. Источник: `common/config/choices.py:343-348` (`FeatureStatusChoices`).

| Значение | Описание |
| - | - |
| `Not Finished` | Функция подготовлена, но пользователь ещё не завершил её. |
| `Approved` | Функция прошла все проверки. |
| `Declined` | Функция не прошла как минимум одну жёсткую проверку (см. `warnings[]` с `log_type: "error"`). |
| `In Review` | Функция вызвала сигналы мягкого отказа и ожидает ручной проверки (см. `warnings[]` с `log_type: "warning"`). |
| `Resub Requested` | Проверяющий запросил у пользователя повторно пройти эту функцию. |

Верификация телефона, электронной почты и личности может дополнительно возвращать `Expired`, когда истекает время, отведённое на соответствующий шаг (`PhoneStatusChoices` в `common/config/choices.py:377-382`, `EmailStatusChoices` в `common/config/choices.py:434-439`).

### Статусы на уровне сессии

Используется в верхнеуровневом поле `status` родительской сессии. Источник: `common/config/choices.py:106-117` (`StatusChoices`).

| Значение | Описание |
| - | - |
| `Not Started` | Сессия создана, но пользователь ещё не начал её. |
| `In Progress` | Пользователь начал процесс; результат ещё не окончательный. |
| `Approved` | Сессия прошла все проверки. |
| `Declined` | Сессия не прошла как минимум одну жёсткую проверку. |
| `In Review` | Сессия ожидает ручной проверки. |
| `Expired` | Сессия истекла до завершения. |
| `Abandoned` | Пользователь покинул процесс, не завершив его. |
| `Kyc Expired` | Истёк срок действия KYC (используется в потоках повторной верификации). |
| `Resubmitted` | Пользователь повторно отправил данные после предыдущего отказа; эта сессия заменена более новой. |
| `Awaiting User` | Система ожидает действия пользователя (например, ввода одноразового кода OTP). |

> [!TIP]
>
> Конечными значениями сессии являются `Approved`, `Declined`, `In Review`, `Expired`, `Kyc Expired` и `Abandoned`. Сессия может получить общее решение, пока отдельная функция остаётся в статусе `In Review`.


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