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

# Error Handling

> Understand error responses and how to handle them.

## Error Response Format

All errors follow a consistent JSON format:

```json theme={null}
{
  "error": {
    "code": "error_code",
    "message": "Human-readable description"
  }
}
```

## Error Codes

### Authentication Errors

| Code           | Status | Description                                                            |
| -------------- | ------ | ---------------------------------------------------------------------- |
| `unauthorized` | 401    | Invalid or missing API key                                             |
| `forbidden`    | 403    | Valid key but action not permitted (e.g., wrong origin for public key) |

### Validation Errors

| Code          | Status | Description                |
| ------------- | ------ | -------------------------- |
| `bad_request` | 400    | Invalid request parameters |
| `not_found`   | 404    | Resource not found         |

### Limit Errors

| Code                     | Status | Description                            |
| ------------------------ | ------ | -------------------------------------- |
| `file_too_large`         | 413    | File exceeds your plan's max file size |
| `storage_limit_exceeded` | 413    | Storage quota exceeded                 |
| `rate_limit_exceeded`    | 429    | Too many requests                      |
| `api_key_limit_exceeded` | 403    | Maximum API keys reached for your plan |

### Account Errors

| Code           | Status | Description                                 |
| -------------- | ------ | ------------------------------------------- |
| `grace_period` | 403    | Account is in grace period—uploads disabled |

### Server Errors

| Code             | Status | Description             |
| ---------------- | ------ | ----------------------- |
| `internal_error` | 500    | Unexpected server error |

## Handling Errors

<CodeGroup>
  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.stashfyle.com/v1/upload', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer sk_live_xxx' },
    body: form
  });

  if (!response.ok) {
    const { error } = await response.json();

    switch (error.code) {
      case 'file_too_large':
        console.error('File is too large. Max size:', error.message);
        break;
      case 'storage_limit_exceeded':
        console.error('Storage full. Upgrade your plan or delete files.');
        break;
      case 'rate_limit_exceeded':
        // Retry after delay
        const retryAfter = response.headers.get('Retry-After');
        await sleep(retryAfter * 1000);
        break;
      default:
        console.error('Upload failed:', error.message);
    }
  }
  ```

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

  response = requests.post(
      'https://api.stashfyle.com/v1/upload',
      headers={'Authorization': 'Bearer sk_live_xxx'},
      files={'file': f}
  )

  if not response.ok:
      error = response.json()['error']

      if error['code'] == 'file_too_large':
          print(f"File too large: {error['message']}")
      elif error['code'] == 'rate_limit_exceeded':
          retry_after = int(response.headers.get('Retry-After', 60))
          time.sleep(retry_after)
      else:
          print(f"Error: {error['message']}")
  ```
</CodeGroup>

## Rate Limit Headers

When rate limited (429), check these headers:

| Header                  | Description                       |
| ----------------------- | --------------------------------- |
| `X-RateLimit-Limit`     | Requests allowed per window       |
| `X-RateLimit-Remaining` | Requests remaining                |
| `X-RateLimit-Reset`     | Unix timestamp when window resets |
| `Retry-After`           | Seconds to wait before retrying   |

## Best Practices

<AccordionGroup>
  <Accordion title="Always check response status">
    Never assume a request succeeded. Check the HTTP status code before processing the response.
  </Accordion>

  <Accordion title="Implement exponential backoff">
    For rate limits and server errors, use exponential backoff with jitter to avoid thundering herd.
  </Accordion>

  <Accordion title="Log error codes">
    Log the error code (not just the message) for easier debugging and monitoring.
  </Accordion>

  <Accordion title="Handle grace period gracefully">
    If you receive `grace_period`, notify users to update their subscription.
  </Accordion>
</AccordionGroup>
