# Website Screenshot Tool: Full Page, Mobile & Bulk (`precious_bathmat/website-screenshot-tool`) Actor

Take full-page screenshots of any list of websites on desktop, laptop, tablet and mobile. Cookie banners hidden, lazy images loaded, dark mode, element screenshots and optional PDF. PNG or JPEG with a direct link per image. No API key.

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

## Pricing

$5.00 / 1,000 screenshots

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

## Website Screenshot Tool: Full Page, Mobile & Bulk

Take **full-page screenshots** of any list of websites, on **desktop, laptop, tablet and mobile**, in one run. Every screenshot gets a **direct link**, so the results drop straight into a spreadsheet, a report or a monitoring workflow.

- **Whole page, top to bottom**, with **lazy-loaded images** scrolled into view first
- **Cookie banners accepted or hidden** for the common consent tools (OneTrust, Cookiebot, Usercentrics, Didomi, Quantcast, Sourcepoint and more)
- **Ads, trackers and chat widgets blocked**, so you see the page, not the ads
- **Four devices** in one run: desktop 1920 px, laptop 1366 px, tablet (iPad) and mobile (iPhone), with real mobile user agents
- **PNG or JPEG**, optional **Retina** resolution, **dark mode**, **one element only** (`#pricing`) and **PDF** copies
- **Pay only for screenshots taken**: pages that fail or show a bot check are free

### What does this website screenshot tool do?

```
https://www.apple.com/iphone/
 desktop  1920 × 16,888 px  JPEG 3.5 MB  → screenshotUrl
 mobile    390 × 20,000 px  JPEG 1.7 MB  → screenshotUrl (cut at the maximum height)
```

1. Paste **web addresses** and pick the **devices**.
2. Each page opens in a real Chrome browser at that device's size. Consent pop-ups are dismissed, ads are blocked and the page is scrolled so every image loads.
3. You get **one row per page and device** with the image link, size, title and HTTP status, plus a CSV.

```mermaid
flowchart LR
    A[Web addresses] --> B[Chrome at desktop,<br/>tablet or mobile size]
    B --> C[Accept cookies,<br/>block ads, scroll]
    C --> D[Full-page PNG or JPEG<br/>+ optional PDF]
    D --> E[One row per screenshot<br/>with a direct link]
```

### Who is it for?

- **Marketers and SEO teams** archiving competitors' landing pages and pricing pages over time
- **Designers and developers** checking responsive layouts on four screen sizes at once
- **QA teams** capturing pages after every release, on a schedule
- **Agencies** building client reports and website audits
- **Compliance and legal teams** keeping dated proof of what a page showed

### What data do you get?

**Screenshots** (dataset, one row per page and device)

| Field | What it tells you |
|---|---|
| `screenshotUrl`, `fileName`, `pdfUrl` | Direct links to the image (and PDF) |
| `url`, `finalUrl`, `title`, `httpStatus` | The page, after redirects |
| `device`, `width`, `height`, `pixelRatio` | Size of the capture |
| `pageHeight`, `cutAtMaxHeight` | How long the page really is; whether the image was cut |
| `fileSizeKb`, `format`, `loadSeconds`, `takenAt` | File and timing |

The images are in the run's key-value store, named after the page and device (`www.apple.com-iphone-mobile.jpg`). `SCREENSHOTS_CSV` lists every screenshot; `RUN_SUMMARY` gives the reason for every page that could not be captured.

### Example: 8 October 2026

**10 well-known sites on desktop and mobile, 19 of 20 screenshots** (JPEG, full page) in 7.5 minutes.

| Page | Desktop height | Mobile height |
|---|---|---|
| apple.com/iphone | 16,888 px | 20,000 px (cut) |
| stripe.com | 14,944 px | 20,000 px (cut) |
| shopify.com | 11,390 px | 11,531 px |
| github.com | 11,479 px | 12,797 px |
| bbc.com/news | 6,083 px | 10,093 px |
| news.ycombinator.com | 1,215 px | 1,800 px |

- Light pages take **about 5 seconds** (Hacker News, Apple's iPhone page); long marketing pages full of video and animation take up to 80 seconds (Stripe, Shopify).
- **Not captured, not charged** (across our test runs): The New York Times answered HTTP 403, Zara showed an "Access Denied" bot check, a fake domain did not exist, and Figma's desktop page crashed the browser tab once.

### Pricing

**$0.005 per screenshot** (one page on one device). Pages that fail, time out or show a bot check are free.

- 100 pages on desktop: **$0.50**
- 100 pages on desktop and mobile: **$1**

### Good to know

- **Very long pages** are cut at 20,000 pixels by default (`cutAtMaxHeight` tells you). Raise **Maximum height** for longer captures; with **High resolution** on, the limit is lower so the image still fits in memory.
- **Bot checks**: a few large sites refuse automated browsers. They are listed in `RUN_SUMMARY`, not charged.
- **Logged-in pages** cannot be captured: this tool sees what a new visitor sees.
- **Memory**: 2 GB and 2 pages at once by default. For hundreds of pages, more memory speeds the run up.
- **Links** to the images open for anyone who has them, without an Apify login (switch **Image links open without login** off to keep them private). They last as long as Apify keeps the run's storage on your plan; copy the files out to keep them longer.
- No login, no API key, no proxies needed.

### Input

| Field | Meaning |
|---|---|
| **Web pages** | Addresses, one per line |
| **Devices** | Desktop, laptop, tablet, mobile (default desktop) |
| **Full page** | On by default |
| **Image format**, **JPEG quality** | PNG by default |
| **Hide cookie banners**, **Block ads and trackers**, **Load lazy images** | All on by default |
| **Extra wait (seconds)** | 1 by default |
| **Page is ready when** | Network quiet (default), load event or HTML parsed |
| **Dark mode**, **High resolution** | Off by default |
| **Only this element**, **Hide these elements** | CSS selectors, optional |
| **Maximum height**, **Custom desktop width** | 20,000 px; 1920 px |
| **Also save as PDF** | Off by default |
| **Image links open without login** | On by default |
| **Pages at once**, **Page timeout** | 2; 60 seconds |

### Integrations

Export to JSON, CSV, Excel or Google Sheets, or connect through the Apify API, webhooks, Make, Zapier and n8n. Schedule it weekly to keep a dated archive of competitors' homepages and pricing pages.

# Actor input Schema

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

One per line: a domain (apple.com) or a full address. Each page is captured once per device.

## `devices` (type: `array`):

Desktop 1920 px, laptop 1366 px, tablet 820 px (iPad Air) and mobile 390 px (iPhone). Pick several to compare layouts; each device is one screenshot.

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

Capture the whole page from top to bottom. Off captures only what fits on the first screen.

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

PNG is sharp and lossless. JPEG files are 5-10 times smaller.

## `jpegQuality` (type: `integer`):

Only for JPEG: 10 (small, blurry) to 100 (large, sharp).

## `hideCookieBanners` (type: `boolean`):

Accept or hide consent pop-ups from the common consent tools (OneTrust, Cookiebot, Usercentrics, Didomi, Quantcast and others) so they do not cover the page.

## `blockAds` (type: `boolean`):

Do not load ads, analytics and chat widgets: pages load faster and screenshots show the page, not the ads.

## `scrollToLoadImages` (type: `boolean`):

Scroll through the page before the screenshot so images and sections that load on scroll appear.

## `delaySeconds` (type: `number`):

Wait this long after the page has loaded, for animations and late content.

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

"Network quiet" waits after the page has loaded until nothing loads for half a second, at most 5 more seconds (best). "Load event" is faster; "HTML parsed" is fastest but may miss images.

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

Ask the site for its dark theme, on sites that have one.

## `selector` (type: `string`):

Optional. Capture one element instead of the page, e.g. "#pricing" or "main table". The first match is used.

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

Optional CSS selectors to hide before capturing: chat widgets, sticky headers, ads. Example: "#intercom-container".

## `highResolution` (type: `boolean`):

Capture at the device's real pixel density: 2x on tablet, 3x on mobile. Sharper, but files are 4-9 times larger and very long pages are cut sooner.

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

Very long pages are cut at this height. The row says when a page was cut.

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

Optional. Replaces the 1920 px desktop width, e.g. 1440 or 2560.

## `savePdf` (type: `boolean`):

Also save each page as a PDF file with selectable text.

## `publicLinks` (type: `boolean`):

Anyone with a screenshot's link can open it (handy in spreadsheets and reports). Off keeps them private to your Apify account.

## `concurrency` (type: `integer`):

How many pages are captured in parallel. 2 suits the default 2 GB of memory; raise memory before raising this.

## `timeoutSecs` (type: `integer`):

Give up on a page that has not loaded within this time.

## Actor input object example

```json
{
  "urls": [
    "https://www.apple.com/iphone/",
    "https://stripe.com",
    "https://www.bbc.com/news"
  ],
  "devices": [
    "desktop"
  ],
  "fullPage": true,
  "format": "png",
  "jpegQuality": 80,
  "hideCookieBanners": true,
  "blockAds": true,
  "scrollToLoadImages": true,
  "delaySeconds": 1,
  "waitUntil": "networkidle",
  "darkMode": false,
  "highResolution": false,
  "maxHeight": 20000,
  "savePdf": false,
  "publicLinks": true,
  "concurrency": 2,
  "timeoutSecs": 60
}
```

# Actor output Schema

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

One row per page and device: image link, size, title, HTTP status, PDF link.

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

Every screenshot and PDF in the run's key-value store.

## `summary` (type: `string`):

Counts and the reason for every page that could not be captured.

# 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": [
        "https://www.apple.com/iphone/",
        "https://stripe.com",
        "https://www.bbc.com/news"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("precious_bathmat/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": [
        "https://www.apple.com/iphone/",
        "https://stripe.com",
        "https://www.bbc.com/news",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("precious_bathmat/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": [
    "https://www.apple.com/iphone/",
    "https://stripe.com",
    "https://www.bbc.com/news"
  ]
}' |
apify call precious_bathmat/website-screenshot-tool --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,precious_bathmat/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/kppGBc43yGYBPsPTN/builds/rAFDoNHGXguZVqQnF/openapi.json
