Error Codes Reference
Understanding error codes helps you handle failures gracefully and debug issues quickly. All errors follow a consistent format with actionable information.
Error Response Format
All error responses have this structure:
Error Response
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description",
"details": {
"field": "Additional context"
}
},
"request_id": "req_abc123xyz"
}
Always include the request_id when contacting support for faster debugging.
HTTP Status Codes
| Status | Meaning | Action |
|---|---|---|
| 400 | Bad Request | Fix the request parameters |
| 401 | Unauthorized | Check your API key |
| 403 | Forbidden | Upgrade plan or check permissions |
| 404 | Not Found | Check the endpoint URL |
| 429 | Rate Limited | Slow down, check rate limit headers |
| 500 | Server Error | Retry with backoff, contact support |
| 503 | Service Unavailable | Check status page, retry later |
Error Codes
Authentication Errors
| Code | Description | Solution |
|---|---|---|
| MISSING_API_KEY | No Authorization header provided | Add Authorization: Bearer sk_live_xxx header |
| INVALID_API_KEY | API key is malformed or doesn't exist | Check your API key in the dashboard |
| EXPIRED_API_KEY | API key has been revoked or expired | Generate a new API key |
| INSUFFICIENT_SCOPE | API key lacks required permissions | Use an API key with the correct scope |
Request Validation Errors
| Code | Description | Solution |
|---|---|---|
| MISSING_PARAMETER | Required parameter not provided | Check details.field for the missing param |
| INVALID_PARAMETER | Parameter value is invalid | Check details for valid values |
| INVALID_URL | URL is malformed or invalid | Ensure URL is properly encoded and valid |
| INVALID_HTML | HTML content is malformed | Validate your HTML structure |
| INVALID_SELECTOR | CSS selector is invalid | Test selector in browser DevTools |
| BODY_TOO_LARGE | Request body exceeds 10MB limit | Reduce HTML size or use URL instead |
Capture Errors
| Code | Description | Solution |
|---|---|---|
| URL_NOT_ACCESSIBLE | Cannot reach the target URL | Ensure URL is publicly accessible |
| URL_BLOCKED | URL is blocked by our system | Contact support if legitimate |
| TIMEOUT | Page took too long to load | Use async endpoint or optimize page |
| ELEMENT_NOT_FOUND | Selector didn't match any element | Verify selector matches an element |
| NAVIGATION_FAILED | Browser navigation error | Check URL returns valid HTML |
| RENDER_FAILED | Page rendering crashed | Simplify page or contact support |
| CONTENT_TOO_LARGE | Generated output exceeds limits | Reduce page size or use smaller viewport |
Rate Limiting Errors
| Code | Description | Solution |
|---|---|---|
| RATE_LIMITED | Too many requests | Wait and retry, check Retry-After header |
| QUOTA_EXCEEDED | Monthly quota exhausted | Upgrade plan or wait for reset |
| CONCURRENT_LIMIT | Too many concurrent requests | Reduce parallel requests |
Account Errors
| Code | Description | Solution |
|---|---|---|
| ACCOUNT_SUSPENDED | Account has been suspended | Contact support |
| PAYMENT_REQUIRED | Payment method failed | Update billing information |
| FEATURE_NOT_AVAILABLE | Feature requires higher plan | Upgrade your subscription |
Handling Errors
Recommended Error Handling
error-handling.js
async function captureScreenshot(url) {
try {
const response = await fetch('https://api.screencraft.dev/v2/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ url }),
});
const data = await response.json();
if (!response.ok) {
// Handle specific errors
switch (data.error.code) {
case 'RATE_LIMITED':
// Implement exponential backoff
const retryAfter = response.headers.get('Retry-After') || 60;
await sleep(retryAfter * 1000);
return captureScreenshot(url); // Retry
case 'TIMEOUT':
// Use async endpoint for slow pages
return captureScreenshotAsync(url);
case 'QUOTA_EXCEEDED':
// Alert user to upgrade
throw new Error('Monthly quota exceeded. Please upgrade your plan.');
default:
throw new Error(data.error.message);
}
}
return data.data;
} catch (error) {
console.error('Screenshot failed:', error);
throw error;
}
} Retry Strategy
retry.js
async function withRetry(fn, maxRetries = 3) {
let lastError;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
lastError = error;
// Don't retry on client errors (4xx)
if (error.status >= 400 && error.status < 500) {
throw error;
}
// Exponential backoff
const delay = Math.min(1000 * Math.pow(2, attempt), 30000);
console.log(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
throw lastError;
} Debugging Tips
- Check the request_id: Include it when contacting support
- Verify the URL: Test it in a browser first
- Check rate limit headers: Monitor
X-RateLimit-*headers - Use test mode: Use
sk_test_keys for development - Enable verbose logging: Log full request/response for debugging
- Check status page: Visit /status for service issues
Need Help?
If you're still having issues:
- Email: [email protected]
- Include the
request_idfrom the error response - Provide the full request and response (redact API keys)