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

# Manejo de Errores y Códigos de Respuesta

> Guía completa para manejar errores de la API y códigos de respuesta

## Introducción

Esta guía cubre todos los posibles códigos de respuesta, formatos de error y mejores prácticas para manejar errores al integrar con la API de Lovi.

## 📊 Códigos de Estado HTTP

### Respuestas Exitosas

#### 200 OK - Solicitud Exitosa

**Notificación Procesada:**

```json theme={null}
{
  "success": true,
  "message": "Notificación puesta en cola correctamente",
  "notification_id": "uuid-notificacion-123",
  "scheduled_time": "2024-12-25T10:30:00Z"
}
```

**Plantillas Recuperadas:**

```json theme={null}
{
  "templates": [
    {
      "id": "template_001",
      "name": "welcome_user",
      "status": "approved"
    }
  ],
  "total": 1
}
```

**Plantilla Creada:**

```json theme={null}
{
  "success": true,
  "message": "Plantilla creada correctamente",
  "template": {
    "id": "new_template_123",
    "name": "order_confirmation",
    "status": "pending"
  }
}
```

***

### Respuestas de Error del Cliente (4xx)

#### 400 Bad Request - Parámetros Inválidos

**Campo Requerido Faltante:**

```json theme={null}
{
  "error": "validation_failed",
  "message": "Campo requerido faltante",
  "details": {
    "field": "contact.number",
    "reason": "Este campo es requerido"
  },
  "request_id": "req_123456789"
}
```

**Formato de Parámetro Inválido:**

```json theme={null}
{
  "error": "validation_failed",
  "message": "Formato de parámetro inválido",
  "details": {
    "field": "datetime_sending",
    "provided": "25-12-2024",
    "expected_format": "ISO 8601 (YYYY-MM-DDTHH:MM:SS)",
    "example": "2024-12-25T10:30:00"
  },
  "request_id": "req_123456790"
}
```

**Número de Teléfono Inválido:**

```json theme={null}
{
  "error": "validation_failed",
  "message": "Formato de número de teléfono inválido",
  "details": {
    "field": "contact.number",
    "provided": "+34-666-033-135",
    "expected_format": "Solo números, sin + ni espacios",
    "example": "34666033135"
  },
  "request_id": "req_123456791"
}
```

**Hora Programada en el Pasado:**

```json theme={null}
{
  "error": "validation_failed",
  "message": "La hora programada debe ser en el futuro",
  "details": {
    "field": "datetime_sending",
    "provided": "2024-12-20T10:00:00",
    "current_time": "2024-12-20T15:30:00Z"
  },
  "request_id": "req_123456792"
}
```

#### 401 Unauthorized - Autenticación Fallida

**Clave de Acceso Inválida:**

```json theme={null}
{
  "error": "unauthorized",
  "message": "Clave de acceso inválida o expirada",
  "details": {
    "reason": "La access_key proporcionada no es válida o ha sido revocada"
  },
  "request_id": "req_123456793"
}
```

**Clave de Acceso Faltante:**

```json theme={null}
{
  "error": "unauthorized",
  "message": "Clave de acceso faltante",
  "details": {
    "reason": "El parámetro access_key es requerido en la URL"
  },
  "request_id": "req_123456794"
}
```

#### 403 Forbidden - Acceso Denegado

**Permisos Insuficientes:**

```json theme={null}
{
  "error": "forbidden",
  "message": "Permisos insuficientes para este recurso",
  "details": {
    "reason": "Tu clave API no tiene permiso para crear plantillas"
  },
  "request_id": "req_123456795"
}
```

#### 404 Not Found - Recurso No Encontrado

**Plantilla No Encontrada:**

```json theme={null}
{
  "error": "template_not_found",
  "message": "Plantilla 'welcome_user' no encontrada o no aprobada",
  "details": {
    "template_name": "welcome_user",
    "language": "es_ES",
    "suggestion": "Verifica el nombre de la plantilla y su estado de aprobación"
  },
  "request_id": "req_123456797"
}
```

#### 422 Unprocessable Entity - Error de Lógica de Negocio

**Plantilla No Aprobada:**

```json theme={null}
{
  "error": "template_not_approved",
  "message": "La plantilla no está en estado aprobado",
  "details": {
    "template_name": "pending_template",
    "current_status": "pending",
    "required_status": "approved"
  },
  "request_id": "req_123456799"
}
```

#### 429 Too Many Requests - Límite de Tasa Excedido

**Límite de Tasa Alcanzado:**

```json theme={null}
{
  "error": "rate_limit_exceeded",
  "message": "Demasiadas solicitudes. Inténtalo de nuevo en 60 segundos",
  "details": {
    "limit": 100,
    "window": "1 hora",
    "reset_time": "2024-12-20T16:30:00Z"
  },
  "retry_after": 60,
  "request_id": "req_123456801"
}
```

***

### Respuestas de Error del Servidor (5xx)

#### 500 Internal Server Error

```json theme={null}
{
  "error": "internal_error",
  "message": "Ocurrió un error inesperado",
  "details": {
    "reason": "Error interno del servidor"
  },
  "request_id": "req_123456803"
}
```

#### 503 Service Unavailable

```json theme={null}
{
  "error": "service_unavailable",
  "message": "Servicio temporalmente no disponible por mantenimiento",
  "details": {
    "maintenance_window": "2024-12-20T02:00:00Z to 2024-12-20T04:00:00Z"
  },
  "request_id": "req_123456805"
}
```

***

## 🔄 Estrategias de Reintento

### Lógica de Reintento Recomendada

| Código de Estado | Acción                                    | Estrategia de Reintento                   |
| ---------------- | ----------------------------------------- | ----------------------------------------- |
| `400, 404, 422`  | ❌ **No reintentar**                       | Corregir la solicitud e intentar de nuevo |
| `401, 403`       | ❌ **No reintentar**                       | Actualizar la autenticación               |
| `429`            | ⏰ **Reintentar con espera**               | Usar el encabezado `retry_after`          |
| `500, 502, 503`  | 🔄 **Reintentar con backoff exponencial** | Máximo 3 intentos                         |

### Ejemplo de Implementación

```javascript theme={null}
async function makeAPIRequest(url, data, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
      });

      const result = await response.json();

      if (response.ok) {
        return result;
      }

      if (response.status === 429) {
        const retryAfter = result.retry_after || 60;
        await sleep(retryAfter * 1000);
        continue;
      }

      if ([500, 502, 503].includes(response.status)) {
        if (attempt < maxRetries) {
          await sleep(Math.pow(2, attempt) * 1000);
          continue;
        }
      }

      throw new APIError(result.error, result.message, response.status);

    } catch (error) {
      if (attempt === maxRetries) throw error;
      await sleep(Math.pow(2, attempt) * 1000);
    }
  }
}
```

***

## 📝 Mejores Prácticas

### Lista de Verificación para el Manejo de Errores

✅ **Validación Previa a la Solicitud**

* Validar formato del número de teléfono
* Verificar campos requeridos
* Validar formato de fecha y hora
* Verificar que la plantilla existe

✅ **Monitorización de Solicitudes**

* Registrar todas las solicitudes a la API
* Incluir request\_id en los registros
* Monitorizar tiempos de respuesta
* Rastrear tasas de error

✅ **Recuperación de Errores**

* Implementar lógica de reintento apropiada
* Almacenar tokens de autenticación en caché
* Manejar los límites de tasa con elegancia
* Proporcionar mensajes de error significativos a los usuarios

### Métricas Clave a Monitorizar

* Tasa de error por endpoint
* Tiempo de respuesta promedio
* Alcances del límite de tasa
* Fallos de autenticación
* Errores de plantilla no encontrada

Recuerda incluir siempre el `request_id` al contactar con soporte para una resolución más rápida de los problemas.
