Screenshot API

A screenshot API for any public page

Send a URL, get back an image of the page as a visitor sees it, after its JavaScript has run and its images have loaded. Pick the size, the format and what to capture: the viewport, the whole page or one element.

One line in a terminal; the body is the image:

curl -f "https://api.scrapercompany.com/v1/screenshot?api_key=$SCRAPERCOMPANY_API_KEY&url=https%3A%2F%2Fexample.com&format=webp" -o screenshot.webp

7,500 credits, one-time. No subscription. Failed calls are free. The free trial covers the travel endpoints.

Endpoints and prices checked against the API on .

Every API on one key

Teams take screenshots for link previews, visual regression checks, archives of what a page said on a given day, competitor and ad monitoring, and evidence for compliance. Running your own capture service means keeping browsers patched, waiting for the right moment to capture, and handling the sites that refuse automated visits. This API does that part. One GET with a URL returns the image, so it also works from a spreadsheet, a no-code tool or a cron job with curl.

You choose what the picture shows. width and height set the viewport, scale 2 or 3 gives a retina image, full_page captures the whole scrollable page, and selector captures one element, such as a chart or a pricing table. wait_until, wait_for and wait_ms decide when to capture; country loads the page from a country you name, for local prices, language and consent banners. format picks PNG, JPEG or WebP, with a quality for the last two.

What you get

body
the image itself (image/png, image/jpeg or image/webp), with response_type: image, the default
X-Upstream-Status
the status the site answered with, so a 404 page is not mistaken for the real one
X-Final-Url
where the page ended up after redirects
image
with response_type: json, the image base64-encoded, beside status_code, final_url, format and media_type
meta
with response_type: json, the size, format and region captured, the time taken and the image size in bytes

What you no longer deal with

Pages that build themselves

The page runs its JavaScript and loads its images, styles and fonts before the capture. wait_until load (the default) or networkidle, a wait_for selector and a wait_ms pause cover pages that keep filling in after they load.

Blocks and bot checks

A refusal, a rate limit or a bot-check page is detected and the capture tries again from a fresh start. premium uses the premium network from the first attempt for sites that refuse standard visits.

Exactly the region you want

Capture the viewport at any size from 320 x 240 to 3840 x 2160, the full page, or the first element that matches a CSS selector, at a device pixel ratio of 1, 2 or 3.

Answers you can check

The site’s own status rides in the X-Upstream-Status header and the final URL in X-Final-Url. An error is always JSON, never an image, so a script can tell a failed capture from a picture.

One call, one image

POST /v1/screenshot, from 1 credit per successful call.

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.png
The image the one-line call returned: the example.com page at the default 1440 by 900 viewport
A real answer, from the one-line call: example.com at the default 1440 x 900 viewport, WebP, 35 KB, 1 credit. Captured 27 October 2026.

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:

With response_type: json (trimmed)
{
  "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
  }
}

Endpoints and price per call

Credits per successful call, and what one call costs on the Starter, Growth, Scale, Business plans. Failed requests cost nothing.

EndpointWhat it returnsCreditsStarter / Growth / Scale / Business
Screenshot a page
POST /v1/screenshot
POST a JSON body: every option, plus headers to send to the sitefrom 1 credit$0.0012 · $0.0010 · $0.0008 · $0.0007
Screenshot a page (GET)
GET /v1/screenshot
The same options as query parameters, with the key as api_key, for tools that can only make a GETfrom 1 credit$0.0012 · $0.0010 · $0.0008 · $0.0007
RequestCredits per pageStarter / Growth / Scale / Business
One capture, most pages (any size, format or region)1$0.0012 · $0.0010 · $0.0008 · $0.0007
A site that refuses standard requests, or with country5$0.0061 · $0.0050 · $0.0040 · $0.0033
With premium75$0.092 · $0.074 · $0.060 · $0.050

See all plans

What do I pay for?

1 credit for most captures, of any size, format or region. A site that refuses standard requests, or a capture with country, is 5, and premium 75; 5 (or 75) is held while the capture runs, and the x-credits-charged header says what was charged. Only a page that answered with a 2xx status and produced an image is charged. An error page is still returned so you can see it, and it is free, as are blocks, timeouts, a selector that never appears and refused URLs.

PNG, JPEG or WebP?

PNG is lossless and best for text-heavy pages and visual diffs. JPEG and WebP are much smaller for photos and long pages; set quality from 1 to 100 (80 by default). quality is refused with PNG rather than silently ignored.

How do I capture the whole page or one element?

full_page: true captures the whole scrollable page instead of the viewport. selector captures only the first element that matches a CSS selector, waited for until it is visible. The two cannot be combined.

When is the page captured?

After wait_until: load by default (images and styles in), domcontentloaded for speed, or networkidle for pages that keep loading data. A page that never goes quiet is captured as it stands instead of failing. Add wait_for to wait for a selector and wait_ms for a fixed pause.

Can I use it from a browser or a no-code tool?

Yes: GET /v1/screenshot takes every option as a query parameter and the key as api_key, and the response body is the image. Keep the key on your server or in your tool; do not put it in a public web page.

Which URLs are refused?

Private, loopback and cloud-metadata addresses, ports other than 80, 443, 8080 and 8443, and hosts on a short denylist, including when a redirect points at one. Those answer 422 and cost nothing.

What are the limits?

timeout_s is the budget for the whole capture, up to 90 seconds (45 by default). An image is at most 10 MB; for a very long page use JPEG or WebP, or the viewport. Requests per minute and concurrency follow your plan.

Do failed requests cost credits?

No. A failed or blocked call (any 4xx or 5xx response) costs 0 credits, and so does a search page that comes back empty. You pay only for successful results.

How do I get an API key?

Create an account on the sign-up page and verify your email. You get a free trial of 50 calls or 14 days, whichever ends first, no card needed on the travel endpoints (hotels, rentals, flights, reviews); for everything else, and after the trial, buy a credit pack (from $15) or pick a plan. You create and rotate keys yourself in the dashboard.

More APIs on the same key

All APIs
Web scraping API

Send a URL, get the page back as HTML, markdown or text. When a site answers with a block, a rate limit or a bot check, the request is retried automatically, and you pay only for a page that comes back with content.

Booking.com API

Look a hotel up by name, then read what Booking.com shows a guest: a nightly price calendar, each room type with its rate plans, and the reviews with the property’s replies. Structured JSON, priced per call.

Expedia API

Look a hotel up by name, then read what Expedia shows a guest for one stay: every room type and rate plan with its total, nightly price and cancellation terms, and the guest reviews with the property’s replies.

Hotels.com API

Find a hotel’s Hotels.com id by name, then read what a guest on the Hotels.com site for their country sees: the headline price for a stay, every room type and rate plan, and the guest reviews.

Start with 50 free calls

Create an account and verify your email: your own API keys and a free trial of 50 calls or 14 days, whichever ends first, no card needed. Then buy a credit pack from $15 or pick a plan from $49 a month.