Error Handling
Understanding and handling Browser7 API errors.
Error Response Format
All API errors return a JSON response with an appropriate HTTP status code:
{
"error": "Error Type",
"message": "Human-readable description of what went wrong"
}
| Field | Type | Description |
|---|---|---|
error | string | Short error identifier |
message | string | Detailed error message for debugging |
HTTP Status Codes
2xx Success
| Code | Status | Description |
|---|---|---|
200 | OK | Request succeeded |
201 | Created | Resource created successfully |
4xx Client Errors
| Code | Status | Description |
|---|---|---|
400 | Bad Request | Invalid request parameters |
401 | Unauthorized | Invalid or missing API key |
402 | Payment Required | Insufficient account balance |
404 | Not Found | Resource not found |
429 | Too Many Requests | Rate limit exceeded |
5xx Server Errors
| Code | Status | Description |
|---|---|---|
500 | Internal Server Error | Unexpected server error |
503 | Service Unavailable | Service temporarily unavailable |
Common Errors
400 Bad Request
Returned when request parameters are invalid or malformed.
Example Response:
{
"error": "Bad Request",
"message": "Invalid URL: must include protocol (http:// or https://)"
}
Common Causes:
- Missing required parameters (e.g.,
urlfield) - Invalid parameter types (e.g., string instead of number)
- Invalid parameter values (e.g., unsupported country code)
- Malformed JSON in request body
- Invalid wait action configuration
- Too many wait actions (max 10)
- Invalid wait action timeout values
Solutions:
- Validate all parameters before sending
- Check parameter types match the API specification
- Ensure JSON is properly formatted
- Review Create Render endpoint documentation
Example:
# Bad - missing protocol
curl -X POST https://api.browser7.com/v1/renders \
-H "Authorization: Bearer b7_your_api_key" \
-H "Content-Type: application/json" \
-d '{"url": "example.com"}'
# Good - includes protocol
curl -X POST https://api.browser7.com/v1/renders \
-H "Authorization: Bearer b7_your_api_key" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
401 Unauthorized
Returned when authentication fails.
Example Response:
{
"error": "Unauthorized",
"message": "Invalid or missing API key"
}
Common Causes:
- API key not included in
Authorizationheader - Malformed
Authorizationheader (missing "Bearer " prefix) - Invalid API key
- Typo in API key
- Using wrong environment's API key
Solutions:
- Verify your API key in the Dashboard
- Ensure header format:
Authorization: Bearer b7_your_api_key - Check for extra spaces or newlines in the API key
- Use environment variables to avoid typos
Example:
# Bad - missing "Bearer " prefix
curl https://api.browser7.com/v1/renders \
-H "Authorization: b7_your_api_key"
# Good - correct format
curl https://api.browser7.com/v1/renders \
-H "Authorization: Bearer b7_your_api_key"
402 Payment Required
Returned when your account has insufficient balance.
Example Response:
{
"error": "Insufficient Balance",
"message": "Your account balance is insufficient to complete this request"
}
Common Causes:
- Account balance is $0.00 or less than $0.01
- Large batch job depleted balance mid-run
Solutions:
- Check your balance: Dashboard or GET /account/balance
- Purchase more renders: Billing → Purchase Renders
- Implement balance checks before batch operations
Example:
const client = new Browser7({ apiKey: process.env.BROWSER7_API_KEY });
// Check balance before batch job
const balance = await client.getAccountBalance();
const rendersNeeded = 1000;
const estimatedCost = rendersNeeded * 0.01;
if (balance.totalBalance < estimatedCost) {
throw new Error(`Insufficient balance: need $${estimatedCost}, have $${balance.totalBalance}`);
}
// Proceed with batch job
404 Not Found
Returned when the requested resource doesn't exist.
Example Response:
{
"error": "Not Found",
"message": "Render not found"
}
Common Causes:
- Invalid render ID
- Typo in render ID
- Render ID from a different account
- Requesting a render that was never created
Solutions:
- Verify the render ID from the create render response
- Check for typos or truncated IDs
- Ensure you're using the correct API key for the account
429 Too Many Requests
Returned when you exceed the rate limit.
Example Response:
{
"error": "Rate Limit Exceeded",
"message": "Too many requests. Please retry after 60 seconds"
}
Common Causes:
- Sending too many requests too quickly
- Not respecting rate limits for your plan
- Aggressive polling without delays
Solutions:
- Implement exponential backoff
- Check the
Retry-Afterheader for suggested wait time - Review Rate Limits documentation
- Space out batch operations
- Use the
retryAfterfield when polling renders
Example:
async function createRenderWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await client.createRender(url, options);
} catch (error) {
if (error.message.includes('429') && i < maxRetries - 1) {
const waitTime = Math.pow(2, i) * 1000; // Exponential backoff
console.log(`Rate limited, waiting ${waitTime}ms...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
} else {
throw error;
}
}
}
}
500 Internal Server Error
Returned when an unexpected server error occurs.
Example Response:
{
"error": "Internal Server Error",
"message": "An unexpected error occurred"
}
Common Causes:
- Temporary server issue
- Bug in the API
- Infrastructure problem
Solutions:
- Retry the request after a short delay
- If the error persists, contact support@browser7.com
- Implement retry logic with exponential backoff
503 Service Unavailable
Returned when the service is temporarily unavailable. The response includes a Retry-After header indicating how many seconds to wait before retrying.
Example Response:
HTTP/1.1 503 Service Unavailable
Retry-After: 2
{
"error": "Service Unavailable",
"message": "Server is at capacity, please retry shortly"
}
Common Causes:
- Server at capacity (all render slots busy)
- Scheduled maintenance
- Infrastructure issues
Solutions:
- Respect the
Retry-Afterheader and retry after the suggested delay - The load balancer will automatically route retries to less loaded servers
- Check status.browser7.com for service status
- If issue persists, contact support
Render-Specific Errors
When a render job fails after being accepted, the GET /v1/renders/:id response (HTTP 422) includes detailed error and billing information:
{
"status": "failed",
"errorCode": "RENDER_TIMEOUT",
"errorMessage": "Overall render exceeded 120 second timeout",
"billable": true,
"charged": true,
"chargedAmountCents": 1
}
Each error code is classified as either user-caused (billable, $0.01) or system error (not billable, $0.00). System errors are never charged - Browser7 does not charge for its own infrastructure failures.
See the Error Codes Reference for the complete list of error codes, their billing classification, and recommended fixes.
Error Handling in SDKs
All Browser7 SDKs provide typed error classes that map directly to HTTP status codes, eliminating the need to parse error message strings.
Node.js
import Browser7, { AuthenticationError, RateLimitError, InsufficientBalanceError, RenderError } from 'browser7';
const client = new Browser7({ apiKey: process.env.BROWSER7_API_KEY });
try {
const result = await client.render('https://example.com');
console.log(result.html);
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Authentication failed - check your API key');
} else if (error instanceof InsufficientBalanceError) {
console.error('Insufficient balance - purchase more renders');
} else if (error instanceof RateLimitError) {
console.error('Rate limited - slow down requests');
} else if (error instanceof RenderError) {
console.error(`Render failed: ${error.errorCode}`);
} else {
console.error('Error:', error.message);
}
}
Python
from browser7 import Browser7, AuthenticationError, RateLimitError, InsufficientBalanceError, RenderError
client = Browser7(api_key=os.environ['BROWSER7_API_KEY'])
try:
result = client.render('https://example.com')
print(result.html)
except AuthenticationError:
print('Authentication failed - check your API key')
except InsufficientBalanceError:
print('Insufficient balance - purchase more renders')
except RateLimitError:
print('Rate limited - slow down requests')
except RenderError as e:
print(f'Render failed: {e.error_code}')
except Exception as e:
print(f'Error: {e}')
PHP
use Browser7\Browser7Client;
use Browser7\AuthenticationError;
use Browser7\RateLimitError;
use Browser7\InsufficientBalanceError;
use Browser7\RenderError;
$client = new Browser7Client($_ENV['BROWSER7_API_KEY']);
try {
$result = $client->render('https://example.com');
echo $result->html;
} catch (AuthenticationError $e) {
echo 'Authentication failed - check your API key';
} catch (InsufficientBalanceError $e) {
echo 'Insufficient balance - purchase more renders';
} catch (RateLimitError $e) {
echo 'Rate limited - slow down requests';
} catch (RenderError $e) {
echo 'Render failed: ' . $e->getErrorCode();
} catch (\Exception $e) {
echo 'Error: ' . $e->getMessage();
}
Best Practices
1. Always Handle Errors
Never assume requests will succeed. Implement proper error handling for all API calls.
2. Log Errors for Debugging
Log full error responses including status codes and messages:
console.error(`API Error [${statusCode}]: ${error.message}`);
3. Implement Retry Logic
Retry transient errors (500, 503) with exponential backoff:
import { Browser7Error } from 'browser7';
async function retryWithBackoff(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
const isRetryable = error.statusCode >= 500 || error.statusCode === 429;
if (isRetryable && i < maxRetries - 1) {
const delay = Math.pow(2, i) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
}
4. Validate Before Sending
Validate parameters client-side before making API calls:
function validateRenderOptions(url, options = {}) {
if (!url || !url.startsWith('http')) {
throw new Error('URL must start with http:// or https://');
}
if (options.waitFor && options.waitFor.length > 10) {
throw new Error('Maximum 10 wait actions allowed');
}
// More validation...
}
5. Monitor Error Rates
Track error rates to identify issues early:
let errorCount = 0;
let requestCount = 0;
async function monitoredRender(url) {
requestCount++;
try {
return await client.render(url);
} catch (error) {
errorCount++;
const errorRate = (errorCount / requestCount) * 100;
if (errorRate > 10) {
console.warn(`High error rate: ${errorRate.toFixed(2)}%`);
}
throw error;
}
}
Getting Help
If you encounter persistent errors:
- Check the API Status Page
- Review this documentation and related endpoint docs
- Search for similar issues in the community
- Contact support@browser7.com with:
- Your API key (last 4 characters only)
- Request and response details
- Timestamp of the error
- Steps to reproduce
Related Documentation
- Authentication - Fix authentication errors
- Rate Limits - Understand and avoid rate limiting
- Create Render - Correct parameter usage
- Get Render - Handle render failures