> ## 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 de ingestão de eventos - Monitoramento não monetário

> Envie atividades não monetárias (logins, jogos, bônus, pagamentos, disputas, segurança da conta) ao mesmo motor da Didit que pontua suas transações.

Transações são o dinheiro. Eventos são todo o resto que a sua plataforma sabe: o login que antecedeu o saque, a mão que moveu fichas entre duas contas, o bônus resgatado duas vezes, o chargeback que chegou uma semana depois.

Os eventos usam um único envelope para todas as categorias, são idempotentes por design e são avaliados pelo [mesmo motor de regras](https://docs.didit.me/pt-br/transaction-monitoring/event-rules.md) que pontua as suas [transações](https://docs.didit.me/pt-br/transaction-monitoring/transactions.md).

> [!NOTE]
>
> A ingestão de eventos é **opcional (opt-in)**. Ative-a em **Transactions → Settings → Event monitoring**.
> Até que você o ative, nada muda: as suas regras de transação existentes continuam sendo acionadas apenas por transações, e uma regra de evento não pode ser criada por acidente, porque uma regra se aplica a transações, a menos que você inclua eventos explicitamente.
>
> Enquanto o recurso não estiver ativado, todos os canais de escrita (`POST /v3/events/`, `POST /v3/events/batch/`, `POST /v3/events/sdk-token/` e o canal de dispositivo `/v1/events/`) respondem `403` com `{"code": "event_monitoring_disabled"}`, e nada é armazenado, enriquecido ou avaliado. As leituras não são afetadas.

## Endpoints

| Endpoint | Autenticação | Use para |
| - | - | - |
| `POST /v3/events/` | Chave de API | Um evento a partir do seu backend |
| `POST /v3/events/batch/` | Chave de API | Até 500 eventos em uma única requisição |
| `POST /v3/events/sdk-token/` | Chave de API | Emitir uma credencial de dispositivo com escopo restrito |
| `POST /v1/events/` | `X-Monitoring-Token` | Um evento a partir do SDK do dispositivo |
| `POST /v1/events/batch/` | `X-Monitoring-Token` | Um buffer do SDK esvaziado |
| `GET /v3/events/` | Chave de API | Listar e filtrar eventos |
| `GET /v3/events/{event_uuid}/` | Chave de API | Um evento com as evidências das regras |
| `GET /v3/events/subjects/{vendor_data}/` | Chave de API | A linha do tempo de um titular (veja `entity_type` abaixo) |
| `GET /v3/events/enrichment-metrics/` | Chave de API | Status do cache de enriquecimento de IP |

O canal `/v3/` é o canal de servidor e usa a mesma autenticação `x-api-key` que o restante da API de transações. O canal `/v1/events/` é o canal de dispositivo. Veja [envio de eventos pelo SDK](https://docs.didit.me/pt-br/transaction-monitoring/sdk-event-submission.md).

## O envelope

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

| Campo | Obrigatório | Observações |
| - | - | - |
| `event_id` | sim | O seu próprio identificador, único por aplicação. É a chave de idempotência. |
| `event_category` | sim | Uma das dez categorias abaixo. |
| `action_type` | sim | String livre, com até 128 caracteres. |
| `occurred_at` | sim | Quando ocorreu no seu sistema. Até 7 dias no passado e 5 minutos no futuro. |
| `subject.vendor_data` | sim | O ID do seu usuário. É resolvido para o mesmo usuário para o qual uma transação seria resolvida. |
| `subject.entity_type` | não | `individual` (padrão) ou `company`. |
| `business.vendor_data` | não | A empresa à qual o evento pertence. |
| `session` | não | `session_id`, `sequence`, `page_url`, `referrer`. |
| `device_context` | não | `fingerprint`, `persistent_device_id`, `bot_score` e `network_context.ip_address`. |
| `transaction_context` | não | `amount`, `currency`, `direction`, `payment_reference_id`. |
| `payload` | não | Os campos de domínio da categoria. Até 16 KB. |
| `custom_values` | não | Até 100 chaves escalares, acessíveis nas regras como `custom_values.<key>`. |

## Categorias

Dez categorias nativas, cada uma com validação tipada e [campos de regra](https://docs.didit.me/pt-br/transaction-monitoring/event-rules.md#campos-de-eventos) gerenciados.

| Categoria | Ações típicas |
| - | - |
| `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` | Qualquer coisa que você definir |

`auth` é a categoria ampla de produto; `security` é o subconjunto voltado à avaliação de risco, com o ciclo de vida ordenado usado pelas regras de tomada de controle de conta (account takeover).

### Chaves obrigatórias do payload

Algumas ações não podem ser correlacionadas sem chaves específicas, por isso a validação as rejeita em vez de armazenar evidências que ninguém consegue relacionar.

| Ação | Obrigatório |
| - | - |
| `gameplay.p2p_settlement` | `game_id`, `counterparty_vendor_data`, `stake_amount`, `net_result_amount`, `role` e um entre `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` e um entre `dispute_id` / `chargeback_id` |
| `security.*_changed` | `changed_field`; alterações em controles da conta ou de saques também exigem `previous_reference_hash` ou `new_reference_hash` |
| `session.bot_signal_observed` | `telemetry_schema_version`, além de um `bot_score` ou pelo menos uma métrica de telemetria |
| `responsible_gambling.self_exclusion_match` | `registry_source`, `exclusion_status`, `identity_match_ref` |

> [!WARNING]
>
> Envie **referências e hashes**, nunca os segredos propriamente ditos. Instrumentos de pagamento, destinos de saque e alterações em controles da conta são armazenados na forma do hash da referência que você envia. Nunca envie um número de cartão, um endereço de saque completo, um hash de senha ou um segredo de MFA.

### Exemplo: uma liquidação 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"
  }
}
```

### Exemplo: um chargeback

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

Os ciclos de vida de disputas aceitam apenas acréscimos (append-only): uma correção é um novo evento `dispute`, nunca uma edição do primeiro.

## Idempotência

`event_id` é único por aplicação e constitui todo o contrato de idempotência.

* **Mesmo `event_id`, mesmo conteúdo** retorna `200` com `"idempotent_replay": true` e o evento armazenado originalmente. Repita a requisição quantas vezes quiser.
* **Mesmo `event_id`, conteúdo diferente** retorna `409`. Você reutilizou um ID por engano.

## Lotes

`POST /v3/events/batch/` aceita até **500 eventos**. Um lote é parcialmente bem-sucedido intencionalmente: uma visualização de página malformada nunca deve derrubar um chargeback no mesmo lote.

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

A resposta é `207 Multi-Status` quando algo foi rejeitado e `201 Created` quando todos os eventos foram registrados.

## Status

| Status | Significado |
| - | - |
| `ACCEPTED` | Armazenado. Nenhuma regra alterou seu status (esta é a resposta normal para a maioria dos eventos). |
| `APPROVED` | Uma regra foi executada e a pontuação ficou abaixo do seu limiar de revisão. |
| `IN_REVIEW` | Uma regra elevou a pontuação acima do limiar de revisão ou definiu o status diretamente. |
| `DECLINED` | Uma regra o recusou. |

`correlation_pending: true` significa que uma regra que envolve vários sujeitos ainda precisa ser executada; a pendência é resolvida em poucos minutos, e o status e a pontuação do evento são atualizados no próprio evento. Veja [regras assíncronas](https://docs.didit.me/pt-br/transaction-monitoring/event-rules.md#regras-em-tempo-real-e-assíncronas).

## Retenção

Os eventos têm volume muito maior que as transações, por isso cada um é classificado em uma classe de retenção ao chegar.

| Classe | Retenção ativa padrão | O que entra aqui |
| - | - | - |
| `low_value` | 14 dias | Visualizações de página, heartbeats, pings de dispositivos detectados, telemetria de bots, visualizações de promoções |
| `standard` | 30 dias | Auth, sessão, gameplay, bônus, afiliados, custom |
| `risk_relevant` | 90 dias | Eventos de segurança e de jogo responsável, e **qualquer evento que tenha correspondido a uma regra** |
| `monetary_or_compliance` | Retenção de transações | Eventos de pagamento e de disputa |

Duas regras decorrem da tabela:

* Um evento que corresponde a uma regra é evidência, por isso é promovido automaticamente para `risk_relevant`.
* Eventos de pagamento e de disputa mantêm a retenção de transações. Eles nunca expiram pelo cronograma de eventos, e as substituições por classe não podem encurtá-la.

Substitua os períodos de retenção das três classes expiráveis por aplicação em **Transactions → Settings → Event monitoring** (1 a 730 dias cada).

## Enriquecimento de IP

Os eventos contam com o mesmo [enriquecimento de IP](https://docs.didit.me/pt-br/transaction-monitoring/ip-enrichment.md) que as transações (país, ASN, indicadores de VPN/proxy e de data center), e o enriquecimento é resolvido **por endereço IP único, nunca por evento**. Uma sessão que dispara 200 visualizações de página a partir de um mesmo endereço resolve esse endereço uma única vez.

A telemetria de baixo valor vai além: ela só lê o enriquecimento se algum outro evento já tiver resolvido aquele endereço. Ela nunca aciona uma consulta por conta própria.

`GET /v3/events/enrichment-metrics/` informa o resultado, e o console mostra os mesmos números acima da lista de eventos:

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

## Consultando eventos

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

Filtros: `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`. Filtros com vários valores repetem o parâmetro (`?status=A&status=B`).

### A linha do tempo de um titular

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

Um `vendor_data` só é único **dentro** de um tipo de entidade: o mesmo id pode identificar um usuário e uma empresa, e a Didit os trata como dois titulares diferentes. `entity_type` indica qual deles você está consultando: `individual` (o padrão) ou `company`. Se você omiti-lo em um id de empresa, a resposta traz a linha do tempo da pessoa física, não as duas. Os mesmos filtros da listagem se aplicam.

`GET /v3/events/{event_uuid}/` acrescenta o payload, o contexto do dispositivo, o enriquecimento de IP, os sinais de risco do titular em cache e cada correspondência de regra com sua evidência, indicando inclusive se cada campo correspondente foi derivado pelo servidor, derivado pelo SDK ou fornecido pelo cliente.

`DELETE /v3/events/{event_uuid}/delete/` exclui um evento. Ele deixa de ser retornado em todas as consultas, e a exclusão é irreversível.

## Próximos passos

> [card] [Regras sobre eventos](https://docs.didit.me/pt-br/transaction-monitoring/event-rules.md)
>
> Regras de velocidade, proporção, sequência e correlação sobre os dados de eventos.

> [card] [Envio de eventos pelo SDK](https://docs.didit.me/pt-br/transaction-monitoring/sdk-event-submission.md)
>
> Capture eventos diretamente do dispositivo com uma credencial com escopo restrito.


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