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

# Reintentos y errores

> Diseña consumidores de webhooks idempotentes y tolerantes a fallos.

Un webhook cruza dos sistemas. Debes asumir que puede haber reintentos, entregas duplicadas, caídas temporales o respuestas tardías.

## Respuestas esperadas

| Respuesta del receptor   | Resultado recomendado                                                       |
| ------------------------ | --------------------------------------------------------------------------- |
| `2xx`                    | Evento aceptado. Bold puede marcar la entrega como correcta.                |
| `4xx`                    | Error del consumidor o datos no aceptados. Revisa configuración y contrato. |
| `5xx`                    | Error temporal del receptor. El evento debe poder reintentarse.             |
| Tiempo de espera agotado | El receptor no respondió a tiempo. Procesa con cola y responde rápido.      |

<Warning>
  No devuelvas `2xx` si descartaste el evento sin guardarlo. Bold asumirá que la entrega fue correcta.
</Warning>

## Intentos automáticos

Bold intenta enviar una notificación hasta cinco veces. Después de cada fallo, programa el siguiente intento con espera exponencial.

| Dato                              | Comportamiento                                                                               |
| --------------------------------- | -------------------------------------------------------------------------------------------- |
| Tiempo máximo de envío            | 30 segundos.                                                                                 |
| Intentos máximos                  | 5 intentos automáticos.                                                                      |
| Espera automática                 | `10 * 2^n` segundos, donde `n` es el número de intentos realizados.                          |
| Estado final tras agotar intentos | `Failure`.                                                                                   |
| Reintento manual                  | Solo para notificaciones en `Failure`, mediante `POST /v1/notifications/webhook/{id}/retry`. |

Cada intento guarda código HTTP, cuerpo de respuesta o mensaje de error. Consulta `GET /v1/notifications/webhook/{id}/attempts` para diagnosticarlo.

| Intento fallido | Siguiente intento aproximado         |
| --------------- | ------------------------------------ |
| 1               | 20 segundos después.                 |
| 2               | 40 segundos después.                 |
| 3               | 80 segundos después.                 |
| 4               | 160 segundos después.                |
| 5               | No hay siguiente intento automático. |

Cuando solicitas un reintento manual, la notificación vuelve a `Pending` y se programa para envío inmediato.

## Reglas para consumidores

* Procesa cada evento de forma idempotente.
* Guarda `eventId` para deduplicar el evento de negocio.
* Guarda `attemptId` si necesitas auditar cada entrega.
* No dependas del orden estricto entre eventos.
* Consulta la API si necesitas confirmar el estado final.
* Registra los datos originales para auditoría y depuración.
* Verifica `X-HMAC-Signature` antes de confiar en los datos.

## Patrón recomendado

<Steps>
  <Step title="Valida los datos enviados">
    Comprueba que `eventName`, `majorVersion`, `minorVersion` y el identificador de entidad son los esperados.
  </Step>

  <Step title="Detecta duplicados">
    Si ya procesaste el evento, devuelve `2xx` y no repitas efectos externos.
  </Step>

  <Step title="Encola el trabajo">
    Guarda el evento en tu sistema y responde rápido.
  </Step>

  <Step title="Procesa en segundo plano">
    Ejecuta llamadas a sistemas de gestión, herramientas de análisis u otros servicios fuera del tiempo de respuesta HTTP.
  </Step>
</Steps>

```pseudo theme={null}
if already_processed(event.eventId):
  return 200

store(event)
enqueue(event.eventId)
return 202
```

<Tip>
  Si tu integración queda desincronizada, usa la API paginada para reconciliar el estado y después reactiva el procesamiento normal de webhooks.
</Tip>
