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

# Error Handling

> Understanding and handling API errors

## Error Response Format

All API errors follow a consistent format:

```json theme={null}
{
  "error": "Brief error description",
  "details": [
    {
      "code": "specific_error_code",
      "message": "Detailed error message",
      "field": "field_name" // Optional, for validation errors
    }
  ]
}
```

## HTTP Status Codes

| Status Code | Description                                          |
| ----------- | ---------------------------------------------------- |
| `200`       | Success                                              |
| `201`       | Created successfully                                 |
| `400`       | Bad Request - Invalid parameters                     |
| `401`       | Unauthorized - Invalid or missing API key            |
| `402`       | Payment Required - Insufficient credits              |
| `403`       | Forbidden - Pro plan required or unauthorized access |
| `404`       | Not Found - Resource doesn't exist                   |
| `409`       | Conflict - Resource already exists                   |
| `429`       | Too Many Requests - Rate limit exceeded              |
| `500`       | Internal Server Error                                |

## Common Error Codes

### Authentication Errors

<AccordionGroup>
  <Accordion title="invalid_api_key">
    **Status**: 401\
    **Cause**: API key is invalid, expired, or malformed\
    **Solution**: Check your API key format and regenerate if necessary
  </Accordion>

  <Accordion title="plan_required">
    **Status**: 403\
    **Cause**: Pro plan required for API access\
    **Solution**: Upgrade to Pro plan
  </Accordion>
</AccordionGroup>

### Rate Limiting Errors

<AccordionGroup>
  <Accordion title="rate_limit_exceeded">
    **Status**: 429\
    **Cause**: Too many requests in a short period\
    **Solution**: Implement exponential backoff and respect rate limits
  </Accordion>
</AccordionGroup>

### Validation Errors

<AccordionGroup>
  <Accordion title="missing_content">
    **Status**: 400\
    **Cause**: No prompt, script, voice\_url, or avatar\_url provided\
    **Solution**: Provide at least one content parameter
  </Accordion>

  <Accordion title="missing_voice">
    **Status**: 400\
    **Cause**: Script provided but no voice specified\
    **Solution**: Add voice\_id or voice\_url when using script
  </Accordion>

  <Accordion title="invalid_voice_id">
    **Status**: 400\
    **Cause**: Specified voice\_id not found\
    **Solution**: Use GET /voice/list to get valid voice IDs
  </Accordion>

  <Accordion title="invalid_avatar_id">
    **Status**: 400\
    **Cause**: Specified avatar\_id not found\
    **Solution**: Use GET /avatar/list to get valid avatar IDs
  </Accordion>

  <Accordion title="invalid_format">
    **Status**: 400\
    **Cause**: Invalid video format specified\
    **Solution**: Use 'vertical', 'square', or 'ads'
  </Accordion>
</AccordionGroup>

### Resource Errors

<AccordionGroup>
  <Accordion title="insufficient_credits">
    **Status**: 402\
    **Cause**: Not enough credits for the operation\
    **Solution**: Purchase more credits or reduce resource usage
  </Accordion>

  <Accordion title="job_not_found">
    **Status**: 404\
    **Cause**: Job ID doesn't exist\
    **Solution**: Verify the job\_id is correct
  </Accordion>

  <Accordion title="unauthorized_job">
    **Status**: 403\
    **Cause**: Job doesn't belong to your workspace\
    **Solution**: Only access jobs created by your API key
  </Accordion>

  <Accordion title="video_not_found">
    **Status**: 404\
    **Cause**: Video ID doesn't exist\
    **Solution**: Verify the video\_id is correct
  </Accordion>
</AccordionGroup>

## Error Handling Best Practices

### 1. Always Check Status Codes

```javascript theme={null}
const response = await fetch('https://app.hoox.video/api/public/v1/generation/start', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer hx_live_your_api_key_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(requestData)
});

if (!response.ok) {
  const error = await response.json();
  console.error('API Error:', error);
  
  // Handle specific error codes
  if (error.details?.[0]?.code === 'insufficient_credits') {
    // Redirect to billing page
  } else if (error.details?.[0]?.code === 'rate_limit_exceeded') {
    // Implement retry with backoff
  }
  
  throw new Error(`API Error: ${error.error}`);
}
```

### 2. Implement Retry Logic

```javascript theme={null}
async function callApiWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);
      
      if (response.status === 429) {
        // Rate limited - wait before retry
        const resetTime = response.headers.get('X-RateLimit-Reset');
        const waitTime = resetTime ? (parseInt(resetTime) * 1000) - Date.now() : 1000 * attempt;
        
        if (attempt < maxRetries) {
          await new Promise(resolve => setTimeout(resolve, Math.max(waitTime, 0)));
          continue;
        }
      }
      
      if (!response.ok) {
        const error = await response.json();
        throw new Error(`API Error: ${error.error}`);
      }
      
      return response;
    } catch (error) {
      if (attempt === maxRetries) throw error;
      
      // Exponential backoff for other errors
      await new Promise(resolve => 
        setTimeout(resolve, 1000 * Math.pow(2, attempt - 1))
      );
    }
  }
}
```

### 3. Handle Validation Errors

```javascript theme={null}
function handleValidationErrors(errorResponse) {
  const errors = errorResponse.details || [];
  const fieldErrors = {};
  
  errors.forEach(error => {
    if (error.field) {
      fieldErrors[error.field] = error.message;
    }
  });
  
  return fieldErrors;
}

// Usage
try {
  const response = await fetch(apiUrl, options);
  if (!response.ok) {
    const error = await response.json();
    
    if (response.status === 400) {
      const fieldErrors = handleValidationErrors(error);
      // Update UI to show field-specific errors
      console.log('Validation errors:', fieldErrors);
    }
  }
} catch (error) {
  console.error('Request failed:', error);
}
```

### 4. Monitor Rate Limits

```javascript theme={null}
function checkRateLimits(response) {
  const limit = response.headers.get('X-RateLimit-Limit');
  const remaining = response.headers.get('X-RateLimit-Remaining');
  const reset = response.headers.get('X-RateLimit-Reset');
  
  console.log(`Rate limit: ${remaining}/${limit}, resets at ${new Date(reset * 1000)}`);
  
  // Warn when approaching limit
  if (parseInt(remaining) < 10) {
    console.warn('Approaching rate limit!');
  }
}
```

## Webhook Error Handling

When using webhooks, you may receive error notifications:

```json theme={null}
{
  "job_id": "run_01234567890abcdef",
  "status": "failed",
  "error": {
    "code": "generation_failed",
    "message": "Video generation failed due to insufficient credits"
  }
}
```

Handle webhook errors in your endpoint:

```javascript theme={null}
app.post('/webhook/hoox', (req, res) => {
  const { job_id, status, error, result } = req.body;
  
  if (status === 'failed') {
    console.error(`Job ${job_id} failed:`, error);
    
    // Handle specific error codes
    switch (error.code) {
      case 'insufficient_credits':
        // Notify user about credit shortage
        break;
      case 'generation_failed':
        // Log for investigation
        break;
      default:
        // Generic error handling
    }
  } else if (status === 'completed') {
    // Handle successful completion
    console.log(`Job ${job_id} completed:`, result);
  }
  
  res.status(200).send('OK');
});
```

<Tip>
  Always implement proper error handling and logging in production applications to diagnose issues quickly.
</Tip>
