Screenshots
The Screenshots API allows you to capture, retrieve, list, and delete website screenshots. All endpoints require authentication.
Create a Screenshot
POST /v1/screenshots
Queues a new screenshot for capture. Returns a 202 Accepted response with the screenshot object in pending status.
Feature Availability
Some parameters are only available on certain plans. If you use a feature not included in your plan, the API returns a 422 error with a message indicating which feature requires an upgrade.
Note: The table below reflects the current plan configuration. Plan features and limits are managed dynamically and may change over time. Always check your current plan details via GET /v1/account for the most up-to-date information.
| Feature / Parameter | Free | Starter | Pro | Business |
|---|---|---|---|---|
url, width, height | Yes | Yes | Yes | Yes |
full_page | Yes | Yes | Yes | Yes |
delay | Yes | Yes | Yes | Yes |
block_cookies | Yes | Yes | Yes | Yes |
selector | Yes | Yes | Yes | Yes |
wait_for_selector | Yes | Yes | Yes | Yes |
omit_background | Yes | Yes | Yes | Yes |
reduced_motion | Yes | Yes | Yes | Yes |
device (mobile/tablet) | — | Yes | Yes | Yes |
retina | — | Yes | Yes | Yes |
block_ads | — | Yes | Yes | Yes |
block_chats | — | Yes | Yes | Yes |
format: pdf | — | Yes | Yes | Yes |
webhook_url | — | Yes | Yes | Yes |
html (HTML rendering) | — | Yes | Yes | Yes |
user_agent | — | Yes | Yes | Yes |
headers, cookies | — | Yes | Yes | Yes |
dark_mode | — | — | Yes | Yes |
css, js | — | — | Yes | Yes |
stealth | — | — | Yes | Yes |
timezone | — | — | Yes | Yes |
extract_metadata | — | — | Yes | Yes |
markdown (Markdown rendering) | — | — | Yes | Yes |
| Batch API | — | — | Yes | Yes |
| Signed URLs | — | Yes | Yes | Yes |
| PDF options (landscape, page size, margins) | — | Yes | Yes | Yes |
geolocation | — | — | — | Yes |
proxy | — | — | — | Yes |
Image Retention
Screenshot images are stored temporarily and automatically deleted after the retention period expires. The retention period depends on your current plan and may change if you upgrade or downgrade:
| Plan | Retention |
|---|---|
| Free | 24 hours |
| Starter | 48 hours |
| Pro | 7 days |
| Business | 30 days |
Once expired, the screenshot metadata remains accessible via the API, but the image file returns 410 Gone. Download images promptly or use webhooks to automate downloads upon completion.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
url | string | Yes* | — | The URL to capture. Must be a valid HTTP or HTTPS URL. Required unless html or markdown is provided. |
html | string | Yes* | — | Raw HTML to render instead of a URL. Max 500,000 characters. Required unless url or markdown is provided. |
markdown | string | Yes* | — | Markdown content to render as a screenshot. Converted to styled HTML automatically. Max 500,000 characters. Required unless url or html is provided. |
width | integer | No | 1280 | Viewport width in pixels. Range: 320–3840. |
height | integer | No | 800 | Viewport height in pixels. Range: 200–2160. |
format | string | No | png | Image format: png, jpeg, webp, avif, tiff, or pdf. |
quality | integer | No | 80 | Image quality for JPEG, WebP, and AVIF formats. Range: 1–100. |
full_page | boolean | No | false | Capture the full scrollable page instead of just the viewport. |
device | string | No | desktop | Device preset: desktop, tablet, or mobile. Sets appropriate viewport and user-agent. |
block_ads | boolean | No | false | Block ads and trackers before capturing. |
block_cookies | boolean | No | true | Block cookie consent banners (OneTrust, CookieBot, etc.) before capturing. Blocks consent scripts, hides banner elements, and attempts to click “Accept” buttons. |
block_chats | boolean | No | false | Block chat widgets (Intercom, Crisp, Tawk, Drift, etc.) before capturing. |
dark_mode | boolean | No | false | Emulate prefers-color-scheme: dark media feature. |
delay | integer | No | 0 | Wait time in seconds before capture (0–10). Useful for pages with animations or lazy-loaded content. |
timeout | integer | No | 30 | Page load timeout in seconds. Range: 5–60. |
css | string | No | — | Custom CSS to inject into the page before capturing. Max 10,000 characters. |
js | string | No | — | Custom JavaScript to execute on the page before capturing. Max 10,000 characters. |
selector | string | No | — | CSS selector of a specific element to capture instead of the full page. Max 500 characters. |
retina | boolean | No | false | Capture at 2x resolution (Retina display). |
resize_width | integer | No | — | Resize the output image to this width in pixels (16–3840). Aspect ratio is preserved. The image will not be enlarged beyond its original size. |
resize_height | integer | No | — | Resize the output image to this height in pixels (16–2160). Aspect ratio is preserved. The image will not be enlarged beyond its original size. |
headers | object | No | — | Custom HTTP headers to send when loading the page. Max 20 headers, each value max 2048 characters. Example: {"X-Custom": "value"} |
cookies | array | No | — | Cookies to set before loading the page. Array of objects with name, value, and optional domain. Max 20 cookies. |
pdf_landscape | boolean | No | false | Generate PDF in landscape orientation. Only applies when format is pdf. |
pdf_page_format | string | No | A4 | PDF page size: A3, A4, A5, Letter, Legal, or Tabloid. |
pdf_margin_top | string | No | 10mm | PDF top margin (e.g. 10mm, 1in, 0). |
pdf_margin_right | string | No | 10mm | PDF right margin. |
pdf_margin_bottom | string | No | 10mm | PDF bottom margin. |
pdf_margin_left | string | No | 10mm | PDF left margin. |
hide_selectors | array | No | — | Array of CSS selectors to hide before capturing (e.g. cookie banners, popups). Max 20 selectors. Example: [".cookie-banner", "#popup"] |
click_selector | string | No | — | CSS selector of an element to click before capturing. Useful for dismissing modals or expanding content. Max 500 characters. |
scroll_to | string | No | — | CSS selector of an element to scroll into view before capturing. Max 500 characters. |
cache_ttl | integer | No | 0 | Cache duration in seconds (0–86400). If a matching screenshot was captured within this period, it is returned immediately without re-rendering. |
wait_for_selector | string | No | — | CSS selector to wait for before capturing. Useful for SPAs and dynamically loaded content. Waits up to 10 seconds. Max 500 characters. |
omit_background | boolean | No | false | Capture with transparent background (PNG and WebP only). Useful for logos and UI elements. |
reduced_motion | boolean | No | false | Emulate prefers-reduced-motion: reduce. Disables CSS animations and transitions for cleaner captures. |
stealth | boolean | No | false | Enable stealth mode to bypass bot detection. Hides automation signals (webdriver, plugins, WebGL, etc.). |
user_agent | string | No | — | Custom User-Agent string. Overrides the device preset User-Agent. Max 500 characters. |
timezone | string | No | — | IANA timezone for the browser context (e.g. America/New_York, Europe/Berlin). Affects Date and Intl APIs. |
geolocation | object | No | — | Emulate browser geolocation. Object with latitude (-90 to 90), longitude (-180 to 180), and optional accuracy (meters). |
proxy | string | No | — | HTTP/SOCKS proxy URL for the request (e.g. http://user:pass@proxy:8080). A dedicated browser is launched per proxy request. |
extract_metadata | boolean | No | false | Extract page metadata (title, description, Open Graph tags, Twitter Card, favicon URL) and include in the response. |
webhook_url | string | No | — | URL to receive a POST notification when the screenshot is ready. See Webhooks. |
response_type | string | No | json (POST) / image (GET) | Controls the response format. image waits for the screenshot to complete and returns the binary file directly. json returns a 202 Accepted response with the screenshot object. The GET /capture endpoint defaults to image; the POST /screenshots endpoint defaults to json. |
Note: You can specify resize_width, resize_height, or both. When both are provided, the image fits inside the given dimensions while maintaining aspect ratio. Resize only applies to image formats (not PDF).
Note: url, html, and markdown are mutually exclusive — provide one of them.
Example Request
cURL
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"width": 1440,
"height": 900,
"format": "webp",
"full_page": true,
"device": "desktop",
"dark_mode": true
}'
PHP
$response = Http::withToken(env('SCREENSHOT_API_KEY'))
->post('https://api.screenshotrun.com/v1/screenshots', [
'url' => 'https://example.com',
'width' => 1440,
'height' => 900,
'format' => 'webp',
'full_page' => true,
'dark_mode' => true,
]);
$screenshot = $response->json('data');
echo "Screenshot ID: " . $screenshot['id'];
Python
import requests
response = requests.post(
"https://api.screenshotrun.com/v1/screenshots",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"url": "https://example.com",
"width": 1440,
"height": 900,
"format": "webp",
"full_page": True,
"dark_mode": True,
}
)
screenshot = response.json()["data"]
print(f"Screenshot ID: {screenshot['id']}")
JavaScript (Node.js)
const response = await fetch("https://api.screenshotrun.com/v1/screenshots", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://example.com",
width: 1440,
height: 900,
format: "webp",
full_page: true,
dark_mode: true,
}),
});
const { data } = await response.json();
console.log(`Screenshot ID: ${data.id}`);
Ruby
require "net/http"
require "json"
require "uri"
uri = URI("https://api.screenshotrun.com/v1/screenshots")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"
request["Content-Type"] = "application/json"
request.body = {
url: "https://example.com",
width: 1440,
height: 900,
format: "webp",
full_page: true,
dark_mode: true
}.to_json
response = http.request(request)
screenshot = JSON.parse(response.body)["data"]
puts "Screenshot ID: #{screenshot['id']}"
Go
payload := strings.NewReader(`{
"url": "https://example.com",
"width": 1440,
"height": 900,
"format": "webp",
"full_page": true,
"dark_mode": true
}`)
req, _ := http.NewRequest("POST", "https://api.screenshotrun.com/v1/screenshots", payload)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
var result struct {
Data struct {
ID string `json:"id"`
} `json:"data"`
}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Screenshot ID: %s\n", result.Data.ID)
Response (202 Accepted)
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"url": "https://example.com",
"options": {
"width": 1440,
"height": 900,
"format": "webp",
"quality": 80,
"full_page": true,
"device": "desktop",
"block_ads": false,
"block_cookies": true,
"dark_mode": true,
"delay": 0,
"timeout": 30,
"retina": false
},
"estimated_time": 5,
"created_at": "2026-03-09T10:30:00.000000Z",
"links": {
"self": "https://api.screenshotrun.com/v1/screenshots/550e8400-e29b-41d4-a716-446655440000"
}
}
}
Quick Capture (GET or POST)
GET /v1/screenshots/capture
POST /v1/screenshots/capture
The simplest way to capture a screenshot. Returns the image binary directly by default (no polling needed). Accepts the same parameters as POST /v1/screenshots.
Use GET with query parameters for simple requests, or POST with a JSON body when sending large payloads like html or markdown.
Example: GET with query parameters
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.screenshotrun.com/v1/screenshots/capture?url=https://example.com&width=1440&format=webp" \
-o screenshot.webp
Example: POST with JSON body
curl -X POST https://api.screenshotrun.com/v1/screenshots/capture \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<h1>Hello World</h1><p>Rendered from HTML</p>",
"width": 1200,
"height": 630
}' \
-o screenshot.png
POST is recommended when sending html or markdown content, as GET query strings have length limits.
Browser / HTML
<a href="https://api.screenshotrun.com/v1/screenshots/capture?url=https://example.com&width=1280&format=png">
Take Screenshot
</a>
To get the async JSON response instead (same as POST /v1/screenshots), pass response_type=json.
Get a Screenshot
GET /v1/screenshots/{id}
Returns the screenshot object with its current status and details.
Example Request
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://api.screenshotrun.com/v1/screenshots/550e8400-e29b-41d4-a716-446655440000
Response — Completed
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"url": "https://example.com",
"options": {
"width": 1440,
"height": 900,
"format": "webp",
"quality": 80,
"full_page": true,
"device": "desktop",
"block_ads": false,
"block_cookies": true,
"dark_mode": true,
"delay": 0,
"timeout": 30,
"retina": false
},
"file_size": 245760,
"mime_type": "image/webp",
"width": 1440,
"height": 3200,
"processing_time_ms": 3450,
"completed_at": "2026-03-09T10:30:05.000000Z",
"expires_at": "2026-04-09T10:30:05.000000Z",
"created_at": "2026-03-09T10:30:00.000000Z",
"links": {
"self": "https://api.screenshotrun.com/v1/screenshots/550e8400-e29b-41d4-a716-446655440000",
"image": "https://api.screenshotrun.com/v1/screenshots/550e8400-e29b-41d4-a716-446655440000/image"
}
}
}
Response — Failed
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "failed",
"url": "https://example.com",
"options": { ... },
"error": {
"message": "Page load timed out after 30 seconds.",
"code": "TIMEOUT"
},
"created_at": "2026-03-09T10:30:00.000000Z",
"links": {
"self": "https://api.screenshotrun.com/v1/screenshots/550e8400-e29b-41d4-a716-446655440000"
}
}
}
Get Screenshot Image
GET /v1/screenshots/{id}/image
Returns the binary image file. Only available for screenshots with completed status.
Example Request
# Download to file
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://api.screenshotrun.com/v1/screenshots/550e8400-.../image \
-o screenshot.webp
Responses
| Status | Description |
|---|---|
200 OK | Image file with appropriate Content-Type header (image/png, image/jpeg, image/webp, image/avif, image/tiff, or application/pdf) |
404 Not Found | Screenshot not ready yet (status is pending or processing) |
410 Gone | Screenshot image has expired and is no longer available |
List Screenshots
GET /v1/screenshots
Returns a paginated list of your screenshots, sorted by creation date (newest first).
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
per_page | integer | 20 | Results per page (max 100) |
status | string | — | Filter by status: pending, processing, completed, failed |
sort_by | string | created_at | Sort field |
sort_dir | string | desc | Sort direction: asc or desc |
date_from | string | — | Filter screenshots created after this date (ISO 8601) |
date_to | string | — | Filter screenshots created before this date (ISO 8601) |
Example Request
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.screenshotrun.com/v1/screenshots?status=completed&per_page=10&sort_dir=desc"
Response
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"url": "https://example.com",
"options": { ... },
"file_size": 245760,
"mime_type": "image/webp",
"width": 1440,
"height": 3200,
"processing_time_ms": 3450,
"completed_at": "2026-03-09T10:30:05.000000Z",
"expires_at": "2026-04-09T10:30:05.000000Z",
"created_at": "2026-03-09T10:30:00.000000Z",
"links": {
"self": "...",
"image": "..."
}
}
],
"links": {
"first": "https://api.screenshotrun.com/v1/screenshots?page=1",
"last": "https://api.screenshotrun.com/v1/screenshots?page=5",
"prev": null,
"next": "https://api.screenshotrun.com/v1/screenshots?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 5,
"links": [
{"url": null, "label": "« Previous", "page": null, "active": false},
{"url": "...?page=1", "label": "1", "page": 1, "active": true},
{"url": "...?page=2", "label": "2", "page": 2, "active": false},
{"url": "...?page=2", "label": "Next »", "page": 2, "active": false}
],
"path": "https://api.screenshotrun.com/v1/screenshots",
"per_page": 10,
"to": 10,
"total": 48
}
}
Delete a Screenshot
DELETE /v1/screenshots/{id}
Permanently deletes a screenshot and its associated image file. This action cannot be undone.
Example Request
curl -X DELETE -H "Authorization: Bearer YOUR_API_KEY" \
https://api.screenshotrun.com/v1/screenshots/550e8400-e29b-41d4-a716-446655440000
Response
Returns 204 No Content on success with an empty body.
Common Use Cases
Capture a mobile screenshot
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"device": "mobile",
"format": "png"
}'
Full-page screenshot in dark mode
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"full_page": true,
"dark_mode": true,
"format": "webp"
}'
Screenshot with delay (wait for animations)
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"delay": 3
}'
Screenshot with resize (thumbnail)
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"resize_width": 320
}'
This captures a full-size screenshot and then resizes it to 320px wide (height auto-calculated to preserve aspect ratio). Useful for generating thumbnails or previews.
Quick capture via GET
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.screenshotrun.com/v1/screenshots/capture?url=https://example.com&format=jpeg&quality=60&resize_width=640"
Screenshot with webhook notification
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"webhook_url": "https://yourapp.com/webhooks/screenshot"
}'
Poll until completed (Python)
import time
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.screenshotrun.com/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}
# Create screenshot
response = requests.post(
f"{BASE_URL}/screenshots",
headers=headers,
json={"url": "https://example.com"}
)
screenshot_id = response.json()["data"]["id"]
# Poll until ready
while True:
status_response = requests.get(
f"{BASE_URL}/screenshots/{screenshot_id}",
headers=headers,
)
data = status_response.json()["data"]
if data["status"] == "completed":
# Download the image
image_response = requests.get(
f"{BASE_URL}/screenshots/{screenshot_id}/image",
headers=headers,
)
with open("screenshot.png", "wb") as f:
f.write(image_response.content)
print("Screenshot saved!")
break
elif data["status"] == "failed":
print(f"Failed: {data['error']['message']}")
break
time.sleep(2) # Wait 2 seconds before next poll
Screenshot with custom headers and cookies
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/dashboard",
"headers": {
"X-Custom-Auth": "token123",
"Accept-Language": "de-DE"
},
"cookies": [
{"name": "session_id", "value": "abc123", "domain": "example.com"},
{"name": "theme", "value": "dark"}
]
}'
HTML to screenshot
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<html><body style=\"padding:40px;font-family:sans-serif\"><h1>Hello World</h1><p>Rendered from raw HTML</p></body></html>",
"width": 800,
"height": 600
}'
When using html, you do not need to provide a url. The HTML is rendered directly in the browser. This is useful for generating images from templates, invoices, reports, or any dynamic content.
PDF with custom options
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/report",
"format": "pdf",
"pdf_landscape": true,
"pdf_page_format": "A3",
"pdf_margin_top": "20mm",
"pdf_margin_bottom": "20mm",
"pdf_margin_left": "15mm",
"pdf_margin_right": "15mm"
}'
Hide elements before capture
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"hide_selectors": [".cookie-banner", "#newsletter-popup", ".ads-container"]
}'
Elements matching the given CSS selectors are hidden (display: none) before the screenshot is taken. Useful for removing cookie consent banners, popups, ads, or any distracting UI elements.
Click before capture
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"click_selector": "#accept-cookies"
}'
Clicks the element matching the selector before taking the screenshot. Useful for dismissing modals, accepting cookie consent, or triggering UI state changes.
Scroll to element
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"scroll_to": "#pricing-section"
}'
Scrolls the page to bring the element into view before capturing. Combine with selector to capture a specific section of the page.
Cached screenshot
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"cache_ttl": 3600
}'
If a screenshot of the same URL with the same options was captured within the last 3600 seconds (1 hour), the existing screenshot is returned immediately without re-rendering. This saves processing time and API credits. Set cache_ttl to 0 (default) to always capture a fresh screenshot.
Inject custom CSS
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"css": "body { font-family: Arial, sans-serif; } .sidebar { display: none; } .main-content { width: 100%; }"
}'
Inject custom CSS to change fonts, hide elements, or adjust the layout before the screenshot is taken. Max 10,000 characters.
Execute JavaScript before capture
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"js": "document.querySelectorAll(\"video\").forEach(v => v.pause()); document.querySelector(\"#banner\")?.remove();"
}'
Execute JavaScript to modify the page before capturing. Useful for pausing videos, removing elements, expanding collapsed content, or triggering UI state changes. Max 10,000 characters.
Stealth mode
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"stealth": true
}'
Stealth mode hides browser automation signals (WebDriver flag, headless Chrome indicators, plugin counts, WebGL vendor) to bypass bot detection on sites that block automated browsers.
Custom User-Agent
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15"
}'
Override the browser User-Agent string. When combined with device, the custom User-Agent takes priority over the device preset.
Set timezone
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/dashboard",
"timezone": "Asia/Tokyo"
}'
Set the browser timezone to an IANA timezone identifier. This affects Date, Intl, and any time-dependent content shown on the page.
Emulate geolocation
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://maps.google.com",
"geolocation": {
"latitude": 48.8566,
"longitude": 2.3522,
"accuracy": 100
}
}'
Emulate the browser geolocation API. Sites that use navigator.geolocation will see the coordinates you provide. The accuracy field is optional and defaults to meters.
Use a proxy
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"proxy": "http://user:[email protected]:8080"
}'
Route the screenshot request through an HTTP or SOCKS proxy. Useful for capturing geo-restricted content or accessing sites behind a firewall. Supports http://, https://, and socks5:// protocols.
Markdown to screenshot
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Monthly Report\n\n## Key Metrics\n\n| Metric | Value |\n|--------|-------|\n| Users | 1,234 |\n| Revenue | $5,678 |\n\n> Data as of June 2026",
"width": 800,
"height": 600
}'
Render Markdown content directly as a screenshot. The Markdown is converted to styled HTML with clean typography, syntax highlighting for code blocks, and proper table formatting. No url parameter needed.
Synchronous capture (response_type: image)
# Returns the image binary directly instead of a JSON response
curl -X POST https://api.screenshotrun.com/v1/screenshots \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"format": "png",
"response_type": "image"
}' \
-o screenshot.png
When response_type is set to image, the API waits for the screenshot to complete and returns the binary image file directly with the appropriate Content-Type header. No polling required.
Tip: The GET /v1/screenshots/capture endpoint defaults to response_type=image, so you don't need to specify it explicitly. For POST /v1/screenshots, the default is json (async).
Batch Screenshots
POST /v1/screenshots/batch
Create multiple screenshots in a single API call. All screenshots share the same options but capture different URLs. Returns a 202 Accepted response with an array of screenshot objects.
Requires: The batch feature on your plan.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
urls | array | Yes | Array of URLs to capture. Min 1, max 100. |
Supported shared parameters: width, height, full_page, format, quality, device, dark_mode, block_ads, block_cookies, block_chats, delay, timeout, css, js, retina, resize_width, resize_height, stealth, omit_background, reduced_motion, user_agent, timezone, wait_for_selector, webhook_url. | |||
Not supported in batch: selector, click_selector, scroll_to, headers, cookies, hide_selectors, html, markdown, pdf_*, geolocation, proxy, cache_ttl, extract_metadata, response_type. | |||
Example Request
curl -X POST https://api.screenshotrun.com/v1/screenshots/batch \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"urls": [
"https://example.com",
"https://example.org",
"https://example.net"
],
"width": 1440,
"format": "webp",
"full_page": true
}'
Response (202 Accepted)
{
"data": [
{
"id": "550e8400-...",
"status": "pending",
"url": "https://example.com",
"options": { ... },
"created_at": "2026-03-09T10:30:00.000000Z",
"links": { "self": "..." }
},
{
"id": "660f9500-...",
"status": "pending",
"url": "https://example.org",
"options": { ... },
"created_at": "2026-03-09T10:30:00.000000Z",
"links": { "self": "..." }
},
{
"id": "770a0600-...",
"status": "pending",
"url": "https://example.net",
"options": { ... },
"created_at": "2026-03-09T10:30:00.000000Z",
"links": { "self": "..." }
}
],
"total": 3
}
Each screenshot is processed independently. Poll each one by its id or use webhook_url to be notified when each completes — a separate webhook is sent for every screenshot in the batch.
Signed URLs
POST /v1/screenshots/{id}/signed-url
Generate an HMAC-signed URL to share a completed screenshot image without requiring an API key. Useful for embedding images in emails, sharing with clients, or displaying in public web pages.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
expires_in | integer | 60 | Expiration time in minutes. Range: 1–43200 (30 days). Pass 0 for a permanent URL. |
Example Request
# Generate a signed URL that expires in 24 hours
curl -X POST https://api.screenshotrun.com/v1/screenshots/550e8400-.../signed-url \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"expires_in": 1440}'
Response
{
"data": {
"url": "https://api.screenshotrun.com/v1/screenshots/550e8400-.../signed-image?expires=1741520400&signature=abc123...",
"expires_at": "2026-03-10T10:30:00+00:00"
}
}
The signed URL can be opened in any browser or used in <img> tags without authentication. Once expired, the URL returns 403 Forbidden.
Example — Permanent signed URL
curl -X POST https://api.screenshotrun.com/v1/screenshots/550e8400-.../signed-url \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"expires_in": 0}'
Permanent URLs remain valid as long as the screenshot image exists (until the retention period ends).