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

# Integrar Antispoofing Facial

> Cómo preparar la imagen, armar la llamada a /inference, manejar el campo info y validar la integración antes de producción.

## El recorrido completo

<Steps>
  <Step title="Verifique conectividad y credenciales">
    ```bash theme={null}
    curl -i -X GET "$BASE_URL/version" -H "Api-Key: $VU_AS_FACE_API_KEY"
    ```

    Un `200` confirma que la URL base y la api-key son correctas. Un `401` significa clave inválida o ambiente equivocado. Evalúe el código de estado, no el cuerpo: los números de versión cambian y no son parte de su contrato.
  </Step>

  <Step title="Prepare la imagen">
    Capture o reciba un JPEG, ajústelo a las dimensiones recomendadas y conviértalo a base64 sin prefijo.
  </Step>

  <Step title="Llame a POST /inference">
    Un único JSON con `image`, `info` y `logAnonymity`.
  </Step>

  <Step title="Aplique la regla de decisión">
    `status === 200 && spoofing === false` aprueba. Todo lo demás, no.
  </Step>
</Steps>

## Requisitos de la imagen

| Aspecto | Valor | Qué pasa si no se cumple |
| - | - | - |
| Resolución recomendada | 640 × 480 (o 480 × 640 en vertical) | Es el tamaño con el que el servicio fue calibrado. |
| Mínimo duro | 224 × 224 | Por debajo: `400` con `Image should be larger than [224, 224]`. |
| Formato | JPEG, calidad ≥ 95 | La compresión agresiva borra las señales que el servicio busca. |
| Codificación | base64 sin prefijo `data:` y sin saltos de línea | El servicio rechaza la carga o falla al decodificar. |

<Warning>
  **Entre 224 × 224 y 640 × 480 no hay error, pero sí menos detección.** Varias capas de análisis necesitan resolución para funcionar. Una imagen chica pasa la validación, se procesa y devuelve `200` —con menos capas mirando—. Es la falla silenciosa más cara de esta integración: no la va a ver en los logs, la va a ver en el fraude.
</Warning>

<Tip>
  Si su app móvil ya captura a mayor resolución, redimensione en el servidor antes de enviar. Enviar 4 000 × 3 000 píxeles no mejora la detección y sí multiplica el tiempo de respuesta y el tamaño del payload.
</Tip>

### Convertir a base64

<CodeGroup>
  ```powershell Windows theme={null}
  [Convert]::ToBase64String([IO.File]::ReadAllBytes("selfie.jpg")) | Set-Content -NoNewline selfie.b64
  ```

  ```bash Linux theme={null}
  base64 -w 0 selfie.jpg > selfie.b64
  ```

  ```bash macOS theme={null}
  base64 -i selfie.jpg -o selfie.b64
  ```
</CodeGroup>

En Linux, `-w 0` evita los saltos de línea que `base64` inserta cada 76 caracteres. Sin esa bandera la cadena llega partida y el servicio no puede decodificarla.

## Cuerpo de la solicitud

```json theme={null}
{
  "info": "onboarding-12345",
  "logAnonymity": true,
  "image": "/9j/4AAQSkZJRgABAQAAAQABAAD...v9Un0ooqDE//2Q=="
}
```

| Campo | Tipo | Descripción |
| - | - | - |
| `image` | string | La selfie en base64, sin prefijo. Obligatorio. |
| `info` | string | Su referencia de negocio. **Debe ser una cadena**: si envía un objeto recibe `422` con `Input should be a valid string`. |
| `logAnonymity` | boolean | Controla el nivel de anonimización con que VU registra la transacción. Acuerde el valor con VU según su política de datos. |

<Tip>
  **Siempre envíe un `info` no vacío** con un identificador que le permita reconstruir el caso: número de trámite, id de sesión de onboarding, lo que use su negocio. Vuelve en la respuesta y es lo que conecta una transacción de VU con un usuario en su sistema cuando algo hay que investigar.
</Tip>

## El campo `info` en la respuesta

Aquí es donde más integraciones se rompen. `info` **no siempre es del mismo tipo**:

| Lo que envía | Lo que vuelve en `info` | Dónde queda su referencia |
| - | - | - |
| Un `info` y hay diagnóstico adjunto | Un **objeto** | En `info.info` (puede ser `null`) |
| Un `info` sin diagnóstico adjunto | Un **string** (el eco de lo que envió) | En `info` |
| Nada | **`null`** | No hay |

Resúelvalo en un solo lugar y nunca lea `info` directamente:

```js theme={null}
function referencia(body) {
  const i = body?.info;
  return i == null             ? null
       : typeof i === "string" ? i
       : i.info ?? null;
}
```

<Warning>
  **En Java, tipe `info` como `Object`, nunca como `String`.** Es la causa número uno de fallas de integración: el mapeo funciona en todas las pruebas —donde `info` vuelve como cadena— y explota en producción la primera vez que un caso trae diagnóstico y `info` llega como objeto. Lo mismo aplica a cualquier deserializador estricto.
</Warning>

## Timeouts y reintentos

| Parámetro | Valor | Motivo |
| - | - | - |
| Timeout | 30 s | El análisis típico tarda cientos de milisegundos, pero deje margen. |
| Reintentos | Máximo 2, con backoff | Más reintentos no mejoran el resultado y multiplican la carga. |
| Qué reintentar | `499` y los `500` que **no** mencionan la imagen ni el payload | Son fallas transitorias del servicio. |
| Qué **no** reintentar | `400`, `401`, `422`, y cualquier `500` determinista | El problema está en su solicitud; reintentar da el mismo error. |

<Warning>
  **Nunca reintente una respuesta con `spoofing: true`.** Es un veredicto, no un error. Reintentar hasta obtener otro resultado convierte su control antifraude en un generador de falsos aprobados.
</Warning>

## Antes de salir a producción

Una integración está lista cuando puede responder que sí a todo esto:

1. La decisión está escrita en positivo: `status === 200 && spoofing === false`.
2. Ninguna rama decide sobre `errorCode`, `values`, `confidence` o `info`.
3. `info` se lee a través de un único resolutor que contempla objeto, string y `null`.
4. En lenguajes tipados, `info` está declarado como tipo dinámico u `Object`.
5. `imageQuality` y sus subcampos se leen como opcionales; ninguna clave se asume presente.
6. Las imágenes salen a 640 × 480 con calidad JPEG ≥ 95.
7. Existe una validación previa que descarta imágenes menores a 224 × 224 antes de gastar una llamada.
8. El base64 se genera sin prefijo `data:` y sin saltos de línea.
9. El timeout está en 30 s.
10. Los reintentos están limitados a 2 y solo para `499` y `500` no deterministas.
11. El `id` de cada transacción queda en su log, junto con el ambiente y la marca de tiempo.
12. La api-key vive solo en el backend y está en un gestor de secretos, no en el código.
13. El equipo sabe que `422 No Face Detected` es un problema de captura y que `422 Bad request` es un problema de código.

<Card title="Respuestas" icon="list-check" href="/vucs/antispoofing-facial/respuestas">
  El siguiente paso: qué significa cada campo de la respuesta y cómo leer el diagnóstico.
</Card>


## Related topics

- [Antispoofing Facial](/vucs/antispoofing-facial/introduccion.md)
- [Integrar ID Analysis](/vucs/id-analysis/integracion.md)
- [Integrar Connection Fingerprint](/vucs/connection-fingerprint/integracion.md)
- [Errores y diagnóstico](/vucs/antispoofing-facial/errores.md)
- [Prueba de vida y biometría facial en Identity Link](/identity-link/prueba-de-vida.md)


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