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

Capture bulk website screenshots and downloadable PDFs with full-page, element, mobile, dark-mode, and overlay-hiding controls.

- **URL**: https://apify.com/fetch_cat/website-screenshot-generator.md
- **Developed by:** [Fetch Cat](https://apify.com/fetch_cat) (community)
- **Categories:** Developer tools, SEO tools, Automation
- **Features:** Limited permissions
- **Stats:** 37 total users, 8 monthly users, 90.8% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.00 / 1,000 capture extracteds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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?

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

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

## How to integrate an Actor?

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

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

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

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

# README

Capture public web pages as PNG or JPEG images or A4 PDF files, with viewport, full-page or visible-element controls. Keep saved-file references and capture metadata in a dataset for your own review and reports. Browser output can vary with page timing, country, cookie state and viewport, and a capture is not a certified complete website archive.

### Quick start

Start with one known public page and a small batch before adding selectors or broader capture lists. The existing example captures Example Domain and Apify documentation:

```json
{
  "startUrls": [
    { "url": "https://example.com" },
    { "url": "https://docs.apify.com" }
  ],
  "screenshotType": "fullPage",
  "outputFormat": "png",
  "viewport": {
    "width": 1366,
    "height": 768,
    "deviceScaleFactor": 1,
    "isMobile": false
  },
  "waitUntil": "auto",
  "delayMs": 1000,
  "hideSelectors": [".cookie-banner"],
  "maxFullPageHeight": 20000,
  "captureTimeoutSecs": 60,
  "maxRetries": 2,
  "maxConcurrency": 2,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

Prefer a video guide? This short Apify walkthrough shows you how to set up and run an Actor. It uses a different Actor, but the setup steps are the same.

https://youtu.be/1OW8gOqlZbY?t=25

### Ready-to-run examples

Open an example, review the input, and run it as-is or adjust the URLs:

- **[Full-page website screenshot](https://apify.com/fetch_cat/website-screenshot-generator/examples/full-page-website-screenshot)**: Capture a whole public page as a PNG.
- **[CSS selector element screenshot](https://apify.com/fetch_cat/website-screenshot-generator/examples/css-selector-element-screenshot)**: Capture a specific visible page element.
- **[Web page to PDF capture](https://apify.com/fetch_cat/website-screenshot-generator/examples/web-page-to-pdf-capture)**: Save public pages as PDF files.

### What you get

Successful captures have a saved screenshot or PDF in the run's key-value store and a dataset row containing its key, record URL and page context. Failed attempts have error information instead of a successful-file claim. Full-page images are clipped at the configured height, 3840 CSS-pixel width or 8-million-physical-pixel safety cap, whichever applies first, with truncation and original document height reported.

### Who is it for?

- **Frontend and QA teams** collecting visual evidence for their own release comparisons.
- **Marketing teams** retaining dated public landing-page observations.
- **Agencies and researchers** preparing source-linked screenshot or PDF material for reports.
- **Automation developers** passing saved capture files and outcome metadata into existing workflows.

### How you can use the data

- **Prepare a release comparison baseline.** Capture the same known public page before and after a change using consistent viewport and timing settings. Store both files and capturedAt in your destination, performing the visual comparison yourself rather than expecting a built-in regression verdict.
- **Review a mobile or dark-mode view.** Set the documented viewport and preferred color scheme, then inspect the actual saved image. Sites must honor the requested scheme, and viewport emulation does not certify behavior on every physical device.
- **Capture a visible content region.** Use a known selector such as main and an optional wait selector, reviewing errors when it is absent or not visible. Hiding known overlays changes the capture appearance without submitting consent choices or modifying the source website.
- **Save a documentation PDF for a report.** Select PDF and retain pdfKey, pdfUrl, finalUrl and collection time. PDF ignores screenshotType and selector and keeps the complete document rather than silently dropping pages. PDF files over 32 MiB are rejected without retry or a successful-capture charge. A long full-page image can instead be clipped, so choose the output appropriate for your report.

Customer max-cost and platform timeout limits are checked before capture work. If the remaining allowance cannot cover startup plus a capture, or there is too little time for useful work and saving, the run succeeds with a warning and a `limitStop` reason in `RUN_SUMMARY`. Completed captures are retained. Actual page, storage and billing failures still fail the run, including incomplete mixed batches.

### Input settings

| Setting | JSON key | Use it for | Example |
| --- | --- | --- | --- |
| Page URLs | `startUrls` | Required list of 1–1000 public HTTP/HTTPS page URLs. | `[{"url":"https://example.com"}]` |
| Screenshot type | `screenshotType` | Capture `viewport` or `fullPage` images. Ignored for PDF output. | `fullPage` |
| Output format | `outputFormat` | Choose `png`, `jpeg`, or `pdf`. | `png` |
| Viewport | `viewport` | Set browser width, height, device scale, and mobile mode. | `{"width":1366,"height":768,"isMobile":false}` |
| Wait until | `waitUntil` | Automatic content/image checks (new omitted-input default), or an explicit page milestone. | `auto` |
| Extra delay in milliseconds | `delayMs` | Wait after load for animations or late-rendered widgets. | `1000` |
| Element selector | `selector` | Capture only the first matching visible element for image output. | `main` |
| Wait for selector | `waitForSelector` | Wait until client-rendered content becomes visible. | `.results` |
| Hide elements | `hideSelectors` | Hide matching overlays before capture. | `[".cookie-banner",".sticky-ad"]` |
| JPEG quality | `jpegQuality` | Set JPEG quality from 1 to 100. | `85` |
| Color scheme | `colorScheme` | Emulate `light`, `dark`, or `no-preference`. | `dark` |
| Device preset | `device` | Capture as `iphone_14`, `iphone_se`, `pixel_7`, `galaxy_s9`, `ipad_pro` or `desktop_hd` (size, density, touch and browser identity). Viewport fields you set override it. | `iphone_14` |
| Browser language | `locale` | Language/region the browser reports. | `de-DE` |
| Time zone | `timezoneId` | IANA time zone the browser reports. | `Europe/London` |
| User agent | `userAgent` | Custom browser identity string. | `Mozilla/5.0 …` |
| Custom CSS | `customCss` | CSS added to each page before capture. | `header{display:none}` |
| Block ads and trackers | `blockAdsAndTrackers` | Block common ad and analytics networks for cleaner captures. | `true` |
| Capture console errors | `captureConsoleErrors` | Save up to 50 console and uncaught page errors per page. | `true` |
| Maximum full-page height | `maxFullPageHeight` | Set a CSS-pixel height ceiling. Full-page images also obey width and physical-pixel safety caps. | `20000` |
| Timeout per page | `captureTimeoutSecs` | Bound each navigation and capture attempt. | `60` |
| Retries per page | `maxRetries` | Retry transient proxy, navigation, and rendering failures. | `2` |
| Capture time budget | `runTimeSecs` | Bound browser work and retain completed results when time runs out. A separate 585-second lifecycle watchdog fails stalled initialization, storage or shutdown. | `570` |
| Maximum concurrent pages | `maxConcurrency` | Requested upper bound. The current safety ceiling is one active page, including saving its file. | `2` |
| Proxy configuration | `proxyConfiguration` | Managed proxy by default. Existing customer proxies and explicit direct settings are respected, without a paid fallback. | `{"useApifyProxy":true}` |

### Output data

The existing illustrative Example Domain row shows shape rather than a fresh capture:

```json
{
  "url": "https://example.com/",
  "finalUrl": "https://example.com/",
  "statusCode": 200,
  "title": "Example Domain",
  "screenshotKey": "0001-example-com.png",
  "screenshotUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/0001-example-com.png?signature=SIGNATURE",
  "pdfKey": null,
  "pdfUrl": null,
  "width": 1366,
  "height": 768,
  "fullPageHeight": 768,
  "truncated": false,
  "format": "png",
  "capturedAt": "2026-07-03T10:00:00.000Z",
  "error": null
}
```

The Actor saves screenshots/PDFs in the default key-value store and writes dataset rows for completed captures or final page errors. URLs not started before a time or charge limit do not receive a fabricated row. Check `RUN_SUMMARY` alongside the dataset. A hard lifecycle timeout fails the run rather than reporting successful emptiness. Previously saved files and rows remain available, but a final summary or in-flight storage/billing operation may be incomplete. Check the run status too.

| Field | Description |
| --- | --- |
| `url` | Requested public URL |
| `finalUrl` | Final browser URL after redirects |
| `statusCode` | HTTP response status code when available |
| `title` | Browser page title |
| `screenshotKey` | Key-value store key for PNG/JPEG captures |
| `screenshotUrl` | Signed link to the saved screenshot record that opens without signing in to Apify |
| `pdfKey` | Key-value store key for PDF captures |
| `pdfUrl` | Signed link to the saved PDF record that opens without signing in to Apify |
| `width` | Captured rectangle width in CSS pixels. Image-file pixels also reflect device scale. |
| `height` | Captured rectangle height in CSS pixels. Image-file pixels also reflect device scale. |
| `fullPageHeight` | Original measured document height in CSS pixels for full-page image requests |
| `truncated` | Whether a full-page image was clipped by the height, width or physical-pixel safety cap |
| `format` | Output format: `png`, `jpeg`, or `pdf` |
| `capturedAt` | ISO timestamp for the capture attempt |
| `error` | Error message when capture failed |
| `device` | Device preset used, or null |
| `blockedAdRequests` | Ad and tracker requests blocked on the page when blocking is on, otherwise null |
| `consoleErrors` | Console and uncaught page errors when capture is on, otherwise null |

#### Download your results

Open your run's dataset, choose **Export** and select JSON, CSV or Excel. JSON keeps nested fields together. CSV and Excel are useful when you want to review the records in a spreadsheet.

See [Apify's download and export guide](https://docs.apify.com/storage/dataset#apify-console) for the available formats and field options.

### Pricing

This Actor uses pay-per-event pricing. The `start` event is charged once when a run starts, and the `capture` event is charged once for each screenshot or PDF that is successfully saved. Failed capture attempts are not charged as successful captures.

From 19 November 2026 (00:00 UTC), platform usage is included in the event prices, so you no longer pay separate compute or storage charges for a run. Before that time, platform usage is charged separately. Higher-volume Apify plans pay a lower price per capture.

The run-start fee applies even when no capture succeeds. Failed captures do not incur a capture fee. See the live [Apify Pricing tab](https://apify.com/fetch_cat/website-screenshot-generator/pricing) for the effective rates and billing terms.

### Tips for best results

- **Start with one URL**: Confirm the site renders correctly before adding a large list.
- **Use Automatic first**: The default starts at DOM readiness, verifies visible content and important visible images, and prepares lazy content with bounded scrolling for full-page images and PDFs. Explicit `domcontentloaded`, `load` and `networkidle` settings remain available. Saved/API inputs specifying a mode keep that choice.
- **Add a small delay**: Use `delayMs` for animations, cookie banners, or client-rendered content.
- **Prefer a selector for app content**: `waitForSelector` is more predictable than a long fixed delay.
- **Hide known overlays**: Add their CSS selectors to `hideSelectors`. The Actor does not try to guess consent choices.
- **Use smaller captures for demanding pages**: The default run memory is 2048 MiB. One page is active at a time for safety. Lower viewport dimensions or device scale to reduce image memory. For very heavy full-page captures involving thousands of requests or multi-thousand-pixel pages, set run memory to 4096 MiB. One known input peaked at approximately 2.2 GB.
- **Use the default connection**: Managed proxy is the existing default for cloud captures. Managed browser requests use a stable proxy session within each capture attempt and HTTP/1.1. A retry uses a fresh session within the same configured pool and country. Retry counts, requested readiness and resource limits are unchanged. Direct access may fail in the cloud. Country, proxy groups and customer proxy settings remain configurable, and Direct and customer proxy pools keep their existing transport.
- **Check the key-value store**: Screenshot and PDF files are stored there. The dataset keeps their keys and URLs.
- **Check `RUN_SUMMARY`**: It reports requested, successful, failed, and time-budget-stopped counts for automation.

### Limits and caveats

- The actor captures public HTTP/HTTPS pages.
- Private, loopback, link-local, and reserved network destinations are rejected, including redirects and browser subrequests.
- Private, login-gated, paywalled, or bot-blocked pages may fail or show limited content.
- With Automatic readiness, a page that answers with an interim security check (HTTP 202) or a non-retryable client error such as 403 or 404 fails promptly with that status and is not retried or charged. HTTP 429 rate limits, server errors and connection timeouts still use the configured bounded retries. A retry must reach verified useful content before a capture is saved or charged.
- CSS selector captures require the target element to be visible within the timeout.
- PDF output ignores `screenshotType` and `selector`.
- Images are limited to 8,000,000 physical pixels, including the square of `deviceScaleFactor`. Full-page images are clipped at that budget, 3840 CSS-pixel width or `maxFullPageHeight`, and return `truncated: true` when clipped. Oversized viewport requests reject before browser work. Oversized element captures return a per-page error without encoding or retrying. A single measured rectangle is captured, so later page growth cannot expand the image buffer.
- Only one browser page is active at a time, including navigation, encoding and file persistence, even when the requested `maxConcurrency` is higher. This safety ceiling can make batches slower. Image caps do not bound arbitrary page DOM, downloaded resources or PDF layout memory. Large pages and PDFs can still exhaust browser memory.
- Automatic preparation scrolls at most 12 steps for at most 15 seconds within existing capture/run deadlines and the image capture rectangle, then restores the original scroll position. PDFs use a separate bounded preparation distance and retain complete-document output. Infinite feeds, delayed embeds, CSS backgrounds and content outside the prepared area may remain incomplete. Rows expose `automaticPreparation` and warnings for unfinished lower images, scrolling limits and capture before full page load. A verified capture does not prove every resource or lazy section finished.
- Each page attempt is limited to 2,000 browser requests for Automatic and `networkidle`, or 1,000 for other explicit modes, and the remaining run time. Exceeding either budget closes that page promptly and returns an error without retrying or charging for an unverified capture. Other pages can still proceed. Persistent background traffic can prevent `networkidle`. After its full navigation timeout, a successful matching main HTTP 200–399 response that reaches page load may still be captured with a clear warning. Rows report `requestedWaitUntil`, `usedWaitUntil`, `readinessFallback` and `warnings`. `RUN_SUMMARY` counts successful fallback captures and the final status message highlights them. If the bounded page-load wait also times out, image output on `/products/SLUG` pages can use DOMContentLoaded only with a matching current main HTTP 200, a visible `h1.title` matching both slug words and the page title, and a visible loaded image at least 200×200 pixels. Missing/wrong headings, unloaded images and detected challenge pages reject this narrow fallback. Product content and document identity are checked again after the configured delay. PDF and unrelated pages do not use this DOM fallback. The warning explicitly identifies incomplete background/lazy content: `truncated: false` means the raster was not clipped, NOT that every review, image or lazy section loaded. Neither fallback proves network idle or complete content. Selector checks and extra delay still apply. Main navigation/access failures, crashes, closed pages, request/deadline limits and storage/billing failures are not converted to successful fallback. On non-Pinterest pages, only fetch submissions to the exact Pinterest advertising-conversion endpoint `https://ct.pinterest.com/v3/` are canceled to avoid stalled nonvisual tracking responses. Pinterest images, scripts, frames and other endpoints remain available. Captures of Pinterest itself keep all its requests. For `networkidle`, readiness requires the main document to reach DOMContentLoaded and all page-frame requests to finish or fail, followed by at least 500 ms without network activity within the original navigation timeout. A stale browser-library lifecycle flag does not extend that timeout. If real requests remain pending at timeout, only the explicitly warned load or narrowly gated product-content fallback described above is possible. Visible frames, page widgets and analytics frames retain their requests.
- Batches whose post-load delays alone cannot fit the processing budget (run time minus a five-second reserve) finish successfully without captures, DNS checks, proxy setup or capture-event billing. The run status message and `RUN_SUMMARY` explicitly warn that no captures were attempted, with `invalidInput: true` and a corrected recipe. This is not capture success. For example, 80 unique pages with a 30-second delay require at least 2,400 seconds of delays, exceeding the default 570-second budget. Split the URLs into smaller runs or reduce `delayMs`. No URLs are silently dropped and higher concurrency does not bypass the one-page ceiling. Admission is not a completion guarantee: navigation, rendering and storage also need time.
- A batch can finish with partial results when individual pages fail or time or charge limits stop further work. If no capture budget remains before browser work starts, the dataset stays empty and `RUN_SUMMARY` reports the charge limit.
- Invalid configuration, essential storage or billing failures still fail the run, even after some useful output was saved. Navigation failures are not proof that a page is private or deleted. If every attempted page fails, the run fails.
- Very request-heavy pages may be stopped with an explicit capture error rather than presented as verified complete captures.
- Restarts and resurrection do not replay an already started run. Existing saved output remains available. Start a new run for another capture.
- Some sites render different content by country, cookie state, viewport, or bot detection.

This actor captures publicly accessible web pages.

Use screenshots and PDFs responsibly, follow the target website's terms, Apify's terms, and applicable laws, and do not use the actor to bypass access controls.

#### Privacy and data handling

This Actor runs with Apify limited permissions and only processes data needed for the documented run. It uses the inputs you provide and the public records needed to produce the documented dataset to produce the output dataset and sends requests to the website URLs you provide. Results are stored in Apify run storage for your account. FetchCat does not use your inputs or outputs for advertising, does not use them for model training, and does not retain them outside the Apify run except for transient support debugging when you explicitly share run details. You are responsible for using the Actor lawfully, respecting the target site's terms, and avoiding unnecessary personal or sensitive data in inputs.

### Automation and integrations

#### Save your settings for next time

Once you have an input that works for you, [save it as an Apify task](https://docs.apify.com/actors/running/tasks). This keeps your settings together so you can use them again without filling in the form from scratch.

#### Run on a schedule

Need fresh results regularly? You can [schedule the Actor or a saved task](https://docs.apify.com/actors/running/schedules) to run at a time that suits you.

Each scheduled run collects the data again. If you want to compare results or highlight changes, add that step in your own workflow.

#### Send results to your other tools

Use **n8n, Make or Zapier** to connect this scraper to the rest of your workflow. For example, you could pass its results to an AI assistant or add records to a spreadsheet. Follow the [Apify integration guides](https://docs.apify.com/integrations) for your chosen tool.

For a custom connection, an [Apify webhook](https://docs.apify.com/integrations/webhooks) can notify your app when a run finishes or fails. Your app can then fetch the results or handle the failure.

### API usage

Want to collect this data from your own app or automation? The examples below send input to the scraper and show how to collect its results.

The Node.js and Python examples wait for the run to finish before reading its results. The cURL example starts the run and returns its details. Wait for that run to finish, then use its `defaultDatasetId` to fetch the results.

For setup instructions, see Apify's [JavaScript client guide](https://docs.apify.com/api/client/js), [Python client guide](https://docs.apify.com/api/client/python) and [Actor runs API reference](https://docs.apify.com/api/v2/acts-runs-post).

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/fetch_cat~website-screenshot-generator/runs?token=YOUR_APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"startUrls":[{"url":"https://example.com"}],"screenshotType":"fullPage","outputFormat":"png"}'
```

#### Node.js

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/website-screenshot-generator').call({
  startUrls: [{ url: 'https://example.com' }],
  screenshotType: 'fullPage',
  outputFormat: 'png'
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient
import os

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("fetch_cat/website-screenshot-generator").call(run_input={
    "startUrls": [{"url": "https://example.com"}],
    "screenshotType": "fullPage",
    "outputFormat": "png",
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### MCP and AI agents

You can ask your AI assistant to collect data with **Website Screenshot Generator** and help you work with the results. The scraper returns the data, and your assistant can then summarize it, compare records or prepare notes.

Connect your assistant through the [Apify MCP server](https://mcp.apify.com/). MCP gives your assistant a way to find this scraper, run it and read the results. Follow the [official setup and sign-in guide](https://docs.apify.com/mcp) for your app.

#### Easier setup with an Apify plugin

If you use a supported coding assistant, the [official Apify plugin](https://docs.apify.com/agents/plugins) can set up the connection for you. It connects your assistant to Apify and includes instructions for common tasks. Follow the guide for your particular app.

#### Use Apify AI in Console

Prefer to keep everything in Apify? Open [Apify AI in Console](https://docs.apify.com/account/apify-ai) and ask it to find Fetch Cat's **Website Screenshot Generator**. You can describe the data you want and ask questions about the results.

Apify AI is currently in beta. It asks for confirmation before starting an Actor, and normal run charges apply.

#### Choose your assistant

- **Claude and Claude Code (Anthropic):** [Apify setup guide](https://docs.apify.com/integrations/claude).
- **ChatGPT and Codex (OpenAI):** [Apify setup guides](https://docs.apify.com/integrations/openai).
- **Grok Bot (xAI):** [Apify plugin guide](https://docs.apify.com/integrations/grok-bot).
- **Gemini CLI (Google):** [MCP server setup guide](https://geminicli.com/docs/tools/mcp-server/). Use the server URL below with the HTTP configuration supported by Gemini CLI.

#### Connect just this scraper

To keep your setup focused on this scraper, add this server configuration to a compatible MCP client:

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

Sign in to Apify when your client asks. If your client uses a Bearer token instead, follow its setup guide and keep the token in its secure configuration. Configuration formats vary by app, so use the linked guide if your client needs a different format.

#### Use Apify's general server

Already connected to the general Apify MCP server at `https://mcp.apify.com`? You can use it to find this scraper without adding another server. Ask your assistant to use **Website Screenshot Generator** by Fetch Cat, or give it the identifier `fetch_cat/website-screenshot-generator`.

Your assistant can check the available settings and retrieve the results from the returned run. If the run is still working, it should follow that run rather than start it again. Both connection options use Apify's hosted service.

#### Example requests

- “Use Fetch Cat’s Website Screenshot Generator to collect one full-page PNG capture of https://example.com with the existing 1366 by 768 viewport and load milestone. Keep the saved-file URL and any truncation or error rather than claiming a complete archive.”
- “Collect one PNG capture of the first visible main element at https://example.com, waiting for main before capture. Keep failure details if the selector is unavailable instead of guessing an element.”
- “Retrieve a PDF capture of https://docs.apify.com with the load milestone. Keep the saved PDF reference, final URL and capture time without expecting an element-only or screenshot-type setting to affect the PDF.”

Normal Apify charges apply. Check the [live Pricing tab](https://apify.com/fetch_cat/website-screenshot-generator/pricing) before asking your assistant to run a larger batch.

### Pay with x402

If your AI agent has a funded wallet, it can pay for Apify usage through [x402](https://docs.apify.com/integrations/x402). This experimental option lets an agent use Apify without a conventional account.

[Apify AGI](https://agi.apify.com/) provides a prepaid API token with a spending cap after payment. Your agent can use that token to run this scraper through the Apify API or an authenticated MCP connection.

Some MCP setups also support paying for each request directly. That is a different payment option, so check the official guide for its availability.

Follow the official guide for wallet setup, supported payment options and current terms. Apify handles the payments. Keep wallet keys and payment tokens in your agent's secure configuration.

#### Other ways for agents to pay

Apify also supports **MPP** for prepaid access through AGI and **Skyfire** for eligible Actors. If your agent already uses one of these, see the [agentic payment guide](https://docs.apify.com/agents/payments) to choose the right setup.

### FAQ

#### Are the image and PDF files downloadable?

Yes. Each successful row includes `screenshotUrl` or `pdfUrl`, and the file also appears in the run's key-value store.

#### Can it capture mobile and dark-mode pages?

Yes. Pick a `device` preset such as `iphone_14` or `pixel_7`, or set a mobile viewport and `isMobile: true`. Use `colorScheme: "dark"` for sites that honor the preferred color scheme.

#### Are failed pages charged as successful captures?

No. The `capture` event is charged only when the output file and its dataset row are saved successfully. The one-time run-start charge still applies.

#### Why was a full-page image truncated?

The page exceeded `maxFullPageHeight`. The row reports the measured `fullPageHeight` and returns `truncated: true` so automation can identify the clipped image.

#### Can cookie banners always be removed automatically?

No universal method can reliably remove every consent interface. Add the site's known CSS selectors to `hideSelectors` for a deterministic capture.

### Related Actors

Explore related actors from the same Apify account:

- [Website Content Crawler Lite](https://apify.com/fetch_cat/website-content-crawler-lite) — Collect text, Markdown, HTML, metadata and discovered links from public website pages.
- [Web Page to Markdown Extractor](https://apify.com/fetch_cat/web-page-to-markdown-extractor) — Convert public web pages into Markdown, readable text and available page metadata.
- [Website Contact Finder](https://apify.com/fetch_cat/website-contact-finder) — Find published email, phone and social profile links on known public company websites.
- [Google News Scraper](https://apify.com/fetch_cat/google-news-scraper) — Collect public Google News feed headlines, dates and links.
- [Bing SERP & Search Results Scraper](https://apify.com/fetch_cat/bing-search-results-scraper) — Collect public Bing web-search result titles, snippets and links.

### Support and feedback

For custom additions or integrations, email <hello@fetchcat.dev>.

Found an error or have a feature request? [Open an issue](https://apify.com/fetch_cat/website-screenshot-generator/issues) with the run URL, a non-sensitive input example and what you expected.

Need help sharing it? See [Apify’s guide to sharing a run when reporting an issue](https://docs.apify.com/account/collaboration/general-resource-access#automatically-sharing-runs-via-actor-issues). Sharing a run can give the developer access to its input, logs and results, so use a run that contains no sensitive data. Please leave out API tokens, passwords, cookies, private documents and personal data. Use a public sample URL or a redacted example instead.

Tried this scraper? We'd love to hear how it worked for you. [Leave a review](https://apify.com/fetch_cat/website-screenshot-generator/reviews) to help others choose the right tool and help us improve it. Your feedback means a lot to us.

Made with care for curious people, AI agents and the possibilities in data. ♥

# Changelog

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

# Actor input Schema

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

1–1000 public HTTP or HTTPS page URLs. Add one URL per page, not a remote URL list. Embedded credentials and private destinations are not supported.

## `screenshotType` (type: `string`):

Capture the viewport or a full-page image. Full-page images are clipped at the configured height, 3840 CSS-pixel width or 8-million-physical-pixel cap and marked truncated. Ignored for PDF output.

## `outputFormat` (type: `string`):

Choose PNG, JPEG, or PDF output.

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

Capture as a common phone, tablet or desktop: sets the viewport size, pixel density, mobile and touch mode and a matching browser identity. Any width, height or density you set in Viewport overrides the preset. Leave empty to use Viewport only.

## `viewport` (type: `object`):

Browser viewport in CSS pixels. Density multiplies both image axes. Viewport-only images exceeding 8,000,000 physical pixels reject before browser work; reduce dimensions or density. Full-page images are clipped to the safety budget.

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

Automatic checks visible content and important images without waiting for background traffic. Full-page images and PDFs receive bounded lazy-loading scrolling; limits and unfinished lower content are reported in warnings. Selectors and extra delay still apply. Explicit DOM, load and network-idle settings retain existing behavior, including warned load fallback and narrowly verified product DOM fallback for image output. Lazy content may remain incomplete even when truncated=false; pending requests are never reported as idle.

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

Optional delay after the selected load milestone. Pages run one at a time. If these delays alone cannot fit runTimeSecs minus a five-second reserve, the run succeeds without captures and displays an explicit invalid-recipe warning before capture work. Split the URLs into smaller runs or reduce delayMs; navigation, rendering and storage need additional time.

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

Optional CSS selector. The first visible element's measured rectangle is captured for images. Elements exceeding 8,000,000 physical pixels fail without encoding or retrying; reduce element size or density. Ignored for PDF.

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

Optional CSS selector that must become visible before capture. Use this for client-rendered content.

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

Up to 100 CSS selectors to hide before capture, for example cookie banners or sticky overlays. Each selector can contain up to 2000 characters.

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

JPEG quality from 1 to 100. Used only when output format is JPEG.

## `colorScheme` (type: `string`):

Preferred browser color scheme for sites that support light or dark mode.

## `locale` (type: `string`):

Language and region the browser reports, for example en-GB or de-DE, so sites show that language version.

## `timezoneId` (type: `string`):

IANA time zone the browser reports, for example Europe/London, so pages show local dates and times.

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

Optional browser identity string. Overrides the device preset's identity.

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

CSS added to every page before capture, for example to hide elements or change fonts. At most 20,000 characters.

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

Block requests to common advertising and analytics networks for cleaner, faster captures. Blocked request counts appear in the output.

## `captureConsoleErrors` (type: `boolean`):

Record up to 50 browser console errors and uncaught page errors per page in the output, useful for site monitoring.

## `maxFullPageHeight` (type: `integer`):

Maximum full-page image height in CSS pixels. Images also obey a 3840 CSS-pixel width and 8,000,000 physical-pixel safety cap, so actual height can be lower. Clipped images are marked truncated.

## `captureTimeoutSecs` (type: `integer`):

Maximum seconds for each navigation, selector wait or image operation, also subject to the total capture budget. A page can require several operations.

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

Retry transient navigation, proxy, and rendering failures. Validation and certificate failures are not retried.

## `runTimeSecs` (type: `integer`):

Total capture budget from input processing, independent of the platform timeout. At expiry, the browser is closed and completed results are retained. Lower platform timeouts can still interrupt the run. Restarts and resurrection do not replay captures from an already started run.

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

Requested upper bound, retained for saved-task/API compatibility. The current safety ceiling is one active page, including navigation, image/PDF encoding and file persistence. Higher requested values do not create concurrent pages.

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

Managed datacenter proxy is the existing default for omitted API inputs and new forms. Existing managed groups/countries and customer proxy URLs remain supported. Explicit useApifyProxy:false without customer proxy URLs attempts direct access, with no paid fallback. Direct cloud egress may fail. Choose either managed proxy or customer URLs, not both. Proxy and browser usage can incur platform costs even when captures fail. No new Automatic strategy is available.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://example.com"
    }
  ],
  "screenshotType": "viewport",
  "outputFormat": "png",
  "device": "",
  "waitUntil": "auto",
  "delayMs": 0,
  "hideSelectors": [],
  "jpegQuality": 85,
  "colorScheme": "no-preference",
  "blockAdsAndTrackers": false,
  "captureConsoleErrors": false,
  "captureTimeoutSecs": 60,
  "maxRetries": 2,
  "runTimeSecs": 570,
  "maxConcurrency": 2,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

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

No description

# 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"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("fetch_cat/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://example.com" }],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("fetch_cat/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://example.com"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call fetch_cat/website-screenshot-generator --silent --output-dataset

```

## MCP server setup

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