> ## 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.

# Error Handling & Response Codes

> Comprehensive guide for handling API errors and response codes

## Introduction

This guide covers all possible response codes, error formats, and best practices for handling errors when integrating with the Lovi API.

## 📊 HTTP Status Codes

### Successful Responses

#### 200 OK - Request Successful

**Notification Processed:**

```json theme={null}
{
  "success": true,
  "message": "Notification queued successfully",
  "notification_id": "uuid-notification-123",
  "scheduled_time": "2024-12-25T10:30:00Z"
}
```

**Templates Retrieved:**

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

**Template Created:**

```json theme={null}
{
  "success": true,
  "message": "Template created successfully",
  "template": {
    "id": "new_template_123",
    "name": "order_confirmation",
    "status": "pending"
  }
}
```

***

### Client Error Responses (4xx)

#### 400 Bad Request - Invalid Parameters

**Missing Required Field:**

```json theme={null}
{
  "error": "validation_failed",
  "message": "Required field missing",
  "details": {
    "field": "contact.number",
    "reason": "This field is required"
  },
  "request_id": "req_123456789"
}
```

**Invalid Parameter Format:**

```json theme={null}
{
  "error": "validation_failed",
  "message": "Invalid parameter format",
  "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"
}
```

**Invalid Phone Number:**

```json theme={null}
{
  "error": "validation_failed",
  "message": "Invalid phone number format",
  "details": {
    "field": "contact.number",
    "provided": "+34-666-033-135",
    "expected_format": "Numbers only, no + or spaces",
    "example": "34666033135"
  },
  "request_id": "req_123456791"
}
```

**Past Scheduled Time:**

```json theme={null}
{
  "error": "validation_failed",
  "message": "Scheduled time must be in the future",
  "details": {
    "field": "datetime_sending",
    "provided": "2024-12-20T10:00:00",
    "current_time": "2024-12-20T15:30:00Z"
  },
  "request_id": "req_123456792"
}
```

#### 401 Unauthorized - Authentication Failed

**Invalid Access Key:**

```json theme={null}
{
  "error": "unauthorized",
  "message": "Invalid or expired access key",
  "details": {
    "reason": "The provided access_key is not valid or has been revoked"
  },
  "request_id": "req_123456793"
}
```

**Missing Access Key:**

```json theme={null}
{
  "error": "unauthorized",
  "message": "Missing access key",
  "details": {
    "reason": "access_key parameter is required in the URL"
  },
  "request_id": "req_123456794"
}
```

#### 403 Forbidden - Access Denied

**Insufficient Permissions:**

```json theme={null}
{
  "error": "forbidden",
  "message": "Insufficient permissions for this resource",
  "details": {
    "reason": "Your API key does not have permission to create templates"
  },
  "request_id": "req_123456795"
}
```

**Company Access Denied:**

```json theme={null}
{
  "error": "forbidden",
  "message": "Access denied to company resources",
  "details": {
    "reason": "API key is not associated with the requested company"
  },
  "request_id": "req_123456796"
}
```

#### 404 Not Found - Resource Not Found

**Template Not Found:**

```json theme={null}
{
  "error": "template_not_found",
  "message": "Template 'welcome_user' not found or not approved",
  "details": {
    "template_name": "welcome_user",
    "language": "es_ES",
    "suggestion": "Check template name and approval status"
  },
  "request_id": "req_123456797"
}
```

**Agent Not Found:**

```json theme={null}
{
  "error": "agent_not_found",
  "message": "Voice agent not found",
  "details": {
    "agent_id": "uuid-invalid-agent",
    "suggestion": "Verify agent_id exists and is active"
  },
  "request_id": "req_123456798"
}
```

#### 422 Unprocessable Entity - Business Logic Error

**Template Not Approved:**

```json theme={null}
{
  "error": "template_not_approved",
  "message": "Template is not in approved status",
  "details": {
    "template_name": "pending_template",
    "current_status": "pending",
    "required_status": "approved"
  },
  "request_id": "req_123456799"
}
```

**Variable Mismatch:**

```json theme={null}
{
  "error": "variable_mismatch",
  "message": "Template variables don't match provided data",
  "details": {
    "template_variables": ["name", "course"],
    "provided_variables": ["name", "email"],
    "missing": ["course"],
    "unexpected": ["email"]
  },
  "request_id": "req_123456800"
}
```

#### 429 Too Many Requests - Rate Limit Exceeded

**Rate Limit Hit:**

```json theme={null}
{
  "error": "rate_limit_exceeded",
  "message": "Too many requests. Try again in 60 seconds",
  "details": {
    "limit": 100,
    "window": "1 hour",
    "reset_time": "2024-12-20T16:30:00Z"
  },
  "retry_after": 60,
  "request_id": "req_123456801"
}
```

**Daily Quota Exceeded:**

```json theme={null}
{
  "error": "quota_exceeded",
  "message": "Daily notification quota exceeded",
  "details": {
    "quota": 10000,
    "used": 10000,
    "reset_time": "2024-12-21T00:00:00Z"
  },
  "request_id": "req_123456802"
}
```

***

### Server Error Responses (5xx)

#### 500 Internal Server Error

**General Server Error:**

```json theme={null}
{
  "error": "internal_error",
  "message": "An unexpected error occurred",
  "details": {
    "reason": "Internal server error"
  },
  "request_id": "req_123456803"
}
```

#### 502 Bad Gateway

**Upstream Service Error:**

```json theme={null}
{
  "error": "service_unavailable",
  "message": "WhatsApp service temporarily unavailable",
  "details": {
    "service": "whatsapp_gateway",
    "estimated_recovery": "2024-12-20T16:00:00Z"
  },
  "request_id": "req_123456804"
}
```

#### 503 Service Unavailable

**Maintenance Mode:**

```json theme={null}
{
  "error": "service_unavailable",
  "message": "Service temporarily unavailable for maintenance",
  "details": {
    "maintenance_window": "2024-12-20T02:00:00Z to 2024-12-20T04:00:00Z"
  },
  "request_id": "req_123456805"
}
```

***

## 🔄 Retry Strategies

### Recommended Retry Logic

| Status Code     | Action                                | Retry Strategy            |
| --------------- | ------------------------------------- | ------------------------- |
| `400, 404, 422` | ❌ **Don't retry**                     | Fix request and try again |
| `401, 403`      | ❌ **Don't retry**                     | Refresh authentication    |
| `429`           | ⏰ **Retry with backoff**              | Use `retry_after` header  |
| `500, 502, 503` | 🔄 **Retry with exponential backoff** | Max 3 attempts            |

### Implementation Example

```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;
      }

      // Handle different error types
      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); // Exponential backoff
          continue;
        }
      }

      // Don't retry for 4xx errors (except 429)
      throw new APIError(result.error, result.message, response.status);

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

***

## 📝 Best Practices

### Error Logging

**Always log these fields:**

```javascript theme={null}
{
  "timestamp": "2024-12-20T15:30:00Z",
  "request_id": "req_123456789",
  "endpoint": "/notify",
  "method": "POST",
  "status_code": 400,
  "error_code": "validation_failed",
  "error_message": "Required field missing",
  "user_id": "user_123",
  "company_id": "company_456"
}
```

### Error Handling Checklist

✅ **Pre-request Validation**

* Validate phone number format
* Check required fields
* Validate datetime format
* Verify template exists

✅ **Request Monitoring**

* Log all API requests
* Include request\_id in logs
* Monitor response times
* Track error rates

✅ **Error Recovery**

* Implement appropriate retry logic
* Cache authentication tokens
* Handle rate limits gracefully
* Provide meaningful error messages to users

✅ **User Experience**

* Show user-friendly error messages
* Provide actionable feedback
* Don't expose internal error details
* Offer alternatives when possible

### Monitoring & Alerting

**Key Metrics to Monitor:**

* Error rate per endpoint
* Average response time
* Rate limit hits
* Authentication failures
* Template not found errors

**Alert Thresholds:**

* Error rate > 5%
* Response time > 2 seconds
* Rate limit hits > 10/hour
* Authentication failures > 20/hour

***

## 🛠️ Development Tools

### Error Testing

**Test different error scenarios:**

```bash theme={null}
# Missing access_key
curl -X POST https://cloud.lovi.ai/functions/v1/notify \
  -H "Content-Type: application/json" \
  -d '{"contact":{"number":"34666033135"}}'

# Invalid phone number
curl -X POST https://cloud.lovi.ai/functions/v1/notify?access_key=test \
  -H "Content-Type: application/json" \
  -d '{"contact":{"number":"+34-666-033-135"}}'

# Past datetime
curl -X POST https://cloud.lovi.ai/functions/v1/notify?access_key=test \
  -H "Content-Type: application/json" \
  -d '{"datetime_sending":"2020-01-01T10:00:00"}'
```

### Error Response Parser

```javascript theme={null}
class LoviAPIError extends Error {
  constructor(response) {
    super(response.message);
    this.name = 'LoviAPIError';
    this.code = response.error;
    this.statusCode = response.status;
    this.requestId = response.request_id;
    this.details = response.details;
  }

  isRetryable() {
    return [429, 500, 502, 503].includes(this.statusCode);
  }

  getRetryAfter() {
    return this.details?.retry_after || 60;
  }
}
```

***

## 🚨 Common Issues & Solutions

### Authentication Issues

**Problem**: `Invalid or expired access key`
**Solution**:

1. Check if access\_key is in URL parameters
2. Verify the key hasn't been revoked
3. Ensure you're using the correct company key

### Template Issues

**Problem**: `Template not found`
**Solutions**:

1. Verify template name spelling
2. Check template language matches
3. Ensure template is approved
4. Use GET /templates to list available templates

### Rate Limiting

**Problem**: `Too many requests`
**Solutions**:

1. Implement exponential backoff
2. Respect retry\_after headers
3. Batch requests when possible
4. Monitor usage patterns

### Data Validation

**Problem**: `Validation failed`
**Solutions**:

1. Validate data before sending
2. Use proper phone number format
3. Check datetime format
4. Verify required fields are present

Remember to always include the `request_id` when contacting support for faster resolution of issues.
