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

# Manejo de errores

> Estructura uniforme de errores de la Facade API y catálogo de códigos.

Todos los errores de la Facade API tienen la **misma forma**, sin importar el recurso o el endpoint. Esto hace que tu integración sea predecible: parseas la respuesta de error una sola vez y la reutilizas en toda la API.

## Estructura uniforme

```json theme={null}
{
  "error": {
    "code": "INVALID_REQUEST",
    "message": "Validation failed: amount must be a positive amount in pesos (e.g. 1500.50).",
    "details": [
      { "field": "amount", "issue": "amount must be a positive amount in pesos (e.g. 1500.50)." }
    ]
  },
  "requestId": "req_3f8a1c9e2b"
}
```

<ResponseField name="error.code" type="string">
  Código estable y legible por máquina. Úsalo para ramificar tu lógica de manejo de errores (no parsees el `message`).
</ResponseField>

<ResponseField name="error.message" type="string">
  Mensaje legible para personas. Puede cambiar con el tiempo: no lo uses para tomar decisiones en tu código.
</ResponseField>

<ResponseField name="error.details" type="array">
  Presente en errores de validación. Lista de `{ field, issue }` que indica qué campo falló y por qué.
</ResponseField>

<ResponseField name="requestId" type="string">
  Identificador único de la petición. Compártelo con soporte para rastrear exactamente qué pasó.
</ResponseField>

## Catálogo de códigos

| HTTP  | Código                    | Cuándo ocurre                                                                                                                                                                             |
| ----- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400` | `INVALID_REQUEST`         | El payload no pasó la validación: campo faltante o inválido, `autopay` junto con `paymentMethods`, fecha mal formada, etc.                                                                |
| `401` | `AUTHENTICATION_FAILED`   | El Token TAPI falta, es inválido o está vencido. Ver [Autenticación](/es/authentication).                                                                                                 |
| `404` | `RESOURCE_NOT_FOUND`      | El recurso referenciado (deuda, producto, contacto, ruta) no existe.                                                                                                                      |
| `409` | `RESOURCE_CONFLICT`       | La llave externa ya existe: `Idempotency-Key`/`externalRequestId` repetido, `externalSubscriptionId` o `externalPaymentLinkId` duplicado. Ver [Idempotencia](/es/conceptos/idempotencia). |
| `422` | `RESOLUTION_ERROR`        | TapiPay no pudo resolver tu configuración interna (organización o modalidades). Es un problema de configuración del lado del sistema, no de tu request.                                   |
| `422` | `BUSINESS_RULE_VIOLATION` | La acción no está permitida por el estado del recurso o una regla de negocio: actualizar una deuda que no está en `PENDING`, cancelar una deuda ya pagada, pagar una liga expirada, etc.  |
| `429` | `RATE_LIMITED`            | Demasiadas peticiones en poco tiempo. Reintenta con backoff.                                                                                                                              |
| `500` | `INTERNAL_ERROR`          | Falla inesperada del servidor. No imputable a tu request.                                                                                                                                 |
| `502` | `SQS_PUBLISH_ERROR`       | Falla temporal al encolar el procesamiento interno de un cobro. Reintenta con tu `Idempotency-Key` para no duplicar.                                                                      |

<Note>
  `RESOLUTION_ERROR` indica que la organización asociada a tu token no está bien configurada en el sistema (por ejemplo, le faltan modalidades activas). Si lo ves de forma persistente, contacta a soporte con el `requestId`.
</Note>

<Note>
  El `401` puede llegar en dos formas. Si la falla ocurre en el API Gateway (falta la `x-api-key` o el token, o son inválidos), la respuesta es `{"message":"Unauthorized"}`, sin el objeto `error`. Si la petición pasa el gateway pero la Facade rechaza la autenticación, usa la forma estándar con `error.code: AUTHENTICATION_FAILED`.
</Note>

## Recomendaciones

<CardGroup cols={2}>
  <Card title="Rama por code" icon="code-branch">
    Decide tu lógica con `error.code`, nunca con el texto de `message`.
  </Card>

  <Card title="Guarda el requestId" icon="bookmark">
    Registra el `requestId` en tus logs: es la forma más rápida de que soporte rastree una petición.
  </Card>

  <Card title="Reintenta con idempotencia" icon="rotate">
    Ante `429`, `500` o `502`, reintenta con la misma `Idempotency-Key` para evitar duplicados.
  </Card>

  <Card title="Valida antes de enviar" icon="circle-check">
    Usa `error.details` para mostrar a tus usuarios qué campo corregir en errores `400`.
  </Card>
</CardGroup>
