Errors
In this guide, we will talk about what happens when something goes wrong while you work with the Screenshot API. Understanding error responses will help you debug issues and handle failures gracefully in your applications.
You can tell if your request was successful by checking the status code when receiving an API response. If a response comes back unsuccessful, you can use the error type and error message to figure out what has gone wrong and implement appropriate error handling.
Most errors are related to authentication issues, invalid parameters, or network problems with the target URL. Always check your API key and request parameters first.
Status codes
Here are the different categories of status codes returned by the Screenshot API:
- Name
200
- Description
OK - Cached screenshot returned immediately
- Name
202
- Description
Accepted - Screenshot job created successfully, use job ID to check status
- Name
400
- Description
Bad Request - Invalid request parameters or malformed JSON
- Name
401
- Description
Unauthorized - Missing or invalid API key
- Name
403
- Description
Forbidden - API key lacks required permissions
- Name
404
- Description
Not Found - Job ID not found or resource doesn't exist
- Name
500
- Description
Internal Server Error - Server error (rare)
Authentication Errors
Authentication errors occur when there are issues with your API key. These are the most common errors you'll encounter.
- Name
ApiKeyRequired
- Description
No API key was provided in the request headers or query parameters.
- Name
InvalidApiKey
- Description
The provided API key is not valid or has been revoked.
- Name
InsufficientPermissions
- Description
The API key doesn't have the required permissions for this operation.
Missing API key (401)
{
"status": 401,
"error": "ApiKeyRequired",
"message": "API key is required"
}
Invalid API key (401)
{
"status": 401,
"error": "InvalidApiKey",
"message": "Invalid API key"
}
Insufficient permissions (403)
{
"status": 403,
"error": "InsufficientPermissions",
"message": "API key does not have the required permissions"
}
Validation Errors
Validation errors occur when your request parameters don't meet the API requirements. These errors include detailed information about what went wrong.
- Name
ValidationError
- Description
One or more request parameters are invalid or missing.
- Name
InvalidUrl
- Description
The provided URL is not a valid HTTP or HTTPS URL.
- Name
ParameterOutOfRange
- Description
A numeric parameter is outside the allowed range.
Invalid URL (400)
{
"status": 400,
"error": "ValidationError",
"message": "URL must be a valid HTTP or HTTPS URL",
"details": {
"field": "url",
"value": "not-a-url",
"constraint": "Must be valid URL"
}
}
Missing viewport (400)
{
"status": 400,
"error": "ValidationError",
"message": "Viewport dimensions are required",
"details": {
"field": "viewport",
"constraint": "Required field"
}
}
Invalid quality (400)
{
"status": 400,
"error": "ValidationError",
"message": "Quality must be at least 1",
"details": {
"field": "quality",
"value": 0,
"constraint": "minimum: 1"
}
}
Job Errors
Job errors occur during screenshot processing. These are returned when checking job status.
- Name
JobNotFound
- Description
The specified job ID doesn't exist or has expired.
- Name
NavigationFailed
- Description
Failed to navigate to the target URL.
- Name
TimeoutError
- Description
Page load exceeded the specified timeout.
- Name
CaptureError
- Description
Error occurred while capturing the screenshot.
Job not found (404)
{
"status": 404,
"error": "JobNotFound",
"message": "Job with ID abc123 not found"
}
Failed job response
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "failed",
"createdAt": "2023-12-07T10:30:00Z",
"failedAt": "2023-12-07T10:30:10Z",
"error": {
"code": "NAVIGATION_FAILED",
"message": "Failed to navigate to URL",
"details": "Timeout waiting for page load"
}
}
Timeout error
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "failed",
"error": {
"code": "TIMEOUT_ERROR",
"message": "Page load timeout exceeded",
"details": "Page took longer than 30000ms to load"
}
}
Error Handling Best Practices
1. Retry Logic
Implement exponential backoff for temporary failures:
async function captureScreenshotWithRetry(url, options, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await fetch('/screenshot', {
method: 'POST',
headers: {
'x-api-key': 'your_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({ url, ...options })
});
if (response.ok) {
return await response.json();
}
if (response.status === 401 || response.status === 403) {
// Don't retry auth errors
throw new Error('Authentication failed');
}
if (attempt === maxRetries) {
throw new Error(`Failed after ${maxRetries} attempts`);
}
// Exponential backoff
await new Promise(resolve =>
setTimeout(resolve, Math.pow(2, attempt) * 1000)
);
} catch (error) {
if (attempt === maxRetries) throw error;
}
}
}
2. Job Status Polling
Handle different job states appropriately:
async function pollJobStatus(jobId, maxWaitTime = 60000) {
const startTime = Date.now();
while (Date.now() - startTime < maxWaitTime) {
const response = await fetch(`/screenshot/status/${jobId}`, {
headers: { 'x-api-key': 'your_api_key' }
});
const status = await response.json();
switch (status.status) {
case 'completed':
return status;
case 'failed':
throw new Error(`Job failed: ${status.error.message}`);
case 'pending':
case 'processing':
await new Promise(resolve => setTimeout(resolve, 2000));
break;
default:
throw new Error(`Unknown status: ${status.status}`);
}
}
throw new Error('Job polling timeout');
}
3. Parameter Validation
Validate parameters before sending requests:
function validateScreenshotRequest(params) {
const errors = [];
if (!params.url || !isValidUrl(params.url)) {
errors.push('Valid URL is required');
}
if (!params.viewport || !params.viewport.width || !params.viewport.height) {
errors.push('Viewport width and height are required');
}
if (params.quality && (params.quality < 1 || params.quality > 100)) {
errors.push('Quality must be between 1 and 100');
}
if (errors.length > 0) {
throw new Error(`Validation failed: ${errors.join(', ')}`);
}
}
function isValidUrl(string) {
try {
const url = new URL(string);
return url.protocol === 'http:' || url.protocol === 'https:';
} catch {
return false;
}
}
Common Error Scenarios
URL Not Reachable
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "failed",
"error": {
"code": "NAVIGATION_FAILED",
"message": "Failed to navigate to URL",
"details": "net::ERR_NAME_NOT_RESOLVED"
}
}
Solution: Verify the URL is correct and accessible from the internet.
Page Load Timeout
{
"error": {
"code": "TIMEOUT_ERROR",
"message": "Page load timeout exceeded",
"details": "Page took longer than 30000ms to load"
}
}
Solution: Increase the timeoutMs
parameter or optimize the target page loading speed.
Invalid Device Emulation
{
"status": 400,
"error": "ValidationError",
"message": "deviceEmulation must be one of: iPhone X, iPhone 12, ..."
}
Solution: Use the /screenshot/devices
endpoint to get valid device names.