DEV Community

Hay Equipos
Hay Equipos

Posted on

How to take full page screenshots of many websites at once

You need screenshots of 200 landing pages for a client report, or a dated visual record of competitor pages every month, or a quick check of how your site renders on mobile after a release. Taking them one at a time in a browser is tedious, the cookie banner covers half of every image, and lazy loaded images show up as blank boxes.

The Website Screenshot API: Bulk Full Page PNG and JPEG, published by Hay Equipos on the Apify Store, takes a list of URLs and returns one screenshot per page, with a direct download link, the page title, the HTTP status and the image size. It runs a real headless Chrome browser, scrolls through each page so lazy images load, and hides common cookie banners before it captures.

What you get back

Each image is saved in the run's key value store, and the dataset gets one row per URL. Illustrative example:

{
  "url": "https://www.example.com/",
  "finalUrl": "https://www.example.com/",
  "statusCode": 200,
  "title": "Example Company: Home",
  "screenshotUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/screenshot_0001_www_example_com_.jpg?signature=<signature>",
  "screenshotKey": "screenshot_0001_www_example_com_.jpg",
  "format": "jpeg",
  "device": "desktop",
  "viewportWidth": 1280,
  "viewportHeight": 800,
  "fullPage": true,
  "imageWidth": 1280,
  "imageHeight": 3420,
  "truncated": false,
  "bytes": 284100,
  "loadTimeMs": 6150,
  "takenAt": "2026-09-27T06:17:50.332Z",
  "error": null
}
Enter fullscreen mode Exit fullscreen mode

screenshotUrl is a signed link that opens the image directly, without an API token, so you can paste it into a sheet or a report.

url statusCode device imageWidth imageHeight truncated error
https://www.example.com/ 200 desktop 1280 3420 false null
https://shop.example.com/ 200 desktop 1280 10000 true null
https://down.example.org/ null desktop null null false net::ERR_NAME_NOT_RESOLVED

Pages that fail still get a row with error filled in, so you know which ones to retry.

Step by step in the Apify Console

  1. Open the actor on the Apify Store (link at the end) and click Try for free.
  2. Add your pages to Page URLs, one per line. A missing https:// is added for you, and duplicates are dropped.
  3. Pick a Device: desktop (1280 by 800), laptop (1440 by 900), tablet (820 by 1180 at 2x) or mobile (390 by 844 at 3x, with an iPhone user agent). You can override the size with a custom viewport width and height.
  4. Leave Full page on to capture the whole scrollable page, or turn it off for the first screen only. Maximum page height (default 10,000 CSS pixels) cuts very long pages.
  5. Choose Image format: PNG (lossless) or JPEG (much smaller, with a quality setting from 1 to 100).
  6. Adjust Wait until (DOM ready, load event, or network idle for heavy single page apps) and Extra wait before capture (default 1,000 ms).
  7. Keep Hide cookie banners and Scroll to load lazy images on. Add your own CSS selectors to Also hide these elements for chat widgets or newsletter popups. Turn on Dark mode if you want the page's dark theme.
  8. Click Start. Open the Output tab and click any screenshotUrl to view or download the image.

Calling it from code

The actor id is pistachio_implementation/website-screenshot-api. Keep your token in APIFY_TOKEN.

curl:

curl -X POST \
  "https://api.apify.com/v2/acts/pistachio_implementation~website-screenshot-api/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://apify.com"], "device": "mobile", "format": "jpeg"}'
Enter fullscreen mode Exit fullscreen mode

Python with apify-client, downloading every image to a local folder:

import os
import urllib.request
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run = client.actor("pistachio_implementation/website-screenshot-api").call(
    run_input={
        "urls": ["https://apify.com", "https://en.wikipedia.org/wiki/Web_scraping"],
        "device": "desktop",
        "fullPage": True,
        "format": "jpeg",
        "jpegQuality": 80,
        "hideCookieBanners": True,
    }
)

os.makedirs("shots", exist_ok=True)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row["error"]:
        print("failed:", row["url"], row["error"])
        continue
    urllib.request.urlretrieve(row["screenshotUrl"], os.path.join("shots", row["screenshotKey"]))
Enter fullscreen mode Exit fullscreen mode

Pricing

Pay per event, with no subscription and no platform usage charges on top:

  • $3.00 per 1,000 screenshots ($0.003 each).
  • Failed pages (DNS errors, timeouts after one retry) are free.

A page that loads and is captured counts as a screenshot, whatever its HTTP status, so check statusCode and title if you capture pages that may be missing or blocked.

Limits and what it does not do

  • No login. Pages behind a login cannot be captured, and the actor never logs in.
  • Sites with strong bot protection may show their challenge page instead of the content. You then get a screenshot of the challenge, and the status code and title help you spot it.
  • Cookie banner hiding covers the most common consent tools (such as OneTrust, Cookiebot, Usercentrics, Didomi and Quantcast) by hiding them with CSS. It never clicks "accept", and it does not catch every custom popup.
  • Pages longer than Maximum page height are cut and marked truncated. Images are also kept under about 16,000 device pixels tall, so on the mobile preset (3x) a full page capture stops at about 5,300 CSS pixels.
  • Speed: two pages at once by default. Light pages take a few seconds, heavy full page captures 20 to 40 seconds at the default 1 GB of memory. You can raise Pages at once up to 5, but above 2 you should give the run 2 GB or more.
  • PNG and JPEG only. There is no PDF output in this version.
  • Images live in the run's storage for your Apify plan's retention period. Download them if you need to keep them longer.

Try it on the Apify Store: https://apify.com/pistachio_implementation/website-screenshot-api

Top comments (0)