Screenshot API
The Screenshot API captures pixel-perfect screenshots of any web page and returns the image as base64, a hosted URL, or raw binary.
For structured data extraction that also includes a screenshot, see the /extract endpoint instead. The Screenshot API is optimized specifically for image capture with full control over format, viewport, and rendering options.
Authentication
All requests require an API key in the Authorization header:
Authorization: Bearer your_api_keyYour API key is available on your Account Page and on the API tab of each recipe. See the main API authentication docs for details.
Endpoints
The base endpoint is https://api.simplescraper.io/v1/screenshot. You can use either POST (recommended, with a JSON body) or GET (with query string parameters). Both accept the same parameters and return the same response.
| Method | Usage |
|---|---|
| POST /v1/screenshot | JSON body - handles special characters in URLs without manual encoding |
| GET /v1/screenshot | Query params - useful for simple integrations and browser testing |
Response formats
The output parameter controls how the screenshot is delivered. The response always includes metadata except when using binary.
| Value | Default | Response type | screenshot field | Storage |
|---|---|---|---|---|
base64 | Yes | JSON | Base64-encoded image string | Not stored (unless store: true) |
url | No | JSON | Public hosted URL | Stored automatically, 30-day TTL |
binary | No | Raw image bytes | N/A (no JSON, Content-Type: image/{format}) | Not stored (unless store: true) |
When output is base64 or binary, you can set store: true to also save the image to cloud storage. The hosted URL will appear in the JSON response as screenshot_url (for base64), or you can make a separate request with output: "url" to get one.
POST /v1/screenshot
Full endpoint
https://api.simplescraper.io/v1/screenshot
Send a POST request with a JSON body to capture a screenshot. This is the recommended method - it handles special characters in URLs without manual encoding.
Request body properties
| Property | Required | Type | Default | Description |
|---|---|---|---|---|
| url | Yes | String | - | Target URL to capture |
| output | No | String | base64 | How the image is delivered: base64, url, or binary |
| store | No | Boolean | false | Save the image to cloud storage. Automatically true when output is url. |
| format | No | String | png | Image format: png, jpeg, or webp |
| quality | No | Number | 80 | JPEG/WebP compression quality, 1-100 (ignored for PNG) |
| full_page | No | Boolean | false | Capture the full scrollable page instead of just the viewport |
| viewport_width | No | Number | 1920 | Browser viewport width in pixels, 320-3840 |
| viewport_height | No | Number | 1080 | Browser viewport height in pixels, 320-3840 |
| device_scale_factor | No | Number | 1 | Pixel density multiplier: 1, 1.5, 2, or 3 |
| delay | No | Number | 0 | Seconds to wait after page load before capture, 0-15 |
| wait_for_selector | No | String | null | CSS selector to wait for before capturing |
| wait_until | No | String | load | Page load event to wait for: load, domcontentloaded, networkidle0, networkidle2 |
| hide_popups | No | Boolean | true | Hide cookie consent popups before capture |
| hide_ads | No | Boolean | true | Hide ad network content during page load |
| hide_background | No | Boolean | false | Make the page background transparent (PNG and WebP only, ignored for JPEG) |
Example: base64 response (default)
async function captureScreenshot(apikey, targetUrl) {
const url = 'https://api.simplescraper.io/v1/screenshot';
const requestBody = {
url: targetUrl,
format: 'png',
viewport_width: 1280,
viewport_height: 800,
device_scale_factor: 2
};
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${apikey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
});
const data = await response.json();
console.log(data.screenshot); // base64-encoded image
} catch (error) {
console.error('error:', error);
}
}
captureScreenshot('YOUR_API_KEY', 'https://example.com');Response
{
"id": "ss_abc123def456",
"url": "https://example.com",
"status": "completed",
"date_captured": "2026-02-25T12:00:00.000Z",
"screenshot": "iVBORw0KGgoAAAANSUhEUgAA...",
"metadata": {
"title": "Example Domain",
"image_size_bytes": 234567,
"capped": false
}
}Example: hosted URL response
const requestBody = {
url: 'https://example.com',
output: 'url',
format: 'png',
viewport_width: 1280,
viewport_height: 800
};
const response = await fetch('https://api.simplescraper.io/v1/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apikey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
});
const data = await response.json();
console.log(data.screenshot); // hosted URL for the screenshotResponse
{
"id": "ss_abc123def456",
"url": "https://example.com",
"status": "completed",
"date_captured": "2026-02-25T12:00:00.000Z",
"screenshot": "https://screenshots.simplescraper.io/ss_abc123def456.png",
"metadata": {
"title": "Example Domain",
"image_size_bytes": 234567,
"capped": false
}
}Hosted images are kept for 30 days. Setting output: "url" automatically sets store: true.
Example: binary response
const requestBody = {
url: 'https://example.com',
output: 'binary',
format: 'jpeg',
quality: 90
};
const response = await fetch('https://api.simplescraper.io/v1/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apikey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
});
// Response is raw image bytes, not JSON
const imageBuffer = await response.arrayBuffer();The response body is the raw image with Content-Type: image/jpeg (or image/png, image/webp depending on format). There is no JSON wrapper. Metadata is not included.
Example: base64 with storage
const requestBody = {
url: 'https://example.com',
output: 'base64',
store: true
};
const response = await fetch('https://api.simplescraper.io/v1/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apikey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
});
const data = await response.json();
console.log(data.screenshot); // base64-encoded image
console.log(data.screenshot_url); // hosted URL for the screenshotResponse
{
"id": "ss_abc123def456",
"url": "https://example.com",
"status": "completed",
"date_captured": "2026-02-25T12:00:00.000Z",
"screenshot": "iVBORw0KGgoAAAANSUhEUgAA...",
"screenshot_url": "https://screenshots.simplescraper.io/ss_abc123def456.png",
"metadata": {
"title": "Example Domain",
"image_size_bytes": 234567,
"capped": false
}
}GET /v1/screenshot
Full endpoint
https://api.simplescraper.io/v1/screenshot?url=https://example.com&format=png
GET requests accept the same parameters as query strings. This is useful for simple integrations, browser testing, or systems that can't send POST bodies.
The parameter names and accepted values are identical to the POST endpoint above. URL-encode the url and wait_for_selector parameters.
Example GET request
async function captureScreenshot(apikey, targetUrl) {
const params = new URLSearchParams({
url: targetUrl,
format: 'png',
viewport_width: '1280',
viewport_height: '800',
device_scale_factor: '2'
});
const requestUrl = `https://api.simplescraper.io/v1/screenshot?${params}`;
try {
const response = await fetch(requestUrl, {
headers: {
'Authorization': `Bearer ${apikey}`
}
});
const data = await response.json();
console.log(data);
} catch (error) {
console.error('error:', error);
}
}
captureScreenshot('YOUR_API_KEY', 'https://example.com');Credits and pricing
Each screenshot request costs 1 credit.
See the Credits page for credit bundles and your current balance.
Error responses
| Status code | Error | Message |
|---|---|---|
| 400 | invalid-url-format | The URL isn't valid. |
| 400 | invalid-value | A parameter is outside its accepted range or not a valid option. |
| 401 | unauthorized | API key is missing or invalid. |
| 402 | insufficient-credits | Not enough credits on your account. |
| 408 | screenshot-timeout | The page took too long to load or render. |
| 429 | rate-limit-exceeded | Too many requests - slow down and retry. |
| 500 | screenshot-failed | The screenshot couldn't be captured. This can happen if the page blocks automated browsers or returns a non-200 response. |
Notes
Full-page capping - Very tall pages may be capped at the browser's maximum capture height. If that happens, metadata.capped will be true in the response. You'll still get everything up to the cap.
Transparent backgrounds - Set hide_background to true to get a transparent background on PNG or WebP screenshots. Handy for pages with no background color set. Has no effect on JPEG since the format doesn't support transparency.
Image storage - When output is url or store is true, the image is saved to cloud storage and kept for 30 days.
The wait_until parameter - Controls when the page is considered "loaded":
load- Waits for theloadevent (all resources including images). This is the default.domcontentloaded- Fires when HTML is parsed, before images and stylesheets finish. Faster but may miss visual content.networkidle0- Waits until there are zero network connections for 500ms. Best for SPAs and pages that fetch data after load.networkidle2- Waits until two or fewer network connections remain for 500ms. Good for pages with persistent connections like analytics or websockets.