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

# Errores

> Códigos de error que puede devolver el gateway y cómo manejarlos.

Todas las respuestas de error siguen el mismo formato JSON:

```json theme={null}
{
  "error": "CODIGO_MAYUSCULAS",
  "message": "Detalle legible",
  "details": { /* opcional, contexto extra */ }
}
```

## Códigos

| HTTP  | `error`            | Causa                                                             | Acción del cliente                                         |
| ----- | ------------------ | ----------------------------------------------------------------- | ---------------------------------------------------------- |
| `400` | `BAD_REQUEST`      | Body inválido / falta campo requerido                             | Corregir payload                                           |
| `400` | `INFERENCE_FAILED` | El gateway no pudo deducir emisor/receptor en un endpoint `_auto` | Reintentar con la versión sin `_auto` y `emisor` explícito |
| `401` | `NO_API_KEY`       | Falta el header `x-api-key`                                       | Agregarlo                                                  |
| `401` | `INVALID_API_KEY`  | Key revocada, mal formada o secreto incorrecto                    | Generar una nueva                                          |
| `401` | `UNAUTHORIZED`     | Sesión Supabase ausente/expirada (rutas de gestión)               | Volver a iniciar sesión                                    |
| `402` | `QUOTA_EXCEEDED`   | Cuota mensual del usuario agotada                                 | Upgrade de plan; **no reintentar**                         |
| `404` | `NOT_FOUND`        | Banxico no devolvió un CEP con esos parámetros                    | Revisar `fecha`, `monto`, `clave_rastreo`                  |
| `429` | `RATE_LIMITED`     | Excediste `per_minute` de la key                                  | Backoff con jitter y reintentar                            |
| `500` | `INTERNAL_ERROR`   | Falla interna no clasificada                                      | Reintentar 1 vez; reportar a soporte si persiste           |
| `502` | `UPSTREAM_ERROR`   | El backend de Banxico devolvió un error transitorio               | El gateway ya hace un reintento; si persiste, esperar      |

## Patrón de manejo recomendado

```typescript theme={null}
async function downloadCep(req: CepReq) {
  const res = await fetch("/api/v1/cep/xml_auto", {
    method: "POST",
    headers: { "x-api-key": process.env.VERIPAY_KEY!, "content-type": "application/json" },
    body: JSON.stringify(req),
  });

  if (res.ok) return Buffer.from(await res.arrayBuffer());

  const err = await res.json();
  switch (err.error) {
    case "RATE_LIMITED":
      await sleep(300 + Math.random() * 500);
      return downloadCep(req);
    case "QUOTA_EXCEEDED":
      throw new UpgradeRequiredError();
    case "INFERENCE_FAILED":
      return downloadCepExplicit(req);
    case "NOT_FOUND":
      return null;
    default:
      throw new Error(`${err.error}: ${err.message}`);
  }
}
```

<Warning>
  Nunca reintentes un `402` ni un `400` — el resultado no cambiará y consumirás cuota de error logging.
</Warning>
