# Bulk Website Screenshot Capture — Full-Page PNG/JPEG (`logiover/bulk-website-screenshot-capture`) Actor

Capture full-page or viewport screenshots of hundreds of URLs in bulk using headless Chromium via Playwright. Desktop, mobile and tablet device profiles. Cookie banner auto-dismiss and lazy-load triggering. PNG or JPEG output in key-value store.

- **URL**: https://apify.com/logiover/bulk-website-screenshot-capture.md
- **Developed by:** [Logiover](https://apify.com/logiover) (community)
- **Categories:** Developer tools, E-commerce
- **Stats:** 4 total users, 4 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $12.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Bulk Website Screenshot Capture — Full-Page & Viewport PNG/JPEG Screenshots

![Apify Actor](https://img.shields.io/badge/Apify-Actor-00A67E?logo=apify\&logoColor=white) ![No API key](https://img.shields.io/badge/No%20API%20key-required-2ea44f) ![Pay per result](https://img.shields.io/badge/Pricing-Pay%20per%20result-1C7ED6) ![Website Tools](https://img.shields.io/badge/Category-Website%20Tools-8B5CF6) ![Export](https://img.shields.io/badge/Export-JSON%20%7C%20CSV%20%7C%20Excel-F59E0B)

Take high-resolution **screenshots of URL lists in bulk**. Each attempted URL gets a structured success or error row with its page metadata; successful captures include a key-value-store download URL. Capture **full-page** or **viewport-only** PNG/JPEG images with desktop, mobile or tablet viewport presets in headless Chromium. Public pages may still differ from a personal browser because authentication, consent, bot defenses and regional delivery remain site-specific.

> ### 🏆 Why this screenshot Actor?
>
> Bounded bulk capture · full-page **or** viewport output · PNG **or** JPEG · desktop/mobile/tablet viewport presets · best-effort cookie-banner dismissal and lazy-load triggering · explicit per-URL failures · exportable manifest.

***

### ✨ What this Actor does / Key features

- 📸 **Bulk capture** — process a bounded URL list; each URL produces either a screenshot row or an explicit error row.
- 🖥️ **Full-page or viewport** — capture the entire scrollable page (`fullPage: true`) or just the visible fold — no more cut-off footers.
- 🧩 **Headless Chromium (Playwright)** — renders client-side JavaScript and captures the resulting page within bounded navigation and handler timeouts.
- 📱 **Three viewport presets** — Desktop (1920×1080), Mobile (390×844) and Tablet (1024×1366), plus a custom viewport. Presets do not spoof a specific device user-agent.
- 🖼️ **PNG or JPEG** — lossless PNG for pixel-perfect archives, or adjustable-quality JPEG for smaller files.
- 🍪 **Cookie-banner auto-dismiss** — best-effort handling for common consent controls; custom or shadow-DOM banners can remain.
- 🔄 **Bounded lazy-load triggering** — scrolls a finite number of steps so infinite-scroll pages cannot trap the run.
- 🔗 **Stored image URLs** — screenshots are saved to the run's key-value store and remain available according to that store's access and retention settings.
- 🛡️ **Proxy support** — Apify Proxy integration; datacenter or residential for geo-restricted or rate-limited pages.
- 💸 **Cost guardrail** — `maxScreenshots` caps the run so a huge URL list can't run away with your budget.

### 🚀 Quick start (3 steps)

1. **Configure** — paste your website URLs into **URLs to Screenshot**, pick a **Device Profile** and **Image Format** (PNG or JPEG), and choose full-page or viewport.
2. **Run** — click **Start**. The Actor opens each page in headless Chromium, dismisses cookie banners, scrolls to trigger lazy content, and captures the shot.
3. **Get your data** — open the **Output** tab and export the manifest, or download each image from its `screenshotUrl` while the run store remains retained and accessible.

### 📥 Input

`startUrls` is optional: empty input captures a small built-in public test set. Direct access is the default; enable proxy routing only when the target requires it.

#### Example — full-page desktop PNGs of competitor homepages

```json
{
  "startUrls": [
    { "url": "https://apify.com" },
    { "url": "https://github.com" },
    { "url": "https://vercel.com" }
  ],
  "deviceProfile": "desktop",
  "fullPage": true,
  "format": "png",
  "waitForTimeout": 3000,
  "maxScreenshots": 100
}
```

#### Example — mobile JPEG snapshots for responsive QA

```json
{
  "startUrls": [
    { "url": "https://stripe.com" },
    { "url": "https://airbnb.com" }
  ],
  "deviceProfile": "mobile",
  "fullPage": false,
  "format": "jpeg",
  "quality": 70,
  "waitForTimeout": 5000
}
```

#### Example — custom viewport with residential proxy for geo-restricted pages

```json
{
  "startUrls": [{ "url": "https://example.com" }],
  "deviceProfile": "custom",
  "viewportWidth": 1440,
  "viewportHeight": 900,
  "fullPage": true,
  "format": "png",
  "waitForTimeout": 8000,
  "maxScreenshots": 50,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `startUrls` | array | built-in test set | Optional URL list. Each URL produces a screenshot or an explicit error row. |
| `deviceProfile` | string (enum) | `desktop` | `desktop` (1920×1080), `mobile` (iPhone 15, 390×844), `tablet` (iPad Pro, 1024×1366) or `custom`. |
| `viewportWidth` | integer | 1920 | Viewport width in px (320–3840). Used only when `deviceProfile` is `custom`. |
| `viewportHeight` | integer | 1080 | Viewport height in px (240–4320). Used only when `deviceProfile` is `custom`. |
| `fullPage` | boolean | true | Capture the entire scrollable page (`true`) or just the visible viewport (`false`). |
| `format` | string (enum) | `png` | `png` (lossless, larger) or `jpeg` (lossy, smaller). |
| `quality` | integer | 80 | JPEG quality percentage (1–100). Ignored when `format` is `png`. |
| `waitForTimeout` | integer | 3000 | Extra wait after page load, in ms (0–30000), for lazy content, animations and dynamic elements. |
| `maxScreenshots` | integer | 100 | Maximum screenshots per run (1–1000). Caps the run to control cost. |
| `proxyConfiguration` | object | direct | Optional proxy routing for geo-restricted or rate-limited pages. |

> **Tip:** For heavy JavaScript apps (dashboards, single-page sites), raise `waitForTimeout` to 5000–8000 ms so everything finishes rendering before the capture. For smaller files when lossless quality isn't critical, use `format: "jpeg"` with `quality: 60`.

### 📤 Output

One row per screenshot, plus the image itself in the key-value store. The dataset is a machine-readable manifest with direct download URLs — export to **JSON, CSV, Excel or XML**. Here is a sample record:

```json
{
  "url": "https://apify.com",
  "screenshotUrl": "https://api.apify.com/v2/key-value-stores/xxxxxxxx/records/screenshot_1.png",
  "pageTitle": "Apify — Full-stack web scraping and data extraction platform",
  "viewportWidth": 1920,
  "viewportHeight": 1080,
  "fullPage": true,
  "format": "png",
  "fileSize": 1240523,
  "capturedAt": "2026-07-06T12:00:00.000Z"
}
```

<details>
<summary><b>📋 Full field reference (click to expand)</b></summary>

| Field | Description |
|-------|-------------|
| `url` | The original URL that was captured. |
| `screenshotUrl` | Permanent public URL to download the screenshot image from the key-value store. |
| `pageTitle` | The page's HTML `<title>` tag content. |
| `viewportWidth` | Browser viewport width in pixels used for the capture. |
| `viewportHeight` | Browser viewport height in pixels used for the capture. |
| `fullPage` | Whether full-page scrolling capture was used (`true`/`false`). |
| `format` | Image format of the saved file: `png` or `jpeg`. |
| `fileSize` | Size of the screenshot file in bytes. |
| `capturedAt` | ISO 8601 timestamp of when the screenshot was taken. |
| `error` | Failure reason when capture did not succeed; screenshot fields are null for that row. |

</details>

The images themselves live in Apify's key-value store as PNG or JPEG files. Download an individual screenshot from its `screenshotUrl` while the store is retained and accessible, or export the files through the Apify API.

### 💡 Use cases

- **Competitive analysis & design inspiration** — capture 50 competitor homepages, pricing pages and product screens in minutes for a swipe file or design review.
- **Visual regression testing & QA** — run the same production URL list on a schedule and compare shots side-by-side to catch layout breaks before customers do.
- **Website archiving & compliance** — archive pages as timestamped, full-page PNGs for regulatory filings, trademark disputes or historical records.
- **Pre-purchase & pre-redesign audits** — document the "before" state of a client site with pixel-perfect, dated screenshots before a project starts.
- **Portfolio & showcase creation** — freelancers and agencies snapshot their work before sites change or disappear.
- **Responsive checks** — capture the same URLs on desktop, mobile and tablet profiles to verify responsive layouts.

### 👥 Who uses it

Marketing & competitive-intelligence teams · web designers & agencies · QA and visual-regression engineers · legal, brand and compliance teams · freelancers building portfolios · growth and lead-gen teams documenting prospect websites at scale.

### 💰 Pricing

This Actor runs on a simple **pay-per-result** model — you pay for the screenshots you capture, with no separate monthly subscription. Use `maxScreenshots` to cap a run and keep costs predictable, and try it on the **free tier** first before scaling up. See the **Pricing** tab on this page for the current rate.

### ❓ Frequently Asked Questions

**Is this a website screenshot API alternative?**
Yes. You paste a URL list and the Actor renders each page in headless Chromium, returning a retained-store download URL for each successful shot and an explicit row for each failure.

**Can I take screenshots without an API key or login?**
Yes. There is no third-party screenshot service, account or key required — only an Apify account. The Actor captures any publicly accessible URL over a real browser.

**How do I take full-page screenshots of a list of URLs in bulk?**
Paste your URL list into **URLs to Screenshot** and keep **Full Page** on. Each successful capture gets a retained-store `screenshotUrl`; failed URLs get an error row.

**Can I capture mobile screenshots of a website?**
Yes. Set **Device Profile** to `mobile` or `tablet` for those viewport sizes. These presets change viewport dimensions but do not impersonate a specific device user-agent.

**How do I export the screenshots to CSV or JSON?**
The dataset manifest (URLs, titles, file sizes, `screenshotUrl`) exports as CSV, JSON, Excel or XML from the Apify console or API. The image files themselves download from each `screenshotUrl`.

**Does it capture behind-login pages?**
Not out of the box — the Actor captures publicly accessible URLs. For authenticated pages you would need to supply session cookies.

**How much data can I get / how many screenshots per run?**
Up to **1,000 screenshots per run** (the `maxScreenshots` ceiling). For very large lists, split them across multiple runs or schedule them. Each screenshot is typically ~1–5 MB depending on page size and format.

**Are the screenshots stored permanently?**
Screenshots stay in Apify's key-value store according to the store's retention and access settings. Download and archive any image that needs longer-lived storage.

**Is it legal to screenshot websites?**
The Actor only captures publicly available web pages. You are responsible for using the resulting images in compliance with the target sites' terms of service and applicable laws (e.g. copyright, GDPR).

### 🔗 More website & lead-gen tools by logiover

Building a full website-intelligence pipeline? Pair the screenshot Actor with the rest of the logiover website toolkit:

| Tool | What it does |
|---|---|
| [Website Change Monitor](https://apify.com/logiover/website-change-monitor) | Detect visual & text changes on any page on a schedule |
| [Website SEO Audit Crawler](https://apify.com/logiover/website-seo-audit-crawler) | Crawl a site and flag on-page SEO issues |
| [Website Tech Stack Detector](https://apify.com/logiover/website-tech-stack-detector) | Identify frameworks, CMS, analytics & hosting |
| [Website Image & Media Extractor](https://apify.com/logiover/website-image-media-extractor) | Pull every image and media asset from a site |
| [Bulk URL Status Checker](https://apify.com/logiover/bulk-url-status-checker) | Check HTTP status of thousands of URLs |
| [Broken Link Checker](https://apify.com/logiover/broken-link-checker) | Find dead links across a whole website |
| [Sitemap to URL Crawler](https://apify.com/logiover/sitemap-to-url-crawler) | Expand sitemaps into a clean URL list to feed here |
| [URL to Markdown](https://apify.com/logiover/url-to-markdown) | Convert any page into clean Markdown |
| [Social Card Preview API](https://apify.com/logiover/social-card-preview-api) | Render OpenGraph/Twitter card previews for URLs |
| [Website Text & Markdown Crawler](https://apify.com/logiover/website-text-markdown-crawler) | Extract readable page text at scale |
| [JSON-LD & Meta Tag Extractor](https://apify.com/logiover/json-ld-schema-meta-tag-extractor) | Pull structured data & meta tags from pages |
| [Website Contact Scraper](https://apify.com/logiover/website-contact-scraper) | Extract emails, phones & socials from websites |

👉 Browse all **[logiover scrapers on Apify Store](https://apify.com/logiover)** — 180+ actors across real estate, jobs, crypto, social media & B2B data.

### ⏰ Scheduling & integration

Schedule this Actor on Apify to build a visual archive of a fixed URL list daily or weekly. Push the manifest to Google Sheets, a database, BI tools or webhooks through the Apify API, and connect it to **Make, n8n or Zapier** — for example, auto-save each shot to a dated Google Drive folder, or ping Slack when a competitor's homepage changes.

### ⭐ Support & feedback

Found a bug or need an extra option (element-level capture, custom headers, a new device profile)? Open an issue on the **Issues** tab — response is usually fast. If this Actor saves you time, a **★★★★★ review** on the Store page genuinely helps and is hugely appreciated. 🙏

### ⚖️ Legal

This Actor captures only publicly available web pages and is intended for legitimate research, QA, archiving and analytics use. You are responsible for complying with the target websites' terms of service, copyright, GDPR and any applicable local laws.

***

### 📝 Changelog

#### 2026-08-01

- Completed the August 2026 full health check: verified empty/programmatic default, Console UI default, and two source-informed alternative inputs on Apify.
- Confirmed successful live execution, non-empty structured output, dataset-field/type integrity, and logical sample quality within the 5-minute quality window.
- Replaced fragile Console-prefill targets with lightweight public pages after the former proxied Apify/GitHub pair timed out; the exact new two-URL desktop PNG input produced 2/2 non-empty screenshots locally.
- Retained explicit all-failed semantics and per-URL failure rows so a transport-wide screenshot failure cannot be reported as a successful empty dataset.

#### 2026-08-01 — Health-check remediation

- August 2026 monthly health-check remediation is in progress; this build contains fixes verified from empty/default, Console-default, targeted live probes, or field-level semantic review.
- Bounded navigation, scrolling, retries and global runtime; fixed failed-request accounting, duplicate URL handling and public key-value-store URLs; and made all-failed batches fail explicitly instead of succeeding with an empty dataset.
- Replaced the fragile Console prefill targets with lightweight public pages and verified the exact two-URL desktop PNG input locally: 2/2 screenshots, valid titles and non-empty image files.
- The final four-input matrix verdict will be appended after post-build cloud revalidation.

#### 2026-07-06

- ✨ README overhaul: gold-standard structure with badge row, named input scenarios, real-schema output sample & full field reference, expanded keyword-gap FAQ, and a website-tools cross-promo grid.

#### 2026-07-01

- Maintenance pass: re-verified end-to-end on live data and confirmed successful runs within the 5-minute quality window on the default input.
- Sharpened Store metadata (SEO title & description) and expanded the FAQ with high-intent, long-tail questions for easier discovery in Google and Apify Store search.
- Added ready-to-run example tasks that cover common real-world use cases.

# Actor input Schema

## `startUrls` (type: `array`):

List of website URLs to capture as screenshots. Each URL produces a PNG or JPEG image stored in key-value storage. Leave empty to capture a default set of well-known sites.

## `viewportWidth` (type: `integer`):

Browser viewport width in pixels. Only used when deviceProfile is set to custom.

## `viewportHeight` (type: `integer`):

Browser viewport height in pixels. Only used when deviceProfile is set to custom.

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

Capture the entire scrollable page (true) or just the visible viewport (false). Full-page captures are larger but show all content.

## `deviceProfile` (type: `string`):

Predefined viewport size. These presets do not spoof a specific browser user-agent; use custom to set viewportWidth and viewportHeight manually.

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

Output image format. PNG is lossless but larger. JPEG is smaller but uses lossy compression.

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

Image quality percentage for JPEG format. Higher values produce better quality but larger files. Ignored when format is PNG.

## `waitForTimeout` (type: `integer`):

Extra wait time in milliseconds after page load to allow lazy-loaded content, animations, and dynamic elements to fully render.

## `maxScreenshots` (type: `integer`):

Maximum total number of screenshots to capture in this run. Caps the run to control costs.

## `proxyConfiguration` (type: `object`):

Optional proxy settings. Direct access is the reliable default; enable Apify Proxy or residential routing for geo-restricted or rate-limited targets.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://example.com"
    },
    {
      "url": "https://news.ycombinator.com"
    }
  ],
  "viewportWidth": 1920,
  "viewportHeight": 1080,
  "fullPage": true,
  "deviceProfile": "desktop",
  "format": "png",
  "quality": 80,
  "waitForTimeout": 3000,
  "maxScreenshots": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All records extracted by this run. Open the Dataset tab to browse, filter, and export as CSV, JSON, or Excel.

# 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 = {
    "startUrls": [
        {
            "url": "https://example.com"
        },
        {
            "url": "https://news.ycombinator.com"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("logiover/bulk-website-screenshot-capture").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 = {
    "startUrls": [
        { "url": "https://example.com" },
        { "url": "https://news.ycombinator.com" },
    ],
    "proxyConfiguration": { "useApifyProxy": False },
}

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

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

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

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://example.com"
    },
    {
      "url": "https://news.ycombinator.com"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call logiover/bulk-website-screenshot-capture --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=logiover/bulk-website-screenshot-capture",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/xZpAfJQawhad16hn6/builds/t1wzcHoc1BlhX8K8a/openapi.json
