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

Capture screenshots of any website using Playwright headless browser. Full-page or viewport capture. Supports batch mode (up to 50 URLs), device presets (desktop/tablet/mobile), CSS selector targeting, PNG/JPEG/WebP output.

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

## Pricing

from $0.005 / actor start

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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 📸 — Full-Page & Viewport Capture via Playwright

**Capture screenshots of any website — full‑page scrollable content or viewport‑only — using a headless Playwright browser engine. Supports batch mode (up to 50 URLs), three device presets (desktop, tablet, mobile), custom viewport dimensions, CSS selector element targeting, and three output formats (PNG, JPEG, WebP). Images are stored in the Apify Key‑Value Store with direct‑access URLs for immediate integration into dashboards, monitoring pipelines, visual regression test suites, and reporting tools.**

Built for anyone who needs automated website screenshots without running their own Playwright infrastructure.

---

### What does it do?

The **Website Screenshot Generator** eliminates the operational overhead of running headless browsers for screenshot capture. Modern websites are increasingly dynamic — reliant on JavaScript rendering, lazy‑loaded images, asynchronous content injection, and complex CSS animations. Taking a reliable screenshot of such a page requires not just a browser engine, but careful orchestration of navigation timing, viewport sizing, content settlement, and error handling. This actor wraps all of that complexity into a single API call.

When you submit a URL, the actor launches an isolated Chromium browser instance via Playwright. It navigates to the target page, waits for the `networkidle` event (ensuring all XHR/fetch requests have settled), applies an optional user‑configurable delay for animations or lazy‑loaded content to complete, then captures the screenshot. The result is pushed to the Apify Key‑Value Store with a deterministic filename derived from the domain and timestamp, and the dataset receives a structured record containing the URL, viewport configuration, page metadata, and a direct download link.

The actor supports two distinct operating modes. **Single URL mode** processes one website at a time with full configuration control — ideal for on‑demand screenshots, manual QA checks, or integration into CI/CD pipelines where a single verification image is needed per run. **Batch mode** accepts an array of up to 50 URLs with per‑item overrides for device preset, viewport size, format, and full‑page flag — enabling portfolio‑wide visual audits, screenshot archives, or mass content verification in a single run. Each URL in a batch is processed sequentially in its own browser context to prevent cookie leakage, session cross‑contamination, or JavaScript state bleed between unrelated domains.

Beyond plain viewport captures, the actor offers three specialised capture modes. **Full‑page mode** scrolls the entire document and composites a single image containing every pixel of the page — essential for capturing infinite‑scroll layouts, long documentation pages, or any content that extends below the fold. **CSS selector mode** targets a specific DOM element by its selector string (e.g., `#main-content`, `.hero-banner`, `img.hero-logo`) and captures only that element's bounding box — perfect for isolating a navigation bar, a specific widget, or a call‑to‑action button for visual regression testing. **Device preset mode** automatically sets the viewport to standard dimensions for desktop (1920×1080), tablet (768×1024), or mobile (375×812) — any dimension can be overridden with custom width and height values for non‑standard layouts.

---

### Who is it for?

| Persona | Typical Need | How the Actor Helps |
|---------|-------------|---------------------|
| **QA Engineer** | Capture screenshots during automated test runs for visual regression detection | Full‑page and viewport modes with CSS selector targeting; deterministic filenames for diff‑based comparison across builds |
| **Web Developer** | Verify responsive layout across multiple viewport sizes without manual browser resizing | Device presets (desktop, tablet, mobile) with custom dimension overrides; batch mode renders the same URL at multiple breakpoints |
| **Content Curator / Editor** | Generate preview thumbnails for article links, bookmark archives, or RSS feed items | PNG/JPEG/WebP output; direct KVS URLs ready for CDN distribution; page title metadata included in each result |
| **Digital Marketer** | Capture competitor landing pages, ad creatives, or promotional banners for market analysis | Batch mode processes up to 50 URLs in one run; per‑item overrides for device and format; timestamped captures for change tracking |
| **Security Researcher** | Document phishing pages, defaced websites, or suspicious content for incident reports | Full‑page capture preserves entire page content; CSS selector mode isolates specific elements; KVS storage provides permanent evidence URLs |
| **DevOps / SRE Engineer** | Integrate screenshot capture into CI/CD pipelines for deployment verification | Fully scriptable via Apify API; charge events only for successful captures; structured JSON output parsable by any automation tool |
| **Platform / Product Manager** | Monitor partner landing pages, onboarding flows, or marketing sites for visual drift | Batch mode with weekly timestamped captures; dataset views for diffing current vs. historical screenshots |
| **Design System Maintainer** | Capture component states (hover, active, focused) across different viewports for documentation | CSS selector mode isolates individual components; custom delay allows hover/focus state animations to settle |

---

### Why use this?

- **Zero browser infrastructure to manage** — No need to install, configure, or patch a headless Chromium instance. The actor ships with Playwright pre‑installed on the Apify platform. Submit a URL, get a screenshot back. No `Dockerfile` tweaking, no `xvfb` setup, no `selenium` grid maintenance.

- **Three capture modes in one tool** — Viewport‑only for fast, targeted captures. Full‑page for scrollable content. CSS selector for element‑level isolation. Choose the right mode per task without switching between different tools or scripts. A single API contract covers all three.

- **Production‑grade error resilience** — Every URL is processed in its own browser context, so a timeout, DNS failure, or SSL error on one page never blocks the rest of the batch. Failed captures are reported with descriptive error messages (timeout vs. network error vs. invalid selector) and excluded from charges — you only pay for successful output.

- **Responsive testing built in** — Three device presets (desktop, tablet, mobile) with the ability to override any dimension independently. Run the same URL through all three presets in a single batch to verify responsive behaviour without touching browser DevTools.

- **Key-Value Store output** — Screenshots are pushed to the Apify Key‑Value Store with deterministic filenames and content‑type headers. Access via the `screenshotUrl` field with the Apify API token, or download directly from the Apify Console run view.

- **Batch processing with per‑item control** — Process up to 50 URLs in a single run, each with independent device, format, full‑page, and delay settings. Mix desktop and mobile captures in the same batch. Override quality for JPEG/WebP per item.

- **Metadata‑rich output** — Every result includes the page title, viewport dimensions, device label, page scroll height, image format, capture timestamp, and the direct KVS download URL — structured JSON ready for downstream processing, database insertion, or reporting.

- **Cost‑effective per‑capture pricing** — The `screenshot-capture` event charges only for successfully captured images. Failed captures (timeout, 404, invalid URL) incur no charge. Full‑page captures and CSS selector captures have separate, lower surcharges — you only pay for the enhanced processing when you use it.

---

### Features

#### Playwright Chromium Engine
The actor uses Playwright's Chromium browser — the same engine that powers modern Chrome. It supports the full modern web platform: ES2023+ JavaScript, WebAssembly, CSS Grid, Flexbox, custom fonts, canvas, WebGL, and service workers. The browser runs in headless mode with `--no-sandbox`, `--disable-dev-shm-usage`, and `--single-process` flags for optimal performance in the Apify container environment.

#### Three Capture Modes

| Mode | Trigger | Use Case |
|------|---------|----------|
| **Viewport** | `fullPage: false` | Fast capture of above‑the‑fold content. Best for preview thumbnails, dashboard widgets, social link cards. |
| **Full‑Page** | `fullPage: true` | Composite image of entire scrollable document. Best for content audits, documentation archives, design reviews. |
| **CSS Selector** | `cssSelector: "#id"` | Isolated capture of a single DOM element. Best for visual regression testing of specific components, widget QA, ad verification. |

#### Device Presets with Custom Overrides

| Preset | Default Viewport | Typical Target |
|--------|-----------------|----------------|
| `desktop` | 1920×1080 | Standard laptop/desktop monitors, 16:9 screens |
| `tablet` | 768×1024 | iPad portrait orientation, medium‑sized tablets |
| `mobile` | 375×812 | iPhone X‑series portrait, modern smartphones |

Any dimension can be overridden independently via the `width` and `height` parameters. Setting `device: "mobile"` with `width: 414` produces an iPhone 11 Pro Max width at mobile viewport height.

#### Image Format Support

| Format | Type | Best For | Quality Support |
|--------|------|----------|-----------------|
| **PNG** | Lossless | UI mockups, design reviews, text‑heavy pages | Not applicable (always lossless) |
| **JPEG** | Lossy | Photo‑heavy pages, preview thumbnails, bandwidth‑sensitive use cases | 1 (smallest) to 100 (highest) |
| **WebP** | Lossy/Lossless | Modern web applications, Chrome/Edge‑first pipelines | 1 (smallest) to 100 (highest) |

PNG is the default format and the safest choice for pixel‑perfect accuracy. JPEG at quality 85 offers excellent compression for photographic content with minimal visual degradation. WebP provides superior compression ratios over JPEG at equivalent quality settings.

#### Configurable Navigation Delay
The `delay` parameter (0–60000ms) injects a pause between page load completion and screenshot capture. This is essential for:
- CSS animations that trigger on page load (fade‑ins, slide‑ups)
- A/B testing scripts that swap content after the `DOMContentLoaded` event
- Lazy‑loaded images triggered by scroll position or intersection observers
- Third‑party widget initialisation (chat widgets, cookie consent banners, social share buttons)

#### Automatic URL Normalisation
URLs submitted without a scheme (`example.com`) are automatically prefixed with `https://`. Invalid URLs (empty strings, malformed hosts, non‑HTTP schemes) are caught during input validation with descriptive error messages before any browser process is launched — saving both time and billing charges.

#### Deterministic Key‑Value Store Naming
Screenshot filenames follow the pattern `{domain_sanitised}_{timestamp}.{ext}`. For example, a screenshot of `https://example.com` captured on 24 July 2026 at 14:30:00 would produce `example_com_20260724_143000_123456.png`. This deterministic naming ensures:
- No filename collisions within a single run (microsecond precision)
- Immediate recognisability of the source domain from the filename
- Idempotent storage keys for the same domain + timestamp combination

---

### Input Parameters

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `url` | string | Yes* | — | Single URL to screenshot. Required when `batchMode` is `false`. |
| `batchData` | array | No* | `[]` | Batch items array. Required when `batchMode` is `true`. Max 50 items. |
| `batchMode` | boolean | No | `false` | Enable batch processing. `true` = use `batchData`, `false` = use `url`. |
| `device` | string | No | `desktop` | Device preset: `desktop` (1920×1080), `tablet` (768×1024), `mobile` (375×812). |
| `fullPage` | boolean | No | `false` | `true` = full scrollable page, `false` = viewport only. |
| `delay` | integer | No | `0` | Milliseconds to wait before capture (max 60000ms). |
| `width` | integer | No | — | Custom viewport width in pixels (320–7680). Overrides device preset. |
| `height` | integer | No | — | Custom viewport height in pixels (240–4320). Overrides device preset. |
| `cssSelector` | string | No | — | CSS selector for element‑specific capture (e.g., `#main`, `.hero`). |
| `format` | string | No | `png` | Output format: `png`, `jpeg`, or `webp`. |
| `quality` | integer | No | — | JPEG/WebP quality (1–100). Ignored for PNG. |

> * Either `url` (single mode) or `batchData` (batch mode) is required, not both.

---

### Example Input

#### Single URL — Viewport PNG

```json
{
  "url": "https://example.com",
  "device": "desktop",
  "fullPage": false,
  "format": "png"
}
````

#### Single URL — Full‑Page JPEG with Quality

```json
{
  "url": "https://example.com",
  "device": "mobile",
  "fullPage": true,
  "format": "jpeg",
  "quality": 85,
  "delay": 2000
}
```

#### CSS Selector — Element Capture

```json
{
  "url": "https://example.com",
  "cssSelector": "h1",
  "format": "png"
}
```

#### Batch Mode — Multiple Devices

```json
{
  "batchMode": true,
  "batchData": [
    {
      "url": "https://example.com",
      "device": "desktop",
      "fullPage": true,
      "format": "png"
    },
    {
      "url": "https://example.com",
      "device": "tablet",
      "fullPage": false,
      "format": "png"
    },
    {
      "url": "https://example.com",
      "device": "mobile",
      "fullPage": false,
      "format": "jpeg",
      "quality": 90
    }
  ]
}
```

***

### Output Format

Each successful screenshot produces a dataset item with the following structure:

```json
{
  "url": "https://example.com",
  "screenshotKey": "example_com_20260724_143000_123456.png",
  "device": "desktop",
  "fullPage": true,
  "format": "png",
  "viewport": {
    "width": 1920,
    "height": 1080
  },
  "pageTitle": "Example Domain",
  "pageHeight": 2430,
  "timestamp": "2026-07-24T14:30:00.123456+00:00",
  "error": null,
  "success": true
}
```

| Field | Type | Description |
|-------|------|-------------|
| `url` | string | The original URL that was screenshotted |
| `screenshotKey` | string | Key‑Value Store record key for the screenshot image. Download via Apify Console (open run → Key-Value Store tab) or via the Apify API with your API token. |
| `device` | string | Resolved device label (`desktop`, `tablet`, `mobile`, or `custom`) |
| `fullPage` | boolean | Whether full‑page capture mode was used |
| `format` | string | Output image format (`png`, `jpeg`, `webp`) |
| `viewport` | object | Actual viewport dimensions `{width, height}` used for capture |
| `pageTitle` | string | Document title from the HTML `<title>` tag |
| `pageHeight` | integer | Total scrollable height of the page in pixels |
| `timestamp` | string | ISO‑8601 UTC timestamp of when the capture was taken |
| `error` | string | Error message if capture failed, otherwise `null` |
| `success` | boolean | Whether the screenshot was captured and stored successfully |

#### Failed Screenshot Example

```json
{
  "url": "https://example.com/nonexistent",
  "screenshotKey": null,
  "device": "desktop",
  "fullPage": false,
  "format": "png",
  "viewport": {
    "width": 1920,
    "height": 1080
  },
  "pageTitle": "",
  "pageHeight": 0,
  "timestamp": "2026-07-24T14:30:05.654321+00:00",
  "error": "Navigation timed out: https://example.com/nonexistent",
  "success": false
}
```

#### Batch Summary Item

After all items are processed, a final summary item is pushed:

```json
{
  "status": "completed",
  "totalUrls": 3,
  "completed": 3,
  "failed": 0,
  "totalScreenshots": 3,
  "fullpageScreenshots": 1,
  "selectorScreenshots": 0,
  "timestamp": "2026-07-24T14:30:06.789012+00:00"
}
```

***

### Use Cases

- **Visual regression testing in CI/CD** — Integrate the actor into your GitHub Actions or GitLab CI pipeline. On each deploy, capture screenshots of critical pages (homepage, login, checkout) and diff them against the previous run's images stored in the KVS. Detect unintended layout shifts, missing elements, or style regressions before they reach production.

- **Multi‑device responsive audit** — Run the same URL through all three device presets in a single batch to verify responsive breakpoints. Capture desktop, tablet, and mobile views simultaneously and compare layouts side‑by‑side. Identify content that is hidden, truncated, or overlapping at specific viewport widths.

- **Competitor landing page monitoring** — Schedule weekly runs targeting competitor homepages, pricing pages, and feature announcements. Track visual changes over time — new product banners, redesigned CTAs, updated testimonials. Archive screenshots for competitive intelligence reports and market analysis presentations.

- **Content archive and digital preservation** — Capture full‑page screenshots of documentation, blog posts, news articles, and policy pages for permanent archival. The KVS stores images indefinitely, providing a timestamped visual record that survives CMS redesigns, content deletions, or domain changes.

- **Widget and component QA** — Use CSS selector mode to isolate specific UI components (navigation bars, cookie consent banners, search result cards, product grids). Capture each component across multiple viewports and formats to verify rendering, responsive behaviour, and visual consistency across the site.

- **Phishing and brand abuse documentation** — Security researchers can document malicious websites by capturing full‑page screenshots as evidence. The deterministic naming and KVS storage provide a forensically sound chain of custody. Batch mode processes multiple suspected phishing URLs in one run.

- **SEO preview generation** — Generate thumbnail previews of web pages for internal dashboards, link previews in messaging platforms, or visual sitemaps. The `screenshotUrl` field provides a directly embeddable image URL — no additional CDN or file hosting required.

- **Onboarding flow verification** — Capture screenshots of multi‑step onboarding flows (signup, email verification, profile setup, first action) to verify visual correctness across browser environments. Use custom delay values to account for server‑side rendering and third‑party script initialisation.

***

### FAQ

**What is the maximum number of URLs I can process in a single run?**
Up to 50 URLs per run when using `batchMode: true`. Each URL is processed sequentially to prevent resource exhaustion and ensure capture reliability. For larger workloads, split your URLs across multiple runs or use the Apify scheduler for periodic processing.

**Which image format should I choose?**
Use **PNG** when pixel accuracy matters — UI mockups, design reviews, text‑heavy content, or any scenario where image quality cannot be compromised. Use **JPEG** for photo‑heavy pages or bandwidth‑sensitive pipelines where smaller file sizes are more important than lossless quality. Use **WebP** when your downstream consumers support it (Chrome, Edge, Opera, and modern CDNs) — it provides 25–35% better compression than JPEG at equivalent quality.

**Does the actor support authentication or login‑gated pages?**
Not directly. The actor is designed for publicly accessible websites. If you need to screenshot pages behind a login, you would need to handle authentication externally and pass a session cookie or authentication token — this is beyond the current scope. Pages that return HTTP 401 or 403 are reported as failed captures.

**How long are screenshots stored in the Key‑Value Store?**
Screenshots persist in the KVS for the duration of the actor run's default retention period (typically 7 days for free accounts, indefinite for paid plans). You can download images to your own storage using the `screenshotUrl` field. For permanent retention, use the Apify KVS API to export records to your own S3/GCS bucket.

**What happens if a URL takes too long to load?**
The actor has a 30‑second navigation timeout per URL. If the page does not reach `networkidle` within that window, the capture is abandoned with a "Navigation timed out" error and no charge is incurred. This prevents a single slow page from blocking an entire batch run.

**Will the screenshots include cookie consent banners or pop‑ups?**
Yes, unless you use `delay: 0` and the page loads them asynchronously after the initial render. Many cookie consent scripts, newsletter pop‑ups, and interstitial ads load after `networkidle`. If you want to exclude them, consider using a CSS selector to target the main content area only, or pipe the URL through a consent‑management proxy before submitting.

**Does full‑page capture work on infinite‑scroll pages?**
Full‑page mode captures the document at its current scroll height. For pages where content loads dynamically as you scroll (infinite scroll feeds, virtualised lists), the actor captures only the content that was rendered at load time. It does not simulate scroll events to trigger further content loading. For such pages, use viewport‑only mode or increase the `delay` to allow initial lazy‑loading to complete.

**Can I specify different settings for each URL in a batch?**
Yes. Every item in `batchData` supports its own `device`, `fullPage`, `delay`, `cssSelector`, `width`, `height`, `format`, and `quality` fields. Any field not set at the item level falls back to the top‑level default. This lets you mix desktop and mobile captures, different formats, and different full‑page flags in the same batch.

**What happens if my batch contains a mix of valid and invalid URLs?**
Invalid URLs (empty, malformed, or non‑HTTP schemes) are caught during input validation and the entire run is rejected with a clear error message — no charges are incurred. Valid URLs that fail at capture time (timeouts, network errors, SSL issues) are reported individually with `success: false` and a descriptive `error` field. Only the successful captures in the batch trigger charges.

**Is the screenshot truly pixel‑perfect?**
The Playwright Chromium engine renders pages identically to standard Chrome/Edge. However, subtle differences may occur compared to Safari (WebKit) or Firefox (Gecko) due to browser engine rendering differences. The screenshot is an accurate representation of how the page renders in Chromium at the specified viewport dimensions. Font rendering, sub‑pixel anti‑aliasing, and system‑level CSS features (scrollbar styling, accent colours) may vary slightly from a native desktop browser.

**Does the actor support JavaScript‑heavy single‑page applications (SPAs)?**
Yes. Playwright waits for `networkidle` before capturing, which means all XHR/fetch requests triggered by React, Vue, Angular, or Svelte applications must settle first. The optional `delay` parameter provides an additional safety margin for SPAs with lazy‑loaded routes, code‑splitting, or deferred third‑party scripts.

**How are duplicate URLs handled in batch mode?**
Duplicate URLs are processed independently — each gets its own browser context and separate screenshot. If you submit the same URL twice in `batchData`, you get two separate captures with different timestamps and screenshot keys. There is no deduplication logic; duplicates are treated as distinct tasks.

**Can I use this actor to monitor my own website for visual changes?**
Yes. Schedule the actor to run daily/weekly via the Apify scheduler and compare `screenshotUrl` outputs across runs. The deterministic naming convention (domain + timestamp) makes it straightforward to build a visual diff pipeline. Use external tools like `pixelmatch` or `resemble.js` to compare the downloaded PNG buffers and flag differences beyond a configurable threshold.

**What formats are available for the metadata output?**
The primary output format is JSON pushed to the Apify dataset. The dataset can be exported via the Apify API in JSON, CSV, XML, RSS, Excel, or HTML formats. The screenshot image itself is stored as a binary record in the KVS with the appropriate `Content-Type` header for direct browser rendering.

***

### Usage & Billing

The actor uses a **pay‑per‑event** pricing model. You are charged only for events that are successfully processed. The following table describes each chargeable event:

| Event Name | Price (USD) | Trigger Condition |
|------------|-------------|-------------------|
| `apify-actor-start` | $0.005 | Fired once when the actor run starts. Always applies. |
| `screenshot-capture` | $0.025 | Fired per successfully captured screenshot. **Not charged for failed captures.** |
| `fullpage-capture` | $0.015 | Surcharge per screenshot captured in full‑page mode (`fullPage: true`). Stacked on top of `screenshot-capture`. |
| `batch-process` | $0.01 | Surcharge fired once when `batchMode` is `true`. Applies regardless of how many items are in the batch. |
| `selector-capture` | $0.01 | Surcharge per screenshot captured with a CSS selector (`cssSelector` is set). Stacked on top of `screenshot-capture`. |

**Charge stacking example — batch full‑page selector capture:**
A batch run with 10 URLs, all using `fullPage: true` and `cssSelector: "#main"` would incur:

- 1 × `apify-actor-start` = $0.005
- 1 × `batch-process` = $0.010
- 10 × `screenshot-capture` = $0.250
- 10 × `fullpage-capture` = $0.150
- 10 × `selector-capture` = $0.100
- **Total = $0.515**

**Charge exclusion example — single URL that times out:**
A single‑URL run where the page fails to load would incur only:

- 1 × `apify-actor-start` = $0.005
- **Total = $0.005**

The minimum charge per run is **$0.10**. The maximum charge per run is capped at **$0.10** for runs with no successful captures (just the start event), scaling proportionally for successful captures. Platform usage fees (Apify compute, storage, and bandwidth) are billed separately by Apify based on your account plan.

***

### MCP Integration

The **Website Screenshot Generator** is available through the Apify MCP (Model Context Protocol) server, enabling AI assistants like Claude Desktop, Cursor, and VS Code to capture website screenshots on demand.

#### Quick Start

Connect your AI assistant to the Apify MCP server and use natural language prompts to trigger screenshot captures. The MCP server handles authentication via OAuth — no API keys needed for browser‑equipped clients.

#### Example Prompts

> "Capture a full‑page screenshot of example.com as a PNG at desktop resolution."
>
> "Take mobile viewport screenshots of example.com and example.org, both as JPEG at 85% quality."
>
> "Screenshot the main content area of example.com using CSS selector '#content' and save as WebP."

#### Claude Desktop Configuration

Add this to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com"
    }
  }
}
```

> **Note:** On first connection, your browser opens to sign in to Apify and authorise access. No manual token configuration is needed for desktop clients.

#### Bearer Token Alternative

For headless/CI/CD clients (Cursor, VS Code, custom scripts) that cannot perform browser‑based OAuth, use the Bearer token configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com",
      "headers": {
        "Authorization": "Bearer YOUR_APIFY_TOKEN"
      }
    }
  }
}
```

Replace `YOUR_APIFY_TOKEN` with your [Apify API token](https://console.apify.com/account/integrations).

#### How It Works

The Apify MCP server exposes all published actors as discoverable tools. Once connected, your AI assistant can search for "Website Screenshot Generator" (or any actor) using the built‑in discovery tools, then invoke it with structured parameters — all through natural language. The actor runs on Apify's infrastructure, and results (screenshot URLs, metadata) are returned directly to the assistant.

For more details, visit the [Apify MCP documentation](https://docs.apify.com/integrations/mcp).

***

### Related Tools

- [**OG Preview Generator**](https://apify.com/perryay/og-preview-generator) — Extract and validate Open Graph meta tags (og:title, og:description, og:image, twitter:card) from any URL. Generate structured preview cards for social media sharing. Pairs with screenshot captures for complete visual preview workflows.

- [**Favicon Downloader & Converter**](https://apify.com/perryay/favicon-downloader-converter) — Detect, analyse, and download favicons from any website. Scans HTML link tags and standard paths to find every available icon. Combine with screenshot captures for complete website visual profiling.

- [**URL Health**](https://apify.com/perryay/url-health) — Comprehensive URL diagnostics: HTTP status codes, response times, redirect chain analysis, SSL/TLS certificate validation, and content‑type detection. Run alongside screenshots to capture both the visual and structural health of web pages.

- [**Link Quality Analyzer**](https://apify.com/perryay/link-quality-analyzer) — Analyse link quality across web pages: broken links, redirect chains, anchor text relevance, and link density. Use with screenshot captures for full‑spectrum page quality assessment.

- [**Content Readability Analyzer**](https://apify.com/perryay/content-readability-analyzer) — Score web page content against 6 readability formulas (Flesch Reading Ease, Flesch‑Kincaid Grade Level, Gunning Fog, Coleman‑Liau, SMOG, Automated Readability Index). Pair with screenshots for visual + textual content analysis.

- [**Website Tech Stack Detector**](https://apify.com/perryay/website-tech-stack-detector) — Identify technologies powering any website: CMS, frameworks, analytics, CDNs, and server software. Use alongside screenshot captures for comprehensive website profiling during competitive intelligence or migration planning.

- [**JSON Studio**](https://apify.com/perryay/json-studio) — Format, validate, diff, transform, and explore JSON documents. Useful for post‑processing screenshot metadata and integrating structured capture results into data pipelines.

# Actor input Schema

## `url` (type: `string`):

URL of the website to screenshot (required when batchMode is false).

## `batchData` (type: `array`):

Array of objects for batch screenshot capture (max 50). Each object supports: url (required), device, fullPage, delay, cssSelector, width, height, format, quality.

## `batchMode` (type: `boolean`):

Enable batch processing mode. When true, provide batchData array. When false, provide a single url.

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

Device preset for viewport dimensions. Overridden by custom width/height. Defaults to desktop if not set.

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

Capture the full scrollable page height (true) or just the visible viewport (false).

## `delay` (type: `integer`):

Delay in milliseconds to wait before capturing the screenshot. Useful for pages with animations or lazy-loaded content. Max: 60000ms (60s).

## `width` (type: `integer`):

Custom viewport width in pixels. Overrides device preset. Min: 320, Max: 7680.

## `height` (type: `integer`):

Custom viewport height in pixels. Overrides device preset. Min: 240, Max: 4320.

## `cssSelector` (type: `string`):

CSS selector to target a specific element on the page. Only this element will be captured in the screenshot. Example: '#main-content', '.hero-banner', 'img.hero-logo'.

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

Output image format. PNG (lossless, default), JPEG (lossy, smaller files), WebP (modern, efficient compression).

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

Quality level for lossy formats (JPEG, WebP). 1 = lowest quality/smallest file, 100 = highest quality/largest file. Ignored for PNG format.

## Actor input object example

```json
{
  "url": "https://example.com",
  "batchData": [
    {
      "url": "https://example.com",
      "device": "desktop",
      "fullPage": true,
      "format": "png"
    },
    {
      "url": "https://example.com",
      "device": "mobile",
      "fullPage": false,
      "format": "jpeg"
    }
  ],
  "batchMode": false,
  "device": "desktop",
  "fullPage": false,
  "delay": 0,
  "width": 1920,
  "height": 1080,
  "format": "png",
  "quality": 90
}
```

# Actor output Schema

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

Per-URL screenshot results in the default dataset

# 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 = {
    "url": "https://example.com",
    "batchData": [
        {
            "url": "https://example.com",
            "device": "desktop",
            "fullPage": true,
            "format": "png"
        },
        {
            "url": "https://example.com",
            "device": "mobile",
            "fullPage": false,
            "format": "jpeg"
        }
    ],
    "delay": 0,
    "width": 1920,
    "height": 1080,
    "quality": 90
};

// Run the Actor and wait for it to finish
const run = await client.actor("perryay/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 = {
    "url": "https://example.com",
    "batchData": [
        {
            "url": "https://example.com",
            "device": "desktop",
            "fullPage": True,
            "format": "png",
        },
        {
            "url": "https://example.com",
            "device": "mobile",
            "fullPage": False,
            "format": "jpeg",
        },
    ],
    "delay": 0,
    "width": 1920,
    "height": 1080,
    "quality": 90,
}

# Run the Actor and wait for it to finish
run = client.actor("perryay/website-screenshot-generator").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 '{
  "url": "https://example.com",
  "batchData": [
    {
      "url": "https://example.com",
      "device": "desktop",
      "fullPage": true,
      "format": "png"
    },
    {
      "url": "https://example.com",
      "device": "mobile",
      "fullPage": false,
      "format": "jpeg"
    }
  ],
  "delay": 0,
  "width": 1920,
  "height": 1080,
  "quality": 90
}' |
apify call perryay/website-screenshot-generator --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Website Screenshot Generator",
        "description": "Capture screenshots of any website using Playwright headless browser. Full-page or viewport capture. Supports batch mode (up to 50 URLs), device presets (desktop/tablet/mobile), CSS selector targeting, PNG/JPEG/WebP output.",
        "version": "1.0",
        "x-build-id": "6vOuQsDRAfIZr9dKz"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/perryay~website-screenshot-generator/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-perryay-website-screenshot-generator",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/perryay~website-screenshot-generator/runs": {
            "post": {
                "operationId": "runs-sync-perryay-website-screenshot-generator",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/perryay~website-screenshot-generator/run-sync": {
            "post": {
                "operationId": "run-sync-perryay-website-screenshot-generator",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "url": {
                        "title": "Single URL",
                        "type": "string",
                        "description": "URL of the website to screenshot (required when batchMode is false)."
                    },
                    "batchData": {
                        "title": "Batch Data",
                        "type": "array",
                        "description": "Array of objects for batch screenshot capture (max 50). Each object supports: url (required), device, fullPage, delay, cssSelector, width, height, format, quality.",
                        "default": []
                    },
                    "batchMode": {
                        "title": "Batch Mode",
                        "type": "boolean",
                        "description": "Enable batch processing mode. When true, provide batchData array. When false, provide a single url.",
                        "default": false
                    },
                    "device": {
                        "title": "Device Preset",
                        "enum": [
                            "desktop",
                            "tablet",
                            "mobile"
                        ],
                        "type": "string",
                        "description": "Device preset for viewport dimensions. Overridden by custom width/height. Defaults to desktop if not set.",
                        "default": "desktop"
                    },
                    "fullPage": {
                        "title": "Full Page Capture",
                        "type": "boolean",
                        "description": "Capture the full scrollable page height (true) or just the visible viewport (false).",
                        "default": false
                    },
                    "delay": {
                        "title": "Capture Delay (ms)",
                        "minimum": 0,
                        "maximum": 60000,
                        "type": "integer",
                        "description": "Delay in milliseconds to wait before capturing the screenshot. Useful for pages with animations or lazy-loaded content. Max: 60000ms (60s).",
                        "default": 0
                    },
                    "width": {
                        "title": "Custom Viewport Width (px)",
                        "minimum": 320,
                        "maximum": 7680,
                        "type": "integer",
                        "description": "Custom viewport width in pixels. Overrides device preset. Min: 320, Max: 7680."
                    },
                    "height": {
                        "title": "Custom Viewport Height (px)",
                        "minimum": 240,
                        "maximum": 4320,
                        "type": "integer",
                        "description": "Custom viewport height in pixels. Overrides device preset. Min: 240, Max: 4320."
                    },
                    "cssSelector": {
                        "title": "CSS Selector",
                        "type": "string",
                        "description": "CSS selector to target a specific element on the page. Only this element will be captured in the screenshot. Example: '#main-content', '.hero-banner', 'img.hero-logo'."
                    },
                    "format": {
                        "title": "Image Format",
                        "enum": [
                            "png",
                            "jpeg",
                            "webp"
                        ],
                        "type": "string",
                        "description": "Output image format. PNG (lossless, default), JPEG (lossy, smaller files), WebP (modern, efficient compression).",
                        "default": "png"
                    },
                    "quality": {
                        "title": "Image Quality (JPEG/WebP)",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Quality level for lossy formats (JPEG, WebP). 1 = lowest quality/smallest file, 100 = highest quality/largest file. Ignored for PNG format."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
