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

# API приёма событий: мониторинг неденежной активности

> Отправляйте в Didit неденежные события: входы, игру, бонусы, платежи, споры и безопасность аккаунта. Они обрабатываются тем же движком, что скорит транзакции.

Транзакции представляют собой деньги. События охватывают всё остальное, что известно вашей платформе: вход в систему, предшествовавший выводу средств, действие, с помощью которого фишки были перемещены между двумя счетами, бонус, полученный дважды, чарджбэк, пришедший неделю спустя.

События используют единую структуру для всех категорий, идемпотентны по своей конструкции и оцениваются [тем же движком правил](https://docs.didit.me/ru/transaction-monitoring/event-rules.md), что и ваши [транзакции](https://docs.didit.me/ru/transaction-monitoring/transactions.md).

> [!NOTE]
>
> Приём событий работает по принципу **opt-in**: его нужно включить явно в **Transactions → Settings → Event monitoring**.
> Пока вы этого не сделаете, ничего не меняется: существующие правила для транзакций продолжают срабатывать только на транзакциях, а правило для событий нельзя создать случайно, поскольку правило применяется к транзакциям, если только вы явно не включите в него события.
>
> Пока функция не включена, все каналы записи, а именно `POST /v3/events/`, `POST /v3/events/batch/`, `POST /v3/events/sdk-token/` и канал устройств `/v1/events/`, возвращают `403` с `{"code": "event_monitoring_disabled"}`, и ничего не сохраняется, не обогащается и не оценивается. Чтение не затрагивается.

## Endpoints

| Endpoint | Аутентификация | Для чего |
| - | - | - |
| `POST /v3/events/` | API-ключ | Одно событие из вашего бэкенда |
| `POST /v3/events/batch/` | API-ключ | До 500 событий в одном запросе |
| `POST /v3/events/sdk-token/` | API-ключ | Выпуск учётных данных устройства с ограниченной областью действия |
| `POST /v1/events/` | `X-Monitoring-Token` | Одно событие из SDK устройства |
| `POST /v1/events/batch/` | `X-Monitoring-Token` | Буфер SDK после сброса |
| `GET /v3/events/` | API-ключ | Список и фильтрация событий |
| `GET /v3/events/{event_uuid}/` | API-ключ | Одно событие с данными о срабатывании правил |
| `GET /v3/events/subjects/{vendor_data}/` | API-ключ | Хронология одного субъекта (см. `entity_type` ниже) |
| `GET /v3/events/enrichment-metrics/` | API-ключ | Состояние кеша IP-обогащения |

Канал `/v3/` серверный и использует ту же аутентификацию через `x-api-key`, что и остальной API транзакций. Канал `/v1/events/` предназначен для устройств: см. [отправка событий из SDK](https://docs.didit.me/ru/transaction-monitoring/sdk-event-submission.md).

## Структура события

```bash theme={null}
curl -X POST https://verification.didit.me/v3/events/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event_id": "login-2026-08-31-000001",
    "event_category": "auth",
    "action_type": "login",
    "occurred_at": "2026-08-31T20:40:31.123Z",
    "time_zone": "UTC",
    "subject": {
      "entity_type": "individual",
      "vendor_data": "user_391"
    },
    "session": { "session_id": "web-session-abc", "sequence": 142 },
    "device_context": {
      "fingerprint": "didit-fp-v2:a8c1",
      "network_context": { "ip_address": "203.0.113.42" }
    },
    "payload": { "method": "password" }
  }'
```

```json theme={null}
{
  "event_uuid": "0f2b...",
  "event_id": "login-2026-08-31-000001",
  "status": "ACCEPTED",
  "score": 0,
  "rules_evaluated_count": 6,
  "rules_matched_count": 0,
  "correlation_pending": false,
  "retention_class": "standard",
  "expires_at": "2026-09-30T20:40:31.123Z",
  "idempotent_replay": false,
  "rule_matches": []
}
```

| Поле | Обязательное | Примечание |
| - | - | - |
| `event_id` | да | Ваш собственный идентификатор, уникальный в пределах приложения. Это ключ идемпотентности. |
| `event_category` | да | Одна из десяти категорий ниже. |
| `action_type` | да | Произвольная строка, до 128 символов. |
| `occurred_at` | да | Когда событие произошло на вашей стороне. Не более 7 дней назад и не более 5 минут вперёд. |
| `subject.vendor_data` | да | Ваш идентификатор пользователя. Сопоставляется с тем же пользователем (User), с которым сопоставилась бы транзакция. |
| `subject.entity_type` | нет | `individual` (по умолчанию) или `company`. |
| `business.vendor_data` | нет | Компания, к которой относится событие. |
| `session` | нет | `session_id`, `sequence`, `page_url`, `referrer`. |
| `device_context` | нет | `fingerprint`, `persistent_device_id`, `bot_score` и `network_context.ip_address`. |
| `transaction_context` | нет | `amount`, `currency`, `direction`, `payment_reference_id`. |
| `payload` | нет | Доменные поля категории. До 16 КБ. |
| `custom_values` | нет | Не более 100 скалярных ключей, на которые можно ссылаться в правилах как `custom_values.<key>`. |

## Категории

Десять категорий первого класса, каждая с типизированной валидацией и управляемыми [полями правил](https://docs.didit.me/ru/transaction-monitoring/event-rules.md#поля-событий).

| Категория | Типичные действия |
| - | - |
| `auth` | `signup`, `login`, `login_failed`, `logout`, `password_forgot`, `password_reset`, `mfa_reset`, `mfa_challenge` |
| `session` | `session_started`, `session_ended`, `page_view`, `sdk_loaded`, `device_seen`, `bot_signal_observed`, `sdk_heartbeat` |
| `gameplay` | `round_started`, `round_completed`, `bet_placed`, `bet_settled`, `cashout`, `limit_change`, `p2p_settlement` |
| `bonus` | `bonus_claimed`, `bonus_wagered`, `bonus_released`, `promotion_viewed` |
| `affiliate` | `affiliate_attributed`, `referral_clicked`, `campaign_joined`, `commission_event` |
| `payment` | `deposit_initiated`, `deposit_completed`, `withdrawal_requested`, `withdrawal_completed`, `withdrawal_address_changed`, `payment_instrument_seen` |
| `dispute` | `chargeback_opened`, `chargeback_won`, `chargeback_lost`, `refund_issued`, `payment_dispute_updated` |
| `security` | `login_attempt`, `login_succeeded`, `login_failed`, `password_changed`, `mfa_changed`, `credential_reset`, `country_changed`, `device_changed`, `account_locked` |
| `responsible_gambling` | `self_exclusion_checked`, `self_exclusion_match`, `re_registration_attempt`, `limit_breach_attempt`, `registry_status_changed` |
| `custom` | Любые действия, которые вы определите |

`auth` - это широкая продуктовая категория, а `security` - подмножество с оценкой риска и упорядоченным жизненным циклом, которое читают правила захвата учётной записи.

### Обязательные ключи payload

Некоторые действия невозможно сопоставить без определённых ключей, поэтому валидация отклоняет такие события, а не сохраняет доказательства, которые никто не сможет связать.

| Действие | Обязательно |
| - | - |
| `gameplay.p2p_settlement` | `game_id`, `counterparty_vendor_data`, `stake_amount`, `net_result_amount`, `role`, и один из `hand_id` / `round_id` / `match_id` |
| `gameplay.bet_placed`, `gameplay.bet_settled` | `game_id` |
| `payment.deposit_*`, `payment.withdrawal_completed`, `payment.withdrawal_requested`, `payment.deposit_initiated` | `payment_reference_id`, `amount`, `currency`, `payment_method`, `status` |
| `payment.withdrawal_address_changed` | `withdrawal_address_hash` |
| `dispute.chargeback_*` | `payment_reference_id`, и один из `dispute_id` / `chargeback_id` |
| `security.*_changed` | `changed_field`; изменения, связанные с управлением учётной записью или выплатами, также требуют `previous_reference_hash` или `new_reference_hash` |
| `session.bot_signal_observed` | `telemetry_schema_version`, а также `bot_score` или хотя бы один показатель телеметрии |
| `responsible_gambling.self_exclusion_match` | `registry_source`, `exclusion_status`, `identity_match_ref` |

> [!WARNING]
>
> Отправляйте **идентификаторы и хэши**, но никогда открытые секреты. Платёжные инструменты, адреса вывода и изменения, связанные с управлением учётной записью, сохраняются в виде хэшированного идентификатора, который вы отправляете. Никогда не отправляйте номер карты, полный адрес вывода, хэш пароля или секрет MFA.

### Пример: P2P-расчёт

```json theme={null}
{
  "event_id": "p2p-hand-8842-user-391",
  "event_category": "gameplay",
  "action_type": "p2p_settlement",
  "occurred_at": "2026-08-31T12:34:17.392Z",
  "subject": { "vendor_data": "user_391" },
  "payload": {
    "game_id": "poker_holdem",
    "table_id": "table_17",
    "hand_id": "hand_8842",
    "role": "winner",
    "counterparty_vendor_data": "user_812",
    "stake_amount": "250.00",
    "net_result_amount": "240.50",
    "effective_margin": "0.038",
    "operator_ledger_ref": "ledger_998123"
  }
}
```

### Пример: чарджбэк

```json theme={null}
{
  "event_id": "chargeback-cb_921-opened",
  "event_category": "dispute",
  "action_type": "chargeback_opened",
  "occurred_at": "2026-08-31T09:22:05.000Z",
  "subject": { "vendor_data": "user_391" },
  "transaction_context": {
    "amount": "1000.00",
    "currency": "EUR",
    "payment_reference_id": "dep_735"
  },
  "payload": {
    "dispute_id": "disp_498",
    "chargeback_id": "cb_921",
    "reason_code": "fraudulent",
    "liability_shift": false
  }
}
```

Жизненный цикл споров только дополняется: исправление оформляется новым событием `dispute`, а первое событие никогда не редактируется.

## Идемпотентность

`event_id` уникален в рамках приложения и представляет собой весь контракт идемпотентности.

* **Тот же `event_id`, то же содержимое** возвращает `200` с `"idempotent_replay": true` и исходно сохранённым событием. Повторяйте запрос сколько угодно раз.
* **Тот же `event_id`, другое содержимое** возвращает `409`. Вы по ошибке повторно использовали идентификатор.

## Пакетная отправка

`POST /v3/events/batch/` принимает до **500 событий**. Частичный успех заложен в дизайн пакета: один некорректный просмотр страницы не должен сломать соседний чарджбэк.

```json theme={null}
{
  "accepted_count": 2,
  "replayed_count": 0,
  "rejected_count": 1,
  "results": [
    { "index": 0, "outcome": "rejected", "errors": { "occurred_at": ["This field is required."] } },
    { "index": 1, "outcome": "accepted", "event_uuid": "…", "status": "ACCEPTED" },
    { "index": 2, "outcome": "accepted", "event_uuid": "…", "status": "IN_REVIEW" }
  ]
}
```

Ответ имеет статус `207 Multi-Status`, если что-то было отклонено, и `201 Created`, если всё принято.

## Статусы

| Статус | Значение |
| - | - |
| `ACCEPTED` | Сохранено. Ни одно правило не изменило его статус (это обычный ответ для большинства событий). |
| `APPROVED` | Правило выполнилось, и оценка осталась ниже вашего порога проверки. |
| `IN_REVIEW` | Правило подняло оценку выше порога проверки либо статус был установлен напрямую. |
| `DECLINED` | Правило отклонило событие. |

`correlation_pending: true` означает, что правило сопоставления между субъектами ещё должно выполниться; оно завершится в течение нескольких минут, и статус и оценка события обновятся на месте. См. [асинхронные правила](https://docs.didit.me/ru/transaction-monitoring/event-rules.md#правила-в-реальном-времени-и-асинхронные-правила).

## Хранение

Объём событий гораздо больше объёма транзакций, поэтому каждое событие при поступлении относится к классу хранения.

| Класс | Срок хранения в горячем режиме по умолчанию | Что сюда попадает |
| - | - | - |
| `low_value` | 14 дней | Просмотры страниц, сигналы heartbeat, пинги о замеченном устройстве, телеметрия ботов, просмотры акций |
| `standard` | 30 дней | Auth, session, gameplay, bonus, affiliate, custom |
| `risk_relevant` | 90 дней | События безопасности и ответственной игры, а также **любое событие, с которым сопоставилось правило** |
| `monetary_or_compliance` | Срок хранения транзакций | События платежей и споров |

Из таблицы следуют два правила:

* Событие, с которым сопоставилось правило, является доказательством, поэтому оно автоматически переводится в `risk_relevant`.
* События платежей и споров сохраняются на срок хранения транзакций. Они никогда не удаляются по расписанию событий, и переопределения для отдельных классов не могут его сократить.

Переопределить срок хранения для трёх классов, которые удаляются по расписанию, можно для каждого приложения в разделе **Transactions → Settings → Event monitoring** (от 1 до 730 дней для каждого класса).

## Обогащение IP

События содержат то же [обогащение IP](https://docs.didit.me/ru/transaction-monitoring/ip-enrichment.md), что и транзакции: страну, ASN, флаги VPN/прокси и дата-центра. Обогащение выполняется **по каждому уникальному адресу, а не по каждому событию**. Сессия, которая генерирует 200 просмотров страниц с одного адреса, обогащает данные об этом адресе только один раз.

Низкоценная телеметрия идёт дальше: она использует обогащение, только если какое-то другое событие уже выполнило обогащение для этого адреса. Она никогда не запускает собственный поиск.

`GET /v3/events/enrichment-metrics/` возвращает результат, а консоль показывает те же числа над списком событий:

```json theme={null}
{
  "events_ingested": 128450,
  "enrichment_lookups": 41230,
  "enrichment_cache_hits": 40118,
  "enrichment_provider_calls": 1112,
  "enrichment_skipped_low_value": 74320,
  "unique_ips_seen": 1112,
  "cache_hit_rate": 0.973,
  "unique_ip_ratio": 0.0087,
  "provider_calls_per_1k_events": 8.65,
  "period_days": 30
}
```

## Чтение событий

```bash theme={null}
curl "https://verification.didit.me/v3/events/?event_category=payment&event_category=dispute&matched_only=true" \
  -H "x-api-key: YOUR_API_KEY"
```

Фильтры: `event_category`, `action_type`, `status`, `retention_class`, `subject_vendor_data`, `business_vendor_data`, `session_id`, `device_fingerprint`, `ip_address`, `game_id`, `round_id`, `affiliate_code`, `payment_reference_id`, `counterparty_vendor_data`, `matched_only`, `occurred_from`, `occurred_to`, `search`. Фильтры с несколькими значениями повторяют параметр (`?status=A&status=B`).

### Таймлайн одного субъекта

```bash theme={null}
curl "https://verification.didit.me/v3/events/subjects/acct_9931/?entity_type=company" \
  -H "x-api-key: YOUR_API_KEY"
```

`vendor_data` уникален только **в пределах** типа сущности: один и тот же идентификатор может относиться и к пользователю, и к компании, и Didit считает их двумя разными субъектами. `entity_type` указывает, какой из них вы запрашиваете: `individual` (по умолчанию) или `company`. Если не указать его для идентификатора компании, вернется таймлайн физического лица, а не оба сразу. Те же фильтры списка применяются и здесь.

`GET /v3/events/{event_uuid}/` добавляет payload, контекст устройства, обогащение IP-данными, кешированные сигналы риска субъекта и все совпадения с правилами с их доказательствами, включая то, было ли значение каждого совпавшего поля вычислено на сервере, получено через SDK или предоставлено клиентом.

`DELETE /v3/events/{event_uuid}/delete/` удаляет одно событие. Оно перестает возвращаться при любом чтении, и удаление необратимо.

## Далее

> [card] [Правила для событий](https://docs.didit.me/ru/transaction-monitoring/event-rules.md)
>
> Правила по скорости, соотношению, последовательности и корреляции на основе данных событий.

> [card] [Отправка событий через SDK](https://docs.didit.me/ru/transaction-monitoring/sdk-event-submission.md)
>
> Фиксируйте события прямо с устройства с помощью учётных данных с ограниченной областью действия.


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