URL in, image out. One endpoint, binary response, no JSON envelope to unwrap.
Most screenshot failures are not crashes, they are a 200 with the wrong picture. The things we handle, because a benchmark of 202 real pages caught each one:
| Parameter | Default | What it does |
|---|---|---|
| url | required | The page to capture. http/https only; private and reserved addresses are refused. |
| format | png | png, jpeg, webp or pdf. |
| full_page | false | Capture the whole scrollable page, scrolling first so lazy images load. |
| viewport_width | 1280 | Viewport width in pixels. |
| viewport_height | 800 | Viewport height in pixels. |
| selector | — | Capture only the element matching this CSS selector. |
| block_ads | false | Block ad networks and collapse the empty slot they leave behind. |
| block_cookie_banners | false | Remove consent banners, including ones injected after load. |
| color_scheme | light | Render the page as light or dark. |
| delay | 0 | Extra wait before capture, in ms. |
| cache | false | Serve a cached image when one exists. Cache hits are never billed. |
| fail_on_blank | false | Return 502 instead of an image when the capture looks blank. |
Failures return JSON with a stable code. Successful captures return the
image bytes directly, with no envelope.
{
"error": {
"code": "invalid_access_key",
"message": "Unknown or revoked API key."
}
}
Common codes: missing_access_key (401), invalid_access_key (403),
quota_exceeded (402), render_timeout (504),
blank_capture (502).
The headline use case is putting a capture straight into an <img src>. A raw
key in public HTML is a billing incident waiting to happen, so sign the URL instead: the
signature covers every parameter, and a tampered URL is refused.
node tools/sign.js "https://example.com" full_page=true
Set REQUIRE_SIGNATURE=true to refuse unsigned requests entirely.
Every response carries your position, so you never need a second request to check:
X-Quota-Limit: 2000
X-Quota-Used: 417
X-Quota-Remaining: 1583
X-Quota-Period: 2026-09