Apify Actors / Website screenshots and PDFs as an API

Apify Actor

Website screenshots and PDFs as an API

Taking one screenshot is a five-line Playwright script. Taking fifty a day, with a browser that doesn't leak memory, a guard against private IPs, and files you can link to, is a small service. This Actor is that service.

Post a list of URLs, pick PNG, JPEG or PDF, and read back one row per URL with the HTTP status, final width and height in pixels, byte size and a fileUrl that opens the file. Failed URLs come back as rows with an error and cost nothing.

Run it on ApifySee input and output

$0.001 per saved file · pay per result, no subscription

Price

EventPriceCharged when
screenshot$0.001a PNG or JPEG file is saved to the key-value store
pdf$0.001a PDF file is saved to the key-value store
Example runUnitsCost
The prefilled sample run2 PNG$0.002
One full run of 50 URLs50 PNG$0.05

What you get

Input

Set the run options in the Apify console, or send the same object through the API.

{
  "urls": [
    "https://news.ycombinator.com",
    "https://example.com"
  ],
  "format": "png",
  "viewportWidth": 1280,
  "fullPage": true,
  "pageTimeoutSecs": 30,
  "maxConcurrency": 2
}

The prefilled input. One URL per line, up to 50 per run. Failed URLs are free.

Output

{
  "url": "https://news.ycombinator.com",
  "status": "success",
  "httpStatus": 200,
  "file": "screenshot-0002-news-ycombinator-com.png",
  "fileUrl": "https://api.apify.com/v2/key-value-stores/REDGccWd0hMLbVgSy/records/screenshot-0002-news-ycombinator-com.png?signature=1jrmKQ809iHohQCvx5rFN",
  "width": 1280,
  "height": 1185,
  "bytes": 214618,
  "clipped": false,
  "error": null
}

One real row. fileUrl is a signed link you can open in a browser or hand to another tool; clipped is true when a very long page hit the 16,384 px height limit.

Run it from your own code

The Actor takes the same input as a JSON body. This call starts a run, waits for it and returns the dataset items.

curl -X POST "https://api.apify.com/v2/acts/zovo-one~website-screenshot-pdf-api/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://news.ycombinator.com", "https://example.com"], "format": "png", "viewportWidth": 1280, "fullPage": true, "pageTimeoutSecs": 30, "maxConcurrency": 2}'

A sync call waits at most 300 seconds. For longer runs, start a run with POST /v2/acts/zovo-one~website-screenshot-pdf-api/runs, wait for it, then read /v2/datasets/<defaultDatasetId>/items.

Limits

50 URLs per run at most, in one output format. Each page gets 30 seconds by default (5 to 120); a page that runs out of time becomes a free failed row. Width times device scale factor may be at most 7680; full-page images are cut at 7680 x 16384 and the row says clipped: true. For PDF, selector and fullPage: false are ignored. It does not log in, solve captchas or get past bot protection, and it refuses localhost, private IP ranges and cloud metadata addresses. A sync call waits 300 seconds, so about 20 URLs fit; for bigger batches start a run and read the dataset afterwards.

Questions

How do I take a screenshot of a website in code?

Post your URLs to this Actor and read the fileUrl from each dataset row. You don't run a browser, install Chromium or write Playwright. The same call works from Python, Node or curl, and the file lands in Apify's key-value store.

Can it save a page as PDF instead of an image?

Yes. Set format to pdf and each URL comes back as a PDF in the same kind of row. One run uses one format, so a page that needs both a PNG and a PDF takes two rows in two runs.

How do I get a mobile screenshot?

Set viewportWidth to a phone width, for example 390, and deviceScaleFactor to 2 for a retina-sized image. Keep width times scale factor at or below 7680.

Why does a row say success when the page showed an error?

status describes the capture, not the page. A 404 page that rendered fine is a successful screenshot with httpStatus: 404. Check httpStatus when you care about the page's own answer.

Do I need an Apify token to open the file link?

No. fileUrl is a signed URL, so it opens without a token until the signature expires. If you need a permanent copy, download it and store it on your side.

Can I capture only part of a page?

Yes, with selector and fullPage: false. It is ignored for PDFs, because Playwright always prints the whole page. If a cookie banner still covers the shot, add its container to hideSelectors.

Support this work

If this Actor saves you time, you can support the work on GitHub Sponsors. Monthly tiers start at $5, and one-time tiers start at $15. Sponsorship is optional, and the tool works the same without it.

Built and maintained by Zovo. Actor on Apify · All Actors.