# Website Screenshot Tool - Bulk Full Page PNG, JPG, WebP, PDF (`jeanswiegers/website-screenshot-tool`) Actor

Capture full-page or viewport screenshots of many websites in PNG, JPEG, WebP or PDF. Device presets (iPhone, Pixel, iPad, laptop), auto-dismisses cookie banners, lazy-load scrolling, dark mode, custom CSS, ad blocking. Public image URLs.

- **URL**: https://apify.com/jeanswiegers/website-screenshot-tool.md
- **Developed by:** [Jean Swiegers](https://apify.com/jeanswiegers) (community)
- **Categories:** Developer tools, Automation, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 screenshot takens

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Bulk Website Screenshot API – Full-Page Screenshots of Many URLs (PNG, JPG, WebP, PDF)

**Take clean screenshots of hundreds of websites in one run.** Full page or viewport, desktop, laptop, iPhone, Pixel or iPad, in PNG, JPEG, WebP or PDF. Cookie banners are dismissed automatically, lazy-loaded images are loaded by scrolling, and every screenshot gets a **public URL** you can drop straight into a spreadsheet, CMS, report or AI pipeline. **No API key, no subscription, no start fee – $0.002 per successful screenshot.**

### What can I use it for?

- 🖼️ **Website thumbnails & previews** for directories, link previews, portfolios and SaaS dashboards
- 🧪 **Visual QA & regression checks** across mobile and desktop after each deploy
- 🕵️ **Competitor & SERP monitoring** – archive how landing pages, pricing pages and ads change over time
- 📑 **Compliance & evidence archiving** – timestamped PDF/PNG captures of web pages
- 🤖 **AI / LLM vision inputs** – feed page screenshots to multimodal models
- 📊 **Agency reporting** – before/after captures for clients

### Features

- **Full-page** or **viewport** captures, with a max-height safety limit
- **Device presets**: Desktop 1920×1080, Laptop 1366×768, iPhone 15, Pixel 7, iPad – or any custom size and pixel ratio (retina)
- **Formats**: PNG, JPEG, WebP (with quality setting) and PDF
- **Auto-dismiss cookie banners**: OneTrust, Cookiebot, Didomi, Quantcast, Sourcepoint, Usercentrics, CookieYes, Osano, Complianz, iubenda and more, plus multilingual text heuristics and a hide-leftovers fallback
- **Wait controls**: load / DOM ready / network idle, wait for a CSS selector, extra delay
- **Lazy-load scrolling**, **hide elements** (chat widgets, popups), **dark mode**, **custom CSS**
- Optional **ad & tracker blocking** for faster, cleaner captures
- Fresh isolated browser context per URL, automatic retries, clear per-URL errors – **you only pay for successful screenshots**

### How to take screenshots of many websites at once

1. Paste your URLs into **URLs** (or upload a text file with one URL per line).
2. Pick a device preset (desktop, laptop, iPhone, Pixel, iPad or a custom size), full page or viewport, and the format (PNG, JPEG, WebP or PDF).
3. Click **Start**. Each screenshot appears in the **Screenshots** view with a preview and a public `screenshotUrl`; export the list as JSON, CSV or Excel, or call the Actor from your own code via the Apify API.

### Input example

```json
{
  "urls": [{ "url": "https://example.com" }, { "url": "https://apify.com" }],
  "device": "iphone",
  "fullPage": true,
  "format": "webp",
  "quality": 80,
  "dismissCookieBanners": true,
  "hideSelectors": ["#intercom-container"],
  "blockAdsAndTrackers": true
}
```

### Output example

Each URL becomes one dataset item; the image is stored in the run's key-value store:

```json
{
  "url": "https://apify.com/",
  "finalUrl": "https://apify.com/",
  "status": "succeeded",
  "httpStatus": 200,
  "title": "Apify: Marketplace of ready-to-run tools for AI",
  "screenshotUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/screenshot-apify.com-desktop-mvdesb7e.png",
  "format": "png",
  "device": "desktop",
  "fullPage": false,
  "width": 1920,
  "height": 1080,
  "truncated": false,
  "sizeBytes": 196311,
  "cookieBanner": "selector:#onetrust-accept-btn-handler",
  "durationMs": 2025,
  "capturedAt": "2026-10-18T05:52:39.301Z",
  "error": null
}
```

The **Screenshots** dataset view shows image previews right in Apify Console. Export as JSON, CSV, Excel or via API.

### How much does it cost?

Pay per event: **$0.002 per successful screenshot** – that's **$2 per 1,000 screenshots**. **No extra platform usage charges** – the compute is included. Failed captures are never charged.

| Screenshots | Price |
|---|---|
| 100 | $0.20 |
| 1,000 | $2.00 |
| 10,000 | $20.00 |
Set a maximum cost per run in Apify Console and the Actor stops cleanly when it is reached.

### FAQ

**Can I use it as a screenshot API?** Yes. Start the Actor through the Apify API (or the JavaScript/Python clients), wait for the run to finish and read `screenshotUrl` from the dataset. Schedules and webhooks let you capture the same pages daily or weekly.

**Can I screenshot a list of URLs from a spreadsheet?** Yes. Copy the URL column into the input, or upload it as a text file with one URL per line. Duplicates and URLs without `https://` are handled for you.

**Does it bypass CAPTCHAs or bot protection?** No. It loads pages like a normal browser and does not attempt to evade anti-bot systems. Pages that block automated browsers will return an error or the block page.

**Why is my full-page screenshot cut off?** Very long pages are limited by `maxHeight` (default 15,000 CSS px) and marked `truncated: true`. Increase it if needed.

**Some images are missing.** Enable `scrollToBottom`, use `waitUntil: networkidle` or add a `delayMs`.

**Is a cookie banner still visible?** Add its selector to `hideSelectors` and open an issue so we add that consent manager.

**How long are screenshots kept?** In the run's default key-value store per your Apify data retention settings. Download or copy them to your own storage if you need them longer.

**Is it legal?** Capturing publicly available pages is generally fine, but respect copyright and each site's terms. No personal data is collected.

# Changelog

This Actor's version history is a separate document: https://apify.com/jeanswiegers/website-screenshot-tool/changelog.md

# Actor input Schema

## `urls` (type: `array`):

Pages to screenshot. URLs without a scheme get https:// added. Duplicates are removed.

## `fullPage` (type: `boolean`):

Capture the whole scrollable page instead of only the visible viewport.

## `device` (type: `string`):

Viewport, pixel ratio and user agent preset. Choose 'custom' to set your own size.

## `customWidth` (type: `integer`):

Viewport width when device is 'custom'.

## `customHeight` (type: `integer`):

Viewport height when device is 'custom'.

## `deviceScaleFactor` (type: `integer`):

Override pixel density, e.g. 2 for retina-quality images. Leave empty to use the preset's value.

## `format` (type: `string`):

Output file type. WebP and JPEG are much smaller than PNG. PDF renders one page with the screen stylesheet.

## `quality` (type: `integer`):

1-100. Ignored for PNG and PDF.

## `waitUntil` (type: `string`):

When navigation is considered finished. 'networkidle' waits for network to quiet down (up to 15 s extra).

## `waitForSelector` (type: `string`):

Optional. Wait until this element is visible before capturing, e.g. '#chart canvas'.

## `delayMs` (type: `integer`):

Wait this long right before capturing (animations, fonts).

## `scrollToBottom` (type: `boolean`):

Scroll through the page first so lazy-loaded images appear. Defaults to on for full-page captures.

## `dismissCookieBanners` (type: `boolean`):

Click 'Accept' on common consent managers (OneTrust, Cookiebot, Didomi, Quantcast, Sourcepoint, Usercentrics, CookieYes...) or hide leftover banners.

## `blockAdsAndTrackers` (type: `boolean`):

Block requests to common ad and analytics networks. Faster captures and cleaner pages.

## `hideSelectors` (type: `array`):

Elements to hide before capturing, e.g. chat widgets: '#intercom-container'.

## `darkMode` (type: `boolean`):

Emulate prefers-color-scheme: dark (works on sites that support it).

## `customCss` (type: `string`):

CSS injected before capturing.

## `maxHeight` (type: `integer`):

Full-page captures taller than this are cut off (marked truncated: true).

## `maxConcurrency` (type: `integer`):

Pages captured in parallel. ~3 per 1 GB memory.

## `navigationTimeoutSecs` (type: `integer`):

Max time to load a page.

## `maxRetries` (type: `integer`):

Retry failed captures. You are only charged for successful screenshots.

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://example.com"
    },
    {
      "url": "https://apify.com"
    }
  ],
  "fullPage": false,
  "device": "desktop",
  "customWidth": 1280,
  "customHeight": 800,
  "format": "png",
  "quality": 80,
  "waitUntil": "load",
  "delayMs": 0,
  "dismissCookieBanners": true,
  "blockAdsAndTrackers": false,
  "darkMode": false,
  "maxHeight": 15000,
  "maxConcurrency": 3,
  "navigationTimeoutSecs": 45,
  "maxRetries": 2
}
```

# Actor output Schema

## `screenshots` (type: `string`):

One item per URL with public screenshot URL, HTTP status, page title, dimensions, size, timing and error details.

## `files` (type: `string`):

The image/PDF files stored in the key-value store.

## `runSummary` (type: `string`):

Totals of succeeded and failed screenshots.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        {
            "url": "https://example.com"
        },
        {
            "url": "https://apify.com"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jeanswiegers/website-screenshot-tool").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": [
        { "url": "https://example.com" },
        { "url": "https://apify.com" },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("jeanswiegers/website-screenshot-tool").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    {
      "url": "https://example.com"
    },
    {
      "url": "https://apify.com"
    }
  ]
}' |
apify call jeanswiegers/website-screenshot-tool --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jeanswiegers/website-screenshot-tool"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/acBFhFpp3c9AOp7S5/builds/3hHeegzbemlxlnBi7/openapi.json
