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

# Códigos de error y respuestas de la Identity Link API

> Referencia completa de códigos HTTP y errores de la Identity Link API con causas, significados y cómo resolverlos.

La Identity Link API de VU utiliza códigos HTTP estándar para indicar el resultado de cada solicitud. Esta página agrupa todos los errores por código de estado, explica por qué ocurren y describe los pasos concretos para solucionarlos. También documenta los cambios de comportamiento introducidos en la versión 2.2.0.

## Formato de respuesta de error

Todas las respuestas de error comparten el mismo esquema:

```json theme={null}
{
  "type": "ErrorResponse",
  "message": "Descripción legible del error"
}
```

En el caso de errores específicos de enlaces (código 409), la respuesta usa el esquema `LinksErrorGetResponse`, donde `code` es **numérico**:

```json theme={null}
{
  "code": 4091,
  "name": "LinkExpired",
  "description": "El enlace ya fue utilizado o expiró",
  "data": {}
}
```

El 404 de ruta inexistente usa un tercer formato, sin `type`: `{"message": "...", "resource": "..."}`. Se describe en [Errores 404](#errores-404-recurso-no-encontrado).

## Errores 400: Solicitud inválida

| Escenario | Causa | Solución |
| - | - | - |
| `invalid request body` | El cuerpo JSON no cumple el esquema esperado o contiene tipos de datos incorrectos. | Valida el JSON contra el esquema del endpoint antes de enviarlo. |
| `missing required field` | Falta un campo obligatorio como `type` en `POST /links` o `grant_type` en `POST /oauth/token`. | Revisa la documentación del endpoint y asegúrate de incluir todos los campos requeridos. |
| `invalid grant_type` | El valor de `grant_type` no es `client_credentials`. | Usa exclusivamente `grant_type=client_credentials` en la solicitud de token. |
| `device source without coordinates` | Se declaró un `source` de dispositivo (`gps`, `wifi` o `cell`) en geolocalización sin `deviceLatitude` ni `deviceLongitude`. | Cuando el origen es del dispositivo, incluye obligatoriamente las coordenadas del dispositivo. Nada aguas abajo puede usar una mitad sola. |
| `server-derived field sent by client` | El cliente envió `tier`, `policy`, `ipDistanceKm` o `serverIp` en `PATCH /verifications`. | Los cuatro se derivan en el servidor y no son propiedades aceptadas. Quítalos del payload. |
| `capturedAt out of range` | El `capturedAt` reportado se aparta más de 24 horas del reloj del servidor. | Sincroniza el reloj del dispositivo y envía la marca de tiempo real de la muestra. |
| `invalid or missing email` | `PATCH /verifications/identify` recibió un email ausente o con formato inválido. | Valida el email en el cliente antes de enviarlo. |

## Errores 401: No autorizado

| Escenario | Causa | Solución |
| - | - | - |
| `expired token` | El `access_token` superó los 3600 segundos de vida útil. | Solicita un nuevo token con `POST /oauth/token`. |
| `missing token` | No se incluyó el encabezado `Authorization: Bearer <token>`. | Agrega el encabezado de autorización en todas las solicitudes protegidas. |
| `invalid clientId/clientSecret` | Las credenciales en el encabezado `Authorization: Basic` son incorrectas o están desactivadas. | Verifica que el `clientId` y `clientSecret` sean correctos. Obténlos desde `GET /users/me`. |

## Errores 403: Prohibido

| Escenario | Causa | Solución |
| - | - | - |
| `no token provided` | El servidor detectó una solicitud autenticada sin token válido. | Incluye el token Bearer en el encabezado `Authorization`. |
| `linkId missing or mismatched` | `GET /verifications/{id}/status` se llamó sin `linkId`, con uno que no corresponde a la verificación, o la verificación no existe. | Envía siempre el `linkId` que originó esa verificación. Es obligatorio desde la versión 2.2.0. |
| `subscription does not belong to caller` | `GET /billing/{idSubscription}` se llamó con una suscripción de otra compañía. | Consulta únicamente suscripciones de tu propia compañía. |

## Errores 404: Recurso no encontrado

| Escenario | Causa | Solución |
| - | - | - |
| `verification not found` | El `verificationId` no existe, expiró, o su Link ya no es válido. | Confirma el UUID y consulta `GET /verifications` para listar las disponibles. |
| `link not found` | El `linkId` no existe. | Revisa el UUID del enlace o lista todos con `GET /links`. |
| `user not found` | La cuenta asociada al token no existe. | Verifica que el token corresponda a una cuenta activa. |
| `customer not found` | La suscripción o el cliente de facturación consultado no existe. | Verifica el identificador de suscripción en Stripe. |
| `given resource is not implemented` | La solicitud no coincidió con ninguna ruta de la API. Este 404 se refiere a la ruta, no a un registro inexistente. El campo `resource` devuelve el path tal como llegó al servidor. | Verifica que la URL incluya el prefijo `/api/v1`: es la causa más común. Confirma también el path y el método HTTP contra la documentación. No hace falta habilitar nada en tu cuenta: todos los endpoints documentados están disponibles con la misma URL base. |

<Tip>
  Desde la versión 2.2.0, los endpoints `PATCH /verifications`, `PATCH /verifications/error` y `PATCH /verifications/identify` devuelven **404** cuando la verificación no existe o expiró. En versiones anteriores a 2.2.0, estos endpoints devolvían 200 sin realizar cambios.
</Tip>

<Tip>
  El 404 de ruta inexistente usa un cuerpo propio: no lleva `type` y expone `resource` con el path recibido.

  ```json theme={null}
  {"message": "given resource is not implemented", "resource": "/webhook-endpoints"}
  ```

  La causa más común es perder `/api/v1` al unir el path con una URL base:

  ```js theme={null}
  new URL('/webhook-endpoints', 'https://api.identity.vu-one.com/api/v1')
  // → https://api.identity.vu-one.com/webhook-endpoints
  new URL('webhook-endpoints', 'https://api.identity.vu-one.com/api/v1')
  // → https://api.identity.vu-one.com/api/webhook-endpoints
  ```

  Termina la URL base en `/` y escribe el path sin `/` inicial, o usa la URL completa.
</Tip>

## Errores 409: Conflicto de estado

| Escenario | Causa | Solución |
| - | - | - |
| `link already used` | El enlace fue consumido previamente por otro usuario. | Crea un nuevo enlace con `POST /links`. |
| `link expired` | El enlace superó el tiempo de expiración configurado en la compañía. | Genera un nuevo enlace o aumenta `linkConfig.expirationTime` en `PATCH /users/me/company`. |
| `verification status does not allow operation` | Se intentó modificar una verificación que ya está en estado `success` o `failed`. | No envíes actualizaciones una vez que la verificación finalizó. |
| `identifierAlreadyBound` | `PATCH /verifications/identify` recibió un email distinto para un Link cuyo `externalUserId` lo fijó la API al crearlo. | Un identificador aportado por la API no se puede sobrescribir. Crea un nuevo Link con el identificador correcto. |

<Tip>
  Desde la versión 2.2.0, `PATCH /verifications` y `PATCH /verifications/error` devuelven **409** cuando el estado de la verificación no permite la operación. En versiones anteriores a 2.2.0, estos endpoints devolvían 200 sin realizar cambios.
</Tip>

## Errores 410: Recurso ya no disponible

| Escenario | Causa | Solución |
| - | - | - |
| `verification expired` | La verificación superó su tiempo de vida máximo. | Crea un nuevo enlace y reinicia el flujo de verificación. |

## Errores 422: Entidad no procesable

| Escenario | Causa | Solución |
| - | - | - |
| `max verifications reached` | Se consumió la cuota mensual de verificaciones. | Consulta `GET /users/me/stats` para verificar el consumo o contacta a soporte para aumentar el límite. |

## Errores 429: Demasiadas solicitudes

| Escenario | Causa | Solución |
| - | - | - |
| `too many requests` | Se superó el límite de tasa. Aplica, entre otros, a `POST /vuone/contact-request`. | Implementa backoff exponencial y respeta el encabezado `Retry-After` si está presente. |

## Errores 500: Error interno del servidor

| Escenario | Causa | Solución |
| - | - | - |
| `internal server error` | Problema transitorio en la infraestructura de VU. | Reintenta la solicitud con backoff exponencial. Si persiste, contacta a soporte. |

## Errores 501: No implementado

| Escenario | Causa | Solución |
| - | - | - |
| `grant_type not supported` | Se envió un `grant_type` distinto de `client_credentials`. | Usa únicamente `client_credentials` en la autenticación OAuth2. |

## Errores 503: Servicio no disponible

| Escenario | Causa | Solución |
| - | - | - |
| `service unavailable` | El servicio está en mantenimiento o experimenta degradación. | Consulta `GET /health/status` para verificar el estado del servicio y reintenta más tarde. |

## Recomendaciones generales

<Steps>
  <Step title="Reintenta con backoff exponencial">
    Para errores 429, 500 y 503, espera 1 segundo antes del primer reintento, luego 2, 4, 8 segundos, hasta un máximo de 5 intentos.
  </Step>

  <Step title="No reintentes errores de cliente">
    Los códigos 400, 401, 403, 404, 409 y 422 indican un problema en la solicitud. Reintentarlos sin cambios produce el mismo resultado.
  </Step>

  <Step title="Valida el cuerpo antes de enviar">
    Usa un validador JSON Schema para asegurarte de que todos los campos obligatorios están presentes y tienen el tipo correcto.
  </Step>

  <Step title="Almacena tokens en caché">
    El `access_token` dura 3600 segundos. No solicites un token nuevo en cada llamada: reutilízalo hasta que expire para evitar 401 innecesarios.
  </Step>

  <Step title="Monitorea el estado del servicio">
    Implementa una verificación periódica de `GET /health/status` para detectar degradaciones antes de que afecten a tus usuarios.
  </Step>
</Steps>


## Related topics

- [Changelog de Identity Link API](/identity-link/changelog.md)
- [Identity Link API: guía de integración completa](/identity-link/introduccion.md)
- [Leer la respuesta](/vucs/antispoofing-facial/respuestas.md)
- [Interpretación de respuestas](/vucs/face-analysis/respuestas.md)


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