> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/lumina-ai-inc/chunkr/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Handling

> Understanding error responses and status codes in the Chunkr API

The Chunkr API uses conventional HTTP status codes to indicate the success or failure of requests. Error responses include descriptive messages to help you understand and resolve issues.

## HTTP Status Codes

### Success Codes

| Status Code | Description       |
| ----------- | ----------------- |
| `200 OK`    | Request succeeded |

### Client Error Codes

| Status Code             | Description                                     |
| ----------------------- | ----------------------------------------------- |
| `400 Bad Request`       | Invalid request parameters or malformed request |
| `401 Unauthorized`      | Authentication failed or missing credentials    |
| `404 Not Found`         | Requested resource does not exist               |
| `429 Too Many Requests` | Rate limit exceeded                             |

### Server Error Codes

| Status Code                 | Description                     |
| --------------------------- | ------------------------------- |
| `500 Internal Server Error` | An error occurred on the server |

## Error Response Format

Error responses return a plain text message in the response body describing the error:

```
Error message text
```

For structured error handling, check both the HTTP status code and the response body message.

## Common Errors

### Authentication Errors (401)

#### Missing Authorization Header

```bash theme={null}
GET /api/v1/task/{task_id}
# Status: 401 Unauthorized
# Response: "Authorization header is missing"
```

**Cause**: The `Authorization` header is not included in the request.

**Solution**: Add the `Authorization` header with your API key:

```bash theme={null}
curl -H "Authorization: YOUR_API_KEY" \
  https://api.chunkr.ai/api/v1/task/{task_id}
```

#### Invalid or Inactive API Key

```bash theme={null}
# Status: 401 Unauthorized
# Response: "Invalid or inactive API key"
```

**Cause**: The API key is incorrect, has been revoked, or marked as inactive.

**Solution**:

* Verify your API key is correct
* Generate a new API key from your dashboard
* Ensure the key hasn't been deactivated

#### Invalid Token Payload

```bash theme={null}
# Status: 401 Unauthorized  
# Response: "Invalid token payload"
```

**Cause**: The Bearer token is malformed, expired, or has an invalid signature.

**Solution**:

* Refresh your OAuth token
* Verify the token is properly formatted
* Check that the token hasn't expired

### Validation Errors (400)

#### Invalid Base64 Data

```bash theme={null}
POST /api/v1/task/parse
# Status: 400 Bad Request
# Response: "Invalid base64 data"
```

**Cause**: The file data provided is not valid base64-encoded content.

**Solution**: Ensure your file is properly base64-encoded:

```python theme={null}
import base64

with open('document.pdf', 'rb') as f:
    file_data = base64.b64encode(f.read()).decode('utf-8')
```

#### Unsupported File Type

```bash theme={null}
POST /api/v1/task/parse
# Status: 400 Bad Request
# Response: "Unsupported file type"
```

**Cause**: The file type is not supported by Chunkr.

**Solution**: Use a supported document format (PDF, images, etc.).

#### File Must Have a Filename

```bash theme={null}
POST /api/v1/task
# Status: 400 Bad Request
# Response: "File must have a filename"
```

**Cause**: When using multipart form upload, the file field is missing a filename.

**Solution**: Ensure your multipart request includes a filename for the file field.

#### Task Cannot Be Updated

```bash theme={null}
PATCH /api/v1/task/{task_id}/parse
# Status: 400 Bad Request
# Response: "Task cannot be updated: status is Processing"
```

**Cause**: You're trying to update a task that's not in a `Succeeded` or `Failed` state.

**Solution**: Wait for the task to complete before attempting to update it.

#### Task Cannot Be Cancelled

```bash theme={null}
GET /api/v1/task/{task_id}/cancel
# Status: 400 Bad Request  
# Response: "Task cannot be cancelled: status is Processing"
```

**Cause**: Only tasks in `Starting` status can be cancelled.

**Solution**: You cannot cancel tasks that have already begun processing.

### Resource Errors (404)

#### Task Not Found

```bash theme={null}
GET /api/v1/task/{task_id}
# Status: 404 Not Found
# Response: "Task not found"
```

**Cause**: The task ID doesn't exist, has expired, or belongs to a different user.

**Solution**:

* Verify the task ID is correct
* Check if the task has expired (expired tasks are automatically deleted)
* Ensure you're using the same API key that created the task

### Rate Limiting Errors (429)

#### Usage Limit Exceeded

```bash theme={null}
POST /api/v1/task/parse
# Status: 429 Too Many Requests
# Response: "Usage limit exceeded"
```

**Cause**: You've exceeded the rate limit for your account or service tier.

**Solution**: Implement exponential backoff and retry logic:

<CodeGroup>
  ```python Python theme={null}
  import time
  import requests

  def create_task_with_retry(data, max_retries=3):
      for attempt in range(max_retries):
          response = requests.post(
              'https://api.chunkr.ai/api/v1/task/parse',
              headers={'Authorization': 'YOUR_API_KEY'},
              json=data
          )
          
          if response.status_code == 429:
              wait_time = (2 ** attempt)  # Exponential backoff
              print(f"Rate limited. Waiting {wait_time}s...")
              time.sleep(wait_time)
              continue
          
          return response
      
      raise Exception("Max retries exceeded")
  ```

  ```javascript JavaScript theme={null}
  async function createTaskWithRetry(data, maxRetries = 3) {
    for (let attempt = 0; attempt < maxRetries; attempt++) {
      const response = await fetch('https://api.chunkr.ai/api/v1/task/parse', {
        method: 'POST',
        headers: {
          'Authorization': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
      });
      
      if (response.status === 429) {
        const waitTime = Math.pow(2, attempt) * 1000;
        console.log(`Rate limited. Waiting ${waitTime}ms...`);
        await new Promise(resolve => setTimeout(resolve, waitTime));
        continue;
      }
      
      return response;
    }
    
    throw new Error('Max retries exceeded');
  }
  ```
</CodeGroup>

<Warning>
  When encountering rate limits, always implement exponential backoff rather than immediately retrying.
</Warning>

### Server Errors (500)

#### Internal Server Error

```bash theme={null}
# Status: 500 Internal Server Error
# Response: "Failed to create task" or specific error message
```

**Cause**: An unexpected error occurred on the server.

**Solution**:

* Check if the error is transient by retrying the request
* Verify your request payload is valid
* Contact support if the error persists

#### Database Connection Error

```bash theme={null}
# Status: 500 Internal Server Error
# Response: "Failed to get client" or "Database connection error"
```

**Cause**: The server couldn't establish a database connection.

**Solution**: This is a server-side issue. Retry the request or contact support.

#### Failed to Process File

```bash theme={null}
POST /api/v1/task/parse
# Status: 500 Internal Server Error
# Response: "Failed to process file"
```

**Cause**: The server encountered an error while processing your file.

**Solution**:

* Verify your file is not corrupted
* Check that the file size is within limits (max 1GB)
* Try with a different file to isolate the issue

## Task-Specific Errors

### Task Status Messages

Tasks can fail with specific messages in the `message` field:

#### Page Limit Exceeded

```json theme={null}
{
  "task_id": "...",
  "status": "Failed",
  "message": "Page limit exceeded"
}
```

**Cause**: The document exceeds your account's page processing limit.

**Solution**: Upgrade your plan or split the document into smaller files.

#### Task Timed Out

```json theme={null}
{
  "task_id": "...",
  "status": "Failed",  
  "message": "Task timed out"
}
```

**Cause**: The task exceeded the maximum processing time (default 10 minutes).

**Solution**:

* The document may be too complex
* Try with a smaller document
* Contact support if timeouts persist

## Error Handling Best Practices

### 1. Check Status Codes

Always check the HTTP status code before parsing the response:

```python theme={null}
response = requests.post(url, headers=headers, json=data)

if response.status_code == 200:
    result = response.json()
else:
    error_message = response.text
    print(f"Error {response.status_code}: {error_message}")
```

### 2. Implement Retry Logic

For transient errors (429, 500), implement retry logic with exponential backoff:

```python theme={null}
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

retry_strategy = Retry(
    total=3,
    status_forcelist=[429, 500, 502, 503, 504],
    backoff_factor=1
)
adapter = HTTPAdapter(max_retries=retry_strategy)
http = requests.Session()
http.mount("https://", adapter)
```

### 3. Handle Specific Error Cases

Different errors require different handling:

```python theme={null}
def handle_api_error(response):
    if response.status_code == 401:
        # Authentication error - check API key
        raise AuthenticationError("Invalid API key")
    elif response.status_code == 404:
        # Resource not found - task may have expired
        raise NotFoundError("Task not found or expired")  
    elif response.status_code == 429:
        # Rate limited - implement backoff
        raise RateLimitError("Rate limit exceeded")
    elif response.status_code >= 500:
        # Server error - retry may help
        raise ServerError("Server error occurred")
    else:
        raise APIError(f"API error: {response.text}")
```

### 4. Log Errors for Debugging

Log both successful and failed requests for debugging:

```python theme={null}
import logging

logger = logging.getLogger(__name__)

try:
    response = requests.post(url, headers=headers, json=data)
    response.raise_for_status()
    logger.info(f"Task created: {response.json()['task_id']}")
except requests.exceptions.RequestException as e:
    logger.error(f"API request failed: {e}")
    logger.error(f"Response: {e.response.text if e.response else 'No response'}")
    raise
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/api/authentication">
    Review authentication methods and requirements
  </Card>

  <Card title="API Overview" icon="book" href="/api/overview">
    Learn about rate limits and API capabilities
  </Card>

  <Card title="Task Endpoints" icon="list-check" href="/api/endpoints/task">
    Explore task management endpoints
  </Card>
</CardGroup>
