Skip to main content

Error Response Format

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

HTTP Status Codes

StatusMeaningAction
400Bad RequestCheck request body
401UnauthorizedVerify API key
402Payment RequiredUpgrade plan or wait for quota reset
429Too Many RequestsSlow down or upgrade plan
500Server ErrorRetry or contact support

Error Codes

Validation Errors (400)

CodeDescriptionSolution
VALIDATION_ERRORInvalid request bodyCheck parameter types and values
INVALID_URLURL is malformedEnsure URL is properly formatted
URL_BLOCKEDURL is not allowedCheck URL against blocklist

Authentication Errors (401)

CodeDescriptionSolution
UNAUTHORIZEDMissing or invalid API keyCheck Authorization header
API_KEY_EXPIREDAPI key has expiredGenerate new key in dashboard
API_KEY_REVOKEDAPI key was revokedGenerate new key in dashboard

Quota Errors (402)

CodeDescriptionSolution
QUOTA_EXCEEDEDMonthly quota reachedUpgrade plan or wait for reset
INSUFFICIENT_CREDITSNot enough creditsPurchase more credits

Rate Limit Errors (429)

CodeDescriptionSolution
RATE_LIMIT_EXCEEDEDToo many requestsSlow down requests
Rate limits reset per minute. Wait 60 seconds before retrying.

Server Errors (500)

CodeDescriptionSolution
CAPTURE_FAILEDScreenshot failedRetry or check target URL
TIMEOUTPage load timed outIncrease timeout or simplify page
INTERNAL_ERRORUnexpected errorRetry 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:
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');
}