Skip to main content

Screenshots from a browser you never have to run.

POST a URL, get the rendered page back as PNG, JPEG, or WebP. Full page or exact viewport, base64 or raw bytes. Most captures cost a fraction of a cent, and failed ones cost nothing.

POST api.spider.cloud/screenshot json
// your first capture
{
  "url": "https://example.com",
  "full_page": true,
  "cdp_params": { "format": "webp" }
}

returns [{ url, content, status }], or the bytes alone with "binary": true

One flag decides what the frame holds.

full_page defaults to true and captures the entire scroll height. Turn it off and you get exactly the viewport you set, nothing below the fold.

"full_page": false viewport crop

The image is exactly the rectangle you asked for. Set width and height, get that many pixels back, and the rest of the scroll never enters the file.

"full_page": true default

The browser scrolls the whole document and stitches one image, footer included. Height follows the page, so a long article comes back long.

390 × 844 phone 768 × 1024 tablet 1440 × 900 desktop
"viewport": { "width": 390, "height": 844, "emulating_mobile": true }

Pick the format by what the image is for.

One cdp_params object selects format and quality per request. The trade is bytes against fidelity.

WebP

"format": "webp"

Smallest of the three at comparable quality. The pick for thumbnails and previews you store by the million.

lossy or lossless quality adjustable

JPEG

"format": "jpeg", "quality": 80

Lossy with a quality dial from 1 to 100, set per request. Turn it down when bytes matter more than crisp text.

lossy quality 1 to 100

PNG

default
"format": "png"

Lossless, every pixel exact, which makes it the record format. Add omit_background for transparency when compositing.

lossless transparency

Ordered by output size: WebP produces the smallest files, JPEG sits in the middle, PNG is the largest and lossless.

Base64 or raw bytes. It shapes your pipeline.

The default keeps the image inside JSON. One flag strips the envelope and streams the file itself.

"binary": false default

Base64 inside JSON

// HTTP 200 · application/json
[
  {
    "url": "https://example.com",
    "content": "iVBORw0KGgoAAAANSUhEUgAA...",
    "status": 200
  }
]
  • The image rides inside JSON as text, so it passes through queues, webhooks, and logs without special handling.
  • You decode before use. Base64 turns every 3 bytes into 4 characters, so the response runs about a third larger than the image itself.
  • Batch a comma split list of URLs and each capture arrives as its own array element with its own status.
"binary": true

Raw bytes

# HTTP 200 · image/jpeg
curl -X POST https://api.spider.cloud/screenshot \
  -H "Authorization: Bearer $SPIDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com", "binary": true,
        "cdp_params": { "format": "jpeg", "quality": 80 } }' \
  | aws s3 cp - s3://captures/example.jpg
  • The response body is the encoded image, nothing wrapped around it. No decode step.
  • Pipe it straight to disk or object storage, as the S3 line above does.
  • The smallest transfer of the two, since the base64 overhead never happens.

From URL to file on disk.

The same request through the Python and JavaScript SDKs or plain HTTP, and what each response field means.

Run this
from spider import Spider
import base64

client = Spider()

result = client.screenshot(
    "https://example.com",
    params={
        "full_page": True,
    },
)

# Decode and save the screenshot
img_data = base64.b64decode(result[0]["content"])
with open("screenshot.png", "wb") as f:
    f.write(img_data)
url
The URL that was rendered, echoed back so batched captures stay matched to their pages.
content
The image, base64 by default. With binary: true there is no JSON at all, the bytes are the whole response.
status
The HTTP status the page itself returned, recorded next to the capture so you can spot redirects and errors without opening the image.

The controls that change the picture.

Request parameters the headless Chrome runtime honors, the same browser behind /crawl.

full_page default true
Capture the whole scroll height instead of only the viewport rectangle.
fast default true
Speed-optimized rendering. Set false for high fidelity when a page leans on iframes or complex PDFs.
viewport object
Width, height, device scale factor, and mobile emulation, per request.
block_images default false
Skip loading images when the layout is what you are checking. Faster and cheaper.
omit_background default false
Drop the page background for transparent captures you can composite.
cdp_params object
Chrome DevTools Protocol passthrough: format, quality, a clip region, capture beyond the viewport.
country_code optional
Route the browser through a specific country to capture localized content and geo-specific pricing.
wait_for optional
Hold the shutter until the page loads or a selector appears, instead of guessing with a sleep.

Four workflows that run on this endpoint.

Not categories, actual pipelines. Each one is a scheduler, this API, and a diff or a bucket.

Visual regression testing

deploy → capture routes → diff against baseline → fail the build

Capture the same routes at a fixed viewport on every deploy and compare pixels against stored baselines. A layout break fails CI before a user sees it.

Link previews and thumbnails

URL pasted → viewport capture → WebP → card image

When someone pastes a link, capture the viewport, take WebP for weight, and store the bytes with binary: true. The card renders from your own storage from then on.

Compliance and archival snapshots

schedule → full-page PNG → timestamp → archive

A lossless full-page PNG is a record of exactly what a visitor saw at that moment. Capture on a schedule and file it with the timestamp.

Competitor and ad monitoring

cron → geo-routed capture → diff → alert

Screenshot competitor pages on a schedule, routed through country_code to see what their visitors in each market see. Diff against the last run and alert on change.

The questions that decide it.

What does a capture cost?

The same metering as every Spider request: $1 per GB of bandwidth plus $0.0001 per minute of CPU time. Most pages land at a fraction of a cent, and failed requests are billed at $0. Volume discounts start at $500.

Pricing

What about pages that block bots?

The capture runs in a real Chrome session with Spider's fingerprinting and session management, so protected pages render like they would for a person. For the hardest targets, route through the Unblocker first.

Unblocker API

How do I keep captures fast?

Fast mode is already the default. Add block_images when you only need layout, and use wait_for to fire the moment the page is ready rather than padding every request with a fixed delay.

Will it match what Chrome shows?

It is Chrome, the same headless runtime behind /crawl. For pages heavy on iframes or embedded PDFs, set fast: false and trade some speed for full rendering fidelity.

More from the API.

One POST between a URL and its picture.

A real Chrome render, an image back in one request, and failed captures billed at zero.