API Reference

Screenshot API converts any URL or HTML snippet into a screenshot or PDF with a single HTTP request. Authenticate with an API key, POST your payload, receive binary image or PDF bytes.

Quickstart

Step 1 — Create a free account at https://screenshotapis.org/signup. Your first API key is created automatically.

Step 2 — Copy your API key from the dashboard. It looks like sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.

Step 3 — Make your first call:

curl -X POST https://screenshotapis.org/v1/screenshot \
  -H "X-Api-Key: sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "format": "png"}' \
  --output screenshot.png

Authentication

Pass your API key in the X-Api-Key request header on every call. You can also pass it as a Bearer token: Authorization: Bearer sk_live_….

X-Api-Key: sk_live_your_key_here

API keys are shown once on creation. If you lose a key, revoke it in the dashboard and create a new one. Keys are stored as one-way hashes — we can never recover the original value.

POST /v1/screenshot

POSThttps://screenshotapis.org/v1/screenshot

Returns raw image bytes (image/png, image/jpeg, or image/webp) on success.

Request body (JSON)

FieldTypeDefaultDescription
urlstringrequired* URL to render. Must be http or https.
htmlstringrequired* Raw HTML to render. Max 5 MB.
formatstringpngOutput format: png · jpeg · webp
viewport_widthint1280Browser width in px (100–3840)
viewport_heightint800Browser height in px (100–2160)
full_pageboolfalseCapture the full scrollable page height
qualityintnullCompression quality 1–100 (jpeg / webp only)
delay_msint0Wait N ms after page load (0–10 000). Useful for animations.
selectorstringnullCSS selector — capture only that element
dark_modeboolfalseEnable prefers-color-scheme: dark
device_scale_factorfloat1.0Pixel ratio (0.5–3.0). Use 2.0 for retina.
block_adsboolfalseBlock ads and tracking scripts
hide_cookie_bannersboolfalseHide common cookie consent banners
inject_cssstringnullCustom CSS to inject into the page
inject_jsstringnullCustom JavaScript to inject into the page
wait_untilstringnetworkidleWait strategy: load · domcontentloaded · networkidle
user_agentstringnullCustom User-Agent string
webhook_urlstringnullURL to POST results to. Returns 202 immediately, delivers async.

* Exactly one of url or html must be provided.

Example — OG image from HTML

curl -X POST https://screenshotapis.org/v1/screenshot \
  -H "X-Api-Key: sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<div style=\"width:1200px;height:630px;background:#0d6efd;color:#fff;display:flex;align-items:center;justify-content:center;font-size:3rem\">My Article Title</div>",
    "viewport_width": 1200,
    "viewport_height": 630,
    "device_scale_factor": 2
  }' \
  --output og-image.png

Example — retina full-page screenshot

curl -X POST https://screenshotapis.org/v1/screenshot \
  -H "X-Api-Key: sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","full_page":true,"device_scale_factor":2}' \
  --output fullpage.png

POST /v1/pdf

POSThttps://screenshotapis.org/v1/pdf

Returns raw PDF bytes (application/pdf) on success with a Content-Disposition: attachment; filename=render.pdf header.

Request body (JSON)

FieldTypeDefaultDescription
urlstringrequired* URL to render
htmlstringrequired* Raw HTML to render. Max 5 MB.
formatstringA4Paper size: A4 · Letter · Legal · A3 · Tabloid
landscapeboolfalseLandscape orientation
margin_topstring1cmTop margin (CSS units: 1cm, 20px, etc.)
margin_rightstring1cmRight margin
margin_bottomstring1cmBottom margin
margin_leftstring1cmLeft margin
print_backgroundbooltrueInclude background colors and images
display_header_footerboolfalseShow header and footer
header_templatestring""HTML for the page header (Chromium template)
footer_templatestring""HTML for the page footer
block_adsboolfalseBlock ads and tracking scripts
hide_cookie_bannersboolfalseHide common cookie consent banners
inject_cssstringnullCustom CSS to inject into the page
inject_jsstringnullCustom JavaScript to inject into the page
wait_untilstringnetworkidleWait strategy: load · domcontentloaded · networkidle
user_agentstringnullCustom User-Agent string
webhook_urlstringnullURL to POST results to. Returns 202 immediately, delivers async.

Example — HTML to PDF invoice

curl -X POST https://screenshotapis.org/v1/pdf \
  -H "X-Api-Key: sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<html><body><h1>Invoice #42</h1><p>Amount due: $100</p></body></html>",
    "format": "A4",
    "margin_top": "2cm",
    "margin_bottom": "2cm"
  }' \
  --output invoice.pdf

GET /v1/usage

GEThttps://screenshotapis.org/v1/usage

Returns current usage statistics for the authenticated user.

Response (JSON)

{
  "plan": "growth",
  "credits_remaining": 5843,
  "renders_today": 12,
  "renders_this_month": 157,
  "renders_total": 2841
}

Error codes

StatusWhen it happens
400Invalid URL, blocked scheme (not http/https), or private IP (SSRF guard)
401Missing or invalid X-Api-Key
402Insufficient credits — upgrade or buy a credit pack
422Render failed: page error, JS crash, selector not found, or timeout
429Rate limit exceeded — see rate limits

Error bodies follow the format: {"detail": "Human-readable message."}

On a 422, the credit is refunded — you are never charged for a failed render.

Rate limits

Rate limits apply per API key. The window is a 60-second sliding window.

PlanRequests / minuteMonthly credits
free10100
starter302,000
growth606,000
business12025,000
scale30075,000

When a rate limit is hit the API returns HTTP 429 with header Retry-After: 60.

Response headers

HeaderDescription
X-Render-Time-MsHow long the render took in milliseconds
X-Credits-RemainingCredits left on your account after this render
X-Request-IdUnique request ID — include in support requests

Webhook callbacks

Add webhook_url to any screenshot or PDF request to receive results asynchronously. The API returns 202 Accepted immediately with a render_id, then POSTs the result to your URL when done.

Request

curl -X POST https://screenshotapis.org/v1/screenshot \
  -H "X-Api-Key: sk_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","webhook_url":"https://your-server.com/hook"}'

Immediate response (202)

{
  "render_id": "render_a1b2c3d4e5f6g7h8",
  "status": "processing",
  "webhook_url": "https://your-server.com/hook"
}

Webhook POST payload

{
  "render_id": "render_a1b2c3d4e5f6g7h8",
  "success": true,
  "url": "https://cdn.screenshotapis.org/renders/42/2026-04-11/abc123.png",
  "content_type": "image/png",
  "render_time_ms": 1230,
  "output_size_bytes": 184320,
  "error": null,
  "timestamp": 1744300000
}

Verifying webhook signatures

Every webhook POST includes an X-Webhook-Signature header — an HMAC-SHA256 hex digest of the JSON body, signed with your API key. Verify it to confirm the payload came from us:

import hmac, hashlib

def verify(body: bytes, signature: str, api_key: str) -> bool:
    expected = hmac.new(api_key.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)