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

# Error Codes

> Complete reference for Imperial API error codes and how to handle them

## Error Response Format

All errors follow a consistent JSON structure:

```json theme={null}
{
  "error": "Human-readable error message",
  "statusCode": 400,
  "details": {
    // Optional additional context
  }
}
```

## HTTP Status Codes

Imperial uses standard HTTP status codes to indicate success or failure.

### Success Codes

| Code | Name    | Description                             |
| ---- | ------- | --------------------------------------- |
| 200  | OK      | Request succeeded                       |
| 201  | Created | Resource created successfully (uploads) |

### Client Error Codes (4xx)

<AccordionGroup>
  <Accordion title="400 Bad Request" icon="circle-exclamation">
    The request was malformed or contains invalid parameters.

    **Common Causes:**

    * Missing required fields
    * Invalid file format
    * Malformed JSON
    * Invalid query parameters

    **Example:**

    ```json theme={null}
    {
      "error": "Validation failed",
      "statusCode": 400,
      "details": {
        "file": "File is required"
      }
    }
    ```

    **Solutions:**

    * Check request body format
    * Verify all required fields are present
    * Ensure file is properly attached
    * Validate parameter types
  </Accordion>

  <Accordion title="401 Unauthorized" icon="lock">
    Missing or invalid authentication credentials.

    **Common Causes:**

    * Missing Authorization header
    * Invalid API key or upload key
    * Expired token
    * Wrong key format

    **Example:**

    ```json theme={null}
    {
      "error": "Invalid or missing API key",
      "statusCode": 401
    }
    ```

    **Solutions:**

    * Include `Authorization: Bearer YOUR_KEY` header
    * Verify key starts with `imperial_live_` or `imperial_upload_`
    * Generate new key if compromised
    * Check key hasn't been revoked
  </Accordion>

  <Accordion title="403 Forbidden" icon="ban">
    Authenticated but lacking required permissions.

    **Common Causes:**

    * Upload key used for non-upload endpoints (Free/Starter)
    * Trying to access another user's resources
    * Tier doesn't support requested feature

    **Example:**

    ```json theme={null}
    {
      "error": "API access requires Pro or Business tier",
      "statusCode": 403
    }
    ```

    **Solutions:**

    * Upgrade to Pro/Business for full API access
    * Use correct authentication type for endpoint
    * Verify you own the resource you're accessing
  </Accordion>

  <Accordion title="404 Not Found" icon="magnifying-glass">
    The requested resource doesn't exist.

    **Common Causes:**

    * Invalid image/upload ID
    * File was deleted
    * Typo in endpoint URL

    **Example:**

    ```json theme={null}
    {
      "error": "Image not found",
      "statusCode": 404
    }
    ```

    **Solutions:**

    * Verify resource ID is correct
    * Check if file was deleted
    * Ensure you own the resource
    * Verify endpoint URL is correct
  </Accordion>

  <Accordion title="413 Payload Too Large" icon="file-arrow-up">
    File size or total request size exceeds limits.

    **Common Causes:**

    * Storage limit exceeded
    * File larger than available space
    * Batch upload too large

    **Example:**

    ```json theme={null}
    {
      "error": "Storage limit exceeded. You've used 4.8 GB of 5 GB.",
      "statusCode": 413
    }
    ```

    **Solutions:**

    * Delete old uploads to free space
    * Enable auto-compression
    * Upgrade to higher tier
    * Split large batch uploads
  </Accordion>

  <Accordion title="415 Unsupported Media Type" icon="file-slash">
    File type is not supported.

    **Common Causes:**

    * Uploading non-image/video files
    * Unsupported video codec
    * Corrupted file

    **Example:**

    ```json theme={null}
    {
      "error": "Only images and videos are allowed",
      "statusCode": 415
    }
    ```

    **Solutions:**

    * Use supported formats: JPEG, PNG, WebP, GIF, MP4, WebM, MOV, AVI
    * Verify file isn't corrupted
    * Check MIME type is correct
  </Accordion>

  <Accordion title="429 Too Many Requests" icon="gauge-high">
    Rate limit exceeded.

    **Common Causes:**

    * Too many requests per minute
    * Operations limit reached for month
    * Aggressive retry logic

    **Example:**

    ```json theme={null}
    {
      "error": "Rate limit exceeded. Try again in 42 seconds.",
      "statusCode": 429,
      "details": {
        "retryAfter": 42
      }
    }
    ```

    **Solutions:**

    * Respect `Retry-After` header
    * Implement exponential backoff
    * Reduce request frequency
    * Upgrade tier for higher rate limits
  </Accordion>
</AccordionGroup>

### Server Error Codes (5xx)

<AccordionGroup>
  <Accordion title="500 Internal Server Error" icon="server">
    An unexpected error occurred on the server.

    **Common Causes:**

    * Database connectivity issues
    * R2 storage unavailable
    * Unhandled exception

    **Example:**

    ```json theme={null}
    {
      "error": "An internal error occurred. Please try again.",
      "statusCode": 500
    }
    ```

    **Solutions:**

    * Retry the request after a delay
    * Check [status page](https://status.imperial.gay) for incidents
    * Contact support if persistent
    * Implement retry logic with backoff
  </Accordion>

  <Accordion title="503 Service Unavailable" icon="triangle-exclamation">
    Service is temporarily unavailable.

    **Common Causes:**

    * Planned maintenance
    * Database migration
    * CDN issues

    **Example:**

    ```json theme={null}
    {
      "error": "Service temporarily unavailable",
      "statusCode": 503,
      "details": {
        "retryAfter": 300
      }
    }
    ```

    **Solutions:**

    * Wait and retry after specified time
    * Check status page for updates
    * Implement circuit breaker pattern
  </Accordion>
</AccordionGroup>

## Common Error Scenarios

### Authentication Errors

<CodeGroup>
  ```bash Missing Header theme={null}
  # ❌ Missing Authorization header
  curl https://api.imperial.gay/images

  # Error Response:

  {
  "error": "Authorization header is required",
  "statusCode": 401
  }

  ```

  ```bash Invalid Key Format theme={null}
  # ❌ Wrong key format
  curl https://api.imperial.gay/images \
    -H "Authorization: imperial_live_xxxxx"

  # Error Response:
  {
    "error": "Authorization must use Bearer scheme",
    "statusCode": 401
  }
  ```

  ```bash Correct Usage theme={null}
  # ✅ Correct format
  curl https://api.imperial.gay/images \
    -H "Authorization: Bearer imperial_live_xxxxx"
  ```
</CodeGroup>

### Upload Errors

<CodeGroup>
  ```bash Storage Exceeded theme={null}
  # Upload when storage full
  curl -X POST https://api.imperial.gay/images/upload \
    -H "Authorization: Bearer YOUR_KEY" \
    -F "file=@large.jpg"

  # Error Response:

  {
  "error": "Storage limit exceeded. You've used 5.0 GB of 5 GB.",
  "statusCode": 413
  }

  ```

  ```bash Invalid File Type theme={null}
  # Upload unsupported file
  curl -X POST https://api.imperial.gay/images/upload \
    -H "Authorization: Bearer YOUR_KEY" \
    -F "file=@document.pdf"

  # Error Response:
  {
    "error": "Only images and videos are allowed",
    "statusCode": 415
  }
  ```

  ```bash Missing File theme={null}
  # Upload without file
  curl -X POST https://api.imperial.gay/images/upload \
    -H "Authorization: Bearer YOUR_KEY"

  # Error Response:
  {
    "error": "Validation failed",
    "statusCode": 400,
    "details": {
      "file": "File is required"
    }
  }
  ```
</CodeGroup>

### Permission Errors

<CodeGroup>
  ```bash Upload Key on List Endpoint theme={null}
  # Using upload key for listing (Free/Starter)
  curl https://api.imperial.gay/images \
    -H "Authorization: Bearer imperial_upload_xxxxx"

  # Error Response:

  {
  "error": "API access requires Pro or Business tier",
  "statusCode": 403
  }

  ```

  ```bash Access Other User's File theme={null}
  # Trying to delete someone else's file
  curl -X DELETE https://api.imperial.gay/images/abc123 \
    -H "Authorization: Bearer YOUR_KEY"

  # Error Response:
  {
    "error": "Image not found",
    "statusCode": 404
  }
  ```
</CodeGroup>

## Rate Limiting

### Rate Limit Headers

Every response includes rate limit information:

```http theme={null}
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 299
X-RateLimit-Reset: 1704643200
```

| Header                  | Description                      |
| ----------------------- | -------------------------------- |
| `X-RateLimit-Limit`     | Max requests per window          |
| `X-RateLimit-Remaining` | Requests left in window          |
| `X-RateLimit-Reset`     | Unix timestamp when limit resets |

### Handling Rate Limits

<CodeGroup>
  ```javascript Node.js theme={null}
  async function uploadWithRetry(file, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
      try {
        const response = await fetch('https://api.imperial.gay/images/upload', {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${API_KEY}`
          },
          body: formData
        });
        
        if (response.status === 429) {
          const retryAfter = response.headers.get('Retry-After') || 60;
          console.log(`Rate limited. Retrying in ${retryAfter}s...`);
          await sleep(retryAfter * 1000);
          continue;
        }
        
        return await response.json();
      } catch (error) {
        if (i === maxRetries - 1) throw error;
        await sleep(Math.pow(2, i) * 1000); // Exponential backoff
      }
    }
  }
  ```

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

  def upload_with_retry(file_path, max_retries=3):
      for attempt in range(max_retries):
          try:
              response = requests.post(
                  'https://api.imperial.gay/images/upload',
                  headers={'Authorization': f'Bearer {API_KEY}'},
                  files={'file': open(file_path, 'rb')}
              )

              if response.status_code == 429:
                  retry_after = int(response.headers.get('Retry-After', 60))
                  print(f'Rate limited. Retrying in {retry_after}s...')
                  time.sleep(retry_after)
                  continue

              return response.json()
          except Exception as e:
              if attempt == max_retries - 1:
                  raise e
              time.sleep(2 ** attempt)  # Exponential backoff
  ```
</CodeGroup>

## Best Practices

### Error Handling

<Steps>
  <Step title="Check Status Code First">
    Use HTTP status code to determine error category (4xx vs 5xx)
  </Step>

  <Step title="Parse Error Message">Display `error` field to users for actionable feedback</Step>

  <Step title="Log Error Details">Store `details` object for debugging and support requests</Step>

  <Step title="Implement Retry Logic">
    Retry 5xx errors with exponential backoff. Don't retry 4xx errors.
  </Step>
</Steps>

### Retry Strategy

<Tip>
  **When to Retry:** - ✅ 500 Internal Server Error - ✅ 503 Service Unavailable - ✅ 429 Rate
  Limited (with backoff) - ❌ 400-404 Client Errors (fix request instead)
</Tip>

### Logging

Log these fields for troubleshooting:

```json theme={null}
{
  "timestamp": "2026-01-08T10:30:00Z",
  "endpoint": "POST /images/upload",
  "statusCode": 413,
  "error": "Storage limit exceeded",
  "requestId": "req_abc123",
  "userId": "user_xyz",
  "tier": "starter"
}
```

## Testing Errors

### Development Tips

<CodeGroup>
  ```bash Test Authentication theme={null}
  # Test invalid API key
  curl https://api.imperial.gay/images \
    -H "Authorization: Bearer invalid_key"

  # Expected: 401 Unauthorized

  ```

  ```bash Test Rate Limit theme={null}
  # Make many rapid requests
  for i in {1..100}; do
    curl https://api.imperial.gay/images \
      -H "Authorization: Bearer YOUR_KEY"
  done

  # Expected: 429 after limit exceeded
  ```

  ```bash Test Storage Limit theme={null}
  # Upload large file when near limit
  curl -X POST https://api.imperial.gay/images/upload \
    -H "Authorization: Bearer YOUR_KEY" \
    -F "file=@huge-file.mp4"

  # Expected: 413 if exceeds remaining space
  ```
</CodeGroup>

## Get Help

<CardGroup cols={2}>
  <Card title="Join Discord" icon="discord" href="https://discord.gg/imperial">
    Ask the community for help
  </Card>

  <Card title="Check Status" icon="signal" href="https://status.imperial.gay">
    View API status and incidents
  </Card>

  <Card title="View Limits" icon="gauge" href="/operations">
    Understand operations and storage
  </Card>

  <Card title="Upgrade Tier" icon="arrow-up" href="/pricing">
    Resolve limit-related errors
  </Card>
</CardGroup>
