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

# Error Handling

> Understanding API errors and responses

# Error Handling

The SuprSonic API uses conventional HTTP response codes and provides structured error messages to help you handle errors gracefully in your applications.

## Error Response Format

All API errors follow a consistent structure:

```json theme={null}
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": {
      "additional": "context-specific details"
    }
  }
}
```

## HTTP Status Codes

The API uses standard HTTP status codes to indicate the success or failure of requests:

| Status Code | Meaning               | Description                                |
| ----------- | --------------------- | ------------------------------------------ |
| `200`       | OK                    | Request succeeded                          |
| `400`       | Bad Request           | Invalid request data or malformed JSON     |
| `401`       | Unauthorized          | Missing, invalid, or expired API key       |
| `403`       | Forbidden             | Valid API key but insufficient permissions |
| `404`       | Not Found             | Requested resource doesn't exist           |
| `429`       | Too Many Requests     | Rate limit exceeded                        |
| `500`       | Internal Server Error | Something went wrong on our end            |

## Error Codes

### Authentication Errors

<CodeGroup>
  ```json AUTHENTICATION_ERROR theme={null}
  {
    "success": false,
    "error": {
      "code": "AUTHENTICATION_ERROR",
      "message": "Authentication required"
    }
  }
  ```

  ```json INVALID_API_KEY theme={null}
  {
    "success": false,
    "error": {
      "code": "INVALID_API_KEY",
      "message": "Invalid API key"
    }
  }
  ```
</CodeGroup>

**Common Causes:**

* Missing `Authorization` header
* Malformed API key format
* Revoked or expired API key
* Using account API key where admin key is required

### Authorization Errors

```json theme={null}
{
  "success": false,
  "error": {
    "code": "AUTHORIZATION_ERROR",
    "message": "Article creation currently requires admin API key"
  }
}
```

**Common Causes:**

* Using account API key for admin-only operations
* Insufficient permissions for the requested action

### Validation Errors

```json theme={null}
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request data",
    "details": {
      "errors": [
        {
          "code": "invalid_type",
          "expected": "string",
          "received": "number",
          "path": ["title"],
          "message": "Expected string, received number"
        }
      ]
    }
  }
}
```

**Common Causes:**

* Missing required fields
* Invalid data types
* Values outside allowed ranges
* Malformed JSON

### Resource Errors

<CodeGroup>
  ```json ACCOUNT_NOT_FOUND theme={null}
  {
    "success": false,
    "error": {
      "code": "ACCOUNT_NOT_FOUND",
      "message": "Account abc123 not found"
    }
  }
  ```

  ```json ARTICLE_NOT_FOUND theme={null}
  {
    "success": false,
    "error": {
      "code": "ARTICLE_NOT_FOUND",
      "message": "Article def456 not found"
    }
  }
  ```
</CodeGroup>

### Rate Limiting

```json theme={null}
{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded"
  }
}
```

Rate limits are applied per API key. See our [rate limits guide](/guides/rate-limits) for details.

## Error Handling Best Practices

### 1. Always Check Response Status

```javascript theme={null}
const response = await fetch('/api/v1/articles', {
  headers: { 'Authorization': `Bearer ${apiKey}` }
});

if (!response.ok) {
  const error = await response.json();
  console.error('API Error:', error.error.message);
  return;
}

const data = await response.json();
```

### 2. Handle Different Error Types

```javascript theme={null}
async function handleApiError(response) {
  const error = await response.json();
  
  switch (error.error.code) {
    case 'AUTHENTICATION_ERROR':
    case 'INVALID_API_KEY':
      // Redirect to login or refresh API key
      redirectToAuth();
      break;
      
    case 'AUTHORIZATION_ERROR':
      // Show permission denied message
      showError('You don\'t have permission for this action');
      break;
      
    case 'VALIDATION_ERROR':
      // Display field-specific errors
      showValidationErrors(error.error.details.errors);
      break;
      
    case 'RATE_LIMIT_EXCEEDED':
      // Implement exponential backoff
      await retryAfterDelay();
      break;
      
    default:
      // Generic error handling
      showError('Something went wrong. Please try again.');
  }
}
```

### 3. Implement Retry Logic

```javascript theme={null}
async function apiRequestWithRetry(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 delay = Math.pow(2, attempt) * 1000; // Exponential backoff
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }
      
      if (response.status >= 500) {
        // Server error - retry
        if (attempt === maxRetries) throw new Error('Server error after retries');
        continue;
      }
      
      return response;
      
    } catch (error) {
      if (attempt === maxRetries) throw error;
    }
  }
}
```

### 4. Validate Before Sending

```javascript theme={null}
function validateArticleData(article) {
  const errors = [];
  
  if (!article.title || article.title.length > 500) {
    errors.push('Title is required and must be 500 characters or less');
  }
  
  if (!article.content) {
    errors.push('Content is required');
  }
  
  if (article.tags && article.tags.length > 20) {
    errors.push('Maximum 20 tags allowed');
  }
  
  return errors;
}

// Use before API call
const validationErrors = validateArticleData(articleData);
if (validationErrors.length > 0) {
  showErrors(validationErrors);
  return;
}
```

## Debugging Tips

### Enable Request/Response Logging

```javascript theme={null}
// Log all API requests and responses
const originalFetch = fetch;
window.fetch = async (...args) => {
  console.log('API Request:', args);
  const response = await originalFetch(...args);
  const clonedResponse = response.clone();
  const body = await clonedResponse.json();
  console.log('API Response:', response.status, body);
  return response;
};
```

### Common Troubleshooting

| Issue                  | Check                                                      |
| ---------------------- | ---------------------------------------------------------- |
| `401 Unauthorized`     | API key format, expiration, proper Bearer token            |
| `403 Forbidden`        | Using admin key for create operations, account permissions |
| `404 Not Found`        | Resource IDs, endpoint URLs, resource existence            |
| `422 Validation Error` | Required fields, data types, field constraints             |
| `429 Rate Limited`     | Request frequency, implement backoff strategy              |

## Support

If you encounter persistent errors:

1. Check our [status page](https://status.suprsonic.com) for known issues
2. Review your API key permissions in the dashboard
3. Contact support with request IDs for faster debugging
