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

# Отчёт о проверке телефона: JSON с OTP и данными оператора

> Отчёты Didit по проверке телефона: оператор, тип линии, OTP и предупреждения о рисках. Оплата за OTP от $0.02 плюс тарифы оператора.

Отчёт «Проверка телефона» фиксирует полный результат проверки номера через OTP: кому был отправлен код, какой оператор и канал использовались для доставки, сколько потребовалось попыток, является ли номер одноразовым или VoIP, а также любые межсессионные совпадения со списком блокировки или сессиями других пользователей.

На этой странице описана структура JSON, возвращаемая endpoint решения, что позволяет анализировать результаты проверки OTP, метаданные оператора и флаги риска для каждого верифицированного номера.

![Отчёт Didit о проверке телефона, показывающий результат проверки OTP, метаданные оператора и флаги риска](https://mintcdn.com/didit-0f962782/z6T2GHM4Zh-iSj-K/images/phone-verification-report.png?fit=max\&auto=format\&n=z6T2GHM4Zh-iSj-K\&q=85\&s=9b5c6c6112303ebc60c0f287aafdb996)

## Обзор

Отчёт по номеру телефона формируется каждый раз, когда узел сценария выполняет функцию Проверка телефона. Каждый отчёт представляет одну проверку через OTP для одного номера телефона и содержит:

* Номер телефона, разбитый на префикс, национальный номер и полный формат E.164, а также код страны ISO и название страны.
* Метаданные оператора (`name`, `type`), определённые по сети назначения.
* Логические флаги риска (`is_disposable`, `is_virtual`), полученные на основе анализа типа линии.
* Фактически использованный канал доставки (`verification_method`) и количество попыток отправки OTP.
* Хронологический журнал `lifecycle[]` для каждого события отправки, повторной попытки, доставки и проверки введённого кода.
* Массив `matches[]`, отображающий совпадения этого же номера в других сессиях с любым статусом — в KYC, KYB и отдельных API-верификациях — либо в вашем списке блокировки.
* Массив `warnings[]` — события риска, зафиксированные в процессе верификации (см. [Предупреждения проверки телефона](https://docs.didit.me/ru/core-technology/phone-verification/warnings-phone-verification.md)).
* Идентификатор `node_id`, указывающий, какой узел графа сценария сформировал данный отчёт (только для сессий V3).

При использовании сценариев с размещённой страницей верификации Didit берёт обмен OTP на себя. Для прямой интеграции через API тот же процесс состоит из двух вызовов: [`POST /v3/phone/send/`](https://docs.didit.me/ru/standalone-apis/phone-send) для отправки кода и [`POST /v3/phone/check/`](https://docs.didit.me/ru/standalone-apis/phone-check) для проверки введённого пользователем значения. Неподтверждённый OTP действителен в течение **5 минут с момента первой отправки** (повторные попытки не продлевают этот интервал). В сессиях сценария пользователям по умолчанию предоставляется 2 попытки отправки OTP (`phone_max_retries`) и 2 попытки ввода кода (`phone_max_check_attempts`) — оба параметра настраиваются индивидуально для каждого узла сценария; исчерпание любого из этих лимитов завершает шаг со статусом `Declined` и причиной `VERIFICATION_CODE_ATTEMPTS_EXCEEDED`. Отдельный API проверки телефона допускает 3 попытки ввода кода на одну верификацию.

## Где это отображается в ответах API

Endpoint решения (`GET /v3/session/{sessionId}/decision/`) возвращает отчёты по номерам телефонов в массиве под ключом во множественном числе **`phone_verifications`**. Этот массив содержит по одной записи для каждого узла «Проверка телефона» в графе сценария — обычно одну, но сценарии с повышением уровня проверки (step-up) могут содержать несколько таких записей.

```json theme={null}
{
  "session_id": "11111111-1111-1111-1111-111111111111",
  "status": "Approved",
  "phone_verifications": [
    { "status": "Approved", "node_id": "feature_phone_1", "...": "..." }
  ]
}
```

Значение `null` означает, что шаг «Проверка телефона» ещё не выполнялся. Если ваш сценарий может запрашивать несколько номеров телефонов, перебирайте массив в цикле (вместо чтения только `phone_verifications[0]`).

## Схема

Каноническая схема с подробным описанием каждого поля приведена на странице [Data models](https://docs.didit.me/ru/reference/data-models.md#проверка-телефона).

```typescript theme={null}
interface PhoneVerification {
  status: "Not Finished" | "Approved" | "Declined" | "In Review" | "Expired";
  phone_number_prefix: string;       // E.g. "+34"
  phone_number: string;              // National number, no prefix
  full_number: string;               // Full E.164, e.g. "+34600600600"
  country_code: string;              // ISO 3166-1 alpha-2, e.g. "ES"
  country_name: string;
  carrier: {
    name: string;
    type:                              // From LineTypeChoices
      | "mobile" | "fixed_line" | "voip" | "isp" | "vpn"
      | "toll_free" | "premium_rate" | "shared_cost" | "local_rate"
      | "satellite" | "pager" | "payphone" | "voice_mail"
      | "calling_cards" | "service" | "short_codes_commercial"
      | "universal_access" | "other" | "unknown";
  };
  is_disposable: boolean;            // Temporary / burner number
  is_virtual: boolean;               // true when carrier.type is voip, isp or vpn
  verification_method:               // Actual channel that delivered the OTP
    | "sms" | "whatsapp" | "telegram" | "voice" | "rcs" | "viber" | "zalo";
  verification_attempts: number;     // OTP send attempts (initial send + resends)
  verified_at: string | null;        // ISO 8601, set when a valid OTP was entered
  warnings: Warning[];               // Risk events emitted during verification
  lifecycle: PhoneLifecycleEvent[];  // OTP send/retry/delivery/check timeline
  matches: PhoneMatch[];             // Cross-session / blocklist matches (max 5)
  node_id: string;                   // Workflow graph node that produced this report
}
```

### Значения статуса

| Статус | Значение |
| - | - |
| `Not Finished` | Отправка одноразового кода инициирована, но верификация ещё не завершена. |
| `Approved` | Пользователь ввёл корректный одноразовый код, и отклоняющих факторов риска не обнаружено. |
| `Declined` | Сработало предупреждение автоматического отклонения (список блокировки, высокий риск, превышение попыток) или действие риска со значением `DECLINE`. |
| `In Review` | Действие риска со значением `REVIEW` перенаправило шаг на ручную проверку. |
| `Expired` | 5-минутное окно ввода одноразового кода истекло без ввода корректного кода — применяется к верификациям, созданным через отдельный API проверки телефона. |

### Типы событий жизненного цикла

Массив `lifecycle[]` отсортирован хронологически. Каждое событие содержит `type`, `timestamp`, `details` и тарифицируемую комиссию `fee` (при наличии):

| Тип события | Когда генерируется |
| - | - |
| `PHONE_VERIFICATION_MESSAGE_SENT` | Первая попытка отправки одноразового кода через запрошенный канал. |
| `PHONE_VERIFICATION_RETRY_MESSAGE_SENT` | Последующая отправка одноразового кода после запроса повторной отправки пользователем. |
| `PHONE_VERIFICATION_BLOCKED` | Отправка заблокирована (спам, подозрительная активность, повторные попытки, недействительный номер). |
| `PHONE_DELIVERY_DELIVERED` | Оператор связи подтвердил доставку по фактически использованному каналу. |
| `PHONE_DELIVERY_UNDELIVERABLE` | Оператор связи сообщил, что сообщение не удалось доставить. |
| `VALID_CODE_ENTERED` | Пользователь ввёл правильный одноразовый код. |
| `INVALID_CODE_ENTERED` | Пользователь ввёл неверный одноразовый код (засчитывается в лимит попыток ввода). |
| `PHONE_VERIFICATION_APPROVED` | Статус на уровне функции установлен в `Approved`. |
| `PHONE_VERIFICATION_DECLINED` | Статус на уровне функции установлен в `Declined`. |
| `PHONE_VERIFICATION_IN_REVIEW` | Статус на уровне функции установлен в `In Review`. |
| `PHONE_VERIFICATION_EXPIRED` | Окно ввода одноразового кода истекло без ввода верного кода. |

Payload `details` зависит от семейства событий:

* **События отправки** (`PHONE_VERIFICATION_MESSAGE_SENT`, `PHONE_VERIFICATION_RETRY_MESSAGE_SENT`, `PHONE_VERIFICATION_BLOCKED`) — `{ status, reason, channel, actual_channel }`. Поле `status` принимает значения `Success`, `Retry` или `Blocked`; `reason` равен `null`, если отправка не была заблокирована (`invalid_phone_number`, `repeated_attempts`, `suspicious`, `spam`, `unknown`); `channel` представляет собой запрошенный канал, а `actual_channel` указывает на канал, через который сообщение было фактически доставлено (например, при отправке в WhatsApp с переключением на SMS при сбое).
* **События доставки** (`PHONE_DELIVERY_DELIVERED`, `PHONE_DELIVERY_UNDELIVERABLE`) — `{ channel, status }` со `status` `delivered` или `undeliverable`.
* **События проверки кода** (`VALID_CODE_ENTERED`, `INVALID_CODE_ENTERED`) — `{ code_tried, status }` со `status` `Approved`, `Declined`, `Failed` или `Expired or Not Found`.
* **События итогового статуса** — `null`, за исключением `PHONE_VERIFICATION_DECLINED` / `PHONE_VERIFICATION_IN_REVIEW`, которые содержат `{ "reason": "<risk code>" }` (например, `PHONE_NUMBER_IN_BLOCKLIST`).

Поле `fee` в событии отправки представляет собой полную стоимость этой отправки: тариф оператора или WhatsApp плюс комиссия Didit в размере $0.02, либо только комиссия Didit в размере $0.02 за код WhatsApp, отправленный с [вашего собственного номера WhatsApp Business](https://docs.didit.me/ru/core-technology/phone-verification/overview.md#отправка-кодов-whatsapp-с-собственного-номера). До подтверждения доставки это предварительная стоимость, а затем фактическая сумма списания. Бесплатными гарантированно являются только отправки со статусом `Blocked`: любая другая отправка тарифицируется в момент финализации верификации или по истечении срока её действия, даже если доставка не была подтверждена или сообщение оказалось недоставляемым. События доставки, проверки и изменения статуса всегда имеют `fee: 0`.

### Совпадения между сессиями

Массив `matches[]` фиксирует другие сессии в том же приложении, где встречался тот же номер — в рамках KYC, KYB и верификаций через отдельный API независимо от их статуса — плюс совпадения со списками блокировки, настроенными в [списках management-api](https://docs.didit.me/ru/management-api/lists/overview.md). Сессии с тем же `vendor_data`, что и у текущей сессии, исключаются (один и тот же конечный пользователь не сопоставляется с самим собой), а размер массива ограничен **5** записями. Если номер находится в вашем списке блокировки, но ни одна из найденных сессий не заблокирована, в начало массива добавляется синтетическая запись с `source: "list_entry"` (все поля сессии равны `null`).

```typescript theme={null}
interface PhoneMatch {
  session_id: string | null;         // null when source = "list_entry"
  session_number: number | null;
  vendor_data: string | null;
  verification_date: string | null;  // ISO 8601, creation date of the matched session
  phone_number: string;
  status: string | null;             // Status of the matched session
  is_blocklisted: boolean;
  api_service: string | null;        // Set when the matched session came from a standalone API
  source: "session" | "list_entry";  // "list_entry" = manual blocklist hit
}
```

## Примеры

### Одобрено — одноразовый код WhatsApp, мобильный оператор связи

```json theme={null}
{
  "status": "Approved",
  "phone_number_prefix": "+34",
  "phone_number": "600600600",
  "full_number": "+34600600600",
  "country_code": "ES",
  "country_name": "Spain",
  "carrier": { "name": "Orange", "type": "mobile" },
  "is_disposable": false,
  "is_virtual": false,
  "verification_method": "whatsapp",
  "verification_attempts": 1,
  "verified_at": "2025-08-24T09:12:39.684292Z",
  "warnings": [],
  "lifecycle": [
    {
      "type": "PHONE_VERIFICATION_MESSAGE_SENT",
      "timestamp": "2025-08-24T09:12:30.580554Z",
      "details": { "status": "Success", "reason": null, "channel": "whatsapp", "actual_channel": "whatsapp" },
      "fee": 0.0509
    },
    {
      "type": "PHONE_DELIVERY_DELIVERED",
      "timestamp": "2025-08-24T09:12:31.000000Z",
      "details": { "channel": "whatsapp", "status": "delivered" },
      "fee": 0
    },
    {
      "type": "VALID_CODE_ENTERED",
      "timestamp": "2025-08-24T09:12:39.662157Z",
      "details": { "code_tried": "123456", "status": "Approved" },
      "fee": 0
    },
    {
      "type": "PHONE_VERIFICATION_APPROVED",
      "timestamp": "2025-08-24T09:12:39.684292Z",
      "details": null,
      "fee": 0
    }
  ],
  "matches": [],
  "node_id": "feature_phone_1"
}
```

### Отклонено — номер VoIP из списка блокировки

Пользователь ввёл корректный одноразовый код, однако на этапе финализации номер был обнаружен в списке блокировки приложения (автоматическое отклонение), а также был определён тип линии VoIP (для `voip_number_action` оставлено значение `NO_ACTION`, поэтому событие зафиксировано как `information`). Поскольку ни одна из найденных сессий не находится в списке блокировки, попадание в список отображается как синтетическое совпадение `list_entry`.

```json theme={null}
{
  "status": "Declined",
  "phone_number_prefix": "+1",
  "phone_number": "5551234567",
  "full_number": "+15551234567",
  "country_code": "US",
  "country_name": "United States",
  "carrier": { "name": "VoIP Carrier", "type": "voip" },
  "is_disposable": false,
  "is_virtual": true,
  "verification_method": "sms",
  "verification_attempts": 1,
  "verified_at": "2025-08-24T09:11:10.221340Z",
  "warnings": [
    {
      "feature": "PHONE",
      "risk": "PHONE_NUMBER_IN_BLOCKLIST",
      "additional_data": { "blocklisted_session_id": null, "blocklisted_session_number": null, "api_service": null },
      "log_type": "error",
      "short_description": "Phone number in blocklist",
      "long_description": "The system detected that the phone number is in the blocklist, which is not allowed.",
      "node_id": "feature_phone_1"
    },
    {
      "feature": "PHONE",
      "risk": "VOIP_NUMBER_DETECTED",
      "additional_data": null,
      "log_type": "information",
      "short_description": "VoIP number detected",
      "long_description": "The system detected that the phone number is a VoIP number, which is not allowed.",
      "node_id": "feature_phone_1"
    }
  ],
  "lifecycle": [
    {
      "type": "PHONE_VERIFICATION_MESSAGE_SENT",
      "timestamp": "2025-08-24T09:11:00.000000Z",
      "details": { "status": "Success", "reason": null, "channel": "sms", "actual_channel": "sms" },
      "fee": 0.0509
    },
    {
      "type": "VALID_CODE_ENTERED",
      "timestamp": "2025-08-24T09:11:10.221340Z",
      "details": { "code_tried": "482917", "status": "Approved" },
      "fee": 0
    },
    {
      "type": "PHONE_VERIFICATION_DECLINED",
      "timestamp": "2025-08-24T09:11:10.350000Z",
      "details": { "reason": "PHONE_NUMBER_IN_BLOCKLIST" },
      "fee": 0
    }
  ],
  "matches": [
    {
      "session_id": null,
      "session_number": null,
      "vendor_data": null,
      "verification_date": null,
      "phone_number": "+15551234567",
      "status": null,
      "is_blocklisted": true,
      "api_service": null,
      "source": "list_entry"
    }
  ],
  "node_id": "feature_phone_1"
}
```

## Связанные разделы

* [Обзор Проверки телефона](https://docs.didit.me/ru/core-technology/phone-verification/overview.md) — работа функции, цены, поддерживаемые каналы.
* [Предупреждения Проверки телефона](https://docs.didit.me/ru/core-technology/phone-verification/warnings-phone-verification.md) — все коды риска, триггеры отклонения и настраиваемые действия.
* [Модели данных — проверка телефона](https://docs.didit.me/ru/reference/data-models.md#проверка-телефона) — каноническая схема с подробным описанием каждого поля.
* [Отдельный API проверки телефона](https://docs.didit.me/ru/standalone-apis/phone-send.md) — endpoints `POST /v3/phone/send/` и [`POST /v3/phone/check/`](https://docs.didit.me/ru/standalone-apis/phone-check).
* [Management API — Списки](https://docs.didit.me/ru/management-api/lists/overview.md) — управление списком блокировки номеров телефонов, из которого формируются записи `matches[]` со значением `source: list_entry`.


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