Screenshot a page
Capture one public URL as it looks to a visitor and return the image.
/v1/screenshotcountry, 75 with premium (5 or 75 held while it runs); a non-2xx page and failed requests are freeThe quickest call is one GET with your key in the URL; the body is the image, saved as screenshot.webp:
curl -f "https://api.scrapercompany.com/v1/screenshot?api_key=$SCRAPERCOMPANY_API_KEY&url=https%3A%2F%2Fexample.com&format=webp" -o screenshot.webp
The page runs its JavaScript and loads its images, styles and fonts, then is waited on until wait_until (load by default) and any wait_for selector or wait_ms, then captured: the viewport (width x height, 1440 x 900 by default, at scale 1-3), the whole page (full_page), or one element (selector). format is png, jpeg (or jpg) or webp, with quality for the last two. GET takes the same fields as query parameters (fullPage is read as full_page) and the key as api_key.
The default answer is the image itself, with the site's own status in X-Upstream-Status; response_type=json returns it base64-encoded with that status and metadata. A refused request is retried automatically; premium=true uses the premium network from the first attempt, country loads the page from that country, and session_id keeps one IP address.
1 credit for most pages; 5 for a site that refuses standard requests (the capture moves to the fallback network) and with country; 75 with premium. 5 (75) is held while the capture runs, so that much must be available; x-credits-charged says what was charged. Only a 2xx page that produced an image is charged: a non-2xx page is still returned, free. A site that refuses every attempt, a timeout_s that runs out, or a wait_for or selector that never appears is a free 503; private and internal addresses are refused (422).
Request
https://api.scrapercompany.com/v1/screenshotAuthenticate with your API key in the x-api-key header (see Authentication).
Run this request on your own API key from this page, with the values you type. Signed out? Sign in or get an API key.
Body
JSON object. Unknown fields are rejected with 422.
- urlstringrequiredmin length 1, max length 2048
The page to capture: an absolute
http://orhttps://URL on port 80, 443, 8080 or 8443. Private, loopback and cloud-metadata addresses, and hosts on the scrape denylist, are refused (422), as is any redirect to one. - formatstringdefault
pngImage format:
png(default, lossless),jpeg(jpgaccepted) orwebp.One of
pngjpegwebp - qualityinteger | nullmin 1, max 100
JPEG or WebP quality, 1-100 (default 80). Not for
png, which is lossless (422). - full_pagebooleandefault
falseCapture the whole scrollable page instead of the viewport. Not with
selector. - widthintegerdefault
1440min 320, max 3840Viewport width in CSS pixels, 320-3840 (default 1440).
- heightintegerdefault
900min 240, max 2160Viewport height in CSS pixels, 240-2160 (default 900). With
full_pagethe image is as tall as the page. - scalenumberdefault
1min 1, max 3Device pixel ratio, 1-3:
2gives a retina image twice the viewport's size in pixels. - wait_untilstringdefault
loadWhen the page counts as loaded:
domcontentloaded(HTML parsed),load(default: images and styles in) ornetworkidle(no requests for 500 ms).loadandnetworkidleare waited for as long astimeout_sallows; a page that never settles is captured as it stands.One of
domcontentloadedloadnetworkidle - wait_forstring | nullmin length 1, max length 500
CSS selector to wait for before the capture, e.g.
#prices .row. Never appearing withintimeout_sis a free 503: retry, or allow more time. - wait_msintegerdefault
0min 0, max 10000A further fixed wait, in milliseconds (0-10000), before the capture.
- selectorstring | nullmin length 1, max length 500
Capture only the first element matching this CSS selector (waited for until it is visible), e.g.
#chart. - premiumbooleandefault
falseUse the premium network from the first attempt, for sites that block standard requests. 75 credits instead of 1-5.
- countrystring | null
Two-letter country (ISO 3166-1) the page must be loaded from, e.g.
DE, for local prices, language and consent banners. 5 credits.251 allowed values
AD, AE, AF, AG, AI, AL, AM, AO, AQ, AR, AS, AT, AU, AW, AX, AZ, BA, BB, BD, BE, BF, BG, BH, BI, BJ, BL, BM, BN, BO, BQ, BR, BS, BT, BV, BW, BY, BZ, CA, CC, CD, CF, CG, CH, CI, CK, CL, CM, CN, CO, CR, CU, CV, CW, CX, CY, CZ, DE, DJ, DK, DM, DO, DZ, EC, EE, EG, EH, ER, ES, ET, FI, FJ, FK, FM, FO, FR, GA, GB, GD, GE, GF, GG, GH, GI, GL, GM, GN, GP, GQ, GR, GS, GT, GU, GW, GY, HK, HM, HN, HR, HT, HU, ID, IE, IL, IM, IN, IO, IQ, IR, IS, IT, JE, JM, JO, JP, KE, KG, KH, KI, KM, KN, KP, KR, KW, KY, KZ, LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, LY, MA, MC, MD, ME, MF, MG, MH, MK, ML, MM, MN, MO, MP, MQ, MR, MS, MT, MU, MV, MW, MX, MY, MZ, NA, NC, NE, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, PA, PE, PF, PG, PH, PK, PL, PM, PN, PR, PS, PT, PW, PY, QA, RE, RO, RS, RU, RW, SA, SB, SC, SD, SE, SG, SH, SI, SJ, SK, SL, SM, SN, SO, SR, SS, ST, SV, SX, SY, SZ, TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UK, UM, US, UY, UZ, VA, VC, VE, VG, VI, VN, VU, WF, WS, XK, YE, YT, ZA, ZM, ZW
- timeout_sintegerdefault
45min 1, max 90Seconds the whole capture may take, every attempt included: at most 90 (default 45). Running out is a free 503 with Retry-After.
- session_idstring | nullpattern ^[A-Za-z0-9_-]{1,64}$
Keep the same IP address across requests that share this id (letters, digits,
_,-; up to 64); ids are scoped to your API key. - response_typestringdefault
imageimage(default): the image itself, with the site's status inX-Upstream-Status.json: a JSON object with the image base64-encoded inimage, plus the status and metadata.One of
imagejson - headersobject
Headers to send to the target, e.g.
Accept-Languageor aCookieyou hold for the site. Hop-by-hop headers,Host,Content-Length,Proxy-*and anything named like an API-key header (X-API-Key) are dropped;AuthorizationandCookieare not sent on to another host after a redirect. Withrenderthey go with the page request only. At most 32.
Example request
curl -f -X POST "https://api.scrapercompany.com/v1/screenshot" \
-H "x-api-key: $SCRAPERCOMPANY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com"
}' \
-o screenshot.pngResponse
200 — The image (response_type image, the default) or JSON carrying it base64-encoded (response_type json); the image answer has the site's status in X-Upstream-Status and the final URL in X-Final-Url. Metered responses carry x-credits-charged and x-credits-remaining headers (see credit headers).
By default the body is the image itself (image/png, image/jpeg or image/webp, as format asks), with the site’s status in the X-Upstream-Status header and the final URL in X-Final-Url. An error is always JSON, never an image. With response_type: json the answer is JSON instead, carrying the same image base64-encoded:
{
"url": "https://example.com/",
"final_url": "https://example.com/",
"status_code": 200,
"format": "png",
"media_type": "image/png",
"image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==",
"meta": {
"render": true,
"premium": false,
"elapsed_s": 2.84,
"format": "png",
"width": 1440,
"height": 900,
"scale": 1,
"full_page": false,
"image_bytes": 21873
}
}Errors
Errors return a JSON body with a detail field. Failed requests are not charged. See Errors for the full list and retry advice.
| Status | Meaning | Retry? |
|---|---|---|
401Unauthorized | Missing or invalid API key. {"detail":"missing or invalid API key"} | No, fix the request |
402Payment Required | Not enough credits for this request: the account's credits mode is {"detail":"insufficient credits: this request costs 5, 0 available. Credits renew 2026-11-01."} | No, fix the request |
422Unprocessable Content | Request validation failed. {"detail":[{"loc":["body","name"],"msg":"Field required","type":"missing"}]} | No, fix the request |
429Too Many Requests | Too many requests: the key's requests-per-minute limit was exceeded, or (in {"detail":"rate limit 60/min exceeded"} | Yes, with backoff |
503Service Unavailable | Temporarily unavailable: a dependency of this endpoint is down, or the upstream source changed its contract. Retry later. {"detail":"database unavailable: OperationalError"} | Yes, with backoff |
Try it
Press Try it above to run this request on your own key, with the values you type (sign in first). For a no-code walkthrough, use the workspace’s guided Try it.
- Export your key:
export SCRAPERCOMPANY_API_KEY=sk_...(no key yet? start a free trial). - Copy the cURL example above and run it in a terminal.
Questions about this page?
Send the page link and your question, and the team will answer.