# 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.

Canonical page: https://scrapercompany.com/screenshot-api. Endpoints and prices checked against the API on 2026-10-27.

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

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

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

## Endpoints and price per call

| Endpoint | Method and path | What it returns | Credits per successful call | Price per call |
| --- | --- | --- | --- | --- |
| [Screenshot a page](https://scrapercompany.com/docs/reference/screenshot) | `POST /v1/screenshot` | POST a JSON body: every option, plus headers to send to the site | from 1 credit | from $0.0012 on Starter, from $0.0010 on Growth, from $0.0008 on Scale, from $0.0007 on Business |
| [Screenshot a page (GET)](https://scrapercompany.com/docs/reference/screenshot-get) | `GET /v1/screenshot` | The same options as query parameters, with the key as api_key, for tools that can only make a GET | from 1 credit | from $0.0012 on Starter, from $0.0010 on Growth, from $0.0008 on Scale, from $0.0007 on Business |

Pricing: free trial of 50 calls or 14 days, whichever ends first, no card needed; Starter $49/month for 40,000 credits; Growth $149/month for 150,000 credits; Scale $399/month for 500,000 credits; Business $999/month for 1,500,000 credits; credit packs $15 for 7,500, $60 for 35,000, $200 for 125,000 (valid 12 months). Failed requests (4xx or 5xx) and empty results cost 0 credits. https://scrapercompany.com/pricing

## Example

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

```bash
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
```

Sample answer: https://scrapercompany.com/samples/screenshot-example.webp (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):

```json
{
  "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
  }
}
```

## FAQ

### 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.

## Read next

- [Screenshot API reference](https://scrapercompany.com/docs/reference/screenshot)
- [Web scraping API](https://scrapercompany.com/web-scraping-api)
- [Price monitoring API](https://scrapercompany.com/price-monitoring-api)
- [Solutions by industry](https://scrapercompany.com/solutions)
- [All APIs](https://scrapercompany.com/apis.md)
