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

# Error Handling

> Error codes and troubleshooting guide

## Error Response Format

```json theme={null}
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message"
  },
  "data": null
}
```

## HTTP Status Codes

| Status | Meaning           | Action                               |
| ------ | ----------------- | ------------------------------------ |
| 400    | Bad Request       | Check request body                   |
| 401    | Unauthorized      | Verify API key                       |
| 402    | Payment Required  | Upgrade plan or wait for quota reset |
| 429    | Too Many Requests | Slow down or upgrade plan            |
| 500    | Server Error      | Retry or contact support             |

## Error Codes

### Validation Errors (400)

| Code               | Description          | Solution                         |
| ------------------ | -------------------- | -------------------------------- |
| `VALIDATION_ERROR` | Invalid request body | Check parameter types and values |
| `INVALID_URL`      | URL is malformed     | Ensure URL is properly formatted |
| `URL_BLOCKED`      | URL is not allowed   | Check URL against blocklist      |

### Authentication Errors (401)

| Code              | Description                | Solution                      |
| ----------------- | -------------------------- | ----------------------------- |
| `UNAUTHORIZED`    | Missing or invalid API key | Check Authorization header    |
| `API_KEY_EXPIRED` | API key has expired        | Generate new key in dashboard |
| `API_KEY_REVOKED` | API key was revoked        | Generate new key in dashboard |

### Quota Errors (402)

| Code                   | Description           | Solution                       |
| ---------------------- | --------------------- | ------------------------------ |
| `QUOTA_EXCEEDED`       | Monthly quota reached | Upgrade plan or wait for reset |
| `INSUFFICIENT_CREDITS` | Not enough credits    | Purchase more credits          |

### Rate Limit Errors (429)

| Code                  | Description       | Solution           |
| --------------------- | ----------------- | ------------------ |
| `RATE_LIMIT_EXCEEDED` | Too many requests | Slow down requests |

<Tip>
  Rate limits reset per minute. Wait 60 seconds before retrying.
</Tip>

### Server Errors (500)

| Code             | Description         | Solution                          |
| ---------------- | ------------------- | --------------------------------- |
| `CAPTURE_FAILED` | Screenshot failed   | Retry or check target URL         |
| `TIMEOUT`        | Page load timed out | Increase timeout or simplify page |
| `INTERNAL_ERROR` | Unexpected error    | Retry or contact support          |

## Troubleshooting

### Common Issues

**"Unauthorized" despite valid key**

* Ensure `Bearer ` prefix is included
* Check for extra whitespace
* Verify key hasn't expired

**"Capture failed" on specific URLs**

* Some sites block headless browsers - try `antiBot: true`
* Site may be down - check manually
* Site may block certain regions - try different `region`

**Slow captures**

* Use `waitUntil: "domcontentloaded"` instead of `networkidle`
* Reduce viewport size
* Check target site performance

**Large file sizes**

* Use `format: "webp"` for better compression
* Reduce `quality` for JPEG/WebP
* Use smaller viewport

## Retry Strategy

Implement exponential backoff for transient errors:

```javascript theme={null}
async function captureWithRetry(params, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch('https://api.snapopa.com/capture', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(params),
    });

    if (response.ok) {
      return response.json();
    }

    if (response.status === 429 || response.status >= 500) {
      await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
      continue;
    }

    throw new Error(`Request failed: ${response.status}`);
  }
  throw new Error('Max retries exceeded');
}
```
