# Website Screenshot Generator (`automation-lab/website-screenshot-generator`) Actor

Capture public webpages in batches as PNG or JPEG with viewport, full-page, image, timing, and navigation metadata for visual QA and archiving.

- **URL**: https://apify.com/automation-lab/website-screenshot-generator.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.36 / 1,000 item extracteds

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/actors/running/actors-in-store.md#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

## Website Screenshot Generator

Capture **website screenshots** from one or many public HTTP(S) URLs as PNG or JPEG files. Each run stores the images in its Apify key-value store and returns typed metadata—including the final URL, HTTP status, page title, dimensions, byte size, navigation time, and capture time—in the default dataset.

Use it for recurring visual QA, release evidence, page previews, design reviews, and timestamped webpage archives. It renders JavaScript in maintained Chromium, supports full-page or viewport-only captures, and keeps a failed URL from discarding successful images elsewhere in the same batch.

### What does Website Screenshot Generator do?

The Actor opens every supplied public URL in an isolated browser context, waits for your selected navigation milestone, optionally pauses for delayed UI, hides configured CSS elements, and captures the rendered page.

It can:

- process up to 100 URLs per run;
- create lossless PNG or compact JPEG images;
- capture the full scrollable page or only the visible viewport;
- emulate desktop or mobile-size viewports;
- produce high-resolution images with a device scale factor up to 3;
- hide cookie banners, chat widgets, or other known selectors;
- record successful and failed requests in one consistent dataset;
- reject localhost, private-network, credential-bearing, and non-HTTP(S) URLs.

### Who is it for?

**QA and engineering teams** capture pages before or after releases and attach durable image evidence to CI or issue workflows.

**Agencies and designers** review landing pages at consistent viewport sizes across client sites.

**Content and compliance teams** create timestamped snapshots of public pages for authorized archiving.

**Developers and data teams** generate preview images and pass capture metadata into webhooks, spreadsheets, databases, or reporting pipelines.

### Why use this Actor?

Unlike a single-image utility, this Actor treats screenshots as structured batch output. Every requested URL gets a typed result row, images use deterministic per-run keys, and partial failures remain diagnosable.

Browser options are explicit rather than hidden: you control viewport, scale, format, JPEG quality, full-page mode, readiness condition, delay, timeout, user agent, and selectors to hide. Images and metadata are separated so downstream systems can query lightweight rows before downloading large files.

### Quick start

1. Open the Actor in Apify Console.
2. Add one or more public webpage URLs under **Webpage URLs**.
3. Keep **Capture full page** enabled for an entire-page archive, or disable it for a viewport screenshot.
4. Choose PNG or JPEG and set the viewport.
5. Click **Start**.
6. Open **Screenshot metadata** for result rows and **Screenshot files** for the images.

Minimal input:

```json
{
  "startUrls": [{ "url": "https://apify.com" }],
  "fullPage": true,
  "format": "png",
  "maxItems": 1
}
```

### Input parameters

| Field | Type | Default | Description |
|---|---:|---:|---|
| `startUrls` | array | required | Public HTTP(S) webpages to capture. |
| `viewportWidth` | integer | `1440` | Viewport width from 320 to 3840 CSS pixels. |
| `viewportHeight` | integer | `900` | Viewport height from 240 to 2160 CSS pixels. |
| `deviceScaleFactor` | number | `1` | Pixel density from 1 to 3. |
| `fullPage` | boolean | `true` | Capture the scrollable page rather than the visible viewport. |
| `format` | string | `png` | `png` or `jpeg`. |
| `quality` | integer | `85` | JPEG quality from 1 to 100; ignored for PNG. |
| `waitUntil` | string | `domcontentloaded` | `load`, `domcontentloaded`, `networkidle`, or `commit`. |
| `delayMs` | integer | `0` | Additional post-navigation wait, up to 30 seconds. |
| `navigationTimeoutSecs` | integer | `45` | Per-page navigation timeout from 5 to 120 seconds. |
| `userAgent` | string | browser default | Optional custom browser User-Agent. |
| `hideSelectors` | string\[] | `[]` | Up to 50 CSS selectors made invisible before capture. |
| `maxItems` | integer | `20` | Maximum supplied URLs processed, up to 100. |

### Capture a mobile JPEG

This example creates a compact viewport-only JPEG with a two-times device scale factor:

```json
{
  "startUrls": [{ "url": "https://github.com/apify" }],
  "viewportWidth": 390,
  "viewportHeight": 844,
  "deviceScaleFactor": 2,
  "fullPage": false,
  "format": "jpeg",
  "quality": 80,
  "maxItems": 1
}
```

### Hide banners and delayed widgets

If you know stable selectors for overlays, provide them in `hideSelectors`. Elements are made invisible without changing the surrounding layout.

```json
{
  "startUrls": [{ "url": "https://docs.apify.com/platform" }],
  "waitUntil": "domcontentloaded",
  "delayMs": 1000,
  "hideSelectors": [".cookie-banner", "[aria-label='Open chat']"],
  "fullPage": true
}
```

Invalid selectors or selectors absent from a page do not create images by themselves. Test your exact target because website markup changes.

### Output data

The default dataset contains one row per processed URL. Successful rows link to the binary image in the run key-value store. Failed rows keep the requested URL, settings, timestamp, and a bounded error message.

| Field | Meaning |
|---|---|
| `sourceUrl`, `finalUrl` | Requested URL and final browser URL after redirects. |
| `status`, `statusCode` | Capture result and main navigation HTTP status. |
| `title`, `contentType` | Rendered document title and response content type. |
| `screenshotKey`, `screenshotUrl` | Image key and Apify API download URL. |
| `format`, `width`, `height` | Image format and capture dimensions in CSS pixels. |
| `viewportWidth`, `viewportHeight`, `deviceScaleFactor` | Browser settings used. |
| `fullPage`, `imageBytes` | Capture mode and stored file size. |
| `navigationDurationMs`, `captureDurationMs` | Browser navigation and image generation timings. |
| `error` | Error detail for failed rows; otherwise `null`. |
| `capturedAt` | ISO 8601 processing timestamp. |

### Example output

A real local full-page capture produced this shape (the store ID below is illustrative):

```json
{
  "sourceUrl": "https://apify.com/",
  "finalUrl": "https://apify.com/",
  "status": "succeeded",
  "statusCode": 200,
  "title": "Apify: The largest marketplace of trusted tools for AI",
  "screenshotKey": "screenshot-001-59c5c2b19965.png",
  "screenshotUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/screenshot-001-59c5c2b19965.png",
  "format": "png",
  "width": 1440,
  "height": 9618,
  "viewportWidth": 1440,
  "viewportHeight": 900,
  "deviceScaleFactor": 1,
  "fullPage": true,
  "imageBytes": 905696,
  "navigationDurationMs": 933,
  "captureDurationMs": 1300,
  "contentType": "text/html; charset=utf-8",
  "error": null,
  "capturedAt": "2026-08-25T06:15:00.000Z"
}
```

### How much does it cost to capture website screenshots?

Pay-per-event pricing has a **$0.005 run start** and one `item` event for each dataset record produced. The BRONZE item price is **$0.002268 per requested URL**; volume tiers reduce the item price on higher Apify plans. Failed URL records are also dataset items because they preserve actionable diagnostics.

At the BRONZE rate:

- 1 URL: about **$0.007268** total;
- 10 URLs: about **$0.02768** total;
- 100 URLs: about **$0.2318** total.

These examples describe Actor charges. Final live prices appear in Apify Console before a run, and the Actor's measured browser infrastructure cost is included rather than billed as a separate event.

### Recurring visual QA and archives

Save the input as an Apify Task, then attach a schedule to capture the same pages daily, weekly, or after a deployment. Each run has separate dataset and key-value-store resources, creating timestamped capture history.

The Actor does not compare pixels, detect changes, annotate screenshots, or send alerts. Connect its output to your own comparison step or use [Website HTML & Text Change Monitor](https://apify.com/automation-lab/website-html-text-change-monitor) when text and HTML diffs are the actual requirement.

### Integrations and workflows

- **CI/CD:** start a Task after deployment and retain the run URL as release evidence.
- **Webhooks:** trigger processing when a run succeeds and send dataset rows to another service.
- **Google Sheets:** export metadata rows while keeping large images in Apify storage.
- **Python or Node.js:** download only screenshots whose status is `succeeded`.
- **Zapier or Make:** route failed rows for inspection and successful image URLs into reports.
- **Apify schedules:** maintain an authorized series of public-page snapshots.

### Run with the Apify API

Replace `YOUR_TOKEN` with an Apify API token.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~website-screenshot-generator/runs?token=YOUR_TOKEN&waitForFinish=120" \
  -H "Content-Type: application/json" \
  -d '{"startUrls":[{"url":"https://apify.com"}],"fullPage":true,"format":"png","maxItems":1}'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/website-screenshot-generator').call({
  startUrls: [{ url: 'https://apify.com' }],
  fullPage: true,
  format: 'png',
  maxItems: 1,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("automation-lab/website-screenshot-generator").call(run_input={
    "startUrls": [{"url": "https://apify.com"}],
    "fullPage": True,
    "format": "png",
    "maxItems": 1,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use with MCP and AI agents

#### Claude Code

Add the Actor to Claude Code through Apify MCP:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/website-screenshot-generator"
```

#### Claude Desktop, Cursor, and VS Code

Use this equivalent MCP configuration in Claude Desktop, Cursor, or VS Code:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/website-screenshot-generator"
    }
  }
}
```

Example prompts:

- “Capture full-page PNG screenshots of these three public release pages at 1440×900.”
- “Create a mobile JPEG of this landing page and return the image URL and navigation timing.”
- “Run my saved screenshot Task and list any failed capture rows.”

### Reliability, limits, and failure behavior

The Actor processes URLs sequentially to keep browser memory predictable. JavaScript-heavy pages, very tall pages, large device scale factors, and PNG output increase runtime, memory, and file size.

A page may render cookie dialogs, regional variants, personalized experiments, or anti-bot challenges. The image records what Chromium received. This Actor does not bypass authentication or CAPTCHA and does not expose an automatic residential-proxy fallback.

One failed URL produces a `failed` row while later URLs continue. If every URL fails, the run exits with an error after saving diagnostic rows. Redirects to private or local infrastructure are outside the supported public-web workflow.

### Troubleshooting

**The page times out with `networkidle`.** Use `domcontentloaded` or `load`; many analytics-heavy pages keep network connections open indefinitely.

**A dynamic component is missing.** Add a bounded `delayMs`, preferably 500–3000 ms, and verify the result. Long arbitrary delays increase cost.

**The screenshot includes a cookie banner.** Add its stable CSS selector to `hideSelectors`. The Actor cannot infer consent behavior safely.

**The image is too large.** Use JPEG, lower `quality`, reduce `deviceScaleFactor`, or disable `fullPage`.

**The run rejects my URL.** Only anonymous public HTTP(S) pages are supported. Localhost, private/reserved network addresses, embedded URL credentials, and other protocols are rejected.

### Legality and responsible use

Capture only pages you are authorized to access and store. Respect website terms, copyright, privacy rights, robots guidance where applicable, and applicable laws. Do not use screenshots to collect private account content, evade access controls, impersonate users, or archive sensitive personal information without a lawful basis.

The user controls submitted URLs and retention. Review Apify storage retention settings when images are used for compliance or archival workflows.

### Related Automation Lab Actors

- [Public Webpage HTML Downloader](https://apify.com/automation-lab/public-webpage-html-downloader) stores source or rendered HTML when pixels are not required.
- [Website HTML & Text Change Monitor](https://apify.com/automation-lab/website-html-text-change-monitor) produces machine-readable text and HTML changes.
- [Bulk Image Format Converter](https://apify.com/automation-lab/bulk-image-format-converter) converts captured or supplied image files into other supported formats.

### FAQ

#### Does this Actor create screenshot history?

Each scheduled run creates a timestamped set of images and metadata, so you can retain authorized historical captures. It does not discover old screenshots from third-party archives or compare captures automatically.

#### Can it capture logged-in pages?

No. The input intentionally supports anonymous public URLs and does not accept account credentials or cookies.

#### Are failed captures charged?

Each emitted dataset record uses the `item` event, including a failed row that contains diagnostics. The run fails when no URL succeeds.

#### Why are image dimensions expressed in CSS pixels?

`width` and `height` describe the captured page or viewport before `deviceScaleFactor`. A scale factor of 2 creates approximately twice as many output pixels in each dimension.

#### Can I capture PDFs or video?

The Actor is designed for rendered public webpages. It does not download original PDF/video assets or record motion. Use a dedicated downloader for those formats.

# Actor input Schema

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

Public HTTP(S) webpages to capture. Each URL produces one metadata record and, when successful, one image in the run's key-value store.

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

Browser viewport width in CSS pixels.

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

Browser viewport height in CSS pixels.

## `deviceScaleFactor` (type: `number`):

Output pixel density. Use 2 for high-resolution captures; higher values create larger images.

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

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

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

PNG preserves exact pixels; JPEG usually produces smaller files.

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

JPEG quality from 1 to 100. Ignored for PNG captures.

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

Browser navigation milestone to wait for before the optional delay and capture.

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

Extra wait after the readiness condition, useful for animations or delayed widgets.

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

Maximum time to wait for each page navigation.

## `userAgent` (type: `string`):

Optional browser User-Agent header. Leave empty to use the maintained Chromium default.

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

Optional CSS selectors for banners or overlays to make invisible before capture (maximum 50).

## `maxItems` (type: `integer`):

Maximum number of supplied URLs processed in one run.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://apify.com"
    }
  ],
  "viewportWidth": 1440,
  "viewportHeight": 900,
  "deviceScaleFactor": 1,
  "fullPage": true,
  "format": "png",
  "quality": 85,
  "waitUntil": "domcontentloaded",
  "delayMs": 0,
  "navigationTimeoutSecs": 45,
  "hideSelectors": [],
  "maxItems": 20
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing one typed result record per requested URL.

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

Key-value store containing the captured PNG and JPEG files.

# 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://apify.com"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/website-screenshot-generator").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://apify.com" }] }

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/website-screenshot-generator").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 '{
  "startUrls": [
    {
      "url": "https://apify.com"
    }
  ]
}' |
apify call automation-lab/website-screenshot-generator --silent --output-dataset

```

## MCP server setup

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

```

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/ysQRjtuPFMtzKcZIW/builds/onGFNDK9LvoHTa0NX/openapi.json
