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

# Error Handling

> Learn how to handle and resolve common errors you might encounter when using the StealthGPT API

## HTTP Status Codes

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

<ResponseField>
  <ResponseField name="200 OK" type="success">
    The request was successful and the response contains the expected data.
  </ResponseField>

  <ResponseField name="400 Bad Request" type="error">
    The request was malformed or contained invalid parameters.
  </ResponseField>

  <ResponseField name="401 Unauthorized" type="error">
    Authentication failed, usually due to an invalid or missing API token.
  </ResponseField>

  <ResponseField name="402 Payment required" type="error">
    Your request cannot be billed. This can happen when you run out of prepaid words and either (a) you haven't accepted pay-as-you-go terms (legacy accounts), (b) you don't have a saved payment method, (c) your account is past due, or (d) billing is temporarily delayed.
  </ResponseField>

  <ResponseField name="403 Forbidden" type="error">
    The requested operation could not be completed (e.g., result not available).
  </ResponseField>

  <ResponseField name="429 Too Many Requests" type="error">
    You've exceeded the rate limits for the API.
  </ResponseField>

  <ResponseField name="500 Internal Server Error" type="error">
    An error occurred on the server. These are typically temporary.
  </ResponseField>
</ResponseField>

## Error Response Format

All error responses follow this consistent format:

```json theme={null}
{
  "message": "Human-readable error message"
}
```

Some error responses may include additional information:

```json theme={null}
{
  "message": "Invalid request",
  "info": [
    {
      "code": "invalid_type",
      "expected": "boolean",
      "received": "string",
      "path": ["rephrase"],
      "message": "Expected boolean, received string"
    }
  ]
}
```

## Common Errors and Solutions

### Authentication Errors

<AccordionGroup>
  <Accordion title="Invalid API Token">
    **Error:** 401 Unauthorized

    **Response:**

    ```json theme={null}
    {
      "message": "Unauthorized"
    }
    ```

    **Solution:** Verify that you're including the correct API token in the `api-token` header. Check your StealthGPT dashboard under the "API Key" tab for the correct token.

    ```bash theme={null}
    # Incorrect
    --header 'api-token: invalid_token'

    # Correct
    --header 'api-token: your_valid_token_here'
    ```
  </Accordion>

  <Accordion title="Missing API Token">
    **Error:** 401 Unauthorized

    **Response:**

    ```json theme={null}
    {
      "message": "API token is missing. You can find it here https://www.stealthgpt.ai/stealthapi"
    }
    ```

    **Solution:** Ensure you're including the `api-token` header in all requests.

    ```bash theme={null}
    # Missing header
    curl --location 'https://stealthgpt.ai/api/stealthify' \
        --header 'Content-Type: application/json' \
        --data '{ "prompt": "test", "rephrase": false }'

    # Correct
    curl --location 'https://stealthgpt.ai/api/stealthify' \
        --header 'api-token: YOUR_API_TOKEN' \
        --header 'Content-Type: application/json' \
        --data '{ "prompt": "test", "rephrase": false, "detector": "turnitin" }'
    ```
  </Accordion>
</AccordionGroup>

### Request Errors

<AccordionGroup>
  <Accordion title="Missing Required Parameters">
    **Error:** 400 Bad Request

    **Response:**

    ```json theme={null}
    {
      "message": "Invalid request",
      "info": [
        {
          "code": "invalid_type",
          "expected": "boolean",
          "received": "undefined",
          "path": ["rephrase"],
          "message": "Required"
        }
      ]
    }
    ```

    **Solution:** Ensure all required parameters are included in your request. For the `/api/stealthify` endpoint, both `prompt` and `rephrase` are required.

    ```bash theme={null}
    # Missing rephrase parameter
    --data '{ "prompt": "test", "detector": "turnitin" }'

    # Correct
    --data '{ "prompt": "test", "rephrase": false }'
    ```
  </Accordion>

  <Accordion title="Invalid Parameter Values">
    **Error:** 400 Bad Request

    **Response:**

    ```json theme={null}
    {
      "message": "Invalid request",
      "info": [
        {
          "code": "invalid_type",
          "expected": "boolean",
          "received": "string",
          "path": ["rephrase"],
          "message": "Expected boolean, received string"
        }
      ]
    }
    ```

    **Solution:** Check that parameter values are in the correct format.

    ```bash theme={null}
    # Invalid boolean value (should be true/false, not "true"/"false")
    --data '{ "prompt": "test", "rephrase": "false" }'

    # Correct
    --data '{ "prompt": "test", "rephrase": false }'
    ```
  </Accordion>

  <Accordion title="Empty Prompt">
    **Error:** 400 Bad Request

    **Response:**

    ```json theme={null}
    {
      "message": "Invalid request",
      "info": [
        {
          "code": "too_small",
          "minimum": 1,
          "type": "string",
          "inclusive": true,
          "exact": false,
          "path": ["prompt"],
          "message": "String must contain at least 1 character(s)"
        }
      ]
    }
    ```

    **Solution:** Ensure the prompt parameter contains non-empty content.

    ```bash theme={null}
    # Empty prompt
    --data '{ "prompt": "", "rephrase": false }'

    # Correct
    --data '{ "prompt": "Write about renewable energy", "rephrase": false }'
    ```
  </Accordion>

  <Accordion title="Word Limit Exceeded">
    **Error:** 400 Bad Request

    **Response:**

    ```json theme={null}
    {
      "message": "The text exceeds the 3,000 word limit"
    }
    ```

    **Solution:** Keep your prompt text under 3,000 words.
  </Accordion>

  <Accordion title="Not Enough Credits">
    **Error:** 402 Payment Required

    **Response:**

    ```json theme={null}
    {
      "message": "Payment required or payment method not set up"
    }
    ```

    **Solution:**

    * If you are **out of prepaid words**, you can:
      * Add prepaid words, or
      * Set up pay-as-you-go billing (saved payment method) and accept the updated pay-as-you-go terms (legacy accounts)
    * For the `/api/stealthify/articles` endpoint, the request may bill to pay-as-you-go when prepaid is insufficient. If pay-as-you-go is not available, you will receive a 402.
  </Accordion>

  <Accordion title="Result Not Available">
    **Error:** 403 Forbidden

    **Response:**

    ```json theme={null}
    {
      "message": "Result is not available"
    }
    ```

    **Solution:** This typically occurs with the articles endpoint when there was an issue generating the article. Try again with a different prompt.
  </Accordion>
</AccordionGroup>

### Rate Limit Errors

<AccordionGroup>
  <Accordion title="Too Many Requests">
    **Error:** 429 Too Many Requests

    **Solution:** Implement request throttling in your application and avoid making too many requests in a short period.

    ```python theme={null}
    # Python example with retry logic
    import requests
    import time

    def call_api_with_retry(url, headers, data, max_retries=3, retry_delay=5):
        for attempt in range(max_retries):
            response = requests.post(url, headers=headers, json=data)
            
            if response.status_code == 429:
                # Wait before retrying
                time.sleep(retry_delay)
                continue
                
            return response
            
        return response  # Return last response if all retries failed
    ```
  </Accordion>
</AccordionGroup>

### Network and Server Errors

<AccordionGroup>
  <Accordion title="Network Timeout">
    **Error:** 504 Gateway Timeout

    **Solution:** Implement timeout handling and retry logic for network issues.

    ```python theme={null}
    # Python example with timeout handling
    import requests
    from requests.exceptions import Timeout, ConnectionError

    def call_api_with_timeout(prompt, rephrase, timeout=10):
        try:
            response = requests.post(
                'https://stealthgpt.ai/api/stealthify',
                headers={
                    'api-token': 'YOUR_API_TOKEN',
                    'Content-Type': 'application/json'
                },
                json={
                    'prompt': prompt,
                    'rephrase': rephrase,
                    'detector': 'turnitin'
                },
                timeout=timeout
            )
            response.raise_for_status()
            return response.json()
        except Timeout:
            print("Request timed out. The server might be experiencing high load.")
            raise
        except ConnectionError:
            print("Network connection error. Please check your internet connection.")
            raise
    ```
  </Accordion>

  <Accordion title="Server Error">
    **Error:** 500 Internal Server Error

    **Solution:** Implement exponential backoff retry logic for server-side errors.

    ```go theme={null}
    // Go example with exponential backoff
    package main

    import (
        "bytes"
        "encoding/json"
        "fmt"
        "net/http"
        "time"
    )

    func callAPIWithBackoff(prompt string, rephrase bool) (*http.Response, error) {
        maxRetries := 3
        baseDelay := time.Second

        requestBody, _ := json.Marshal(map[string]interface{}{
            "prompt":   prompt,
            "rephrase": rephrase,
            "detector": "turnitin",
        })

        for i := 0; i < maxRetries; i++ {
            req, _ := http.NewRequest("POST", "https://stealthgpt.ai/api/stealthify", 
                bytes.NewBuffer(requestBody))
            
            req.Header.Set("api-token", "YOUR_API_TOKEN")
            req.Header.Set("Content-Type", "application/json")

            resp, err := http.DefaultClient.Do(req)
            if err != nil {
                return nil, err
            }

            if resp.StatusCode != 500 {
                return resp, nil
            }

            // Exponential backoff
            delay := baseDelay * time.Duration(1<<uint(i))
            time.Sleep(delay)
        }

        return nil, fmt.Errorf("max retries exceeded")
    }
    ```
  </Accordion>
</AccordionGroup>

### Language-Specific Error Handling Examples

Here are comprehensive error handling examples in different programming languages:

<CodeGroup>
  ```python Python theme={null}
  import requests
  from requests.exceptions import RequestException
  import time

  class StealthGPTError(Exception):
      """Custom exception for StealthGPT API errors"""
      pass

  def call_stealthgpt_api(prompt, rephrase, max_retries=3):
      headers = {
          'api-token': 'YOUR_API_TOKEN',
          'Content-Type': 'application/json'
      }
      data = {
          'prompt': prompt,
          'rephrase': rephrase,
          'detector': 'turnitin'
      }

      for attempt in range(max_retries):
          try:
              response = requests.post(
                  'https://stealthgpt.ai/api/stealthify',
                  headers=headers,
                  json=data,
                  timeout=10
              )
              
              if response.status_code == 200:
                  return response.json()
              
              error_data = response.json()
              error_message = error_data.get('message', 'Unknown error')
                  
              if response.status_code == 429:
                  retry_after = int(response.headers.get('Retry-After', 5))
                  time.sleep(retry_after)
                  continue
                  
              if response.status_code == 400:
                  raise StealthGPTError(f"Invalid request: {error_message}")
                  
              if response.status_code == 401:
                  raise StealthGPTError("Unauthorized: Invalid API token")
              
              if response.status_code == 402:
                  raise StealthGPTError(f"Payment required: {error_message}")
                  
              response.raise_for_status()
              
          except requests.exceptions.Timeout:
              if attempt == max_retries - 1:
                  raise StealthGPTError("Request timed out after multiple attempts")
              time.sleep(2 ** attempt)  # Exponential backoff
              
          except requests.exceptions.RequestException as e:
              raise StealthGPTError(f"Request failed: {str(e)}")
              
      raise StealthGPTError("Max retries exceeded")
  ```

  ```javascript JavaScript theme={null}
  class StealthGPTClient {
    constructor(apiToken) {
      this.apiToken = apiToken;
      this.baseURL = 'https://stealthgpt.ai/api';
      this.maxRetries = 3;
    }

    async stealthify(prompt, rephrase) {
      let lastError;
      
      for (let attempt = 0; attempt < this.maxRetries; attempt++) {
        try {
          const response = await fetch(`${this.baseURL}/stealthify`, {
            method: 'POST',
            headers: {
              'api-token': this.apiToken,
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({ prompt, rephrase, detector: 'turnitin' }),
          });

          if (!response.ok) {
            const errorData = await response.json();
            const errorMessage = errorData.message || 'Unknown error';
            
            switch (response.status) {
              case 400:
                throw new Error(`Invalid request: ${errorMessage}`);
              case 401:
                throw new Error('Unauthorized: Invalid API token');
              case 402:
                throw new Error(`Payment required: ${errorMessage}`);
              case 403:
                throw new Error(`Forbidden: ${errorMessage}`);
              case 429:
                const retryAfter = parseInt(response.headers.get('Retry-After') || '5');
                await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
                continue;
              default:
                throw new Error(`API error: ${errorMessage}`);
            }
          }

          return await response.json();
          
        } catch (error) {
          lastError = error;
          
          if (error.message.includes('Invalid') || 
              error.message.includes('Unauthorized') || 
              error.message.includes('Payment required')) {
            throw error; // Don't retry client errors
          }
          
          // Exponential backoff for other errors
          await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));
        }
      }

      throw lastError || new Error('Max retries exceeded');
    }
  }
  ```
</CodeGroup>

## Best Practices for Error Handling

1. **Implement Retry Logic**: For transient errors (like 429 or 500), implement retry logic with exponential backoff.

2. **Validate Inputs**: Validate all parameters before sending requests to avoid 400 errors.

3. **Check Response Status**: Always check the HTTP status code before trying to process the response.

4. **Error Logging**: Log detailed error information for troubleshooting.

5. **Handle Errors Gracefully**: Provide user-friendly error messages in your application rather than exposing raw API errors.

```javascript theme={null}
// Node.js example of comprehensive error handling
async function callStealthGPT(prompt, rephrase) {
  try {
    const response = await axios.post('https://stealthgpt.ai/api/stealthify', {
      prompt,
      rephrase,
      detector: 'turnitin'
    }, {
      headers: {
        'api-token': process.env.API_TOKEN,
        'Content-Type': 'application/json'
      }
    });
    
    return response.data;
  } catch (error) {
    // Handle different error types
    if (error.response) {
      // The request was made and server responded with an error code
      const errorMessage = error.response.data.message || 'Unknown error';
      
      switch (error.response.status) {
        case 400:
          console.error('Invalid request parameters:', error.response.data);
          throw new Error(`Invalid request: ${errorMessage}`);
        case 401:
          console.error('Authentication failed');
          throw new Error('API authentication failed. Please check your API token.');
        case 402:
          console.error('Payment required');
          throw new Error(`Payment required: ${errorMessage}`);
        case 403:
          console.error('Forbidden');
          throw new Error(`Operation not allowed: ${errorMessage}`);
        case 429:
          console.error('Rate limit exceeded');
          throw new Error('Too many requests. Please try again later.');
        default:
          console.error(`Error ${error.response.status}:`, error.response.data);
          throw new Error('An error occurred while processing your request.');
      }
    } else if (error.request) {
      // The request was made but no response received
      console.error('No response received:', error.request);
      throw new Error('No response from server. Please check your connection.');
    } else {
      // Something else caused the error
      console.error('Error setting up request:', error.message);
      throw new Error('Failed to send request.');
    }
  }
} 
```
