Website Screenshot API
Capture browser-rendered screenshots of any website in multiple sizes and formats. Use cases include web page previews, visual change tracking, PDF generation, and automatic adult-content blurring.
1 Authentication
Authenticate every request using either Basic HTTP Authentication (for server-side use) or Pre-signed URLs (for embedding in front-end applications).
Basic HTTP Authentication
Use your access key as the HTTP username and secret key as the password,
base64-encoded in the Authorization: Basic header.
# Image request with Basic Auth
curl -v -u "access-key:secret-key" \
"https://api.webshrinker.com/thumbnails/v2/aHR0cHM6Ly93d3cud2Vic2hyaW5rZXIuY29tLw==?size=xlarge" \
-o screenshot.png
Pre-signed URLs
Sign requests with an MD5 hash of secret-key:request-url.
The resulting hash parameter replaces your secret key.
WS_ACCESS_KEY="your access key"
WS_SECRET_KEY="your secret key"
URL=$(echo -n "http://www.example.com" | base64)
REQUEST="thumbnails/v2/$URL?key=$WS_ACCESS_KEY&size=xlarge"
HASH=$(echo -n "$WS_SECRET_KEY:$REQUEST" | (md5sum || md5))
echo "https://api.webshrinker.com/$REQUEST&hash=$HASH"
<?php
function webshrinker_v2($access_key, $secret_key, $url, $options=array()) {
$options['key'] = $access_key;
$parameters = http_build_query($options);
$request = sprintf("thumbnails/v2/%s?%s", base64_encode($url), $parameters);
$hash = md5(sprintf("%s:%s", $secret_key, $request));
return "https://api.webshrinker.com/{$request}&hash={$hash}";
}
$access_key = "your access key";
$secret_key = "your secret key";
$url = "http://www.example.com/";
$signedUrl = webshrinker_v2($access_key, $secret_key, $url, ['size' => 'xlarge']);
echo "$signedUrl\n";
?>
try:
from urllib import urlencode
except ImportError:
from urllib.parse import urlencode
from base64 import urlsafe_b64encode
import hashlib
def webshrinker_v2(access_key, secret_key, url, params):
params['key'] = access_key
request = "thumbnails/v2/%s?%s" % (urlsafe_b64encode(url).decode('utf-8'), urlencode(params, True))
signed = hashlib.md5("{}:{}".format(secret_key, request).encode('utf-8')).hexdigest()
return "https://api.webshrinker.com/%s&hash=%s" % (request, signed)
access_key = "your access key"
secret_key = "your secret key"
url = b"http://www.example.com"
params = {'size': 'xlarge'}
print(webshrinker_v2(access_key, secret_key, url, params))
2 Image Request
Returns the screenshot image directly (PNG). If the screenshot is still being generated, a placeholder image is returned with a 202 Accepted status code.
Example Request
# aHR0cHM6Ly93d3cud2Vic2hyaW5rZXIuY29tLw== = base64("https://www.webshrinker.com/")
curl -v -u "access-key:secret-key" \
"https://api.webshrinker.com/thumbnails/v2/aHR0cHM6Ly93d3cud2Vic2hyaW5rZXIuY29tLw==?size=xlarge" \
-o screenshot.png
<?php
function webshrinker_v2($access_key, $secret_key, $url, $options=array()) {
$options['key'] = $access_key;
$parameters = http_build_query($options);
$request = sprintf("thumbnails/v2/%s?%s", base64_encode($url), $parameters);
$hash = md5(sprintf("%s:%s", $secret_key, $request));
return "https://api.webshrinker.com/{$request}&hash={$hash}";
}
$access_key = "your access key";
$secret_key = "your secret key";
$url = "http://www.example.com";
$request = webshrinker_v2($access_key, $secret_key, $url, ['size' => 'xlarge']);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$image_data = curl_exec($ch);
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
switch($status_code) {
case 200:
// $image_data contains the screenshot PNG
file_put_contents('screenshot.png', $image_data);
echo "Screenshot saved to screenshot.png\n";
break;
case 202:
// Placeholder image returned; screenshot being generated
file_put_contents('screenshot.png', $image_data);
echo "Screenshot being created, placeholder saved\n";
break;
case 400: echo "Bad or malformed HTTP request\n"; break;
case 401: echo "Unauthorized - check your access and secret key\n"; break;
case 402: echo "Account request limit reached\n"; break;
}
?>
try:
from urllib import urlencode
except ImportError:
from urllib.parse import urlencode
from base64 import urlsafe_b64encode
import hashlib, requests
def webshrinker_v2(access_key, secret_key, url, params):
params['key'] = access_key
request = "thumbnails/v2/%s?%s" % (urlsafe_b64encode(url).decode('utf-8'), urlencode(params, True))
signed = hashlib.md5("{}:{}".format(secret_key, request).encode('utf-8')).hexdigest()
return "https://api.webshrinker.com/%s&hash=%s" % (request, signed)
access_key = "your access key"
secret_key = "your secret key"
url = b"https://www.webshrinker.com"
params = {'size': 'xlarge'}
api_url = webshrinker_v2(access_key, secret_key, url, params)
response = requests.get(api_url)
if response.status_code == 200:
with open("screenshot.png", "wb") as f:
f.write(response.content)
print("Screenshot saved to screenshot.png")
elif response.status_code == 202:
with open("screenshot.png", "wb") as f:
f.write(response.content)
print("Screenshot being generated, placeholder saved")
elif response.status_code == 400: print("Bad or malformed HTTP request")
elif response.status_code == 401: print("Unauthorized - check your keys")
elif response.status_code == 402: print("Account request limit reached")
else: print("A general error occurred, try again")
3 Info Request
Returns metadata about a screenshot as JSON, including the current state, a pre-signed image URL, and the last updated timestamp.
curl -v -u "access-key:secret-key" \
"https://api.webshrinker.com/thumbnails/v2/aHR0cHM6Ly93d3cud2Vic2hyaW5rZXIuY29tLw==/info"
<?php
function webshrinker_info_v2($access_key, $secret_key, $url, $options=array()) {
$options['key'] = $access_key;
$parameters = http_build_query($options);
$request = sprintf("thumbnails/v2/%s/info?%s", base64_encode($url), $parameters);
$hash = md5(sprintf("%s:%s", $secret_key, $request));
return "https://api.webshrinker.com/{$request}&hash={$hash}";
}
$access_key = "your access key";
$secret_key = "your secret key";
$url = "http://www.example.com";
$request = webshrinker_info_v2($access_key, $secret_key, $url, ['size' => 'xlarge']);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
print_r(json_decode($response));
?>
try:
from urllib import urlencode
except ImportError:
from urllib.parse import urlencode
from base64 import urlsafe_b64encode
import hashlib, requests
def webshrinker_info_v2(access_key, secret_key, url, params):
params['key'] = access_key
request = "thumbnails/v2/%s/info?%s" % (urlsafe_b64encode(url).decode('utf-8'), urlencode(params, True))
signed = hashlib.md5("{}:{}".format(secret_key, request).encode('utf-8')).hexdigest()
return "https://api.webshrinker.com/%s&hash=%s" % (request, signed)
access_key = "your access key"
secret_key = "your secret key"
url = b"http://www.example.com"
params = {'size': 'xlarge'}
api_url = webshrinker_info_v2(access_key, secret_key, url, params)
response = requests.get(api_url)
data = response.json()
if response.status_code == 200:
print(data)
elif response.status_code == 400: print("Bad or malformed HTTP request")
elif response.status_code == 401: print("Unauthorized - check your keys")
elif response.status_code == 402: print("Account request limit reached")
else: print("A general error occurred, try again")
Response
{
"data": [
{
"image": "https://api.webshrinker.com/thumbnails/v2/aHR0cHM6Ly93d3cud2Vic2hyaW5rZXIuY29tLw==?size=xlarge&key=TvQu6ARhl2Zs7BVV1plU&hash=97462c219208614dec16cf9098433f6f",
"state": "READY",
"updated": "Mon, 30 May 2016 23:13:06 +0000",
"url": "https://www.webshrinker.com/"
}
]
}
{
"data": [
{
"image": "https://api.webshrinker.com/thumbnails/v2/aHR0cHM6Ly93d3cud2Vic2hyaW5rZXIuY29tLw==?size=xlarge&key=TvQu6ARhl2Zs7BVV1plU&hash=97462c219208614dec16cf9098433f6f",
"state": "REFRESH",
"updated": "Mon, 30 May 2016 18:03:26 +0000",
"url": "https://www.webshrinker.com/"
}
]
}
4 Query Parameters
| Parameter | Required | Default | Description |
|---|---|---|---|
key |
Required* | — | Access key. Required for pre-signed URL auth. |
size |
Required | — | Preset size name (e.g., xlarge) or custom WxH (e.g., 320x240). |
delay |
Optional | 0 | Additional seconds to wait after page load before capturing. |
expires |
Optional | 0 | Unix timestamp after which the pre-signed URL expires. |
fullpage |
Optional | false | Set to true to capture the full page height instead of the viewport. |
hideadult |
Optional | 0 | Set to 1 to pixelate/blur screenshots of adult-categorized sites. |
refresh |
Optional | false | Force a new screenshot, bypassing cached versions. |
pixelate |
Optional | varies | Blur intensity level. Options: 2, 4, 6, 10, 16. |
viewport |
Optional | 1280x1024 | Browser window dimensions in WxH format. |
width |
Optional | — | Custom output width in pixels (max 2048). Overrides size width. |
_ |
Optional | — | Cache buster — any value to bypass CDN caching. |
5 Screenshot Sizes
Use a preset size name with the size parameter,
or specify a custom resolution in WxH format
(e.g., 800x600).
| Name | Dimensions (W × H) |
|---|---|
micro | 75 × 56 |
tiny | 90 × 68 |
verysmall | 100 × 75 |
small | 120 × 90 |
large | 200 × 150 |
xlarge | 320 × 240 |
2xlarge | 550 × 412 |
3xlarge | 1024 × 768 |
4xlarge | 1280 × 1024 |
| custom | e.g., 320x240 (any W × H) |
6 Screenshot States
The state field in the info response indicates
the current status of the screenshot.
| State | Description |
|---|---|
READY |
Screenshot has been generated and is available. |
REFRESH |
Site is being revisited to generate an updated screenshot. The previous image is still available. |
PROCESSING |
Screenshot is currently being generated. No image is available yet. |
ERROR |
The site could not be accessed or the screenshot could not be generated. |
7 HTTP Status Codes
| Code | Status | Description |
|---|---|---|
| 200 | OK | Screenshot returned successfully. |
| 202 | Accepted | Screenshot being generated; placeholder image returned. |
| 400 | Bad Request | Invalid or malformed request parameters. |
| 401 | Unauthorized | Invalid API credentials or signature. |
| 402 | Payment Required | Account balance depleted. |
| 429 | Too Many Requests | Rate limit exceeded. |
| 500 | Server Error | Internal server error. Retry the request. |