Capture screenshots and PDFs
Capture a page as a PNG, JPEG or WebP screenshot with screenshot=true, or print it to PDF with response_format=pdf. Both run on full-browser rendering.
Use this when you need the page as it looks rather than as it reads: visual regression checks, archiving a page as evidence, a thumbnail for a link preview, or a printable PDF of an invoice or report. Set screenshot: true for an image, or response_format: "pdf" for a document, together with js_render: true.
Both need full-browser rendering, and you do not name it: Spicrawl routes the request there automatically. Because that is not the path js_render alone would use (JavaScript rendering cannot draw a page), the response carries X-Warning: ENGINE_SUBSTITUTED. If the deployment has no full-browser rendering, the request is refused before anything is spent. The engine and headless fields are deprecated and ignored (X-Warning: ENGINE_IGNORED).
Minimal request
curl https://api.spicrawl.com/v1/scrape \
-H "Authorization: Bearer $SPICRAWL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/products/42", "js_render": true, "screenshot": true, "screenshot_fullpage": true}'What comes back
screenshot: true always returns the JSON envelope. The rendered page is under content and each image is an object in screenshots:
{
"url": "https://example.com/products/42",
"final_url": "https://example.com/products/42",
"status": 200,
"content": "<!doctype html><html>…",
"credits": 8,
"screenshots": [
{
"label": "final",
"encoding": "base64",
"data": "iVBORw0KGgoAAAANSUhEUgAA…",
"size_bytes": 184223,
"format": "png",
"width": 800,
"height": 3412
}
],
"warnings": []
}- The top-level screenshot has
label: "final". Screenshots taken by ascreenshotbrowser action carry that step's label. widthandheightare omitted when they were not measured.- If you asked for another
response_format(for examplemarkdown), the response is still the envelope, withcontentin the format you asked for, andX-Warning: FORMAT_COERCED. screenshotslists delivered images only. An image that could not be delivered is reported inwarnings, and the request is charged 0 credits even though the page comes back.
With response_format: "pdf", the body is the PDF bytes (Content-Type: application/pdf), not the envelope. Save it as a file. Setting screenshot, extract, autoparse, links, ai_extract or network_capture at the same time switches the response to the envelope with X-Warning: FORMAT_COERCED, so leave them off for a PDF.
curl https://api.spicrawl.com/v1/scrape \
-H "Authorization: Bearer $SPICRAWL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/invoices/2026-09", "js_render": true, "response_format": "pdf"}' \
-o invoice.pdfThe CLI refuses to write PDF bytes to a terminal: pass -o FILE, or --json to get the output base64-encoded.
Options
| Field | Default | Effect |
|---|---|---|
screenshot | false | Capture an image. Forces the JSON envelope. |
screenshot_fullpage | false | Capture the whole scrollable page instead of the viewport. Requires screenshot: true. Cannot be combined with screenshot_selector. |
screenshot_selector | none | CSS selector of one element to capture. Requires screenshot: true. Cannot be combined with screenshot_fullpage. |
screenshot_format | png | png, jpeg, jpg or webp. |
screenshot_quality | 0 (default quality) | 0–100, used by jpeg and webp. A value above 0 requires screenshot: true. |
response_format | html | pdf returns a browser-printed PDF. |
wait, wait_for | none | Let late content load before capture. See JavaScript rendering. |
block_resources | see below | Resource classes the browser does not load. |
screenshot_format is not validated by the API. An unrecognised value (for example "gif") is not a 400: PNG is used silently. Check the format field on each returned screenshot to see what you got.
Images and fonts load by default here. Full-browser rendering blocks nothing unless you send block_resources, so a capture shows the real page. An explicit block_resources list still applies, so leave it unset unless you want those resources missing from the capture.
Failure modes
| Code | HTTP | What to do |
|---|---|---|
ERR::REQUEST::CAPABILITY_UNSUPPORTED | 400 | The deployment has no full-browser rendering, so nothing can draw a page. Drop the screenshot or PDF. 0 credits. |
ERR::REQUEST::INCOMPATIBLE_FLAGS | 400 | screenshot_fullpage or screenshot_selector without screenshot: true, both at once, or screenshot or response_format: "pdf" without js_render: true. |
ERR::ENGINE::UNAVAILABLE | 503 | Full-browser rendering is not deployed or has no free slot. Retry after Retry-After. |
ERR::ENGINE::RENDER_FAILED | 502 | The page could not be rendered. Retry once; if it repeats, try wait_for on a stable selector. |
A missing element for screenshot_selector, or any other capture that could not be delivered, is not an error: the page is returned, the image is absent from screenshots, warnings says why, and the charge is 0.
Cost
A screenshot or PDF adds no credits on top of the rendering price. Full-browser rendering is 8 credits, or 32 on a premium_proxy Coming soon exit. A deployment that serves it on a stronger tier bills that tier, up to 25, and says so with ENGINE_SUBSTITUTED. Full-browser rendering always runs on a real display, which adds about 1 s of startup.
Failures, undelivered screenshots and non-billable target statuses cost 0. A repeat of the same request inside the cache window is served from the cache, image included, and billed at the price of the fetch that stored it: 8 credits. X-Credits-Charged is what was billed. See Credits.
Related
- Browser actions to screenshot the page between steps
- JavaScript rendering for
waitandwait_for - Anti-bot when the page behind the screenshot is protected
- Caching
Network capture
Record the XHR and fetch responses a page makes while it renders with network_capture, and read their JSON bodies from the network array.
Browser actions
Drive a rendered page with the actions array: wait_for, wait_for_navigation, click, fill, select, scroll, evaluate and screenshot steps, up to 50 per request, before the page is captured.