> ## Documentation Index
> Fetch the complete documentation index at: https://developers.argosidentity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Guía completa de incorporación

> Guía de integración paso a paso para clientes que adoptan ARGOS ID check por primera vez

# Guía completa de incorporación de ID check

Esta guía está escrita para **desarrolladores que están integrando ID check en su servicio por primera vez**. Recorre las preocupaciones reales que enfrentará durante la integración, paso a paso, presentando las tecnologías que ARGOS proporciona en cada etapa.

<Info>
  **Prerrequisitos**

  * Cuenta de ARGOS Identity ([Regístrese en idcheck.argosidentity.com](https://idcheck.argosidentity.com/))
  * Acceso al dashboard y confirmación de la API key
</Info>

***

## Principio fundamental de la integración de ID check

Hay algo crítico que entender primero al integrar ID check en su sistema.

<Warning>
  **ID check es un servicio basado en Liveform.**

  Todo el proceso de verificación de identidad (captura de documentos de identidad con cámara, toma de selfies, verificación por IA) se realiza en el **Liveform alojado por ARGOS**. Los clientes no pueden construir ni reemplazar esta interfaz por sí mismos.

  Solo hay una cosa que necesita hacer: **Enviar a sus usuarios a la URL del Liveform.**
</Warning>

**Rol de la API:**

La API de ID check sirve como canal para la transferencia segura de información hacia y desde el sistema ARGOS. Sus propósitos principales son:

| Propósito                           | APIs relacionadas                      | Descripción                                                                                       |
| ----------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------- |
| **Gestión de tokens**               | POST/GET/DELETE Token                  | Crear y gestionar URLs de un solo uso en modo privado                                             |
| **Recuperación y gestión de datos** | GET/PATCH/DELETE Submission, GET Image | Consultar, modificar, eliminar datos de Submission verificados, recuperar imágenes                |
| **Integración de sistemas**         | POST Review, PUT Image                 | Procesar submissions pendientes, agregar/reemplazar imágenes para integración de flujo de trabajo |
| **Migración**                       | POST Submission                        | Migrar datos KYC existentes, insertar datos en situaciones especiales, pruebas de desarrollo      |

***

## Tabla de contenido

<CardGroup cols={3}>
  <Card title="Parte 1: Fundamentos" icon="1">
    Configuración de cuenta, conceptos fundamentales
  </Card>

  <Card title="Parte 2: Integración" icon="2">
    Conexión con Liveform, recepción de resultados, uso de datos
  </Card>

  <Card title="Parte 3: Producción" icon="3">
    Fortalecimiento de seguridad, pruebas, puesta en producción
  </Card>
</CardGroup>

***

## Parte 1: Fundamentos

### ¿Qué es ARGOS ID check?

ARGOS ID check es una **plataforma de verificación de identidad impulsada por IA**. Cuando los usuarios capturan sus documentos de identidad y toman selfies, la IA analiza la autenticidad del documento y entrega resultados de verificación.

<CardGroup cols={2}>
  <Card title="Verificación de documentos" icon="id-card">
    Verifique pasaportes, licencias de conducir, documentos nacionales de identidad, permisos de residencia y otros documentos de identidad emitidos por una amplia variedad de países.
  </Card>

  <Card title="Detección de fraude con IA" icon="shield-halved">
    Detecte automáticamente falsificación, sustitución de fotos y manipulación de documentos con IA.
  </Card>

  <Card title="Extracción de datos" icon="database">
    Extraiga automáticamente nombre, fecha de nacimiento, nacionalidad y otra información de documentos de identidad.
  </Card>

  <Card title="Cumplimiento KYC/AML" icon="scale-balanced">
    Reglas de verificación personalizables y capacidades de auditoría.
  </Card>
</CardGroup>

***

### Configuración de cuenta e información esencial

<Steps>
  <Step title="Crear su cuenta">
    Regístrese en [idcheck.argosidentity.com](https://idcheck.argosidentity.com/), verifique su correo electrónico e inicie sesión en el dashboard.
  </Step>

  <Step title="Confirmar información esencial">
    Confirme los siguientes tres elementos desde el dashboard. Cada elemento se puede encontrar en el menú **Project Management** en el nuevo dashboard.

    **1. Project ID (PID) y URL del Liveform**

    Navegue a **Project Management → Project Settings → Project Info** para confirmar.

    * **Project ID (PID)** — Identificador único del proyecto
    * **URL del Liveform** — La URL de la página de verificación de identidad para proporcionar a los usuarios (en la sección Project Pipeline)

    <Frame caption="Confirme el PID y la URL del Liveform en la página Project Info">
      <img src="https://mintcdn.com/argosidentity/IPUXz6Pq0_-rrbuX/images/dashboard/new/pj/project-setting/project-info/main_en.png?fit=max&auto=format&n=IPUXz6Pq0_-rrbuX&q=85&s=309600db69a00f3aa6b2f1509c783bb6" alt="Project Info — PID y URL del Liveform" width="2048" height="672" data-path="images/dashboard/new/pj/project-setting/project-info/main_en.png" />
    </Frame>

    **2. API Key**

    Navegue a **Project Management → Project Settings → Integration Info** para confirmar.

    * **API Key** — Se usa para la autenticación de solicitudes de API (nunca la exponga externamente)

    <Frame caption="Confirme la API Key en la página Integration Info">
      <img src="https://mintcdn.com/argosidentity/SCyJH7SnZdUydn0h/images/dashboard/new/pj/project-setting/integration-info/api_key_en.png?fit=max&auto=format&n=SCyJH7SnZdUydn0h&q=85&s=85b93d3bade789145f212743312c4a95" alt="Integration Info — API Key" width="1864" height="133" data-path="images/dashboard/new/pj/project-setting/integration-info/api_key_en.png" />
    </Frame>

    ```
    API Key:      argos_live_abc123xyz...
    Project ID:   pid_abc123
    Liveform URL: https://form.argosidentity.com?pid=pid_abc123
    ```

    <Warning>
      **Nota de seguridad**: Trate su API key como una contraseña. Nunca la exponga en código del lado del cliente (frontend) ni la incluya en git. Siempre almacénela en variables de entorno del lado del servidor.
    </Warning>
  </Step>
</Steps>

***

### Conceptos fundamentales

<AccordionGroup>
  <Accordion title="Submission" icon="file-lines">
    Un **Submission** representa un solo intento de verificación de identidad. Cuando un usuario captura y envía su documento de identidad en el Liveform, se crea un Submission.

    **Propiedades clave:**

    * **Submission ID** — Identificador único (ej., `sub_abc123`)
    * **KYC Status** — `approved`, `rejected`, `pending` (en espera de revisión manual), `incomplete` (no enviado / inacabado)
    * **Datos extraídos** — Nombre, fecha de nacimiento, nacionalidad, etc.
    * **Imágenes** — Fotos del documento de identidad y selfies
    * **Metadatos** — Marcas de tiempo, dirección IP, userid/email pasados por el cliente, etc.

    **Flujo de estado del Submission:**

    ```
    (El usuario abre/completa el Liveform) → Incomplete (aún no enviado)
                                          → tras envío y revisión → Approved | Rejected | Pending
    ```

    `Created` es un nombre de trigger de webhook, no un estado KYC. El enum oficial de estados KYC tiene cuatro valores: `Approved`, `Rejected`, `Pending`, `Incomplete`.
  </Accordion>

  <Accordion title="Liveform" icon="browser">
    **Liveform** es la página de verificación de identidad alojada por ARGOS. Los clientes simplemente necesitan proporcionar esta URL a sus usuarios.

    * **Escritorio**: Muestra un código QR para escanear con el móvil
    * **Móvil**: Procede directamente a la interfaz de cámara

    **Estructura de URL base:**

    ```
    https://form.argosidentity.com?pid={project_id}
    ```

    Puede personalizar la información del usuario, restricciones de países, opciones de seguridad y más agregando parámetros de query string.
  </Accordion>

  <Accordion title="Webhook" icon="webhook">
    Los **Webhooks** envían solicitudes HTTP POST en tiempo real a su servidor cuando ocurren eventos de verificación. Este es el **método más recomendado** para recibir resultados de verificación en producción.

    **Eventos clave:**

    * `approved` — Verificación aprobada
    * `rejected` — Verificación rechazada
    * `submit` — Enviado con estado pendiente
    * `updated` — Datos actualizados
    * `delete` — Submission eliminado
    * `created` — Submission creado
    * `retry` — Reintento del usuario
    * `token_expired` — Token expirado
    * `injection` — Datos inyectados vía API
    * `aml` — Verificación AML completada
    * `aml_monitor` — Resultado de monitoreo continuo AML

    Registre su URL de webhook en **Project Management → Project Settings → Integration Info**.
  </Accordion>

  <Accordion title="Token — Modo privado" icon="key">
    Usar un **Token** hace que las URLs del Liveform sean de un solo uso (modo privado).

    **Casos de uso:**

    * Evitar que la misma URL sea compartida con múltiples personas
    * Proporcionar enlaces de verificación válidos solo para usuarios específicos
    * Usar en servicios críticos de seguridad (finanzas, salud, etc.)

    **Cómo funciona:**

    * Genere un tokenId único en su servidor y regístrelo con ARGOS
    * Agregue el parámetro `token` a la URL del Liveform y entréguela al usuario
    * Expira 3 minutos después del primer uso o cuando el submission alcanza un estado de decisión
  </Accordion>

  <Accordion title="Return URL" icon="arrow-turn-down-right">
    **Return URL** es la URL a la que los usuarios son redirigidos después de completar la verificación y hacer clic en "OK" o después de 5 segundos.

    Configúrela en el dashboard, y el estado KYC (`kycStatus`), email, userid, campos personalizados, etc. se pasan como parámetros de consulta.

    **Ejemplo:**

    ```
    https://suapp.com/verificacion-completa?kycStatus=approved&userid=user123&email=user@example.com
    ```

    <Info>
      Return URL es para el flujo de experiencia de usuario (UX). Use **webhooks** como el canal oficial para recibir resultados de verificación.
    </Info>
  </Accordion>

  <Accordion title="Query Strings y cifrado" icon="lock">
    Los **query strings** personalizan el comportamiento del Liveform:

    * `email`, `userid`, `cf1`\~`cf3` — Prellenar información del usuario
    * `blacklistCountries=false`, `ageLimit=false` — Anular temporalmente políticas

    **Los parámetros sensibles a la seguridad deben cifrarse:**

    * `allowedCountries` — Restringir países permitidos
    * `allowedIdTypes` — Restringir tipos de documentos permitidos
    * `selectedIssuingCountry`, `selectedIdType` — Omitir pantallas de selección
    * `token` — Token de modo privado

    **Módulos de cifrado:**

    * **AES-256-ECB** — Cifrado de bloque rápido y simple
    * **AES-256-GCM** — Cifrado mejorado con autenticación e integridad

    **Claves de cifrado:**

    * **API Key** — La API key predeterminada asignada al proyecto
    * **secretKey personalizada** — Una clave dedicada emitida por separado desde el dashboard (se muestra solo una vez después de la emisión; debe reemitirse si se pierde)

    Use la **Herramienta de cifrado/descifrado de Query String** del dashboard (**Project Management → Project Settings → Project Info**) para generar y probar URLs cifradas directamente sin escribir código.

    Más información: [Guía de Query String y Token](/es/idcheck/getting-started/liveform-url/querystring-and-token-guide) | [Guía de cifrado](/es/idcheck/getting-started/encrypt-and-decrypt-data/overview)
  </Accordion>
</AccordionGroup>

***

## Parte 2: Integración

Resuelva las preocupaciones reales que enfrentan los desarrolladores, paso a paso.

***

### P1. "¿Cómo hago que los usuarios verifiquen su identidad desde mi aplicación?"

**Respuesta: Envíe a los usuarios a la URL del Liveform.**

Copie la URL del Liveform desde el dashboard y entréguela a los usuarios mediante enlaces de botón, redirecciones, enlaces de correo electrónico o cualquier otro método.

<Steps>
  <Step title="Obtenga su URL del Liveform">
    Copie la URL del Liveform desde **Project Management → Project Settings → Project Info** (sección Project Pipeline) en el dashboard:

    ```
    https://form.argosidentity.com?pid={your_project_id}
    ```
  </Step>

  <Step title="Entréguela a los usuarios desde su aplicación">
    **Aplicación web — Botón de enlace:**

    ```html theme={null}
    <a href="https://form.argosidentity.com?pid={your_pid}" target="_blank">
      Verify Your Identity
    </a>
    ```

    **Aplicación móvil — Abrir navegador externo:**

    ```javascript theme={null}
    // React Native example
    import { Linking } from 'react-native';

    const startVerification = () => {
      Linking.openURL('https://form.argosidentity.com?pid={your_pid}');
    };
    ```

    **Redirección del backend:**

    ```javascript theme={null}
    // Node.js Express example
    app.get('/verify', (req, res) => {
      res.redirect('https://form.argosidentity.com?pid={your_pid}');
    });
    ```
  </Step>

  <Step title="Probar el flujo básico">
    Abra la URL directamente en un navegador para probar el flujo de verificación básico.

    <div style={{ display: 'flex', gap: '1rem', alignItems: 'flex-start', flexWrap: 'wrap' }}>
      <div style={{ flex: 4, minWidth: '280px' }}>
        <Frame>
          <img src="https://mintcdn.com/argosidentity/VXdwPNlYPp7G6zXO/images/liveform/liveForm_pc_en.png?fit=max&auto=format&n=VXdwPNlYPp7G6zXO&q=85&s=151bcf5fb1e0fe584fda1ffa4b6e1647" alt="Interfaz del Liveform desde PC" style={{ width: 'auto', height: '30', objectFit: 'contain' }} width="1917" height="991" data-path="images/liveform/liveForm_pc_en.png" />
        </Frame>
      </div>

      <div style={{ flex: 1, minWidth: '10' }}>
        <Frame>
          <img src="https://mintcdn.com/argosidentity/VXdwPNlYPp7G6zXO/images/liveform/liveForm_mobile_en.png?fit=max&auto=format&n=VXdwPNlYPp7G6zXO&q=85&s=2604982b094d726c209608b28d4632a7" alt="Interfaz del Liveform desde móvil" style={{ width: 'auto', height: '40', objectFit: 'contain' }} width="411" height="907" data-path="images/liveform/liveForm_mobile_en.png" />
        </Frame>
      </div>
    </div>

    * **Escritorio**: Se muestra un código QR; escanee con el móvil para continuar
    * **Móvil**: Procede directamente a la interfaz de cámara
  </Step>
</Steps>

***

### P2. "¿Puedo pasar la información del usuario de mi servicio con anticipación?"

**Respuesta: Agregue parámetros de query string a la URL.**

Si los usuarios ya se han registrado, prellenar su correo electrónico, ID de usuario, etc. significa que no necesitarán volver a ingresarlos en el Liveform. Estos valores también se guardan con los datos del Submission y se pueden usar más tarde al consultar mediante webhooks o la API GET Submission.

**Parámetros clave:**

| Parámetro           | Descripción                                                              | Ejemplo            |
| ------------------- | ------------------------------------------------------------------------ | ------------------ |
| `email`             | Correo electrónico del usuario                                           | `user@example.com` |
| `userid`            | ID de usuario interno                                                    | `user_12345`       |
| `cf1`, `cf2`, `cf3` | Metadatos personalizados (ej., ID de campaña, identificador de servicio) | `campaign_summer`  |
| `sid`               | Submission ID (usado para actualizaciones)                               | `sub_abc123`       |

**URL de ejemplo:**

```javascript theme={null}
const email = encodeURIComponent("user@example.com");
const userid = "user_12345";
const liveformUrl = `https://form.argosidentity.com?pid={your_pid}&email=${email}&userid=${userid}&cf1=campaign_summer`;
```

<Tip>
  Al poner el ID de usuario de su sistema interno en `userid`, puede buscar más tarde los resultados de verificación de ese usuario directamente mediante webhooks o la API GET Submission.
</Tip>

***

### P3. "Me preocupa que la URL sea compartida con múltiples personas"

**Respuesta: Registre un Token para usar el modo privado (URL de un solo uso).**

Agregar un Token a la URL del Liveform la hace de un solo uso. Después del primer uso, una vez que pasan 3 minutos o la verificación se completa, ya no se puede usar.

<Steps>
  <Step title="Genere un tokenId único en su servidor y regístrelo con ARGOS">
    ```bash theme={null}
    curl -X POST 'https://rest-api.argosidentity.com/v3/submission/tokens' \
      -H 'x-api-key: YOUR_API_KEY' \
      -H 'Content-Type: text/plain' \
      -d '{"tokenId": ["user-session-001", "user-session-002"]}'
    ```

    **Respuesta:**

    ```json theme={null}
    {
      "success": true,
      "message": "All tokens are now in the pool",
      "summary": {
        "totalSubmitted": 2,
        "currentCount": 2
      }
    }
    ```

    <Warning>
      La API de registro de Token solo debe llamarse **desde el lado del servidor**. Como incluye la API key, nunca debe llamarse directamente desde el cliente (frontend).
    </Warning>
  </Step>

  <Step title="Entregue la URL del Liveform con Token al usuario">
    ```javascript theme={null}
    const tokenId = "user-session-001";
    const secureUrl = `https://form.argosidentity.com?pid={your_pid}&token=${tokenId}`;

    // Entregar al usuario por correo electrónico, SMS, etc.
    sendEmail(userEmail, `Verification link: ${secureUrl}`);
    ```
  </Step>

  <Step title="Manejar la expiración del Token">
    Los tokens se invalidan cuando:

    * Han pasado **3 minutos** desde el primer uso
    * El Submission asociado con el Token alcanza un estado de decisión (approved/rejected/pending)

    Cuando un token expira, genere uno nuevo y entrégueselo al usuario.

    **Limitaciones del Token:**

    * Máximo **100,000** tokens por proyecto
    * Máximo **500** tokens por solicitud de API
    * Formato del Token ID: 8-64 caracteres, alfanuméricos + `-_.`
  </Step>
</Steps>

Más información: [API POST Token](/es/idcheck/api-reference/api-reference-guide/post-token) | [Guía de Query String y Token](/es/idcheck/getting-started/liveform-url/querystring-and-token-guide)

***

### P4. "Quiero permitir solo países o tipos de documentos específicos"

**Respuesta: Use parámetros de query string cifrados.**

Los parámetros sensibles a la seguridad como `allowedCountries` y `allowedIdTypes` deben cifrarse y colocarse en el parámetro `encrypted`. Puede elegir entre los módulos de cifrado **AES-256-ECB** o **AES-256-GCM**, y usar la **API key** del proyecto o una **secretKey personalizada** emitida por separado desde el dashboard como clave de cifrado.

<Tip>
  **Genere URLs cifradas directamente desde el dashboard**

  Para generar y probar URLs cifradas del Liveform sin escribir código, use la **Herramienta de cifrado/descifrado de Query String** del dashboard.

  → **Project Management → Project Settings → Project Info → Query String Encryption/Decryption Tool**

  Ingrese los parámetros a cifrar y se genera automáticamente una URL cifrada. También puede descifrar URLs cifradas existentes para verificar los parámetros incluidos.
</Tip>

<Frame caption="Herramienta de cifrado/descifrado de Query String">
  <img src="https://mintcdn.com/argosidentity/IPUXz6Pq0_-rrbuX/images/dashboard/new/pj/project-setting/project-info/encryption_tool.png?fit=max&auto=format&n=IPUXz6Pq0_-rrbuX&q=85&s=6f4a93f3ff8e727ea7638491c218881e" alt="Herramienta de cifrado/descifrado de Query String" width="1631" height="859" data-path="images/dashboard/new/pj/project-setting/project-info/encryption_tool.png" />
</Frame>

**Cifrado con código:**

```javascript theme={null}
const CryptoJS = require('crypto-js');

function encryptQueryParams(data, apiKey) {
  const hashedKey = CryptoJS.SHA256(apiKey);
  const key = CryptoJS.lib.WordArray.create(hashedKey.words.slice(0, 8), 32);
  const encrypted = CryptoJS.AES.encrypt(
    JSON.stringify(data),
    key,
    { mode: CryptoJS.mode.ECB }
  );
  return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}

// Ejemplo 1: Restringir países y tipos de documentos permitidos
const config1 = {
  allowedCountries: "USA,KOR,JPN",        // ISO Alpha-3 codes
  allowedIdTypes: "passport,drivers_license"
};

// Ejemplo 2: Preseleccionar país y tipo de documento (omitir pantallas de selección)
const config2 = {
  selectedIssuingCountry: "KOR",
  selectedIdType: "drivers_license"
};

const encrypted = encryptQueryParams(config1, YOUR_API_KEY);
const liveformUrl = `https://form.argosidentity.com?pid={your_pid}&encrypted=${encodeURIComponent(encrypted)}`;
```

**Parámetros que requieren cifrado:**

| Parámetro                         | Descripción                                                                                                 |
| --------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `allowedCountries`                | Países a permitir (códigos ISO Alpha-3, separados por comas)                                                |
| `allowedIdTypes`                  | Tipos de documentos a permitir                                                                              |
| `selectedIssuingCountry`          | Omitir selección de país y especificar directamente                                                         |
| `selectedIdType`                  | Omitir selección de tipo de documento y especificar directamente (debe usarse con `selectedIssuingCountry`) |
| `projectionId` / `projectionName` | Aplicar Projection para excluir campos específicos                                                          |
| `auxidField`                      | Verificación de identidad adicional (ej., verificación por SMS de número de teléfono)                       |

<Warning>
  `selectedIdType` siempre debe usarse junto con `selectedIssuingCountry`. Usarlo solo causará un error.
</Warning>

Más información: [Guía de Query String y Token](/es/idcheck/getting-started/liveform-url/querystring-and-token-guide)

***

### P5. "Quiero redirigir a los usuarios de vuelta a mi aplicación después de la verificación"

**Respuesta: Configure una Return URL en el dashboard.**

Cuando los usuarios terminan la verificación y hacen clic en "OK", son redirigidos a la URL configurada. Los resultados de KYC se pasan como parámetros de consulta.

<Steps>
  <Step title="Configurar Return URL en el dashboard">
    Ingrese la Return URL en **Project Management → Project Settings → Integration Info**:

    <Frame caption="Configuración de Return URL">
      <img src="https://mintcdn.com/argosidentity/bSOR6O7Y3jW8lg8K/images/dashboard/new/pj/project-setting/integration-info/return_url_en.png?fit=max&auto=format&n=bSOR6O7Y3jW8lg8K&q=85&s=008eb64366d5da7899b41ad14ae5fdfb" alt="Configuración de Return URL" width="779" height="470" data-path="images/dashboard/new/pj/project-setting/integration-info/return_url_en.png" />
    </Frame>

    ```
    https://suapp.com/verificacion-completa
    ```
  </Step>

  <Step title="Manejar los resultados de la redirección">
    Los usuarios son redirigidos con los siguientes parámetros:

    ```
    https://suapp.com/verificacion-completa?kycStatus=approved&userid=user123&email=user@example.com&cf1=campaign_summer
    ```

    **Parámetros pasados:**

    * `kycStatus` — `approved`, `rejected`, `pending`
    * `userid` — ID de usuario pasado en la URL del Liveform
    * `email` — Correo electrónico del usuario
    * `cf1`, `cf2`, `cf3` — Campos personalizados

    ```javascript theme={null}
    // Express.js example
    app.get('/verification-complete', async (req, res) => {
      const { userid, kycStatus } = req.query;

      if (kycStatus === 'approved') {
        await updateUser(userid, { verified: true });
        res.render('verification-success');
      } else if (kycStatus === 'pending') {
        res.render('verification-pending');
      } else {
        res.render('verification-rejected');
      }
    });
    ```
  </Step>
</Steps>

<Warning>
  El `kycStatus` pasado mediante Return URL es para transiciones de pantalla de experiencia de usuario (UX). Para registrar oficialmente los resultados de verificación en su base de datos o reflejarlos en sistemas internos, se recomienda usar **webhooks**. Los parámetros de Return URL pueden ser manipulados.
</Warning>

Más información: [Guía de Return URL](/es/idcheck/getting-started/liveform-url/return-url-guide)

***

### P6. "Quiero recibir resultados de verificación en mi servidor en tiempo real"

**Respuesta: Configure Webhooks.**

Los Webhooks envían solicitudes HTTP POST instantáneas a su servidor cuando ocurren eventos de verificación. Este es el **método más confiable y recomendado** para recibir resultados de verificación.

<Steps>
  <Step title="Crear un endpoint de Webhook">
    Cree un endpoint HTTPS en su servidor para recibir solicitudes POST:

    ```javascript theme={null}
    // Node.js Express example
    const express = require('express');
    const app = express();
    app.use(express.json());

    app.post('/webhooks/idcheck', async (req, res) => {
      const event = req.body;

      // Procesar según el tipo de evento
      switch (event.webhook_trigger) {
        case 'approved':
          // Manejar aprobación de verificación
          await db.users.update({ id: event.userid, verified: true });
          break;

        case 'rejected':
          // Manejar rechazo de verificación
          await db.users.update({ id: event.userid, verified: false });
          break;

        case 'submit':
          // Manejar revisión manual pendiente
          await notifyAdmin(`${event.userid} requires manual review`);
          break;
      }

      // Responda 200 de inmediato (los webhooks de ARGOS son unidireccionales, sin reintentos)
      res.status(200).json({ received: true });
    });
    ```

    <Warning>
      **Principios importantes de implementación de Webhooks:**

      * ARGOS entrega los webhooks **normalmente en menos de 5 segundos** desde que ocurre el evento. Los webhooks son notificaciones unidireccionales (one-way) y no se reintentan automáticamente ante fallos de entrega. Para evitar eventos perdidos, considere usar GET Submission API como mecanismo de reconciliación.
      * Devuelva 200 OK inmediatamente al recibir la solicitud y ejecute cualquier procesamiento pesado de forma asíncrona.
      * Implemente manejo de **idempotencia**, ya que el mismo trigger (p. ej. `updated`) puede dispararse nuevamente para el mismo Submission ID.
    </Warning>
  </Step>

  <Step title="Registrar la URL del Webhook en el dashboard">
    Ingrese la URL del endpoint en la sección **Webhook Settings** bajo **Project Management → Project Settings → Integration Info**:

    ```
    https://suapp.com/webhooks/idcheck
    ```

    <Frame caption="Configuración de URL de Webhook">
      <img src="https://mintcdn.com/argosidentity/SCyJH7SnZdUydn0h/images/dashboard/new/pj/project-setting/integration-info/webhook-setting_en.png?fit=max&auto=format&n=SCyJH7SnZdUydn0h&q=85&s=e3c037d7c75472e9c48742ebba12938c" alt="Pantalla de configuración de Webhook" width="927" height="505" data-path="images/dashboard/new/pj/project-setting/integration-info/webhook-setting_en.png" />
    </Frame>

    <Info>
      Las URLs de Webhook deben usar **HTTPS**. Para desarrollo local, use [ngrok](https://ngrok.com/) o [webhook.site](https://webhook.site) para pruebas.
    </Info>
  </Step>

  <Step title="Revisar los eventos de Webhook">
    **Todos los tipos de eventos:**

    | Evento          | Descripción                          | Caso de uso                                                 |
    | --------------- | ------------------------------------ | ----------------------------------------------------------- |
    | `approved`      | Verificación aprobada                | Actualizar estado del usuario, otorgar acceso al servicio   |
    | `rejected`      | Verificación rechazada               | Notificar al usuario, solicitar reenvío                     |
    | `submit`        | Estado pendiente                     | Notificación al administrador, solicitud de revisión manual |
    | `updated`       | Datos actualizados                   | Sincronización de BD                                        |
    | `delete`        | Submission eliminado                 | Limpieza de datos relacionados                              |
    | `created`       | Submission creado                    | Rastrear inicios de verificación                            |
    | `retry`         | Reintento del usuario                | Monitorear patrones de reintento                            |
    | `token_expired` | Token expirado                       | Emitir nuevo token                                          |
    | `injection`     | Datos inyectados vía API (Injection) | Registro de operaciones de API                              |
    | `aml`           | Verificación AML completada          | Procesar resultados de cumplimiento                         |
    | `aml_monitor`   | Resultado de monitoreo continuo AML  | Procesamiento de monitoreo continuo                         |

    Más información: [Guía detallada de eventos de Webhook](/es/idcheck/webhooks/overview)
  </Step>
</Steps>

***

### P7. "Quiero integrar datos de verificación con nuestra BD/sistema"

**Respuesta: Use la API GET Submission para consultar datos de verificación.**

Mientras que la recepción en tiempo real mediante webhooks es posible, use la API GET Submission cuando necesite consultar directamente datos específicos de un Submission en un momento dado.

```bash theme={null}
# Consultar un submission por Submission ID
curl -X GET 'https://rest-api.argosidentity.com/v3/submission?submission_id={submission_id}' \
  -H 'x-api-key: YOUR_API_KEY'

# Consultar por ID de usuario
curl -X GET 'https://rest-api.argosidentity.com/v3/submission?userid={userid}' \
  -H 'x-api-key: YOUR_API_KEY'

# Consultar por correo electrónico
curl -X GET 'https://rest-api.argosidentity.com/v3/submission?email={email}' \
  -H 'x-api-key: YOUR_API_KEY'

# Consultar lista completa (paginación)
curl -X GET 'https://rest-api.argosidentity.com/v3/submission?count=50' \
  -H 'x-api-key: YOUR_API_KEY'
```

**Parámetros de consulta:**

| Parámetro                 | Descripción                                                                |
| ------------------------- | -------------------------------------------------------------------------- |
| `submission_id`           | Consultar un submission por su ID único                                    |
| `userid`                  | Consultar todos los submissions que coincidan con el ID de usuario         |
| `email`                   | Consultar todos los submissions que coincidan con el correo electrónico    |
| `count`                   | Número de resultados a devolver (predeterminado: 50)                       |
| `start_date` / `end_date` | Filtro de rango de fechas (YYYY-MM-DD)                                     |
| `request_type`            | Consultar solo tipos de datos específicos (`kyc`, `aml`, `data`, `others`) |

**Ejemplo de respuesta:**

```json theme={null}
{
  "Items": [
    {
      "data": {
        "full_name": "John Doe",
        "gender": "male",
        "nationality": "USA",
        "date_of_birth": "1990-01-01",
        "idType": "passport",
        "idcard_issuingCountry": "USA",
        "cf1": "campaign_summer"
      },
      "email": "user@example.com",
      "submission_id": "sub_abc123",
      "userid": "user_12345",
      "created_at": "2024-01-15-10-30-00-000",
      "kyc": {
        "result": "approved",
        "comment": [],
        "commentCode": []
      },
      "image": {
        "idImage": "{idImage URL}",
        "selfieImage": "{selfieImage URL}"
      }
    }
  ]
}
```

**Otras APIs de gestión de datos e integración de sistemas:**

| API                          | Propósito                                                                                |
| ---------------------------- | ---------------------------------------------------------------------------------------- |
| `PATCH /submission`          | Modificar datos del Submission (kycStatus, fullName, email, etc.)                        |
| `DELETE /submission`         | Eliminar Submission completo (para solicitudes de eliminación de datos GDPR, etc.)       |
| `DELETE /submission/partial` | Eliminar solo imágenes (preservar metadatos)                                             |
| `GET /image`                 | Recuperar imágenes almacenadas en un Submission (documentos de identidad, selfies, etc.) |
| `PUT /image`                 | Agregar o reemplazar imágenes en un Submission existente (codificadas en Base64)         |
| `POST /submission/review`    | Aprobar/rechazar Submissions pendientes vía API (automatizar revisión manual)            |

<Info>
  `POST /submission/review` permite a los clientes revisar submissions pendientes directamente vía API cuando el revisor del proyecto está configurado como 'Client'. Los submissions ya aprobados/rechazados no pueden modificarse.
</Info>

Más información: [API GET Submission](/es/idcheck/api-reference/api-reference-guide/get-submission) | [API Review](/es/idcheck/api-reference/api-reference-guide/post-client-review)

***

### P8. "Quiero migrar datos KYC existentes a ARGOS"

**Respuesta: Use la API POST Submission (Migración).**

Esta API se usa en las siguientes situaciones:

* **Migración de datos**: Transferir datos de KYC completados de sistemas existentes al dashboard de ARGOS
* **Situaciones especiales**: Insertar datos directamente en casos excepcionales donde la verificación de ID Check es difícil
* **Desarrollo y pruebas**: Usar durante el desarrollo para probar varios escenarios

<Warning>
  Los Submissions creados a través de esta API **no pasan por el proceso de verificación estándar de ARGOS (verificación por IA)**. La precisión y validez de los datos enviados es enteramente responsabilidad del cliente.

  La verificación de identidad estándar para nuevos usuarios siempre debe realizarse a través del **Liveform**.
</Warning>

```bash theme={null}
curl -X POST 'https://rest-api.argosidentity.com/v3/submission/migration' \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: YOUR_API_KEY' \
  -d '{
    "admin": "admin@yourcompany.com",
    "email": "user@example.com",
    "fullName": "John Doe",
    "birthDate": "1990-01-01",
    "kycStatus": "approved",
    "idType": "passport",
    "issuingCountry": "USA",
    "nationality": "USA",
    "gender": "male",
    "userid": "user_12345"
  }'
```

**Campos obligatorios:**

| Campo       | Descripción                                                                               |
| ----------- | ----------------------------------------------------------------------------------------- |
| `admin`     | Correo electrónico del administrador del proyecto (debe estar registrado en el dashboard) |
| `email`     | Dirección de correo electrónico del solicitante KYC                                       |
| `fullName`  | Nombre completo del solicitante                                                           |
| `birthDate` | Fecha de nacimiento (YYYY-MM-DD)                                                          |
| `kycStatus` | `approved` o `rejected`                                                                   |

**Campos opcionales:** `idType`, `issuingCountry`, `nationality`, `gender`, `issueDate`, `expireDate`, `identityNumber`, `documentNumber`, `userid`, `cf1`\~`cf3`, etc.

**Notas:**

* Solo se admiten datos de tipo string. Para datos de imagen, use la [API PUT Image](/es/idcheck/api-reference/api-reference-guide/put-image) por separado.
* Para mayor seguridad, puede cifrar el cuerpo de la solicitud con AES-256-ECB antes de enviar.

Más información: [API POST Submission](/es/idcheck/api-reference/api-reference-guide/post-submission)

***

## Parte 3: Implementación en producción

### Fortalecimiento de seguridad

Complete estas configuraciones de seguridad antes de implementar en producción.

<AccordionGroup>
  <Accordion title="1. Gestión segura de API Key" icon="key">
    Las API keys nunca deben exponerse en código del lado del cliente (frontend) ni en git.

    **Usar variables de entorno (obligatorio):**

    ```bash theme={null}
    # .env file
    ARGOS_API_KEY=argos_live_abc123xyz...
    ARGOS_PROJECT_ID=pid_abc123
    ```

    ```javascript theme={null}
    // Load in Node.js
    require('dotenv').config();
    const apiKey = process.env.ARGOS_API_KEY;
    ```

    **Patrón de proxy del backend (recomendado):**

    ```javascript theme={null}
    // ❌ Llamar a la API de ARGOS directamente desde el frontend — Nunca haga esto
    // fetch('https://rest-api.argosidentity.com/...', { headers: { 'x-api-key': '...' } })

    // ✅ El frontend solo llama a su propia API del backend
    // El servidor backend llama a la API de ARGOS y devuelve los resultados
    app.post('/api/start-verification', authenticateUser, async (req, res) => {
      const tokenId = `session-${req.user.id}-${Date.now()}`;

      // Llamar a la API de ARGOS solo desde el lado del servidor
      await fetch('https://rest-api.argosidentity.com/v3/submission/tokens', {
        method: 'POST',
        headers: { 'x-api-key': process.env.ARGOS_API_KEY, 'Content-Type': 'text/plain' },
        body: JSON.stringify({ tokenId: [tokenId] })
      });

      const liveformUrl = `https://form.argosidentity.com?pid=${process.env.ARGOS_PROJECT_ID}&token=${tokenId}`;
      res.json({ liveformUrl });
    });
    ```

    Asegúrese de agregar a `.gitignore`:

    ```
    .env
    .env.local
    .env.production
    ```
  </Accordion>

  <Accordion title="2. Configuración de lista blanca de IP" icon="shield-check">
    Registrar las IPs del servidor que llaman a la API de ARGOS en la lista blanca bloquea el acceso a la API desde IPs no autorizadas (403).

    Registre las IPs de su servidor en **Project Management → Project Settings → System Operation → IP Whitelist Management**:

    <Frame caption="Gestión de lista blanca de IP">
      <img src="https://mintcdn.com/argosidentity/SCyJH7SnZdUydn0h/images/dashboard/new/pj/project-setting/system-operation/ip_whitelist_en.png?fit=max&auto=format&n=SCyJH7SnZdUydn0h&q=85&s=2ee7f0453f553eb6c38dc1a96664707a" alt="Gestión de lista blanca de IP" width="928" height="308" data-path="images/dashboard/new/pj/project-setting/system-operation/ip_whitelist_en.png" />
    </Frame>

    ```
    52.12.34.56
    52.12.34.57
    ```

    <Warning>
      Debe registrar **todas** las IPs del servidor que llaman a la API: servidores de producción, servidores de staging, IPs de pipelines CI/CD, etc.
    </Warning>
  </Accordion>

  <Accordion title="3. Habilitar cifrado de datos de Webhook" icon="lock">
    Puede cifrar datos KYC sensibles transmitidos mediante webhooks.

    Configure **"Secure Data Transfer"** en **ON** en **Project Management → Security Settings → Data Protection**.

    <Frame caption="Configuración de transferencia segura de datos">
      <img src="https://mintcdn.com/argosidentity/352WpTnZFyEfW7I6/images/dashboard/new/data_protection/secure_data_transfer.png?fit=max&auto=format&n=352WpTnZFyEfW7I6&q=85&s=cedeafc03cbd672531f76091fc3e6786" alt="Configuración de transferencia segura de datos" width="2246" height="227" data-path="images/dashboard/new/data_protection/secure_data_transfer.png" />
    </Frame>

    Cuando está habilitado, los payloads de webhook se entregan cifrados en el siguiente formato:

    ```json theme={null}
    {
      "response": {
        "body": "encrypted-string"
      }
    }
    ```

    **Método de descifrado (AES-256-CBC):**

    ```javascript theme={null}
    const CryptoJS = require('crypto-js');

    function decryptWebhook(encryptedData, apiKey) {
      const hashedKey = CryptoJS.SHA256(apiKey);
      const key = CryptoJS.lib.WordArray.create(hashedKey.words.slice(0, 8), 32);
      const iv = CryptoJS.lib.WordArray.create(hashedKey.words.slice(8, 12), 16);

      const cipherParams = CryptoJS.lib.CipherParams.create({
        ciphertext: CryptoJS.enc.Base64.parse(encryptedData)
      });

      const decrypted = CryptoJS.AES.decrypt(cipherParams, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
      });

      return JSON.parse(decrypted.toString(CryptoJS.enc.Utf8));
    }

    app.post('/webhooks/idcheck', (req, res) => {
      const event = decryptWebhook(req.body.response.body, process.env.ARGOS_API_KEY);
      // Procesar evento...
      res.status(200).json({ received: true });
    });
    ```

    <Warning>
      **Diferencias de método de cifrado:**

      * Descifrado de **Webhook**: **AES-256-CBC**
      * **Solicitudes/respuestas de API**: **AES-256-ECB**
      * **Query strings**: **AES-256-ECB** o **AES-256-GCM**

      No confunda los métodos de cifrado para cada propósito.
    </Warning>

    Más información: [Guía de cifrado](/es/idcheck/getting-started/encrypt-and-decrypt-data/overview)
  </Accordion>
</AccordionGroup>

***

### Lista de verificación de pruebas

Verifique los siguientes elementos antes de implementar en producción.

<Steps>
  <Step title="Pruebas del flujo del Liveform">
    <AccordionGroup>
      <Accordion title="Flujo básico" icon="browser">
        * [ ] La URL básica del Liveform carga correctamente en escritorio/móvil
        * [ ] El código QR se escanea en el móvil y el flujo procede
        * [ ] La solicitud de permiso de cámara funciona correctamente
        * [ ] La captura de documento y selfie seguida del envío se completa
      </Accordion>

      <Accordion title="Parámetros de Query String" icon="link">
        * [ ] La información del usuario se prellena con los parámetros `email`, `userid`
        * [ ] Los parámetros cifrados (`allowedCountries`, etc.) funcionan correctamente
        * [ ] La URL en modo privado con Token funciona correctamente
        * [ ] Se muestra la pantalla de error apropiada al acceder a un Token expirado
      </Accordion>

      <Accordion title="Return URL" icon="arrow-turn-down-right">
        * [ ] Se redirige a la Return URL después de completar la verificación
        * [ ] Los parámetros `kycStatus`, `userid`, `email` se pasan correctamente
        * [ ] Los parámetros se pasan mediante el parámetro `encrypted` cuando la opción de cifrado está habilitada
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Pruebas de Webhook">
    <AccordionGroup>
      <Accordion title="Verificación de recepción de Webhook" icon="webhook">
        **Método de prueba 1: Usando webhook.site**

        ```
        1. Visite https://webhook.site
        2. Copie la URL única generada
        3. Ingrésela en el campo URL de Webhook del dashboard
        4. Realice una verificación de prueba en el Liveform
        5. Verifique el payload en webhook.site
        ```

        **Método de prueba 2: Usando ngrok (desarrollo local)**

        ```bash theme={null}
        # Ejecutar servidor local
        node server.js   # port 3000

        # Exponer externamente en una terminal separada
        ngrok http 3000

        # Ingrese la URL HTTPS generada en el dashboard
        # ej., https://abc123.ngrok.io/webhooks/idcheck
        ```

        * [ ] El endpoint de Webhook recibe eventos correctamente
        * [ ] Los eventos `approved`, `rejected`, `submit` se procesan correctamente
        * [ ] Se devuelve respuesta 200 OK de inmediato al recibir el webhook
        * [ ] El manejo de idempotencia para webhooks duplicados funciona
        * [ ] Los webhooks cifrados se descifran correctamente
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Pruebas de API">
    * [ ] GET Submission devuelve datos correctos
    * [ ] La consulta por `userid`, `email` funciona
    * [ ] El registro de Token (POST Token) y la recuperación (GET Token) funcionan correctamente
    * [ ] Solo las IPs autorizadas pueden acceder cuando la lista blanca de IP está habilitada
    * [ ] Se devuelve respuesta 403 para solicitudes con API keys inválidas
  </Step>

  <Step title="Pruebas de seguridad">
    * [ ] La API key no está expuesta en código del lado del cliente
    * [ ] La API key no está incluida en el historial de git
    * [ ] La URL de Webhook usa HTTPS
    * [ ] No se otorgan permisos basándose únicamente en los parámetros de Return URL (verificar mediante webhook)
  </Step>
</Steps>

***

### Lista de verificación de transición a producción

<Steps>
  <Step title="Verificación final de configuración del dashboard">
    * [ ] La URL de Webhook está configurada con la dirección del servidor de producción (HTTPS)
    * [ ] Todas las IPs del servidor de producción están registradas en la lista blanca de IP
    * [ ] La transferencia segura de datos (cifrado de webhook) está configurada según sea necesario
    * [ ] La Return URL está configurada con la dirección de la aplicación de producción
    * [ ] La configuración del proyecto (tipos de documentos permitidos, lista negra de países, límites de edad, etc.) coincide con los requisitos
  </Step>

  <Step title="Verificación final del código">
    * [ ] La API key se carga desde variables de entorno
    * [ ] No hay API keys codificadas en el código
    * [ ] El manejo de errores y el registro están implementados en el handler de webhook
    * [ ] El manejo de idempotencia de webhook está implementado
    * [ ] El frontend no llama directamente a la API de ARGOS
  </Step>

  <Step title="Configuración de monitoreo">
    Métricas clave a rastrear en producción:

    * Inicios de verificación vs. completados
    * Ratios de aprobado / rechazado / pendiente
    * Tasa de fallos en la recepción de webhooks
    * Frecuencia de reemisión de tokens debido a expiración
  </Step>
</Steps>

***

## Próximos pasos

Una vez que haya completado la integración, explore funciones avanzadas con la documentación a continuación.

<CardGroup cols={2}>
  <Card title="Guía de Query String y Token" icon="link" href="/es/idcheck/getting-started/liveform-url/querystring-and-token-guide">
    Todas las opciones para personalizar el Liveform
  </Card>

  <Card title="Referencia de eventos de Webhook" icon="webhook" href="/es/idcheck/webhooks/overview">
    Guía detallada del payload de cada evento
  </Card>

  <Card title="Guía de cifrado" icon="lock" href="/es/idcheck/getting-started/encrypt-and-decrypt-data/overview">
    Implementación de cifrado AES-256-ECB, GCM, CBC
  </Card>

  <Card title="Referencia de API" icon="code" href="/es/idcheck/api-reference/api-reference-guide/overview">
    Especificaciones completas de API para GET Submission, Token API y más
  </Card>

  <Card title="Guía de Return URL" icon="arrow-turn-down-right" href="/es/idcheck/getting-started/liveform-url/return-url-guide">
    Configuración de redirección posterior a la verificación
  </Card>

  <Card title="Navegadores y dispositivos recomendados" icon="mobile" href="/es/idcheck/getting-started/recommended-browsers-and-devices">
    Verifique los entornos compatibles con el Liveform
  </Card>
</CardGroup>
