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

# Integración de monitorización de transacciones: API KYT

> Integra el KYT de Didit: tiempo real o por lotes, partes, idempotencia, histórico y webhooks. 1,000 al mes incluidas, luego $0.001 cada una.

Esta guía cubre todo lo necesario para integrar la Monitorización de transacciones. El [inicio rápido](https://docs.didit.me/es/transaction-monitoring/quickstart.md) te permite empezar; esta página te permite pasar a producción.

## Arquitectura

```mermaid theme={null}
sequenceDiagram
    participant You as Your platform
    participant Didit as Didit API
    participant Rules as Rule engine
    participant AML as AML providers
    participant Webhook as Your webhook

    You->>Didit: POST /v3/transactions/ (txn_id, parties, amount)
    Didit->>Didit: IP enrichment (inline)
    Didit->>AML: Screen wallet or transaction hash + address
    AML-->>Didit: Hits / clean
    Didit->>Rules: Evaluate all active rules
    Rules-->>Didit: Score + matched rules + actions
    Didit-->>You: Transaction record with status
    Didit->>Webhook: transaction.created
    Didit->>Webhook: transaction.status.updated (if async rules)
```

## Autenticación

Encabezado estándar `x-api-key`. Se usan las mismas claves que para las sesiones y las entidades. Consulta [Autenticación de la API](https://docs.didit.me/es/getting-started/api-authentication.md).

## Envío de una transacción

Un único endpoint: `POST /v3/transactions/`. Consulta [envío de transacciones](https://docs.didit.me/es/transaction-monitoring/transactions.md) para ver el esquema completo.

**Payload mínimo:**

```json theme={null}
{
  "transaction_id": "tx-0001",
  "transaction_category": "finance",
  "transaction_details": {
    "direction": "outbound",
    "amount": "500.00",
    "currency": "EUR"
  },
  "subject": { "entity_type": "person", "vendor_data": "user-42", "full_name": "John Doe" },
  "counterparty": { "entity_type": "company", "full_name": "Acme Corp" }
}
```

**Payload más completo, con métodos de pago, contexto del dispositivo y propiedades personalizadas:**

```json theme={null}
{
  "transaction_id": "tx-0002",
  "transaction_at": "2026-04-16T10:00:00Z",
  "transaction_category": "finance",
  "transaction_details": {
    "direction": "outbound",
    "amount": "12500.00",
    "currency": "USD",
    "action_type": "withdrawal"
  },
  "subject": {
    "entity_type": "person",
    "vendor_data": "user-42",
    "full_name": "John Doe",
    "country_code": "US",
    "device_context": {
      "fingerprint": "fp-9f2c...",
      "user_agent": "Mozilla/5.0 ...",
      "browser_family": "Chrome",
      "platform": "web",
      "network_context": { "ip_address": "203.0.113.5" }
    },
    "payment_method": {
      "method_type": "bank_account",
      "account_id": "US12345678901234567890",
      "issuing_country": "US"
    }
  },
  "counterparty": {
    "entity_type": "company",
    "vendor_data": "biz-acme",
    "full_name": "Acme Corp",
    "country_code": "US",
    "payment_method": {
      "method_type": "bank_account",
      "account_id": "US09876543210987654321",
      "issuing_country": "US"
    }
  },
  "custom_properties": {
    "invoice_id": "INV-2026-00042",
    "category": "b2b_goods"
  }
}
```

Se aceptan alias en camelCase para todos los campos de primer nivel (`txnId`, `txnDate`, `type`, `info`, `applicant`, `props`, `travelRule`, `includeCryptoScreening`): el formato de transmisión del SDK y el formato snake\_case se procesan de la misma manera.

## Modelado de las partes

Toda transacción tiene un `subject` obligatorio (tu cliente, la parte que monitorizas) y una `counterparty` opcional (la otra parte). Cada una lleva su propio `payment_method` y, opcionalmente, el contexto `device`.

En la respuesta, ambas se devuelven en el array `parties` con los roles `APPLICANT` y `COUNTERPARTY`; una parte sin `vendor_data` se almacena como una instantánea externa (`kind: EXTERNAL`) sin ninguna entidad vinculada.

Consulta [payload de transacciones](https://docs.didit.me/es/transaction-monitoring/transactions.md) para ver los campos de las partes.

## Idempotencia

`txn_id` (el `transaction_id` que envías) es único por aplicación.
Volver a enviar un `transaction_id` que ya existe devuelve `400` con `A transaction with this transaction_id already exists.` en el campo `transaction_id`; cuando se envían dos solicitudes idénticas al mismo tiempo, la segunda recibe `409`.
Ninguna de las dos respuestas devuelve la transacción existente.
Ante un `400` o un `409` por un `transaction_id` duplicado, busca la transacción existente en lugar de volver a enviarla: léela con [`GET /v3/transactions/{uuid}/`](https://docs.didit.me/es/management-api/transactions/get) usando el `uuid` de la primera respuesta, o usa el `transaction_id` (el uuid de Didit) que el webhook `transaction.created` incluye junto a tu `txn_id`.

**Genera siempre el `txn_id` de tu lado** antes de enviar la transacción; no dependas de un ID generado por Didit para la idempotencia. Usa el ID de tu propia base de datos, un UUID o un hash de los campos de la transacción.

## Tiempo real frente a lotes

* **Tiempo real**: recomendado para la mayoría de los casos de uso. Envía la transacción en el momento en que se produce en tu sistema. Las reglas se evalúan de forma síncrona y devuelven la decisión.
* **Lotes / carga retroactiva**: para la ingesta de datos históricos, pasa un `txn_date` con una fecha pasada. Las reglas se siguen ejecutando y pueden disparar webhooks. Para evitar que se disparen reglas durante la carga retroactiva, usa la importación CSV de la consola con la opción "dry ingest".

## Ingesta del historial

Cuando migras desde otro sistema de monitorización de transacciones:

1. Exporta tus transacciones históricas a un CSV.
2. Usa *Transactions → Import history* en la consola (o envíalas por API en un bucle) con un `txn_date` en el pasado.
3. Activa las reglas solo cuando termine la ingesta, o usa "dry ingest" para omitir la evaluación de reglas.

> [!WARNING]
>
> Decide con cuidado si quieres evaluar reglas sobre el historial. Pasar 6 meses de historial por una regla de "20 transferencias en 30 días" generará miles de alertas de golpe.

## Webhooks

Suscríbete a:

* `transaction.created`: cada transacción enviada.
* `transaction.status.updated`: cambios de estado (por ejemplo, un analista pasa la transacción de `IN_REVIEW` a `APPROVED`, o una comprobación AML asíncrona actualiza la puntuación).

Todos los detalles: [webhooks de TM](https://docs.didit.me/es/transaction-monitoring/webhooks.md).

```typescript theme={null}
app.post('/webhooks/didit-tm', (req, res) => {
  if (!verifySignature(req)) return res.status(401).end();

  const { webhook_type, status, txn_id } = req.body;
  if (webhook_type === 'transaction.status.updated' && status === 'DECLINED') {
    suspendTransaction(txn_id);
  }
  res.status(200).end();
});
```

## Gestión de estados

| Estado | Qué hacer |
| - | - |
| `APPROVED` | Procesa la transacción con normalidad. |
| `IN_REVIEW` | Retén la transacción hasta que se resuelva la revisión del analista o la nueva comprobación automática. |
| `DECLINED` | Rechaza la transacción. Muestra al usuario un error genérico. |
| `AWAITING_USER` | El usuario debe actuar antes de que la transacción pueda liquidarse: lee el bloque `action_required` y entrega su `url` al usuario (los SDK pueden [gestionarlo automáticamente](https://docs.didit.me/es/transaction-monitoring/sdk-transaction-submission.md#acciones-requeridas-del-usuario)). |

Consulta [estados de TM](https://docs.didit.me/es/transaction-monitoring/statuses.md).

## Vinculación de transacciones con entidades

Incluye `vendor_data` para cada parte. Ventajas:

* Cada transacción se agrega al perfil del usuario o de la empresa.
* Las reglas de velocidad y de comportamiento disponen de todo el historial para evaluar.
* El bloqueo de una entidad se propaga automáticamente a las transacciones futuras.

La falta de `vendor_data` no es un error bloqueante (la transacción se almacena como una instantánea externa), pero pierdes la agregación a nivel de entidad.

## Sesiones de remediación

Cuando la acción de una regla pasa una transacción a `AWAITING_USER`, Didit crea automáticamente una **sesión de remediación**: una sesión de verificación alojada estándar para el mismo `vendor_data`.
Las reglas personalizadas siempre indican el flujo de verificación (workflow) en la propia acción; en las reglas integradas de la biblioteca, el flujo se toma del [flujo de remediación de la configuración de transacciones](https://docs.didit.me/es/transaction-monitoring/settings.md#flujo-de-remediación), después del flujo de Autenticación biométrica de tu aplicación (cuando el sujeto tiene un rostro de referencia almacenado) y, por último, del flujo predeterminado de tu aplicación.
Las transacciones de Travel Rule quedan excluidas de este mecanismo automático: su acción pendiente es la prueba de propiedad de la wallet.
La transacción (la respuesta, cada consulta posterior y cada webhook) la incluye en el bloque canónico `action_required`:

```json theme={null}
{
  "status": "AWAITING_USER",
  "action_required": {
    "type": "verification_session",
    "url": "https://verify.didit.me/session/...",
    "session_id": "11111111-2222-3333-4444-555555555555",
    "session_token": "SESSION_TOKEN",
    "status": "Not Started"
  },
  "remediation": {
    "session_id": "11111111-2222-3333-4444-555555555555",
    "session_token": "SESSION_TOKEN",
    "url": "https://verify.didit.me/session/...",
    "status": "Not Started"
  }
}
```

`remediation` se mantiene por compatibilidad con versiones anteriores; `action_required` es el bloque canónico (también incluye acciones `wallet_ownership` para las transferencias de [Travel Rule](https://docs.didit.me/es/transaction-monitoring/travel-rule.md)).
Una acción `wallet_ownership` no cambia por sí sola el estado de la transacción: la transacción conserva el estado que le asignen tus reglas, a menudo `APPROVED`, así que comprueba `action_required` en cada respuesta, no solo en `AWAITING_USER`.

El usuario completa la verificación. En un flujo de **Autenticación biométrica**, se trata de una selfie con prueba de vida que se compara con el rostro capturado en su onboarding KYC original, el paso de verificación adicional más sólido para las [transacciones de alto valor](https://docs.didit.me/es/transaction-monitoring/sdk-transaction-submission.md#ejemplo-biometría-reforzada-para-un-retiro-de-alto-valor).
Cuando la sesión alcanza una decisión, la transacción adopta automáticamente esa decisión (`APPROVED` (`decision_reason_code: user_action_approved`), `DECLINED` (`user_action_declined`) o `IN_REVIEW` (`user_action_in_review`)) y se envía un webhook `transaction.status.updated`.

> [!NOTE]
>
> Se puede seleccionar cualquier tipo de flujo excepto KYB.
> Los flujos de Autenticación biométrica (y los flujos en los que la coincidencia facial se ejecuta antes de la verificación de identidad) requieren que el sujeto ya tenga un rostro de referencia almacenado de una verificación aprobada; los usuarios que no lo tienen se envían en su lugar al flujo predeterminado de tu aplicación, y se añade una nota en la transacción que registra la sustitución.

## Buenas prácticas

| Práctica | Por qué |
| - | - |
| Envía siempre `vendor_data` | Permite la agregación. |
| Usa tu propio `txn_id` | Idempotencia. |
| Suscríbete tanto a `transaction.created` como a `transaction.status.updated` | Para detectar cambios de estado asíncronos (p. ej., resultados de la revisión de un analista). |
| Define los umbrales de las reglas de forma deliberada | Umbrales bajos = más alertas; altos = más riesgo no detectado. Consulta [puntuación de riesgo](https://docs.didit.me/es/transaction-monitoring/risk-scoring.md). |
| Supervisa en la consola el número de ejecuciones de cada regla | Para detectar reglas que nunca se activan (mal configuradas) o que se activan para todo (demasiado permisivas). |
| Prueba las reglas en modo TEST antes de pasar a producción | Consulta [reglas](https://docs.didit.me/es/transaction-monitoring/rules.md). |

## Límites de solicitudes

Consulta [límites de solicitudes](https://docs.didit.me/es/integration/rate-limiting.md). La creación de transacciones es uno de los endpoints con mayor volumen; los límites habituales son de cientos de solicitudes por segundo. Gestiona las ráfagas con cuidado.

## Próximos pasos

> [card] [Transacciones](https://docs.didit.me/es/transaction-monitoring/transactions.md)
>
> Referencia completa del payload.

> [card] [Reglas](https://docs.didit.me/es/transaction-monitoring/rules.md)
>
> Cómo se evalúan las reglas.

> [card] [Webhooks](https://docs.didit.me/es/transaction-monitoring/webhooks.md)
>
> Catálogo de eventos.

> [card] [Solución de problemas](https://docs.didit.me/es/transaction-monitoring/troubleshooting.md)
>
> Problemas de integración habituales.


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