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

# Error Handling

> Understanding and handling API error responses

# Error Handling

The Artos API returns standard HTTP status codes with detailed error messages. This guide explains how to handle common errors.

## HTTP Status Codes

| Status                | Code | Description                            |
| --------------------- | ---- | -------------------------------------- |
| Success               | 200  | Request succeeded (GET, PUT)           |
| Created               | 201  | Resource created (POST)                |
| Accepted              | 202  | Request accepted for async processing  |
| Bad Request           | 400  | Invalid parameters or validation error |
| Unauthorized          | 401  | Missing or invalid authentication      |
| Forbidden             | 403  | Insufficient permissions               |
| Not Found             | 404  | Resource does not exist                |
| Unprocessable Entity  | 422  | Request validation error               |
| Internal Server Error | 500  | Server-side error                      |

## Error Response Format

All error responses return a JSON object with error details:

```json theme={null}
{
  "detail": "Error message describing what went wrong"
}
```

For some endpoints, errors may include additional context:

```json theme={null}
{
  "error": "error_code",
  "error_description": "Detailed description",
  "details": {
    "field": "value",
    "suggestion": "How to fix it"
  }
}
```

## Common Errors

### 401 Unauthorized - Missing Token

**Error**:

```json theme={null}
{
  "detail": "Not authenticated"
}
```

**Cause**: Authorization header is missing or empty

**Solution**: Include a valid Bearer token:

```bash theme={null}
curl -X GET "https://api.artosai.com/api/v1/templates/" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

***

### 401 Unauthorized - Invalid Token

**Error**:

```json theme={null}
{
  "detail": "Invalid authentication credentials"
}
```

**Cause**:

* Token is malformed
* Token has expired
* Token was revoked
* Token is for a different organization

**Solution**:

1. Verify token format is correct
2. Obtain a fresh token from your administrator
3. Check token hasn't been revoked
4. Verify token is for the correct environment

***

### 403 Forbidden - Wrong Organization

**Error**:

```json theme={null}
{
  "detail": "User has no organization or not authorized"
}
```

**Cause**:

* User's token doesn't have an organization
* Resource belongs to a different organization
* User is not member of the organization

**Solution**: Contact your organization administrator to verify your account setup

***

### 404 Not Found - Resource Missing

**Error**:

```json theme={null}
{
  "detail": "Document not found or not accessible"
}
```

**Cause**:

* Resource ID is incorrect
* Resource has been deleted
* Resource belongs to a different organization

**Solution**:

1. Verify the resource ID is correct
2. Check that the resource exists in your organization
3. List available resources to find the correct ID

***

### 400 Bad Request - Validation Error

**Error**:

```json theme={null}
{
  "detail": "Missing required parameter: document_type"
}
```

**Cause**: Request is missing required fields or has invalid values

**Solution**:

1. Check the API documentation for required fields
2. Verify all required parameters are included
3. Ensure values match the correct type and format

***

### 422 Unprocessable Entity - Invalid Structure

**Error**:

```json theme={null}
{
  "detail": "Request validation error"
}
```

**Cause**: Request structure is invalid or doesn't match schema

**Solution**:

1. Review the request body format
2. Ensure nested objects are properly structured
3. Validate against the OpenAPI specification

***

### 500 Internal Server Error

**Error**:

```json theme={null}
{
  "detail": "Internal server error"
}
```

**Cause**: Server-side processing error

**Solution**:

1. Retry the request after a brief delay
2. Check the Artos status page
3. Contact support if the error persists

***

## Error Handling Best Practices

### 1. Implement Exponential Backoff

Retry failed requests with increasing delays:

```python theme={null}
import time
import requests

def make_request_with_retry(url, headers, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = requests.get(url, headers=headers)
            if response.status_code == 200:
                return response.json()
            elif response.status_code >= 500:
                # Server error - retry
                wait = 2 ** attempt  # 1s, 2s, 4s
                print(f"Retrying in {wait}s...")
                time.sleep(wait)
            else:
                # Client error - don't retry
                print(f"Error: {response.status_code}")
                print(response.json())
                break
        except requests.exceptions.RequestException as e:
            print(f"Request failed: {e}")
            wait = 2 ** attempt
            time.sleep(wait)

    raise Exception("Max retries exceeded")
```

### 2. Check Status Codes

Always check the response status before processing:

```python theme={null}
import requests

response = requests.get(
    "https://api.artosai.com/api/v1/documents/doc-id",
    headers={"Authorization": f"Bearer {token}"}
)

if response.status_code == 200:
    document = response.json()
    print(f"Document: {document}")
elif response.status_code == 404:
    print("Document not found")
elif response.status_code == 401:
    print("Authentication failed")
else:
    print(f"Error: {response.status_code}")
    print(response.json())
```

### 3. Handle Async Operations

For async operations (202 responses), implement status polling:

```python theme={null}
import time

# Request document generation
response = requests.post(
    "https://api.artosai.com/api/v1/documents/generate",
    headers=headers,
    json=payload
)

if response.status_code == 202:
    task_id = response.json()['task_id']

    # Poll status
    while True:
        status = requests.get(
            f"https://api.artosai.com/api/v1/documents/status/{task_id}",
            headers=headers
        ).json()

        print(f"Status: {status['status']}")

        if status['status'] == 'Complete':
            print("Done!")
            break
        elif status['status'] == 'Failed':
            print(f"Error: {status['error']}")
            break

        time.sleep(5)
```

### 4. Validate Input

Validate input before sending requests:

```python theme={null}
def generate_document(payload):
    # Check required fields
    required = [
        'document_type',
        'file_paths',
        'document_set_key',
        'document_set_name',
        'generic_mrt_id',
        'output_name'
    ]

    for field in required:
        if field not in payload:
            raise ValueError(f"Missing required field: {field}")

    # Check types
    if not isinstance(payload['file_paths'], list):
        raise ValueError("file_paths must be an array")

    if len(payload['file_paths']) == 0:
        raise ValueError("file_paths cannot be empty")

    # Make request
    return requests.post(
        "https://api.artosai.com/api/v1/documents/generate",
        headers=headers,
        json=payload
    )
```

### 5. Log Errors for Debugging

Log error details for troubleshooting:

```python theme={null}
import logging
import json

logger = logging.getLogger(__name__)

try:
    response = requests.get(url, headers=headers)
    response.raise_for_status()
except requests.exceptions.HTTPError as e:
    error_data = e.response.json()
    logger.error(
        "API request failed",
        extra={
            "status_code": e.response.status_code,
            "url": e.response.url,
            "error": error_data,
            "request_body": payload
        }
    )
    raise
```

***

## Debugging Tips

### 1. Enable Debug Logging

```python theme={null}
import logging
import requests

logging.basicConfig(level=logging.DEBUG)
logging.getLogger("urllib3").setLevel(logging.DEBUG)

response = requests.get(url, headers=headers)
```

### 2. Check Token Validity

Verify your token hasn't expired:

```bash theme={null}
# Tokens are JWT - you can decode them at jwt.io
# Or implement validation in your code

import jwt

token = "your_token"
try:
    decoded = jwt.decode(token, options={"verify_signature": False})
    print(f"Token expires at: {decoded.get('exp')}")
except jwt.InvalidTokenError:
    print("Token is invalid")
```

### 3. Test with curl

Use curl for quick testing:

```bash theme={null}
# Test authentication
curl -i -H "Authorization: Bearer $TOKEN" \
  https://api.artosai.com/api/v1/templates/

# Check response headers
curl -v -H "Authorization: Bearer $TOKEN" \
  https://api.artosai.com/api/v1/templates/

# Pretty-print JSON
curl -s -H "Authorization: Bearer $TOKEN" \
  https://api.artosai.com/api/v1/templates/ | jq '.'
```

### 4. Review OpenAPI Spec

Check the OpenAPI specification at `/api-reference/openapi-v1.json` for:

* Required parameters
* Expected response formats
* Status codes for each endpoint

***

## Support

If you encounter persistent errors:

1. **Check the documentation** - Review endpoint documentation for parameters
2. **Verify your token** - Contact your administrator if token issues
3. **Check system status** - Look for maintenance or outages
4. **Enable debug logging** - Get detailed request/response information
5. **Contact support** - Reach out to [internal@artosai.com](mailto:internal@artosai.com) with error details
