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

# Errores

> Catálogo cerrado de códigos de error: estado HTTP, causa y cómo corregirlo.

Todas las respuestas 4xx y 5xx tienen el mismo cuerpo:

```json theme={null}
{
  "codigo": "esquema_invalido",
  "mensaje": "extra.margen es obligatorio en COMPRA_CAT",
  "campo": "eventos.0.extra.margen",
  "trace_id": "tr_8f2a"
}
```

`campo` es la ruta del campo que falla (`eventos.0.extra.margen`) cuando aplica;
`trace_id` sirve para citar el caso al operador. Nunca se revelan detalles internos.

| código                    | HTTP | causa                                                                                                              | corrección                                                                                      |
| ------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- |
| `esquema_invalido`        | 422  | Un campo no cumple el contrato (tipo, rango, formato o campo obligatorio ausente).                                 | Corrige el campo que indica `campo`; el validador del lado del CRM lo detecta antes de enviar.  |
| `campo_desconocido`       | 422  | El cuerpo trae un campo que el contrato no define.                                                                 | Elimínalo. Los atributos propios de cada tipo de evento van dentro de `extra`.                  |
| `ts_fuera_de_rango`       | 422  | La fecha está en el futuro (más de 5 minutos) o es más antigua que la antigüedad máxima del inquilino.             | Revisa la zona horaria del conector: `ts` debe ser el momento del evento, en UTC.               |
| `duplicado`               | 200  | El `event_id` ya se recibió. No es un error: el evento se descarta y se cuenta en `duplicados`.                    | Nada. Reenviar un lote es seguro.                                                               |
| `no_autenticado`          | 401  | Falta el token, está caducado o la firma no es válida.                                                             | Pide un token nuevo con las credenciales del sistema (duran 15 minutos).                        |
| `sin_permiso`             | 403  | La credencial no tiene el ámbito necesario, la IP no está en la lista permitida o el recurso es de otro inquilino. | Pide al operador el ámbito que falta. La respuesta es la misma para «no existe» y «no es tuyo». |
| `no_encontrado`           | 404  | El `decision_id` o el `cliente_ref` no existe (o no pertenece a esta credencial).                                  | Comprueba el identificador; para decisiones, que no hayan pasado más de 7 días.                 |
| `limite_excedido`         | 429  | Se superó el límite de ritmo o la cuota del inquilino.                                                             | Espera el tiempo de `Retry-After` y reintenta con espera exponencial; el SDK lo hace solo.      |
| `idempotencia_conflicto`  | 422  | La misma `Idempotency-Key` se reutilizó con un cuerpo distinto en las últimas 24 horas.                            | Usa una clave nueva por petición distinta; repite la misma clave solo para reintentar la misma. |
| `decision_caducada`       | 409  | Se intentó confirmar la ejecución después de `caduca_en`.                                                          | Confirma la ejecución en cuanto apliques la decisión; si caducó, pide una decisión nueva.       |
| `ejecucion_ya_confirmada` | 409  | La decisión ya tiene una confirmación de ejecución.                                                                | Solo se admite una confirmación por decisión. Si fue un error, avisa al operador.               |
| `inquilino_pausado`       | 503  | El operador pausó las decisiones de este inquilino.                                                                | Aplica tu regla de respaldo y regístrala como decisión de respaldo; el SDK lo hace solo.        |
| `error_interno`           | 500  | Fallo interno del motor. La respuesta nunca incluye detalles internos.                                             | Reintenta; si persiste, cita `trace_id` al operador.                                            |
