Features Pricing Docs Blog Try Demo Log In Sign Up

Screenshots

The Screenshots API allows you to capture, retrieve, list, and delete website screenshots. All endpoints require authentication.

Create a Screenshot

http
POST /api/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 /api/v1/account for the most up-to-date information.

Feature / ParameterFreeStarterProBusiness
url, width, heightYesYesYesYes
full_pageYesYesYesYes
delayYesYesYesYes
block_cookiesYesYesYesYes
selectorYesYesYesYes
wait_for_selectorYesYesYesYes
omit_backgroundYesYesYesYes
reduced_motionYesYesYesYes
device (mobile/tablet)YesYesYes
retinaYesYesYes
block_adsYesYesYes
block_chatsYesYesYes
format: pdfYesYesYes
webhook_urlYesYesYes
html (HTML rendering)YesYesYes
user_agentYesYesYes
headers, cookiesYesYesYes
dark_modeYesYes
css, jsYesYes
stealthYesYes
timezoneYesYes
extract_metadataYesYes
markdown (Markdown rendering)YesYes
Batch APIYesYes
Signed URLsYesYesYes
PDF options (landscape, page size, margins)YesYesYes
S3 exportYes
geolocationYes
proxyYes

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:

PlanRetention
Free24 hours
Starter48 hours
Pro7 days
Business30 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

ParameterTypeRequiredDefaultDescription
urlstringYes*The URL to capture. Must be a valid HTTP or HTTPS URL. Required unless html or markdown is provided.
htmlstringYes*Raw HTML to render instead of a URL. Max 500,000 characters. Required unless url or markdown is provided.
markdownstringYes*Markdown content to render as a screenshot. Converted to styled HTML automatically. Max 500,000 characters. Required unless url or html is provided.
widthintegerNo1280Viewport width in pixels. Range: 320–3840.
heightintegerNo800Viewport height in pixels. Range: 200–2160.
formatstringNopngImage format: png, jpeg, webp, avif, tiff, or pdf.
qualityintegerNo80Image quality for JPEG, WebP, and AVIF formats. Range: 1–100.
full_pagebooleanNofalseCapture the full scrollable page instead of just the viewport.
devicestringNodesktopDevice preset: desktop, tablet, or mobile. Sets appropriate viewport and user-agent.
block_adsbooleanNofalseBlock ads and trackers before capturing.
block_cookiesbooleanNotrueBlock cookie consent banners (OneTrust, CookieBot, etc.) before capturing. Blocks consent scripts, hides banner elements, and attempts to click “Accept” buttons.
block_chatsbooleanNofalseBlock chat widgets (Intercom, Crisp, Tawk, Drift, etc.) before capturing.
dark_modebooleanNofalseEmulate prefers-color-scheme: dark media feature.
delayintegerNo0Wait time in seconds before capture (0–10). Useful for pages with animations or lazy-loaded content.
timeoutintegerNo30Page load timeout in seconds. Range: 5–60.
cssstringNoCustom CSS to inject into the page before capturing. Max 10,000 characters.
jsstringNoCustom JavaScript to execute on the page before capturing. Max 10,000 characters.
selectorstringNoCSS selector of a specific element to capture instead of the full page. Max 500 characters.
retinabooleanNofalseCapture at 2x resolution (Retina display).
resize_widthintegerNoResize 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_heightintegerNoResize the output image to this height in pixels (16–2160). Aspect ratio is preserved. The image will not be enlarged beyond its original size.
headersobjectNoCustom HTTP headers to send when loading the page. Max 20 headers, each value max 2048 characters. Example: {"X-Custom": "value"}
cookiesarrayNoCookies to set before loading the page. Array of objects with name, value, and optional domain. Max 20 cookies.
pdf_landscapebooleanNofalseGenerate PDF in landscape orientation. Only applies when format is pdf.
pdf_page_formatstringNoA4PDF page size: A3, A4, A5, Letter, Legal, or Tabloid.
pdf_margin_topstringNo10mmPDF top margin (e.g. 10mm, 1in, 0).
pdf_margin_rightstringNo10mmPDF right margin.
pdf_margin_bottomstringNo10mmPDF bottom margin.
pdf_margin_leftstringNo10mmPDF left margin.
hide_selectorsarrayNoArray of CSS selectors to hide before capturing (e.g. cookie banners, popups). Max 20 selectors. Example: [".cookie-banner", "#popup"]
click_selectorstringNoCSS selector of an element to click before capturing. Useful for dismissing modals or expanding content. Max 500 characters.
scroll_tostringNoCSS selector of an element to scroll into view before capturing. Max 500 characters.
cache_ttlintegerNo0Cache duration in seconds (0–86400). If a matching screenshot was captured within this period, it is returned immediately without re-rendering.
wait_for_selectorstringNoCSS selector to wait for before capturing. Useful for SPAs and dynamically loaded content. Waits up to 10 seconds. Max 500 characters.
omit_backgroundbooleanNofalseCapture with transparent background (PNG and WebP only). Useful for logos and UI elements.
reduced_motionbooleanNofalseEmulate prefers-reduced-motion: reduce. Disables CSS animations and transitions for cleaner captures.
stealthbooleanNofalseEnable stealth mode to bypass bot detection. Hides automation signals (webdriver, plugins, WebGL, etc.).
user_agentstringNoCustom User-Agent string. Overrides the device preset User-Agent. Max 500 characters.
timezonestringNoIANA timezone for the browser context (e.g. America/New_York, Europe/Berlin). Affects Date and Intl APIs.
geolocationobjectNoEmulate browser geolocation. Object with latitude (-90 to 90), longitude (-180 to 180), and optional accuracy (meters).
proxystringNoHTTP/SOCKS proxy URL for the request (e.g. http://user:pass@proxy:8080). A dedicated browser is launched per proxy request.
extract_metadatabooleanNofalseExtract page metadata (title, description, Open Graph tags, Twitter Card, favicon URL) and include in the response.
webhook_urlstringNoURL to receive a POST notification when the screenshot is ready. See Webhooks.

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

bash
curl -X POST https://screenshotrun.com/api/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

php
$response = Http::withToken(env('SCREENSHOT_API_KEY'))
    ->post('https://screenshotrun.com/api/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

python
import requests

response = requests.post(
    "https://screenshotrun.com/api/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)

javascript
const response = await fetch("https://screenshotrun.com/api/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}`);

Response (202 Accepted)

json
{
  "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://screenshotrun.com/api/v1/screenshots/550e8400-e29b-41d4-a716-446655440000"
    }
  }
}

Create a Screenshot (GET)

http
GET /api/v1/screenshots/capture

Alternative to the POST endpoint — creates a screenshot using query parameters instead of a JSON body. Accepts the same parameters as the POST endpoint. Returns a 202 Accepted response.

This is useful for simple integrations, testing in the browser address bar, or embedding screenshot URLs directly in HTML.

Example Request

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://screenshotrun.com/api/v1/screenshots/capture?url=https://example.com&width=1440&format=webp&full_page=true"

Parameters are passed as query string instead of JSON body. All parameters from the POST endpoint are supported.

Browser / HTML

html
<a href="https://screenshotrun.com/api/v1/screenshots/capture?url=https://example.com&width=1280&format=png">
  Take Screenshot
</a>

The response format is identical to the POST endpoint.

Get a Screenshot

http
GET /api/v1/screenshots/{id}

Returns the screenshot object with its current status and details.

Example Request

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://screenshotrun.com/api/v1/screenshots/550e8400-e29b-41d4-a716-446655440000

Response — Completed

json
{
  "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://screenshotrun.com/api/v1/screenshots/550e8400-e29b-41d4-a716-446655440000",
      "image": "https://screenshotrun.com/api/v1/screenshots/550e8400-e29b-41d4-a716-446655440000/image"
    }
  }
}

Response — Failed

json
{
  "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://screenshotrun.com/api/v1/screenshots/550e8400-e29b-41d4-a716-446655440000"
    }
  }
}

Get Screenshot Image

http
GET /api/v1/screenshots/{id}/image

Returns the binary image file. Only available for screenshots with completed status.

Example Request

bash
# Download to file
curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://screenshotrun.com/api/v1/screenshots/550e8400-.../image \
  -o screenshot.webp

Responses

StatusDescription
200 OKImage file with appropriate Content-Type header (image/png, image/jpeg, image/webp, image/avif, image/tiff, or application/pdf)
404 Not FoundScreenshot not ready yet (status is pending or processing)
410 GoneScreenshot image has expired and is no longer available

List Screenshots

http
GET /api/v1/screenshots

Returns a paginated list of your screenshots, sorted by creation date (newest first).

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number
per_pageinteger20Results per page (max 100)
statusstringFilter by status: pending, processing, completed, failed
sort_bystringcreated_atSort field
sort_dirstringdescSort direction: asc or desc
date_fromstringFilter screenshots created after this date (ISO 8601)
date_tostringFilter screenshots created before this date (ISO 8601)

Example Request

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://screenshotrun.com/api/v1/screenshots?status=completed&per_page=10&sort_dir=desc"

Response

json
{
  "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://screenshotrun.com/api/v1/screenshots?page=1",
    "last": "https://screenshotrun.com/api/v1/screenshots?page=5",
    "prev": null,
    "next": "https://screenshotrun.com/api/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://screenshotrun.com/api/v1/screenshots",
    "per_page": 10,
    "to": 10,
    "total": 48
  }
}

Delete a Screenshot

http
DELETE /api/v1/screenshots/{id}

Permanently deletes a screenshot and its associated image file. This action cannot be undone.

Example Request

bash
curl -X DELETE -H "Authorization: Bearer YOUR_API_KEY" \
  https://screenshotrun.com/api/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

bash
curl -X POST https://screenshotrun.com/api/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

bash
curl -X POST https://screenshotrun.com/api/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)

bash
curl -X POST https://screenshotrun.com/api/v1/screenshots \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "delay": 3
  }'

Screenshot with resize (thumbnail)

bash
curl -X POST https://screenshotrun.com/api/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

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://screenshotrun.com/api/v1/screenshots/capture?url=https://example.com&format=jpeg&quality=60&resize_width=640"

Screenshot with webhook notification

bash
curl -X POST https://screenshotrun.com/api/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)

python
import time
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://screenshotrun.com/api/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

bash
curl -X POST https://screenshotrun.com/api/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

bash
curl -X POST https://screenshotrun.com/api/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

bash
curl -X POST https://screenshotrun.com/api/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

bash
curl -X POST https://screenshotrun.com/api/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

bash
curl -X POST https://screenshotrun.com/api/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

bash
curl -X POST https://screenshotrun.com/api/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

bash
curl -X POST https://screenshotrun.com/api/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.

Batch Screenshots

http
POST /api/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

ParameterTypeRequiredDescription
urlsarrayYesArray of URLs to capture. Min 1, max 100.
All other parameters from the single screenshot endpoint are supported (width, height, format, etc.).

Example Request

bash
curl -X POST https://screenshotrun.com/api/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)

json
{
  "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 is ready.

Signed URLs

http
POST /api/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

ParameterTypeDefaultDescription
expires_ininteger60Expiration time in minutes. Range: 1–43200 (30 days). Pass 0 for a permanent URL.

Example Request

bash
# Generate a signed URL that expires in 24 hours
curl -X POST https://screenshotrun.com/api/v1/screenshots/550e8400-.../signed-url \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expires_in": 1440}'

Response

json
{
  "data": {
    "url": "https://screenshotrun.com/api/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

bash
curl -X POST https://screenshotrun.com/api/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).