Skip to main content

Get Render

Retrieve the status and result of a render job.

Endpoint

GET /v1/renders/:id

Request

Path Parameters

ParameterTypeRequiredDescription
idstringYesThe render ID returned from POST /renders

Headers

HeaderRequiredDescription
AuthorizationYesBearer token with your API key

Response

Success Response (200 OK)

The response varies based on the render status:

Processing

While the render is still in progress:

{
"status": "processing",
"retryAfter": 1
}

Completed

When the render has finished successfully:

{
"status": "completed",
"html": "base64-encoded-gzipped-html-content",
"loadStrategy": "default",
"selectedCity": {
"name": "new.york",
"displayName": "New York",
"latitude": 40.7128,
"longitude": -74.0060,
"timezoneId": "America/New_York"
},
"bandwidthMetrics": {
"networkBytes": 2048576,
"cachedBytes": 512000,
"cacheHitRate": "20.0%"
},
"captcha": {
"detected": false,
"handled": false
},
"timingBreakdown": {
"browserInitMs": 245,
"navigationMs": 607,
"loadStrategyMs": 156,
"captchaMs": 0,
"waitActionsMs": 0,
"screenshotMs": 0,
"htmlCaptureMs": 89,
"totalMs": 759
},
"fetchResponses": "base64-encoded-gzipped-json-array",
"screenshot": "base64-encoded-jpeg-or-png-image",
"retryAfter": 1
}

Failed

When the render has failed (HTTP 422):

{
"status": "failed",
"errorCode": "RENDER_TIMEOUT",
"errorMessage": "Overall render exceeded 120 second timeout",
"billable": true,
"charged": true,
"chargedAmountCents": 1,
"retryAfter": 1
}

The errorCode tells you exactly what went wrong, and the billable field tells you whether you were charged. System errors (billable: false) are never charged. See Error Codes Reference for all error codes and their billing classification.

Response Fields

FieldTypeAlways PresentDescription
statusstringYesRender status: processing, completed, or failed
htmlstringCompleted onlyBase64-encoded, gzipped HTML content
loadStrategystringCompleted onlyLoad strategy used: default (standard page stabilization) or custom (user-specified waitFor actions)
screenshotstringCompleted only (if requested)Base64-encoded screenshot image (JPEG or PNG). Only present if includeScreenshot: true was specified in request
selectedCityobjectCompleted onlyGeographic location used for rendering
bandwidthMetricsobjectCompleted onlyNetwork usage statistics
captchaobjectCompleted onlyCAPTCHA detection and handling information
timingBreakdownobjectCompleted onlyPerformance metrics in milliseconds
fetchResponsesstringCompleted only (if requested)Base64-encoded, gzipped JSON array of fetch responses
errorCodestringFailed onlyMachine-readable error code (e.g., RENDER_TIMEOUT). See Error Codes
errorMessagestringFailed onlyHuman-readable error description
billablebooleanYesWhether this render was billed
chargedbooleanYesWhether a charge was applied to your account balance
chargedAmountCentsnumberYesAmount charged in cents (1 for billable, 0 for system errors)
retryAfternumberYesServer-suggested seconds to wait before next poll

Selected City Object

{
"name": "new.york",
"displayName": "New York",
"latitude": 40.7128,
"longitude": -74.0060,
"timezoneId": "America/New_York"
}

Bandwidth Metrics Object

{
"networkBytes": 2048576,
"cachedBytes": 512000,
"cacheHitRate": "20.0%"
}
FieldTypeDescription
networkBytesnumberBytes downloaded from network
cachedBytesnumberBytes served from browser cache
cacheHitRatestringPercentage of requests served from cache

CAPTCHA Object

{
"detected": true,
"handled": true,
"sitekey": "6LdABCDEFGHIJKLMNOP"
}
FieldTypeDescription
detectedbooleanWhether a CAPTCHA was detected
handledbooleanWhether the CAPTCHA was successfully solved
sitekeystringCAPTCHA site key (if detected)

Timing Breakdown Object

Performance timing breakdown showing milliseconds spent in each phase of the render. Useful for debugging slow renders and optimizing performance.

All times in milliseconds:

{
"browserInitMs": 245,
"navigationMs": 607,
"loadStrategyMs": 156,
"captchaMs": 0,
"waitActionsMs": 0,
"screenshotMs": 0,
"htmlCaptureMs": 89,
"totalMs": 759
}
FieldTypeDescription
browserInitMsnumberTime to initialize the browser instance
navigationMsnumberTime for page navigation (loading the URL)
loadStrategyMsnumberTime waiting for load strategy (networkIdle, domContentLoaded, etc.)
captchaMsnumberTime spent detecting and solving CAPTCHAs
waitActionsMsnumberTime spent executing user's waitFor actions
screenshotMsnumberTime to capture user screenshot (0 if not requested)
htmlCaptureMsnumberTime to extract the final HTML
totalMsnumberTotal render time (sum of all phases)

Data Retention

Render data is retained for 365 days with the following access patterns:

API Access (24 Hours)

Renders are available via this API endpoint for 24 hours after creation. During this window:

  • Retrieval time: <50ms (optimized for real-time workflows)
  • Typical usage: Poll for completion, retrieve results, process immediately

This covers the vast majority of web scraping workflows where results are retrieved within minutes or hours of creation.

Dashboard Access (365 Days)

After 24 hours, renders remain accessible via the Browser7 Dashboard for the full 365-day retention period:

  • View render details and metadata
  • Download HTML, screenshots, and fetch responses
  • Export or analyze historical renders

Note: If you need programmatic access to renders older than 24 hours, please contact support to discuss enterprise API options.

Data Decompression

The html and fetchResponses fields are compressed to reduce bandwidth:

  1. Content is gzipped
  2. Gzipped data is base64-encoded
  3. Encoded string is returned in JSON

Decompression Examples

Node.js:

const zlib = require('zlib');
const { promisify } = require('util');
const gunzip = promisify(zlib.gunzip);

// Decompress HTML
const buffer = Buffer.from(result.html, 'base64');
const decompressed = await gunzip(buffer);
const html = decompressed.toString('utf-8');

// Decompress fetchResponses
const fetchBuffer = Buffer.from(result.fetchResponses, 'base64');
const fetchDecompressed = await gunzip(fetchBuffer);
const fetchResponses = JSON.parse(fetchDecompressed.toString('utf-8'));

Python:

import base64
import gzip
import json

# Decompress HTML
html_bytes = base64.b64decode(result['html'])
html = gzip.decompress(html_bytes).decode('utf-8')

# Decompress fetchResponses
fetch_bytes = base64.b64decode(result['fetchResponses'])
fetch_responses = json.loads(gzip.decompress(fetch_bytes).decode('utf-8'))

PHP:

// Decompress HTML
$htmlBytes = base64_decode($result['html']);
$html = gzdecode($htmlBytes);

// Decompress fetchResponses
$fetchBytes = base64_decode($result['fetchResponses']);
$fetchResponses = json_decode(gzdecode($fetchBytes), true);

Note: All Browser7 SDKs handle decompression automatically.

Polling Pattern

Renders are processed asynchronously. Poll this endpoint until the status changes from processing:

  1. Create render with POST /renders
  2. Wait 2-3 seconds before first poll
  3. GET /renders/:id to check status
  4. If status is processing, wait retryAfter seconds and repeat step 3
  5. If status is completed, process the HTML
  6. If status is failed, handle the error

Polling Best Practices

  • Respect retryAfter - Use the server-suggested interval for optimal performance
  • Initial delay - Wait 2-3 seconds before first poll (renders rarely complete instantly)
  • Timeout - Set a maximum polling time (e.g., 60 seconds)
  • Exponential backoff - If implementing custom retry logic, increase intervals gradually

Examples

Basic Request

curl https://api.browser7.com/v1/renders/ren_abc123xyz \
-H "Authorization: Bearer b7_your_api_key"

Polling Loop (Bash)

RENDER_ID="ren_abc123xyz"

# Wait before first poll
sleep 3

# Poll until completed or failed
while true; do
RESPONSE=$(curl -s https://api.browser7.com/v1/renders/$RENDER_ID \
-H "Authorization: Bearer b7_your_api_key")

STATUS=$(echo $RESPONSE | jq -r '.status')

if [ "$STATUS" = "completed" ]; then
echo "Render completed!"
echo $RESPONSE | jq -r '.html' | base64 -d | gunzip
break
elif [ "$STATUS" = "failed" ]; then
echo "Render failed!"
echo $RESPONSE | jq -r '.error'
break
else
echo "Status: $STATUS - waiting..."
sleep 1
fi
done

SDK Examples

The SDKs provide both low-level and high-level methods:

Node.js

const Browser7 = require('browser7');
const client = new Browser7({ apiKey: 'b7_your_api_key' });

// Low-level: Get render status
const result = await client.getRender('ren_abc123xyz');
console.log(result.status); // 'processing' | 'completed' | 'failed'

if (result.status === 'completed') {
console.log(result.html); // Automatically decompressed
}

// High-level: Automatic polling (recommended)
const result = await client.render('https://example.com');
// Returns when completed, html is already decompressed
console.log(result.html);

Python

from browser7 import Browser7

client = Browser7(api_key='b7_your_api_key')

# Low-level: Get render status
result = client.get_render('ren_abc123xyz')
print(result.status) # 'processing' | 'completed' | 'failed'

if result.status == 'completed':
print(result.html) # Automatically decompressed

# High-level: Automatic polling (recommended)
result = client.render('https://example.com')
# Returns when completed, html is already decompressed
print(result.html)

PHP

use Browser7\Browser7Client;

$client = new Browser7Client('b7_your_api_key');

// Low-level: Get render status
$result = $client->getRender('ren_abc123xyz');
echo $result->status; // 'processing' | 'completed' | 'failed'

if ($result->status === 'completed') {
echo $result->html; // Automatically decompressed
}

// High-level: Automatic polling (recommended)
$result = $client->render('https://example.com');
// Returns when completed, html is already decompressed
echo $result->html;

Error Responses

404 Not Found

Returned when the render ID doesn't exist:

{
"error": "Not Found",
"message": "Render not found"
}

Common causes:

  • Invalid render ID
  • Render ID from a different account
  • Typo in the render ID

401 Unauthorized

See Authentication for authentication error details.